ablanco/yith-library-web-client

View on GitHub
yithwebclient/static/js/prod/vendor.js

Summary

Maintainability
A
0 mins
Test Coverage


// Source: yithwebclient/static/vendor/jquery/jquery.js

(function( window, undefined ) {

// Can't do this because several apps including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
// Support: Firefox 18+
//"use strict";
var
    // A central reference to the root jQuery(document)
    rootjQuery,

    // The deferred used on DOM ready
    readyList,

    // Support: IE9
    // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
    core_strundefined = typeof undefined,

    // Use the correct document accordingly with window argument (sandbox)
    location = window.location,
    document = window.document,
    docElem = document.documentElement,

    // Map over jQuery in case of overwrite
    _jQuery = window.jQuery,

    // Map over the $ in case of overwrite
    _$ = window.$,

    // [[Class]] -> type pairs
    class2type = {},

    // List of deleted data cache ids, so we can reuse them
    core_deletedIds = [],

    core_version = "2.0.3",

    // Save a reference to some core methods
    core_concat = core_deletedIds.concat,
    core_push = core_deletedIds.push,
    core_slice = core_deletedIds.slice,
    core_indexOf = core_deletedIds.indexOf,
    core_toString = class2type.toString,
    core_hasOwn = class2type.hasOwnProperty,
    core_trim = core_version.trim,

    // Define a local copy of jQuery
    jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor 'enhanced'
        return new jQuery.fn.init( selector, context, rootjQuery );
    },

    // Used for matching numbers
    core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,

    // Used for splitting on whitespace
    core_rnotwhite = /\S+/g,

    // A simple way to check for HTML strings
    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
    // Strict HTML recognition (#11290: must start with <)
    rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

    // Match a standalone tag
    rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,

    // Matches dashed string for camelizing
    rmsPrefix = /^-ms-/,
    rdashAlpha = /-([\da-z])/gi,

    // Used by jQuery.camelCase as callback to replace()
    fcamelCase = function( all, letter ) {
        return letter.toUpperCase();
    },

    // The ready event handler and self cleanup method
    completed = function() {
        document.removeEventListener( "DOMContentLoaded", completed, false );
        window.removeEventListener( "load", completed, false );
        jQuery.ready();
    };

jQuery.fn = jQuery.prototype = {
    // The current version of jQuery being used
    jquery: core_version,

    constructor: jQuery,
    init: function( selector, context, rootjQuery ) {
        var match, elem;

        // HANDLE: $(""), $(null), $(undefined), $(false)
        if ( !selector ) {
            return this;
        }

        // Handle HTML strings
        if ( typeof selector === "string" ) {
            if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
                // Assume that strings that start and end with <> are HTML and skip the regex check
                match = [ null, selector, null ];

            } else {
                match = rquickExpr.exec( selector );
            }

            // Match html or make sure no context is specified for #id
            if ( match && (match[1] || !context) ) {

                // HANDLE: $(html) -> $(array)
                if ( match[1] ) {
                    context = context instanceof jQuery ? context[0] : context;

                    // scripts is true for back-compat
                    jQuery.merge( this, jQuery.parseHTML(
                        match[1],
                        context && context.nodeType ? context.ownerDocument || context : document,
                        true
                    ) );

                    // HANDLE: $(html, props)
                    if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
                        for ( match in context ) {
                            // Properties of context are called as methods if possible
                            if ( jQuery.isFunction( this[ match ] ) ) {
                                this[ match ]( context[ match ] );

                            // ...and otherwise set as attributes
                            } else {
                                this.attr( match, context[ match ] );
                            }
                        }
                    }

                    return this;

                // HANDLE: $(#id)
                } else {
                    elem = document.getElementById( match[2] );

                    // Check parentNode to catch when Blackberry 4.6 returns
                    // nodes that are no longer in the document #6963
                    if ( elem && elem.parentNode ) {
                        // Inject the element directly into the jQuery object
                        this.length = 1;
                        this[0] = elem;
                    }

                    this.context = document;
                    this.selector = selector;
                    return this;
                }

            // HANDLE: $(expr, $(...))
            } else if ( !context || context.jquery ) {
                return ( context || rootjQuery ).find( selector );

            // HANDLE: $(expr, context)
            // (which is just equivalent to: $(context).find(expr)
            } else {
                return this.constructor( context ).find( selector );
            }

        // HANDLE: $(DOMElement)
        } else if ( selector.nodeType ) {
            this.context = this[0] = selector;
            this.length = 1;
            return this;

        // HANDLE: $(function)
        // Shortcut for document ready
        } else if ( jQuery.isFunction( selector ) ) {
            return rootjQuery.ready( selector );
        }

        if ( selector.selector !== undefined ) {
            this.selector = selector.selector;
            this.context = selector.context;
        }

        return jQuery.makeArray( selector, this );
    },

    // Start with an empty selector
    selector: "",

    // The default length of a jQuery object is 0
    length: 0,

    toArray: function() {
        return core_slice.call( this );
    },

    // Get the Nth element in the matched element set OR
    // Get the whole matched element set as a clean array
    get: function( num ) {
        return num == null ?

            // Return a 'clean' array
            this.toArray() :

            // Return just the object
            ( num < 0 ? this[ this.length + num ] : this[ num ] );
    },

    // Take an array of elements and push it onto the stack
    // (returning the new matched element set)
    pushStack: function( elems ) {

        // Build a new jQuery matched element set
        var ret = jQuery.merge( this.constructor(), elems );

        // Add the old object onto the stack (as a reference)
        ret.prevObject = this;
        ret.context = this.context;

        // Return the newly-formed element set
        return ret;
    },

    // Execute a callback for every element in the matched set.
    // (You can seed the arguments with an array of args, but this is
    // only used internally.)
    each: function( callback, args ) {
        return jQuery.each( this, callback, args );
    },

    ready: function( fn ) {
        // Add the callback
        jQuery.ready.promise().done( fn );

        return this;
    },

    slice: function() {
        return this.pushStack( core_slice.apply( this, arguments ) );
    },

    first: function() {
        return this.eq( 0 );
    },

    last: function() {
        return this.eq( -1 );
    },

    eq: function( i ) {
        var len = this.length,
            j = +i + ( i < 0 ? len : 0 );
        return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
    },

    map: function( callback ) {
        return this.pushStack( jQuery.map(this, function( elem, i ) {
            return callback.call( elem, i, elem );
        }));
    },

    end: function() {
        return this.prevObject || this.constructor(null);
    },

    // For internal use only.
    // Behaves like an Array's method, not like a jQuery method.
    push: core_push,
    sort: [].sort,
    splice: [].splice
};

// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;

jQuery.extend = jQuery.fn.extend = function() {
    var options, name, src, copy, copyIsArray, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    if ( typeof target === "boolean" ) {
        deep = target;
        target = arguments[1] || {};
        // skip the boolean and the target
        i = 2;
    }

    // Handle case when target is a string or something (possible in deep copy)
    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
        target = {};
    }

    // extend jQuery itself if only one argument is passed
    if ( length === i ) {
        target = this;
        --i;
    }

    for ( ; i < length; i++ ) {
        // Only deal with non-null/undefined values
        if ( (options = arguments[ i ]) != null ) {
            // Extend the base object
            for ( name in options ) {
                src = target[ name ];
                copy = options[ name ];

                // Prevent never-ending loop
                if ( target === copy ) {
                    continue;
                }

                // Recurse if we're merging plain objects or arrays
                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                    if ( copyIsArray ) {
                        copyIsArray = false;
                        clone = src && jQuery.isArray(src) ? src : [];

                    } else {
                        clone = src && jQuery.isPlainObject(src) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // Don't bring in undefined values
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
};

jQuery.extend({
    // Unique for each copy of jQuery on the page
    expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),

    noConflict: function( deep ) {
        if ( window.$ === jQuery ) {
            window.$ = _$;
        }

        if ( deep && window.jQuery === jQuery ) {
            window.jQuery = _jQuery;
        }

        return jQuery;
    },

    // Is the DOM ready to be used? Set to true once it occurs.
    isReady: false,

    // A counter to track how many items to wait for before
    // the ready event fires. See #6781
    readyWait: 1,

    // Hold (or release) the ready event
    holdReady: function( hold ) {
        if ( hold ) {
            jQuery.readyWait++;
        } else {
            jQuery.ready( true );
        }
    },

    // Handle when the DOM is ready
    ready: function( wait ) {

        // Abort if there are pending holds or we're already ready
        if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
            return;
        }

        // Remember that the DOM is ready
        jQuery.isReady = true;

        // If a normal DOM Ready event fired, decrement, and wait if need be
        if ( wait !== true && --jQuery.readyWait > 0 ) {
            return;
        }

        // If there are functions bound, to execute
        readyList.resolveWith( document, [ jQuery ] );

        // Trigger any bound ready events
        if ( jQuery.fn.trigger ) {
            jQuery( document ).trigger("ready").off("ready");
        }
    },

    // See test/unit/core.js for details concerning isFunction.
    // Since version 1.3, DOM methods and functions like alert
    // aren't supported. They return false on IE (#2968).
    isFunction: function( obj ) {
        return jQuery.type(obj) === "function";
    },

    isArray: Array.isArray,

    isWindow: function( obj ) {
        return obj != null && obj === obj.window;
    },

    isNumeric: function( obj ) {
        return !isNaN( parseFloat(obj) ) && isFinite( obj );
    },

    type: function( obj ) {
        if ( obj == null ) {
            return String( obj );
        }
        // Support: Safari <= 5.1 (functionish RegExp)
        return typeof obj === "object" || typeof obj === "function" ?
            class2type[ core_toString.call(obj) ] || "object" :
            typeof obj;
    },

    isPlainObject: function( obj ) {
        // Not plain objects:
        // - Any object or value whose internal [[Class]] property is not "[object Object]"
        // - DOM nodes
        // - window
        if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
            return false;
        }

        // Support: Firefox <20
        // The try/catch suppresses exceptions thrown when attempting to access
        // the "constructor" property of certain host objects, ie. |window.location|
        // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
        try {
            if ( obj.constructor &&
                    !core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
                return false;
            }
        } catch ( e ) {
            return false;
        }

        // If the function hasn't returned already, we're confident that
        // |obj| is a plain object, created by {} or constructed with new Object
        return true;
    },

    isEmptyObject: function( obj ) {
        var name;
        for ( name in obj ) {
            return false;
        }
        return true;
    },

    error: function( msg ) {
        throw new Error( msg );
    },

    // data: string of html
    // context (optional): If specified, the fragment will be created in this context, defaults to document
    // keepScripts (optional): If true, will include scripts passed in the html string
    parseHTML: function( data, context, keepScripts ) {
        if ( !data || typeof data !== "string" ) {
            return null;
        }
        if ( typeof context === "boolean" ) {
            keepScripts = context;
            context = false;
        }
        context = context || document;

        var parsed = rsingleTag.exec( data ),
            scripts = !keepScripts && [];

        // Single tag
        if ( parsed ) {
            return [ context.createElement( parsed[1] ) ];
        }

        parsed = jQuery.buildFragment( [ data ], context, scripts );

        if ( scripts ) {
            jQuery( scripts ).remove();
        }

        return jQuery.merge( [], parsed.childNodes );
    },

    parseJSON: JSON.parse,

    // Cross-browser xml parsing
    parseXML: function( data ) {
        var xml, tmp;
        if ( !data || typeof data !== "string" ) {
            return null;
        }

        // Support: IE9
        try {
            tmp = new DOMParser();
            xml = tmp.parseFromString( data , "text/xml" );
        } catch ( e ) {
            xml = undefined;
        }

        if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
            jQuery.error( "Invalid XML: " + data );
        }
        return xml;
    },

    noop: function() {},

    // Evaluates a script in a global context
    globalEval: function( code ) {
        var script,
                indirect = eval;

        code = jQuery.trim( code );

        if ( code ) {
            // If the code includes a valid, prologue position
            // strict mode pragma, execute code by injecting a
            // script tag into the document.
            if ( code.indexOf("use strict") === 1 ) {
                script = document.createElement("script");
                script.text = code;
                document.head.appendChild( script ).parentNode.removeChild( script );
            } else {
            // Otherwise, avoid the DOM node creation, insertion
            // and removal by using an indirect global eval
                indirect( code );
            }
        }
    },

    // Convert dashed to camelCase; used by the css and data modules
    // Microsoft forgot to hump their vendor prefix (#9572)
    camelCase: function( string ) {
        return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
    },

    nodeName: function( elem, name ) {
        return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
    },

    // args is for internal usage only
    each: function( obj, callback, args ) {
        var value,
            i = 0,
            length = obj.length,
            isArray = isArraylike( obj );

        if ( args ) {
            if ( isArray ) {
                for ( ; i < length; i++ ) {
                    value = callback.apply( obj[ i ], args );

                    if ( value === false ) {
                        break;
                    }
                }
            } else {
                for ( i in obj ) {
                    value = callback.apply( obj[ i ], args );

                    if ( value === false ) {
                        break;
                    }
                }
            }

        // A special, fast, case for the most common use of each
        } else {
            if ( isArray ) {
                for ( ; i < length; i++ ) {
                    value = callback.call( obj[ i ], i, obj[ i ] );

                    if ( value === false ) {
                        break;
                    }
                }
            } else {
                for ( i in obj ) {
                    value = callback.call( obj[ i ], i, obj[ i ] );

                    if ( value === false ) {
                        break;
                    }
                }
            }
        }

        return obj;
    },

    trim: function( text ) {
        return text == null ? "" : core_trim.call( text );
    },

    // results is for internal usage only
    makeArray: function( arr, results ) {
        var ret = results || [];

        if ( arr != null ) {
            if ( isArraylike( Object(arr) ) ) {
                jQuery.merge( ret,
                    typeof arr === "string" ?
                    [ arr ] : arr
                );
            } else {
                core_push.call( ret, arr );
            }
        }

        return ret;
    },

    inArray: function( elem, arr, i ) {
        return arr == null ? -1 : core_indexOf.call( arr, elem, i );
    },

    merge: function( first, second ) {
        var l = second.length,
            i = first.length,
            j = 0;

        if ( typeof l === "number" ) {
            for ( ; j < l; j++ ) {
                first[ i++ ] = second[ j ];
            }
        } else {
            while ( second[j] !== undefined ) {
                first[ i++ ] = second[ j++ ];
            }
        }

        first.length = i;

        return first;
    },

    grep: function( elems, callback, inv ) {
        var retVal,
            ret = [],
            i = 0,
            length = elems.length;
        inv = !!inv;

        // Go through the array, only saving the items
        // that pass the validator function
        for ( ; i < length; i++ ) {
            retVal = !!callback( elems[ i ], i );
            if ( inv !== retVal ) {
                ret.push( elems[ i ] );
            }
        }

        return ret;
    },

    // arg is for internal usage only
    map: function( elems, callback, arg ) {
        var value,
            i = 0,
            length = elems.length,
            isArray = isArraylike( elems ),
            ret = [];

        // Go through the array, translating each of the items to their
        if ( isArray ) {
            for ( ; i < length; i++ ) {
                value = callback( elems[ i ], i, arg );

                if ( value != null ) {
                    ret[ ret.length ] = value;
                }
            }

        // Go through every key on the object,
        } else {
            for ( i in elems ) {
                value = callback( elems[ i ], i, arg );

                if ( value != null ) {
                    ret[ ret.length ] = value;
                }
            }
        }

        // Flatten any nested arrays
        return core_concat.apply( [], ret );
    },

    // A global GUID counter for objects
    guid: 1,

    // Bind a function to a context, optionally partially applying any
    // arguments.
    proxy: function( fn, context ) {
        var tmp, args, proxy;

        if ( typeof context === "string" ) {
            tmp = fn[ context ];
            context = fn;
            fn = tmp;
        }

        // Quick check to determine if target is callable, in the spec
        // this throws a TypeError, but we will just return undefined.
        if ( !jQuery.isFunction( fn ) ) {
            return undefined;
        }

        // Simulated bind
        args = core_slice.call( arguments, 2 );
        proxy = function() {
            return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
        };

        // Set the guid of unique handler to the same of original handler, so it can be removed
        proxy.guid = fn.guid = fn.guid || jQuery.guid++;

        return proxy;
    },

    // Multifunctional method to get and set values of a collection
    // The value/s can optionally be executed if it's a function
    access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
        var i = 0,
            length = elems.length,
            bulk = key == null;

        // Sets many values
        if ( jQuery.type( key ) === "object" ) {
            chainable = true;
            for ( i in key ) {
                jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
            }

        // Sets one value
        } else if ( value !== undefined ) {
            chainable = true;

            if ( !jQuery.isFunction( value ) ) {
                raw = true;
            }

            if ( bulk ) {
                // Bulk operations run against the entire set
                if ( raw ) {
                    fn.call( elems, value );
                    fn = null;

                // ...except when executing function values
                } else {
                    bulk = fn;
                    fn = function( elem, key, value ) {
                        return bulk.call( jQuery( elem ), value );
                    };
                }
            }

            if ( fn ) {
                for ( ; i < length; i++ ) {
                    fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
                }
            }
        }

        return chainable ?
            elems :

            // Gets
            bulk ?
                fn.call( elems ) :
                length ? fn( elems[0], key ) : emptyGet;
    },

    now: Date.now,

    // A method for quickly swapping in/out CSS properties to get correct calculations.
    // Note: this method belongs to the css module but it's needed here for the support module.
    // If support gets modularized, this method should be moved back to the css module.
    swap: function( elem, options, callback, args ) {
        var ret, name,
            old = {};

        // Remember the old values, and insert the new ones
        for ( name in options ) {
            old[ name ] = elem.style[ name ];
            elem.style[ name ] = options[ name ];
        }

        ret = callback.apply( elem, args || [] );

        // Revert the old values
        for ( name in options ) {
            elem.style[ name ] = old[ name ];
        }

        return ret;
    }
});

jQuery.ready.promise = function( obj ) {
    if ( !readyList ) {

        readyList = jQuery.Deferred();

        // Catch cases where $(document).ready() is called after the browser event has already occurred.
        // we once tried to use readyState "interactive" here, but it caused issues like the one
        // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
        if ( document.readyState === "complete" ) {
            // Handle it asynchronously to allow scripts the opportunity to delay ready
            setTimeout( jQuery.ready );

        } else {

            // Use the handy event callback
            document.addEventListener( "DOMContentLoaded", completed, false );

            // A fallback to window.onload, that will always work
            window.addEventListener( "load", completed, false );
        }
    }
    return readyList.promise( obj );
};

// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
    class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

function isArraylike( obj ) {
    var length = obj.length,
        type = jQuery.type( obj );

    if ( jQuery.isWindow( obj ) ) {
        return false;
    }

    if ( obj.nodeType === 1 && length ) {
        return true;
    }

    return type === "array" || type !== "function" &&
        ( length === 0 ||
        typeof length === "number" && length > 0 && ( length - 1 ) in obj );
}

// All jQuery objects should point back to these
rootjQuery = jQuery(document);

(function( window, undefined ) {

var i,
    support,
    cachedruns,
    Expr,
    getText,
    isXML,
    compile,
    outermostContext,
    sortInput,

    // Local document vars
    setDocument,
    document,
    docElem,
    documentIsHTML,
    rbuggyQSA,
    rbuggyMatches,
    matches,
    contains,

    // Instance-specific data
    expando = "sizzle" + -(new Date()),
    preferredDoc = window.document,
    dirruns = 0,
    done = 0,
    classCache = createCache(),
    tokenCache = createCache(),
    compilerCache = createCache(),
    hasDuplicate = false,
    sortOrder = function( a, b ) {
        if ( a === b ) {
            hasDuplicate = true;
            return 0;
        }
        return 0;
    },

    // General-purpose constants
    strundefined = typeof undefined,
    MAX_NEGATIVE = 1 << 31,

    // Instance methods
    hasOwn = ({}).hasOwnProperty,
    arr = [],
    pop = arr.pop,
    push_native = arr.push,
    push = arr.push,
    slice = arr.slice,
    // Use a stripped-down indexOf if we can't use a native one
    indexOf = arr.indexOf || function( elem ) {
        var i = 0,
            len = this.length;
        for ( ; i < len; i++ ) {
            if ( this[i] === elem ) {
                return i;
            }
        }
        return -1;
    },

    booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",

    // Regular expressions

    // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
    whitespace = "[\\x20\\t\\r\\n\\f]",
    // http://www.w3.org/TR/css3-syntax/#characters
    characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",

    // Loosely modeled on CSS identifier characters
    // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
    // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
    identifier = characterEncoding.replace( "w", "w#" ),

    // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
    attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
        "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",

    // Prefer arguments quoted,
    //   then not containing pseudos/brackets,
    //   then attribute selectors/non-parenthetical expressions,
    //   then anything else
    // These preferences are here to reduce the number of selectors
    //   needing tokenize in the PSEUDO preFilter
    pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",

    // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
    rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),

    rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
    rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),

    rsibling = new RegExp( whitespace + "*[+~]" ),
    rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),

    rpseudo = new RegExp( pseudos ),
    ridentifier = new RegExp( "^" + identifier + "$" ),

    matchExpr = {
        "ID": new RegExp( "^#(" + characterEncoding + ")" ),
        "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
        "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
        "ATTR": new RegExp( "^" + attributes ),
        "PSEUDO": new RegExp( "^" + pseudos ),
        "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
            "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
            "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
        "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
        // For use in libraries implementing .is()
        // We use this for POS matching in `select`
        "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
            whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
    },

    rnative = /^[^{]+\{\s*\[native \w/,

    // Easily-parseable/retrievable ID or TAG or CLASS selectors
    rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

    rinputs = /^(?:input|select|textarea|button)$/i,
    rheader = /^h\d$/i,

    rescape = /'|\\/g,

    // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
    runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
    funescape = function( _, escaped, escapedWhitespace ) {
        var high = "0x" + escaped - 0x10000;
        // NaN means non-codepoint
        // Support: Firefox
        // Workaround erroneous numeric interpretation of +"0x"
        return high !== high || escapedWhitespace ?
            escaped :
            // BMP codepoint
            high < 0 ?
                String.fromCharCode( high + 0x10000 ) :
                // Supplemental Plane codepoint (surrogate pair)
                String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
    };

// Optimize for push.apply( _, NodeList )
try {
    push.apply(
        (arr = slice.call( preferredDoc.childNodes )),
        preferredDoc.childNodes
    );
    // Support: Android<4.0
    // Detect silently failing push.apply
    arr[ preferredDoc.childNodes.length ].nodeType;
} catch ( e ) {
    push = { apply: arr.length ?

        // Leverage slice if possible
        function( target, els ) {
            push_native.apply( target, slice.call(els) );
        } :

        // Support: IE<9
        // Otherwise append directly
        function( target, els ) {
            var j = target.length,
                i = 0;
            // Can't trust NodeList.length
            while ( (target[j++] = els[i++]) ) {}
            target.length = j - 1;
        }
    };
}

function Sizzle( selector, context, results, seed ) {
    var match, elem, m, nodeType,
        // QSA vars
        i, groups, old, nid, newContext, newSelector;

    if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
        setDocument( context );
    }

    context = context || document;
    results = results || [];

    if ( !selector || typeof selector !== "string" ) {
        return results;
    }

    if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
        return [];
    }

    if ( documentIsHTML && !seed ) {

        // Shortcuts
        if ( (match = rquickExpr.exec( selector )) ) {
            // Speed-up: Sizzle("#ID")
            if ( (m = match[1]) ) {
                if ( nodeType === 9 ) {
                    elem = context.getElementById( m );
                    // Check parentNode to catch when Blackberry 4.6 returns
                    // nodes that are no longer in the document #6963
                    if ( elem && elem.parentNode ) {
                        // Handle the case where IE, Opera, and Webkit return items
                        // by name instead of ID
                        if ( elem.id === m ) {
                            results.push( elem );
                            return results;
                        }
                    } else {
                        return results;
                    }
                } else {
                    // Context is not a document
                    if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
                        contains( context, elem ) && elem.id === m ) {
                        results.push( elem );
                        return results;
                    }
                }

            // Speed-up: Sizzle("TAG")
            } else if ( match[2] ) {
                push.apply( results, context.getElementsByTagName( selector ) );
                return results;

            // Speed-up: Sizzle(".CLASS")
            } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
                push.apply( results, context.getElementsByClassName( m ) );
                return results;
            }
        }

        // QSA path
        if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
            nid = old = expando;
            newContext = context;
            newSelector = nodeType === 9 && selector;

            // qSA works strangely on Element-rooted queries
            // We can work around this by specifying an extra ID on the root
            // and working up from there (Thanks to Andrew Dupont for the technique)
            // IE 8 doesn't work on object elements
            if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
                groups = tokenize( selector );

                if ( (old = context.getAttribute("id")) ) {
                    nid = old.replace( rescape, "\\$&" );
                } else {
                    context.setAttribute( "id", nid );
                }
                nid = "[id='" + nid + "'] ";

                i = groups.length;
                while ( i-- ) {
                    groups[i] = nid + toSelector( groups[i] );
                }
                newContext = rsibling.test( selector ) && context.parentNode || context;
                newSelector = groups.join(",");
            }

            if ( newSelector ) {
                try {
                    push.apply( results,
                        newContext.querySelectorAll( newSelector )
                    );
                    return results;
                } catch(qsaError) {
                } finally {
                    if ( !old ) {
                        context.removeAttribute("id");
                    }
                }
            }
        }
    }

    // All others
    return select( selector.replace( rtrim, "$1" ), context, results, seed );
}


function createCache() {
    var keys = [];

    function cache( key, value ) {
        // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
        if ( keys.push( key += " " ) > Expr.cacheLength ) {
            // Only keep the most recent entries
            delete cache[ keys.shift() ];
        }
        return (cache[ key ] = value);
    }
    return cache;
}


function markFunction( fn ) {
    fn[ expando ] = true;
    return fn;
}


function assert( fn ) {
    var div = document.createElement("div");

    try {
        return !!fn( div );
    } catch (e) {
        return false;
    } finally {
        // Remove from its parent by default
        if ( div.parentNode ) {
            div.parentNode.removeChild( div );
        }
        // release memory in IE
        div = null;
    }
}


function addHandle( attrs, handler ) {
    var arr = attrs.split("|"),
        i = attrs.length;

    while ( i-- ) {
        Expr.attrHandle[ arr[i] ] = handler;
    }
}


function siblingCheck( a, b ) {
    var cur = b && a,
        diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
            ( ~b.sourceIndex || MAX_NEGATIVE ) -
            ( ~a.sourceIndex || MAX_NEGATIVE );

    // Use IE sourceIndex if available on both nodes
    if ( diff ) {
        return diff;
    }

    // Check if b follows a
    if ( cur ) {
        while ( (cur = cur.nextSibling) ) {
            if ( cur === b ) {
                return -1;
            }
        }
    }

    return a ? 1 : -1;
}


function createInputPseudo( type ) {
    return function( elem ) {
        var name = elem.nodeName.toLowerCase();
        return name === "input" && elem.type === type;
    };
}


function createButtonPseudo( type ) {
    return function( elem ) {
        var name = elem.nodeName.toLowerCase();
        return (name === "input" || name === "button") && elem.type === type;
    };
}


function createPositionalPseudo( fn ) {
    return markFunction(function( argument ) {
        argument = +argument;
        return markFunction(function( seed, matches ) {
            var j,
                matchIndexes = fn( [], seed.length, argument ),
                i = matchIndexes.length;

            // Match elements found at the specified indexes
            while ( i-- ) {
                if ( seed[ (j = matchIndexes[i]) ] ) {
                    seed[j] = !(matches[j] = seed[j]);
                }
            }
        });
    });
}


isXML = Sizzle.isXML = function( elem ) {
    // documentElement is verified for cases where it doesn't yet exist
    // (such as loading iframes in IE - #4833)
    var documentElement = elem && (elem.ownerDocument || elem).documentElement;
    return documentElement ? documentElement.nodeName !== "HTML" : false;
};

// Expose support vars for convenience
support = Sizzle.support = {};


setDocument = Sizzle.setDocument = function( node ) {
    var doc = node ? node.ownerDocument || node : preferredDoc,
        parent = doc.defaultView;

    // If no document and documentElement is available, return
    if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
        return document;
    }

    // Set our document
    document = doc;
    docElem = doc.documentElement;

    // Support tests
    documentIsHTML = !isXML( doc );

    // Support: IE>8
    // If iframe document is assigned to "document" variable and if iframe has been reloaded,
    // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
    // IE6-8 do not support the defaultView property so parent will be undefined
    if ( parent && parent.attachEvent && parent !== parent.top ) {
        parent.attachEvent( "onbeforeunload", function() {
            setDocument();
        });
    }

    

    // Support: IE<8
    // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
    support.attributes = assert(function( div ) {
        div.className = "i";
        return !div.getAttribute("className");
    });

    

    // Check if getElementsByTagName("*") returns only elements
    support.getElementsByTagName = assert(function( div ) {
        div.appendChild( doc.createComment("") );
        return !div.getElementsByTagName("*").length;
    });

    // Check if getElementsByClassName can be trusted
    support.getElementsByClassName = assert(function( div ) {
        div.innerHTML = "<div class='a'></div><div class='a i'></div>";

        // Support: Safari<4
        // Catch class over-caching
        div.firstChild.className = "i";
        // Support: Opera<10
        // Catch gEBCN failure to find non-leading classes
        return div.getElementsByClassName("i").length === 2;
    });

    // Support: IE<10
    // Check if getElementById returns elements by name
    // The broken getElementById methods don't pick up programatically-set names,
    // so use a roundabout getElementsByName test
    support.getById = assert(function( div ) {
        docElem.appendChild( div ).id = expando;
        return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
    });

    // ID find and filter
    if ( support.getById ) {
        Expr.find["ID"] = function( id, context ) {
            if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
                var m = context.getElementById( id );
                // Check parentNode to catch when Blackberry 4.6 returns
                // nodes that are no longer in the document #6963
                return m && m.parentNode ? [m] : [];
            }
        };
        Expr.filter["ID"] = function( id ) {
            var attrId = id.replace( runescape, funescape );
            return function( elem ) {
                return elem.getAttribute("id") === attrId;
            };
        };
    } else {
        // Support: IE6/7
        // getElementById is not reliable as a find shortcut
        delete Expr.find["ID"];

        Expr.filter["ID"] =  function( id ) {
            var attrId = id.replace( runescape, funescape );
            return function( elem ) {
                var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
                return node && node.value === attrId;
            };
        };
    }

    // Tag
    Expr.find["TAG"] = support.getElementsByTagName ?
        function( tag, context ) {
            if ( typeof context.getElementsByTagName !== strundefined ) {
                return context.getElementsByTagName( tag );
            }
        } :
        function( tag, context ) {
            var elem,
                tmp = [],
                i = 0,
                results = context.getElementsByTagName( tag );

            // Filter out possible comments
            if ( tag === "*" ) {
                while ( (elem = results[i++]) ) {
                    if ( elem.nodeType === 1 ) {
                        tmp.push( elem );
                    }
                }

                return tmp;
            }
            return results;
        };

    // Class
    Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
        if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
            return context.getElementsByClassName( className );
        }
    };

    

    // QSA and matchesSelector support

    // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
    rbuggyMatches = [];

    // qSa(:focus) reports false when true (Chrome 21)
    // We allow this because of a bug in IE8/9 that throws an error
    // whenever `document.activeElement` is accessed on an iframe
    // So, we allow :focus to pass through QSA all the time to avoid the IE error
    // See http://bugs.jquery.com/ticket/13378
    rbuggyQSA = [];

    if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
        // Build QSA regex
        // Regex strategy adopted from Diego Perini
        assert(function( div ) {
            // Select is set to empty string on purpose
            // This is to test IE's treatment of not explicitly
            // setting a boolean content attribute,
            // since its presence should be enough
            // http://bugs.jquery.com/ticket/12359
            div.innerHTML = "<select><option selected=''></option></select>";

            // Support: IE8
            // Boolean attributes and "value" are not treated correctly
            if ( !div.querySelectorAll("[selected]").length ) {
                rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
            }

            // Webkit/Opera - :checked should return selected option elements
            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
            // IE8 throws error here and will not see later tests
            if ( !div.querySelectorAll(":checked").length ) {
                rbuggyQSA.push(":checked");
            }
        });

        assert(function( div ) {

            // Support: Opera 10-12/IE8
            // ^= $= *= and empty values
            // Should not select anything
            // Support: Windows 8 Native Apps
            // The type attribute is restricted during .innerHTML assignment
            var input = doc.createElement("input");
            input.setAttribute( "type", "hidden" );
            div.appendChild( input ).setAttribute( "t", "" );

            if ( div.querySelectorAll("[t^='']").length ) {
                rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
            }

            // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
            // IE8 throws error here and will not see later tests
            if ( !div.querySelectorAll(":enabled").length ) {
                rbuggyQSA.push( ":enabled", ":disabled" );
            }

            // Opera 10-11 does not throw on post-comma invalid pseudos
            div.querySelectorAll("*,:x");
            rbuggyQSA.push(",.*:");
        });
    }

    if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
        docElem.mozMatchesSelector ||
        docElem.oMatchesSelector ||
        docElem.msMatchesSelector) )) ) {

        assert(function( div ) {
            // Check to see if it's possible to do matchesSelector
            // on a disconnected node (IE 9)
            support.disconnectedMatch = matches.call( div, "div" );

            // This should fail with an exception
            // Gecko does not error, returns false instead
            matches.call( div, "[s!='']:x" );
            rbuggyMatches.push( "!=", pseudos );
        });
    }

    rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
    rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );

    

    // Element contains another
    // Purposefully does not implement inclusive descendent
    // As in, an element does not contain itself
    contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
        function( a, b ) {
            var adown = a.nodeType === 9 ? a.documentElement : a,
                bup = b && b.parentNode;
            return a === bup || !!( bup && bup.nodeType === 1 && (
                adown.contains ?
                    adown.contains( bup ) :
                    a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
            ));
        } :
        function( a, b ) {
            if ( b ) {
                while ( (b = b.parentNode) ) {
                    if ( b === a ) {
                        return true;
                    }
                }
            }
            return false;
        };

    

    // Document order sorting
    sortOrder = docElem.compareDocumentPosition ?
    function( a, b ) {

        // Flag for duplicate removal
        if ( a === b ) {
            hasDuplicate = true;
            return 0;
        }

        var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );

        if ( compare ) {
            // Disconnected nodes
            if ( compare & 1 ||
                (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {

                // Choose the first element that is related to our preferred document
                if ( a === doc || contains(preferredDoc, a) ) {
                    return -1;
                }
                if ( b === doc || contains(preferredDoc, b) ) {
                    return 1;
                }

                // Maintain original order
                return sortInput ?
                    ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
                    0;
            }

            return compare & 4 ? -1 : 1;
        }

        // Not directly comparable, sort on existence of method
        return a.compareDocumentPosition ? -1 : 1;
    } :
    function( a, b ) {
        var cur,
            i = 0,
            aup = a.parentNode,
            bup = b.parentNode,
            ap = [ a ],
            bp = [ b ];

        // Exit early if the nodes are identical
        if ( a === b ) {
            hasDuplicate = true;
            return 0;

        // Parentless nodes are either documents or disconnected
        } else if ( !aup || !bup ) {
            return a === doc ? -1 :
                b === doc ? 1 :
                aup ? -1 :
                bup ? 1 :
                sortInput ?
                ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
                0;

        // If the nodes are siblings, we can do a quick check
        } else if ( aup === bup ) {
            return siblingCheck( a, b );
        }

        // Otherwise we need full lists of their ancestors for comparison
        cur = a;
        while ( (cur = cur.parentNode) ) {
            ap.unshift( cur );
        }
        cur = b;
        while ( (cur = cur.parentNode) ) {
            bp.unshift( cur );
        }

        // Walk down the tree looking for a discrepancy
        while ( ap[i] === bp[i] ) {
            i++;
        }

        return i ?
            // Do a sibling check if the nodes have a common ancestor
            siblingCheck( ap[i], bp[i] ) :

            // Otherwise nodes in our document sort first
            ap[i] === preferredDoc ? -1 :
            bp[i] === preferredDoc ? 1 :
            0;
    };

    return doc;
};

Sizzle.matches = function( expr, elements ) {
    return Sizzle( expr, null, null, elements );
};

Sizzle.matchesSelector = function( elem, expr ) {
    // Set document vars if needed
    if ( ( elem.ownerDocument || elem ) !== document ) {
        setDocument( elem );
    }

    // Make sure that attribute selectors are quoted
    expr = expr.replace( rattributeQuotes, "='$1']" );

    if ( support.matchesSelector && documentIsHTML &&
        ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
        ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {

        try {
            var ret = matches.call( elem, expr );

            // IE 9's matchesSelector returns false on disconnected nodes
            if ( ret || support.disconnectedMatch ||
                    // As well, disconnected nodes are said to be in a document
                    // fragment in IE 9
                    elem.document && elem.document.nodeType !== 11 ) {
                return ret;
            }
        } catch(e) {}
    }

    return Sizzle( expr, document, null, [elem] ).length > 0;
};

Sizzle.contains = function( context, elem ) {
    // Set document vars if needed
    if ( ( context.ownerDocument || context ) !== document ) {
        setDocument( context );
    }
    return contains( context, elem );
};

Sizzle.attr = function( elem, name ) {
    // Set document vars if needed
    if ( ( elem.ownerDocument || elem ) !== document ) {
        setDocument( elem );
    }

    var fn = Expr.attrHandle[ name.toLowerCase() ],
        // Don't get fooled by Object.prototype properties (jQuery #13807)
        val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
            fn( elem, name, !documentIsHTML ) :
            undefined;

    return val === undefined ?
        support.attributes || !documentIsHTML ?
            elem.getAttribute( name ) :
            (val = elem.getAttributeNode(name)) && val.specified ?
                val.value :
                null :
        val;
};

Sizzle.error = function( msg ) {
    throw new Error( "Syntax error, unrecognized expression: " + msg );
};


Sizzle.uniqueSort = function( results ) {
    var elem,
        duplicates = [],
        j = 0,
        i = 0;

    // Unless we *know* we can detect duplicates, assume their presence
    hasDuplicate = !support.detectDuplicates;
    sortInput = !support.sortStable && results.slice( 0 );
    results.sort( sortOrder );

    if ( hasDuplicate ) {
        while ( (elem = results[i++]) ) {
            if ( elem === results[ i ] ) {
                j = duplicates.push( i );
            }
        }
        while ( j-- ) {
            results.splice( duplicates[ j ], 1 );
        }
    }

    return results;
};


getText = Sizzle.getText = function( elem ) {
    var node,
        ret = "",
        i = 0,
        nodeType = elem.nodeType;

    if ( !nodeType ) {
        // If no nodeType, this is expected to be an array
        for ( ; (node = elem[i]); i++ ) {
            // Do not traverse comment nodes
            ret += getText( node );
        }
    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
        // Use textContent for elements
        // innerText usage removed for consistency of new lines (see #11153)
        if ( typeof elem.textContent === "string" ) {
            return elem.textContent;
        } else {
            // Traverse its children
            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                ret += getText( elem );
            }
        }
    } else if ( nodeType === 3 || nodeType === 4 ) {
        return elem.nodeValue;
    }
    // Do not include comment or processing instruction nodes

    return ret;
};

Expr = Sizzle.selectors = {

    // Can be adjusted by the user
    cacheLength: 50,

    createPseudo: markFunction,

    match: matchExpr,

    attrHandle: {},

    find: {},

    relative: {
        ">": { dir: "parentNode", first: true },
        " ": { dir: "parentNode" },
        "+": { dir: "previousSibling", first: true },
        "~": { dir: "previousSibling" }
    },

    preFilter: {
        "ATTR": function( match ) {
            match[1] = match[1].replace( runescape, funescape );

            // Move the given value to match[3] whether quoted or unquoted
            match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );

            if ( match[2] === "~=" ) {
                match[3] = " " + match[3] + " ";
            }

            return match.slice( 0, 4 );
        },

        "CHILD": function( match ) {
            
            match[1] = match[1].toLowerCase();

            if ( match[1].slice( 0, 3 ) === "nth" ) {
                // nth-* requires argument
                if ( !match[3] ) {
                    Sizzle.error( match[0] );
                }

                // numeric x and y parameters for Expr.filter.CHILD
                // remember that false/true cast respectively to 0/1
                match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
                match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );

            // other types prohibit arguments
            } else if ( match[3] ) {
                Sizzle.error( match[0] );
            }

            return match;
        },

        "PSEUDO": function( match ) {
            var excess,
                unquoted = !match[5] && match[2];

            if ( matchExpr["CHILD"].test( match[0] ) ) {
                return null;
            }

            // Accept quoted arguments as-is
            if ( match[3] && match[4] !== undefined ) {
                match[2] = match[4];

            // Strip excess characters from unquoted arguments
            } else if ( unquoted && rpseudo.test( unquoted ) &&
                // Get excess from tokenize (recursively)
                (excess = tokenize( unquoted, true )) &&
                // advance to the next closing parenthesis
                (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {

                // excess is a negative index
                match[0] = match[0].slice( 0, excess );
                match[2] = unquoted.slice( 0, excess );
            }

            // Return only captures needed by the pseudo filter method (type and argument)
            return match.slice( 0, 3 );
        }
    },

    filter: {

        "TAG": function( nodeNameSelector ) {
            var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
            return nodeNameSelector === "*" ?
                function() { return true; } :
                function( elem ) {
                    return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
                };
        },

        "CLASS": function( className ) {
            var pattern = classCache[ className + " " ];

            return pattern ||
                (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
                classCache( className, function( elem ) {
                    return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
                });
        },

        "ATTR": function( name, operator, check ) {
            return function( elem ) {
                var result = Sizzle.attr( elem, name );

                if ( result == null ) {
                    return operator === "!=";
                }
                if ( !operator ) {
                    return true;
                }

                result += "";

                return operator === "=" ? result === check :
                    operator === "!=" ? result !== check :
                    operator === "^=" ? check && result.indexOf( check ) === 0 :
                    operator === "*=" ? check && result.indexOf( check ) > -1 :
                    operator === "$=" ? check && result.slice( -check.length ) === check :
                    operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
                    operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
                    false;
            };
        },

        "CHILD": function( type, what, argument, first, last ) {
            var simple = type.slice( 0, 3 ) !== "nth",
                forward = type.slice( -4 ) !== "last",
                ofType = what === "of-type";

            return first === 1 && last === 0 ?

                // Shortcut for :nth-*(n)
                function( elem ) {
                    return !!elem.parentNode;
                } :

                function( elem, context, xml ) {
                    var cache, outerCache, node, diff, nodeIndex, start,
                        dir = simple !== forward ? "nextSibling" : "previousSibling",
                        parent = elem.parentNode,
                        name = ofType && elem.nodeName.toLowerCase(),
                        useCache = !xml && !ofType;

                    if ( parent ) {

                        // :(first|last|only)-(child|of-type)
                        if ( simple ) {
                            while ( dir ) {
                                node = elem;
                                while ( (node = node[ dir ]) ) {
                                    if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
                                        return false;
                                    }
                                }
                                // Reverse direction for :only-* (if we haven't yet done so)
                                start = dir = type === "only" && !start && "nextSibling";
                            }
                            return true;
                        }

                        start = [ forward ? parent.firstChild : parent.lastChild ];

                        // non-xml :nth-child(...) stores cache data on `parent`
                        if ( forward && useCache ) {
                            // Seek `elem` from a previously-cached index
                            outerCache = parent[ expando ] || (parent[ expando ] = {});
                            cache = outerCache[ type ] || [];
                            nodeIndex = cache[0] === dirruns && cache[1];
                            diff = cache[0] === dirruns && cache[2];
                            node = nodeIndex && parent.childNodes[ nodeIndex ];

                            while ( (node = ++nodeIndex && node && node[ dir ] ||

                                // Fallback to seeking `elem` from the start
                                (diff = nodeIndex = 0) || start.pop()) ) {

                                // When found, cache indexes on `parent` and break
                                if ( node.nodeType === 1 && ++diff && node === elem ) {
                                    outerCache[ type ] = [ dirruns, nodeIndex, diff ];
                                    break;
                                }
                            }

                        // Use previously-cached element index if available
                        } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
                            diff = cache[1];

                        // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
                        } else {
                            // Use the same loop as above to seek `elem` from the start
                            while ( (node = ++nodeIndex && node && node[ dir ] ||
                                (diff = nodeIndex = 0) || start.pop()) ) {

                                if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
                                    // Cache the index of each encountered element
                                    if ( useCache ) {
                                        (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
                                    }

                                    if ( node === elem ) {
                                        break;
                                    }
                                }
                            }
                        }

                        // Incorporate the offset, then check against cycle size
                        diff -= last;
                        return diff === first || ( diff % first === 0 && diff / first >= 0 );
                    }
                };
        },

        "PSEUDO": function( pseudo, argument ) {
            // pseudo-class names are case-insensitive
            // http://www.w3.org/TR/selectors/#pseudo-classes
            // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
            // Remember that setFilters inherits from pseudos
            var args,
                fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
                    Sizzle.error( "unsupported pseudo: " + pseudo );

            // The user may use createPseudo to indicate that
            // arguments are needed to create the filter function
            // just as Sizzle does
            if ( fn[ expando ] ) {
                return fn( argument );
            }

            // But maintain support for old signatures
            if ( fn.length > 1 ) {
                args = [ pseudo, pseudo, "", argument ];
                return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
                    markFunction(function( seed, matches ) {
                        var idx,
                            matched = fn( seed, argument ),
                            i = matched.length;
                        while ( i-- ) {
                            idx = indexOf.call( seed, matched[i] );
                            seed[ idx ] = !( matches[ idx ] = matched[i] );
                        }
                    }) :
                    function( elem ) {
                        return fn( elem, 0, args );
                    };
            }

            return fn;
        }
    },

    pseudos: {
        // Potentially complex pseudos
        "not": markFunction(function( selector ) {
            // Trim the selector passed to compile
            // to avoid treating leading and trailing
            // spaces as combinators
            var input = [],
                results = [],
                matcher = compile( selector.replace( rtrim, "$1" ) );

            return matcher[ expando ] ?
                markFunction(function( seed, matches, context, xml ) {
                    var elem,
                        unmatched = matcher( seed, null, xml, [] ),
                        i = seed.length;

                    // Match elements unmatched by `matcher`
                    while ( i-- ) {
                        if ( (elem = unmatched[i]) ) {
                            seed[i] = !(matches[i] = elem);
                        }
                    }
                }) :
                function( elem, context, xml ) {
                    input[0] = elem;
                    matcher( input, null, xml, results );
                    return !results.pop();
                };
        }),

        "has": markFunction(function( selector ) {
            return function( elem ) {
                return Sizzle( selector, elem ).length > 0;
            };
        }),

        "contains": markFunction(function( text ) {
            return function( elem ) {
                return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
            };
        }),

        // "Whether an element is represented by a :lang() selector
        // is based solely on the element's language value
        // being equal to the identifier C,
        // or beginning with the identifier C immediately followed by "-".
        // The matching of C against the element's language value is performed case-insensitively.
        // The identifier C does not have to be a valid language name."
        // http://www.w3.org/TR/selectors/#lang-pseudo
        "lang": markFunction( function( lang ) {
            // lang value must be a valid identifier
            if ( !ridentifier.test(lang || "") ) {
                Sizzle.error( "unsupported lang: " + lang );
            }
            lang = lang.replace( runescape, funescape ).toLowerCase();
            return function( elem ) {
                var elemLang;
                do {
                    if ( (elemLang = documentIsHTML ?
                        elem.lang :
                        elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {

                        elemLang = elemLang.toLowerCase();
                        return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
                    }
                } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
                return false;
            };
        }),

        // Miscellaneous
        "target": function( elem ) {
            var hash = window.location && window.location.hash;
            return hash && hash.slice( 1 ) === elem.id;
        },

        "root": function( elem ) {
            return elem === docElem;
        },

        "focus": function( elem ) {
            return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
        },

        // Boolean properties
        "enabled": function( elem ) {
            return elem.disabled === false;
        },

        "disabled": function( elem ) {
            return elem.disabled === true;
        },

        "checked": function( elem ) {
            // In CSS3, :checked should return both checked and selected elements
            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
            var nodeName = elem.nodeName.toLowerCase();
            return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
        },

        "selected": function( elem ) {
            // Accessing this property makes selected-by-default
            // options in Safari work properly
            if ( elem.parentNode ) {
                elem.parentNode.selectedIndex;
            }

            return elem.selected === true;
        },

        // Contents
        "empty": function( elem ) {
            // http://www.w3.org/TR/selectors/#empty-pseudo
            // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
            //   not comment, processing instructions, or others
            // Thanks to Diego Perini for the nodeName shortcut
            //   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
                    return false;
                }
            }
            return true;
        },

        "parent": function( elem ) {
            return !Expr.pseudos["empty"]( elem );
        },

        // Element/input types
        "header": function( elem ) {
            return rheader.test( elem.nodeName );
        },

        "input": function( elem ) {
            return rinputs.test( elem.nodeName );
        },

        "button": function( elem ) {
            var name = elem.nodeName.toLowerCase();
            return name === "input" && elem.type === "button" || name === "button";
        },

        "text": function( elem ) {
            var attr;
            // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
            // use getAttribute instead to test this case
            return elem.nodeName.toLowerCase() === "input" &&
                elem.type === "text" &&
                ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
        },

        // Position-in-collection
        "first": createPositionalPseudo(function() {
            return [ 0 ];
        }),

        "last": createPositionalPseudo(function( matchIndexes, length ) {
            return [ length - 1 ];
        }),

        "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
            return [ argument < 0 ? argument + length : argument ];
        }),

        "even": createPositionalPseudo(function( matchIndexes, length ) {
            var i = 0;
            for ( ; i < length; i += 2 ) {
                matchIndexes.push( i );
            }
            return matchIndexes;
        }),

        "odd": createPositionalPseudo(function( matchIndexes, length ) {
            var i = 1;
            for ( ; i < length; i += 2 ) {
                matchIndexes.push( i );
            }
            return matchIndexes;
        }),

        "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
            var i = argument < 0 ? argument + length : argument;
            for ( ; --i >= 0; ) {
                matchIndexes.push( i );
            }
            return matchIndexes;
        }),

        "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
            var i = argument < 0 ? argument + length : argument;
            for ( ; ++i < length; ) {
                matchIndexes.push( i );
            }
            return matchIndexes;
        })
    }
};

Expr.pseudos["nth"] = Expr.pseudos["eq"];

// Add button/input type pseudos
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
    Expr.pseudos[ i ] = createInputPseudo( i );
}
for ( i in { submit: true, reset: true } ) {
    Expr.pseudos[ i ] = createButtonPseudo( i );
}

// Easy API for creating new setFilters
function setFilters() {}
setFilters.prototype = Expr.filters = Expr.pseudos;
Expr.setFilters = new setFilters();

function tokenize( selector, parseOnly ) {
    var matched, match, tokens, type,
        soFar, groups, preFilters,
        cached = tokenCache[ selector + " " ];

    if ( cached ) {
        return parseOnly ? 0 : cached.slice( 0 );
    }

    soFar = selector;
    groups = [];
    preFilters = Expr.preFilter;

    while ( soFar ) {

        // Comma and first run
        if ( !matched || (match = rcomma.exec( soFar )) ) {
            if ( match ) {
                // Don't consume trailing commas as valid
                soFar = soFar.slice( match[0].length ) || soFar;
            }
            groups.push( tokens = [] );
        }

        matched = false;

        // Combinators
        if ( (match = rcombinators.exec( soFar )) ) {
            matched = match.shift();
            tokens.push({
                value: matched,
                // Cast descendant combinators to space
                type: match[0].replace( rtrim, " " )
            });
            soFar = soFar.slice( matched.length );
        }

        // Filters
        for ( type in Expr.filter ) {
            if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
                (match = preFilters[ type ]( match ))) ) {
                matched = match.shift();
                tokens.push({
                    value: matched,
                    type: type,
                    matches: match
                });
                soFar = soFar.slice( matched.length );
            }
        }

        if ( !matched ) {
            break;
        }
    }

    // Return the length of the invalid excess
    // if we're just parsing
    // Otherwise, throw an error or return tokens
    return parseOnly ?
        soFar.length :
        soFar ?
            Sizzle.error( selector ) :
            // Cache the tokens
            tokenCache( selector, groups ).slice( 0 );
}

function toSelector( tokens ) {
    var i = 0,
        len = tokens.length,
        selector = "";
    for ( ; i < len; i++ ) {
        selector += tokens[i].value;
    }
    return selector;
}

function addCombinator( matcher, combinator, base ) {
    var dir = combinator.dir,
        checkNonElements = base && dir === "parentNode",
        doneName = done++;

    return combinator.first ?
        // Check against closest ancestor/preceding element
        function( elem, context, xml ) {
            while ( (elem = elem[ dir ]) ) {
                if ( elem.nodeType === 1 || checkNonElements ) {
                    return matcher( elem, context, xml );
                }
            }
        } :

        // Check against all ancestor/preceding elements
        function( elem, context, xml ) {
            var data, cache, outerCache,
                dirkey = dirruns + " " + doneName;

            // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
            if ( xml ) {
                while ( (elem = elem[ dir ]) ) {
                    if ( elem.nodeType === 1 || checkNonElements ) {
                        if ( matcher( elem, context, xml ) ) {
                            return true;
                        }
                    }
                }
            } else {
                while ( (elem = elem[ dir ]) ) {
                    if ( elem.nodeType === 1 || checkNonElements ) {
                        outerCache = elem[ expando ] || (elem[ expando ] = {});
                        if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
                            if ( (data = cache[1]) === true || data === cachedruns ) {
                                return data === true;
                            }
                        } else {
                            cache = outerCache[ dir ] = [ dirkey ];
                            cache[1] = matcher( elem, context, xml ) || cachedruns;
                            if ( cache[1] === true ) {
                                return true;
                            }
                        }
                    }
                }
            }
        };
}

function elementMatcher( matchers ) {
    return matchers.length > 1 ?
        function( elem, context, xml ) {
            var i = matchers.length;
            while ( i-- ) {
                if ( !matchers[i]( elem, context, xml ) ) {
                    return false;
                }
            }
            return true;
        } :
        matchers[0];
}

function condense( unmatched, map, filter, context, xml ) {
    var elem,
        newUnmatched = [],
        i = 0,
        len = unmatched.length,
        mapped = map != null;

    for ( ; i < len; i++ ) {
        if ( (elem = unmatched[i]) ) {
            if ( !filter || filter( elem, context, xml ) ) {
                newUnmatched.push( elem );
                if ( mapped ) {
                    map.push( i );
                }
            }
        }
    }

    return newUnmatched;
}

function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
    if ( postFilter && !postFilter[ expando ] ) {
        postFilter = setMatcher( postFilter );
    }
    if ( postFinder && !postFinder[ expando ] ) {
        postFinder = setMatcher( postFinder, postSelector );
    }
    return markFunction(function( seed, results, context, xml ) {
        var temp, i, elem,
            preMap = [],
            postMap = [],
            preexisting = results.length,

            // Get initial elements from seed or context
            elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),

            // Prefilter to get matcher input, preserving a map for seed-results synchronization
            matcherIn = preFilter && ( seed || !selector ) ?
                condense( elems, preMap, preFilter, context, xml ) :
                elems,

            matcherOut = matcher ?
                // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
                postFinder || ( seed ? preFilter : preexisting || postFilter ) ?

                    // ...intermediate processing is necessary
                    [] :

                    // ...otherwise use results directly
                    results :
                matcherIn;

        // Find primary matches
        if ( matcher ) {
            matcher( matcherIn, matcherOut, context, xml );
        }

        // Apply postFilter
        if ( postFilter ) {
            temp = condense( matcherOut, postMap );
            postFilter( temp, [], context, xml );

            // Un-match failing elements by moving them back to matcherIn
            i = temp.length;
            while ( i-- ) {
                if ( (elem = temp[i]) ) {
                    matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
                }
            }
        }

        if ( seed ) {
            if ( postFinder || preFilter ) {
                if ( postFinder ) {
                    // Get the final matcherOut by condensing this intermediate into postFinder contexts
                    temp = [];
                    i = matcherOut.length;
                    while ( i-- ) {
                        if ( (elem = matcherOut[i]) ) {
                            // Restore matcherIn since elem is not yet a final match
                            temp.push( (matcherIn[i] = elem) );
                        }
                    }
                    postFinder( null, (matcherOut = []), temp, xml );
                }

                // Move matched elements from seed to results to keep them synchronized
                i = matcherOut.length;
                while ( i-- ) {
                    if ( (elem = matcherOut[i]) &&
                        (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {

                        seed[temp] = !(results[temp] = elem);
                    }
                }
            }

        // Add elements to results, through postFinder if defined
        } else {
            matcherOut = condense(
                matcherOut === results ?
                    matcherOut.splice( preexisting, matcherOut.length ) :
                    matcherOut
            );
            if ( postFinder ) {
                postFinder( null, results, matcherOut, xml );
            } else {
                push.apply( results, matcherOut );
            }
        }
    });
}

function matcherFromTokens( tokens ) {
    var checkContext, matcher, j,
        len = tokens.length,
        leadingRelative = Expr.relative[ tokens[0].type ],
        implicitRelative = leadingRelative || Expr.relative[" "],
        i = leadingRelative ? 1 : 0,

        // The foundational matcher ensures that elements are reachable from top-level context(s)
        matchContext = addCombinator( function( elem ) {
            return elem === checkContext;
        }, implicitRelative, true ),
        matchAnyContext = addCombinator( function( elem ) {
            return indexOf.call( checkContext, elem ) > -1;
        }, implicitRelative, true ),
        matchers = [ function( elem, context, xml ) {
            return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
                (checkContext = context).nodeType ?
                    matchContext( elem, context, xml ) :
                    matchAnyContext( elem, context, xml ) );
        } ];

    for ( ; i < len; i++ ) {
        if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
            matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
        } else {
            matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );

            // Return special upon seeing a positional matcher
            if ( matcher[ expando ] ) {
                // Find the next relative operator (if any) for proper handling
                j = ++i;
                for ( ; j < len; j++ ) {
                    if ( Expr.relative[ tokens[j].type ] ) {
                        break;
                    }
                }
                return setMatcher(
                    i > 1 && elementMatcher( matchers ),
                    i > 1 && toSelector(
                        // If the preceding token was a descendant combinator, insert an implicit any-element `*`
                        tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
                    ).replace( rtrim, "$1" ),
                    matcher,
                    i < j && matcherFromTokens( tokens.slice( i, j ) ),
                    j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
                    j < len && toSelector( tokens )
                );
            }
            matchers.push( matcher );
        }
    }

    return elementMatcher( matchers );
}

function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
    // A counter to specify which element is currently being matched
    var matcherCachedRuns = 0,
        bySet = setMatchers.length > 0,
        byElement = elementMatchers.length > 0,
        superMatcher = function( seed, context, xml, results, expandContext ) {
            var elem, j, matcher,
                setMatched = [],
                matchedCount = 0,
                i = "0",
                unmatched = seed && [],
                outermost = expandContext != null,
                contextBackup = outermostContext,
                // We must always have either seed elements or context
                elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
                // Use integer dirruns iff this is the outermost matcher
                dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);

            if ( outermost ) {
                outermostContext = context !== document && context;
                cachedruns = matcherCachedRuns;
            }

            // Add elements passing elementMatchers directly to results
            // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
            for ( ; (elem = elems[i]) != null; i++ ) {
                if ( byElement && elem ) {
                    j = 0;
                    while ( (matcher = elementMatchers[j++]) ) {
                        if ( matcher( elem, context, xml ) ) {
                            results.push( elem );
                            break;
                        }
                    }
                    if ( outermost ) {
                        dirruns = dirrunsUnique;
                        cachedruns = ++matcherCachedRuns;
                    }
                }

                // Track unmatched elements for set filters
                if ( bySet ) {
                    // They will have gone through all possible matchers
                    if ( (elem = !matcher && elem) ) {
                        matchedCount--;
                    }

                    // Lengthen the array for every element, matched or not
                    if ( seed ) {
                        unmatched.push( elem );
                    }
                }
            }

            // Apply set filters to unmatched elements
            matchedCount += i;
            if ( bySet && i !== matchedCount ) {
                j = 0;
                while ( (matcher = setMatchers[j++]) ) {
                    matcher( unmatched, setMatched, context, xml );
                }

                if ( seed ) {
                    // Reintegrate element matches to eliminate the need for sorting
                    if ( matchedCount > 0 ) {
                        while ( i-- ) {
                            if ( !(unmatched[i] || setMatched[i]) ) {
                                setMatched[i] = pop.call( results );
                            }
                        }
                    }

                    // Discard index placeholder values to get only actual matches
                    setMatched = condense( setMatched );
                }

                // Add matches to results
                push.apply( results, setMatched );

                // Seedless set matches succeeding multiple successful matchers stipulate sorting
                if ( outermost && !seed && setMatched.length > 0 &&
                    ( matchedCount + setMatchers.length ) > 1 ) {

                    Sizzle.uniqueSort( results );
                }
            }

            // Override manipulation of globals by nested matchers
            if ( outermost ) {
                dirruns = dirrunsUnique;
                outermostContext = contextBackup;
            }

            return unmatched;
        };

    return bySet ?
        markFunction( superMatcher ) :
        superMatcher;
}

compile = Sizzle.compile = function( selector, group  ) {
    var i,
        setMatchers = [],
        elementMatchers = [],
        cached = compilerCache[ selector + " " ];

    if ( !cached ) {
        // Generate a function of recursive functions that can be used to check each element
        if ( !group ) {
            group = tokenize( selector );
        }
        i = group.length;
        while ( i-- ) {
            cached = matcherFromTokens( group[i] );
            if ( cached[ expando ] ) {
                setMatchers.push( cached );
            } else {
                elementMatchers.push( cached );
            }
        }

        // Cache the compiled function
        cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
    }
    return cached;
};

function multipleContexts( selector, contexts, results ) {
    var i = 0,
        len = contexts.length;
    for ( ; i < len; i++ ) {
        Sizzle( selector, contexts[i], results );
    }
    return results;
}

function select( selector, context, results, seed ) {
    var i, tokens, token, type, find,
        match = tokenize( selector );

    if ( !seed ) {
        // Try to minimize operations if there is only one group
        if ( match.length === 1 ) {

            // Take a shortcut and set the context if the root selector is an ID
            tokens = match[0] = match[0].slice( 0 );
            if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
                    support.getById && context.nodeType === 9 && documentIsHTML &&
                    Expr.relative[ tokens[1].type ] ) {

                context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
                if ( !context ) {
                    return results;
                }
                selector = selector.slice( tokens.shift().value.length );
            }

            // Fetch a seed set for right-to-left matching
            i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
            while ( i-- ) {
                token = tokens[i];

                // Abort if we hit a combinator
                if ( Expr.relative[ (type = token.type) ] ) {
                    break;
                }
                if ( (find = Expr.find[ type ]) ) {
                    // Search, expanding context for leading sibling combinators
                    if ( (seed = find(
                        token.matches[0].replace( runescape, funescape ),
                        rsibling.test( tokens[0].type ) && context.parentNode || context
                    )) ) {

                        // If seed is empty or no tokens remain, we can return early
                        tokens.splice( i, 1 );
                        selector = seed.length && toSelector( tokens );
                        if ( !selector ) {
                            push.apply( results, seed );
                            return results;
                        }

                        break;
                    }
                }
            }
        }
    }

    // Compile and execute a filtering function
    // Provide `match` to avoid retokenization if we modified the selector above
    compile( selector, match )(
        seed,
        context,
        !documentIsHTML,
        results,
        rsibling.test( selector )
    );
    return results;
}

// One-time assignments

// Sort stability
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;

// Support: Chrome<14
// Always assume duplicates if they aren't passed to the comparison function
support.detectDuplicates = hasDuplicate;

// Initialize against the default document
setDocument();

// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
// Detached nodes confoundingly follow *each other*
support.sortDetached = assert(function( div1 ) {
    // Should return 1, but returns 4 (following)
    return div1.compareDocumentPosition( document.createElement("div") ) & 1;
});

// Support: IE<8
// Prevent attribute/property "interpolation"
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
if ( !assert(function( div ) {
    div.innerHTML = "<a href='#'></a>";
    return div.firstChild.getAttribute("href") === "#" ;
}) ) {
    addHandle( "type|href|height|width", function( elem, name, isXML ) {
        if ( !isXML ) {
            return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
        }
    });
}

// Support: IE<9
// Use defaultValue in place of getAttribute("value")
if ( !support.attributes || !assert(function( div ) {
    div.innerHTML = "<input/>";
    div.firstChild.setAttribute( "value", "" );
    return div.firstChild.getAttribute( "value" ) === "";
}) ) {
    addHandle( "value", function( elem, name, isXML ) {
        if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
            return elem.defaultValue;
        }
    });
}

// Support: IE<9
// Use getAttributeNode to fetch booleans when getAttribute lies
if ( !assert(function( div ) {
    return div.getAttribute("disabled") == null;
}) ) {
    addHandle( booleans, function( elem, name, isXML ) {
        var val;
        if ( !isXML ) {
            return (val = elem.getAttributeNode( name )) && val.specified ?
                val.value :
                elem[ name ] === true ? name.toLowerCase() : null;
        }
    });
}

jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;
jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;


})( window );
// String to Object options format cache
var optionsCache = {};

// Convert String-formatted options into Object-formatted ones and store in cache
function createOptions( options ) {
    var object = optionsCache[ options ] = {};
    jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
        object[ flag ] = true;
    });
    return object;
}


jQuery.Callbacks = function( options ) {

    // Convert options from String-formatted to Object-formatted if needed
    // (we check in cache first)
    options = typeof options === "string" ?
        ( optionsCache[ options ] || createOptions( options ) ) :
        jQuery.extend( {}, options );

    var // Last fire value (for non-forgettable lists)
        memory,
        // Flag to know if list was already fired
        fired,
        // Flag to know if list is currently firing
        firing,
        // First callback to fire (used internally by add and fireWith)
        firingStart,
        // End of the loop when firing
        firingLength,
        // Index of currently firing callback (modified by remove if needed)
        firingIndex,
        // Actual callback list
        list = [],
        // Stack of fire calls for repeatable lists
        stack = !options.once && [],
        // Fire callbacks
        fire = function( data ) {
            memory = options.memory && data;
            fired = true;
            firingIndex = firingStart || 0;
            firingStart = 0;
            firingLength = list.length;
            firing = true;
            for ( ; list && firingIndex < firingLength; firingIndex++ ) {
                if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
                    memory = false; // To prevent further calls using add
                    break;
                }
            }
            firing = false;
            if ( list ) {
                if ( stack ) {
                    if ( stack.length ) {
                        fire( stack.shift() );
                    }
                } else if ( memory ) {
                    list = [];
                } else {
                    self.disable();
                }
            }
        },
        // Actual Callbacks object
        self = {
            // Add a callback or a collection of callbacks to the list
            add: function() {
                if ( list ) {
                    // First, we save the current length
                    var start = list.length;
                    (function add( args ) {
                        jQuery.each( args, function( _, arg ) {
                            var type = jQuery.type( arg );
                            if ( type === "function" ) {
                                if ( !options.unique || !self.has( arg ) ) {
                                    list.push( arg );
                                }
                            } else if ( arg && arg.length && type !== "string" ) {
                                // Inspect recursively
                                add( arg );
                            }
                        });
                    })( arguments );
                    // Do we need to add the callbacks to the
                    // current firing batch?
                    if ( firing ) {
                        firingLength = list.length;
                    // With memory, if we're not firing then
                    // we should call right away
                    } else if ( memory ) {
                        firingStart = start;
                        fire( memory );
                    }
                }
                return this;
            },
            // Remove a callback from the list
            remove: function() {
                if ( list ) {
                    jQuery.each( arguments, function( _, arg ) {
                        var index;
                        while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
                            list.splice( index, 1 );
                            // Handle firing indexes
                            if ( firing ) {
                                if ( index <= firingLength ) {
                                    firingLength--;
                                }
                                if ( index <= firingIndex ) {
                                    firingIndex--;
                                }
                            }
                        }
                    });
                }
                return this;
            },
            // Check if a given callback is in the list.
            // If no argument is given, return whether or not list has callbacks attached.
            has: function( fn ) {
                return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
            },
            // Remove all callbacks from the list
            empty: function() {
                list = [];
                firingLength = 0;
                return this;
            },
            // Have the list do nothing anymore
            disable: function() {
                list = stack = memory = undefined;
                return this;
            },
            // Is it disabled?
            disabled: function() {
                return !list;
            },
            // Lock the list in its current state
            lock: function() {
                stack = undefined;
                if ( !memory ) {
                    self.disable();
                }
                return this;
            },
            // Is it locked?
            locked: function() {
                return !stack;
            },
            // Call all callbacks with the given context and arguments
            fireWith: function( context, args ) {
                if ( list && ( !fired || stack ) ) {
                    args = args || [];
                    args = [ context, args.slice ? args.slice() : args ];
                    if ( firing ) {
                        stack.push( args );
                    } else {
                        fire( args );
                    }
                }
                return this;
            },
            // Call all the callbacks with the given arguments
            fire: function() {
                self.fireWith( this, arguments );
                return this;
            },
            // To know if the callbacks have already been called at least once
            fired: function() {
                return !!fired;
            }
        };

    return self;
};
jQuery.extend({

    Deferred: function( func ) {
        var tuples = [
                // action, add listener, listener list, final state
                [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
                [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
                [ "notify", "progress", jQuery.Callbacks("memory") ]
            ],
            state = "pending",
            promise = {
                state: function() {
                    return state;
                },
                always: function() {
                    deferred.done( arguments ).fail( arguments );
                    return this;
                },
                then: function(  ) {
                    var fns = arguments;
                    return jQuery.Deferred(function( newDefer ) {
                        jQuery.each( tuples, function( i, tuple ) {
                            var action = tuple[ 0 ],
                                fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
                            // deferred[ done | fail | progress ] for forwarding actions to newDefer
                            deferred[ tuple[1] ](function() {
                                var returned = fn && fn.apply( this, arguments );
                                if ( returned && jQuery.isFunction( returned.promise ) ) {
                                    returned.promise()
                                        .done( newDefer.resolve )
                                        .fail( newDefer.reject )
                                        .progress( newDefer.notify );
                                } else {
                                    newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
                                }
                            });
                        });
                        fns = null;
                    }).promise();
                },
                // Get a promise for this deferred
                // If obj is provided, the promise aspect is added to the object
                promise: function( obj ) {
                    return obj != null ? jQuery.extend( obj, promise ) : promise;
                }
            },
            deferred = {};

        // Keep pipe for back-compat
        promise.pipe = promise.then;

        // Add list-specific methods
        jQuery.each( tuples, function( i, tuple ) {
            var list = tuple[ 2 ],
                stateString = tuple[ 3 ];

            // promise[ done | fail | progress ] = list.add
            promise[ tuple[1] ] = list.add;

            // Handle state
            if ( stateString ) {
                list.add(function() {
                    // state = [ resolved | rejected ]
                    state = stateString;

                // [ reject_list | resolve_list ].disable; progress_list.lock
                }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
            }

            // deferred[ resolve | reject | notify ]
            deferred[ tuple[0] ] = function() {
                deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
                return this;
            };
            deferred[ tuple[0] + "With" ] = list.fireWith;
        });

        // Make the deferred a promise
        promise.promise( deferred );

        // Call given func if any
        if ( func ) {
            func.call( deferred, deferred );
        }

        // All done!
        return deferred;
    },

    // Deferred helper
    when: function( subordinate  ) {
        var i = 0,
            resolveValues = core_slice.call( arguments ),
            length = resolveValues.length,

            // the count of uncompleted subordinates
            remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,

            // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
            deferred = remaining === 1 ? subordinate : jQuery.Deferred(),

            // Update function for both resolve and progress values
            updateFunc = function( i, contexts, values ) {
                return function( value ) {
                    contexts[ i ] = this;
                    values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
                    if( values === progressValues ) {
                        deferred.notifyWith( contexts, values );
                    } else if ( !( --remaining ) ) {
                        deferred.resolveWith( contexts, values );
                    }
                };
            },

            progressValues, progressContexts, resolveContexts;

        // add listeners to Deferred subordinates; treat others as resolved
        if ( length > 1 ) {
            progressValues = new Array( length );
            progressContexts = new Array( length );
            resolveContexts = new Array( length );
            for ( ; i < length; i++ ) {
                if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
                    resolveValues[ i ].promise()
                        .done( updateFunc( i, resolveContexts, resolveValues ) )
                        .fail( deferred.reject )
                        .progress( updateFunc( i, progressContexts, progressValues ) );
                } else {
                    --remaining;
                }
            }
        }

        // if we're not waiting on anything, resolve the master
        if ( !remaining ) {
            deferred.resolveWith( resolveContexts, resolveValues );
        }

        return deferred.promise();
    }
});
jQuery.support = (function( support ) {
    var input = document.createElement("input"),
        fragment = document.createDocumentFragment(),
        div = document.createElement("div"),
        select = document.createElement("select"),
        opt = select.appendChild( document.createElement("option") );

    // Finish early in limited environments
    if ( !input.type ) {
        return support;
    }

    input.type = "checkbox";

    // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
    // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
    support.checkOn = input.value !== "";

    // Must access the parent to make an option select properly
    // Support: IE9, IE10
    support.optSelected = opt.selected;

    // Will be defined later
    support.reliableMarginRight = true;
    support.boxSizingReliable = true;
    support.pixelPosition = false;

    // Make sure checked status is properly cloned
    // Support: IE9, IE10
    input.checked = true;
    support.noCloneChecked = input.cloneNode( true ).checked;

    // Make sure that the options inside disabled selects aren't marked as disabled
    // (WebKit marks them as disabled)
    select.disabled = true;
    support.optDisabled = !opt.disabled;

    // Check if an input maintains its value after becoming a radio
    // Support: IE9, IE10
    input = document.createElement("input");
    input.value = "t";
    input.type = "radio";
    support.radioValue = input.value === "t";

    // #11217 - WebKit loses check when the name is after the checked attribute
    input.setAttribute( "checked", "t" );
    input.setAttribute( "name", "t" );

    fragment.appendChild( input );

    // Support: Safari 5.1, Android 4.x, Android 2.3
    // old WebKit doesn't clone checked state correctly in fragments
    support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;

    // Support: Firefox, Chrome, Safari
    // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
    support.focusinBubbles = "onfocusin" in window;

    div.style.backgroundClip = "content-box";
    div.cloneNode( true ).style.backgroundClip = "";
    support.clearCloneStyle = div.style.backgroundClip === "content-box";

    // Run tests that need a body at doc ready
    jQuery(function() {
        var container, marginDiv,
            // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
            divReset = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",
            body = document.getElementsByTagName("body")[ 0 ];

        if ( !body ) {
            // Return for frameset docs that don't have a body
            return;
        }

        container = document.createElement("div");
        container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";

        // Check box-sizing and margin behavior.
        body.appendChild( container ).appendChild( div );
        div.innerHTML = "";
        // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
        div.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%";

        // Workaround failing boxSizing test due to offsetWidth returning wrong value
        // with some non-1 values of body zoom, ticket #13543
        jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
            support.boxSizing = div.offsetWidth === 4;
        });

        // Use window.getComputedStyle because jsdom on node.js will break without it.
        if ( window.getComputedStyle ) {
            support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
            support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";

            // Support: Android 2.3
            // Check if div with explicit width and no margin-right incorrectly
            // gets computed margin-right based on width of container. (#3333)
            // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
            marginDiv = div.appendChild( document.createElement("div") );
            marginDiv.style.cssText = div.style.cssText = divReset;
            marginDiv.style.marginRight = marginDiv.style.width = "0";
            div.style.width = "1px";

            support.reliableMarginRight =
                !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
        }

        body.removeChild( container );
    });

    return support;
})( {} );


var data_user, data_priv,
    rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
    rmultiDash = /([A-Z])/g;

function Data() {
    // Support: Android < 4,
    // Old WebKit does not have Object.preventExtensions/freeze method,
    // return new empty object instead with no [[set]] accessor
    Object.defineProperty( this.cache = {}, 0, {
        get: function() {
            return {};
        }
    });

    this.expando = jQuery.expando + Math.random();
}

Data.uid = 1;

Data.accepts = function( owner ) {
    // Accepts only:
    //  - Node
    //    - Node.ELEMENT_NODE
    //    - Node.DOCUMENT_NODE
    //  - Object
    //    - Any
    return owner.nodeType ?
        owner.nodeType === 1 || owner.nodeType === 9 : true;
};

Data.prototype = {
    key: function( owner ) {
        // We can accept data for non-element nodes in modern browsers,
        // but we should not, see #8335.
        // Always return the key for a frozen object.
        if ( !Data.accepts( owner ) ) {
            return 0;
        }

        var descriptor = {},
            // Check if the owner object already has a cache key
            unlock = owner[ this.expando ];

        // If not, create one
        if ( !unlock ) {
            unlock = Data.uid++;

            // Secure it in a non-enumerable, non-writable property
            try {
                descriptor[ this.expando ] = { value: unlock };
                Object.defineProperties( owner, descriptor );

            // Support: Android < 4
            // Fallback to a less secure definition
            } catch ( e ) {
                descriptor[ this.expando ] = unlock;
                jQuery.extend( owner, descriptor );
            }
        }

        // Ensure the cache object
        if ( !this.cache[ unlock ] ) {
            this.cache[ unlock ] = {};
        }

        return unlock;
    },
    set: function( owner, data, value ) {
        var prop,
            // There may be an unlock assigned to this node,
            // if there is no entry for this "owner", create one inline
            // and set the unlock as though an owner entry had always existed
            unlock = this.key( owner ),
            cache = this.cache[ unlock ];

        // Handle: [ owner, key, value ] args
        if ( typeof data === "string" ) {
            cache[ data ] = value;

        // Handle: [ owner, { properties } ] args
        } else {
            // Fresh assignments by object are shallow copied
            if ( jQuery.isEmptyObject( cache ) ) {
                jQuery.extend( this.cache[ unlock ], data );
            // Otherwise, copy the properties one-by-one to the cache object
            } else {
                for ( prop in data ) {
                    cache[ prop ] = data[ prop ];
                }
            }
        }
        return cache;
    },
    get: function( owner, key ) {
        // Either a valid cache is found, or will be created.
        // New caches will be created and the unlock returned,
        // allowing direct access to the newly created
        // empty data object. A valid owner object must be provided.
        var cache = this.cache[ this.key( owner ) ];

        return key === undefined ?
            cache : cache[ key ];
    },
    access: function( owner, key, value ) {
        var stored;
        // In cases where either:
        //
        //   1. No key was specified
        //   2. A string key was specified, but no value provided
        //
        // Take the "read" path and allow the get method to determine
        // which value to return, respectively either:
        //
        //   1. The entire cache object
        //   2. The data stored at the key
        //
        if ( key === undefined ||
                ((key && typeof key === "string") && value === undefined) ) {

            stored = this.get( owner, key );

            return stored !== undefined ?
                stored : this.get( owner, jQuery.camelCase(key) );
        }

        // [*]When the key is not a string, or both a key and value
        // are specified, set or extend (existing objects) with either:
        //
        //   1. An object of properties
        //   2. A key and value
        //
        this.set( owner, key, value );

        // Since the "set" path can have two possible entry points
        // return the expected data based on which path was taken[*]
        return value !== undefined ? value : key;
    },
    remove: function( owner, key ) {
        var i, name, camel,
            unlock = this.key( owner ),
            cache = this.cache[ unlock ];

        if ( key === undefined ) {
            this.cache[ unlock ] = {};

        } else {
            // Support array or space separated string of keys
            if ( jQuery.isArray( key ) ) {
                // If "name" is an array of keys...
                // When data is initially created, via ("key", "val") signature,
                // keys will be converted to camelCase.
                // Since there is no way to tell _how_ a key was added, remove
                // both plain key and camelCase key. #12786
                // This will only penalize the array argument path.
                name = key.concat( key.map( jQuery.camelCase ) );
            } else {
                camel = jQuery.camelCase( key );
                // Try the string as a key before any manipulation
                if ( key in cache ) {
                    name = [ key, camel ];
                } else {
                    // If a key with the spaces exists, use it.
                    // Otherwise, create an array by matching non-whitespace
                    name = camel;
                    name = name in cache ?
                        [ name ] : ( name.match( core_rnotwhite ) || [] );
                }
            }

            i = name.length;
            while ( i-- ) {
                delete cache[ name[ i ] ];
            }
        }
    },
    hasData: function( owner ) {
        return !jQuery.isEmptyObject(
            this.cache[ owner[ this.expando ] ] || {}
        );
    },
    discard: function( owner ) {
        if ( owner[ this.expando ] ) {
            delete this.cache[ owner[ this.expando ] ];
        }
    }
};

// These may be used throughout the jQuery core codebase
data_user = new Data();
data_priv = new Data();


jQuery.extend({
    acceptData: Data.accepts,

    hasData: function( elem ) {
        return data_user.hasData( elem ) || data_priv.hasData( elem );
    },

    data: function( elem, name, data ) {
        return data_user.access( elem, name, data );
    },

    removeData: function( elem, name ) {
        data_user.remove( elem, name );
    },

    // TODO: Now that all calls to _data and _removeData have been replaced
    // with direct calls to data_priv methods, these can be deprecated.
    _data: function( elem, name, data ) {
        return data_priv.access( elem, name, data );
    },

    _removeData: function( elem, name ) {
        data_priv.remove( elem, name );
    }
});

jQuery.fn.extend({
    data: function( key, value ) {
        var attrs, name,
            elem = this[ 0 ],
            i = 0,
            data = null;

        // Gets all values
        if ( key === undefined ) {
            if ( this.length ) {
                data = data_user.get( elem );

                if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
                    attrs = elem.attributes;
                    for ( ; i < attrs.length; i++ ) {
                        name = attrs[ i ].name;

                        if ( name.indexOf( "data-" ) === 0 ) {
                            name = jQuery.camelCase( name.slice(5) );
                            dataAttr( elem, name, data[ name ] );
                        }
                    }
                    data_priv.set( elem, "hasDataAttrs", true );
                }
            }

            return data;
        }

        // Sets multiple values
        if ( typeof key === "object" ) {
            return this.each(function() {
                data_user.set( this, key );
            });
        }

        return jQuery.access( this, function( value ) {
            var data,
                camelKey = jQuery.camelCase( key );

            // The calling jQuery object (element matches) is not empty
            // (and therefore has an element appears at this[ 0 ]) and the
            // `value` parameter was not undefined. An empty jQuery object
            // will result in `undefined` for elem = this[ 0 ] which will
            // throw an exception if an attempt to read a data cache is made.
            if ( elem && value === undefined ) {
                // Attempt to get data from the cache
                // with the key as-is
                data = data_user.get( elem, key );
                if ( data !== undefined ) {
                    return data;
                }

                // Attempt to get data from the cache
                // with the key camelized
                data = data_user.get( elem, camelKey );
                if ( data !== undefined ) {
                    return data;
                }

                // Attempt to "discover" the data in
                // HTML5 custom data-* attrs
                data = dataAttr( elem, camelKey, undefined );
                if ( data !== undefined ) {
                    return data;
                }

                // We tried really hard, but the data doesn't exist.
                return;
            }

            // Set the data...
            this.each(function() {
                // First, attempt to store a copy or reference of any
                // data that might've been store with a camelCased key.
                var data = data_user.get( this, camelKey );

                // For HTML5 data-* attribute interop, we have to
                // store property names with dashes in a camelCase form.
                // This might not apply to all properties...*
                data_user.set( this, camelKey, value );

                // *... In the case of properties that might _actually_
                // have dashes, we need to also store a copy of that
                // unchanged property.
                if ( key.indexOf("-") !== -1 && data !== undefined ) {
                    data_user.set( this, key, value );
                }
            });
        }, null, value, arguments.length > 1, null, true );
    },

    removeData: function( key ) {
        return this.each(function() {
            data_user.remove( this, key );
        });
    }
});

function dataAttr( elem, key, data ) {
    var name;

    // If nothing was found internally, try to fetch any
    // data from the HTML5 data-* attribute
    if ( data === undefined && elem.nodeType === 1 ) {
        name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
        data = elem.getAttribute( name );

        if ( typeof data === "string" ) {
            try {
                data = data === "true" ? true :
                    data === "false" ? false :
                    data === "null" ? null :
                    // Only convert to a number if it doesn't change the string
                    +data + "" === data ? +data :
                    rbrace.test( data ) ? JSON.parse( data ) :
                    data;
            } catch( e ) {}

            // Make sure we set the data so it isn't changed later
            data_user.set( elem, key, data );
        } else {
            data = undefined;
        }
    }
    return data;
}
jQuery.extend({
    queue: function( elem, type, data ) {
        var queue;

        if ( elem ) {
            type = ( type || "fx" ) + "queue";
            queue = data_priv.get( elem, type );

            // Speed up dequeue by getting out quickly if this is just a lookup
            if ( data ) {
                if ( !queue || jQuery.isArray( data ) ) {
                    queue = data_priv.access( elem, type, jQuery.makeArray(data) );
                } else {
                    queue.push( data );
                }
            }
            return queue || [];
        }
    },

    dequeue: function( elem, type ) {
        type = type || "fx";

        var queue = jQuery.queue( elem, type ),
            startLength = queue.length,
            fn = queue.shift(),
            hooks = jQuery._queueHooks( elem, type ),
            next = function() {
                jQuery.dequeue( elem, type );
            };

        // If the fx queue is dequeued, always remove the progress sentinel
        if ( fn === "inprogress" ) {
            fn = queue.shift();
            startLength--;
        }

        if ( fn ) {

            // Add a progress sentinel to prevent the fx queue from being
            // automatically dequeued
            if ( type === "fx" ) {
                queue.unshift( "inprogress" );
            }

            // clear up the last queue stop function
            delete hooks.stop;
            fn.call( elem, next, hooks );
        }

        if ( !startLength && hooks ) {
            hooks.empty.fire();
        }
    },

    // not intended for public consumption - generates a queueHooks object, or returns the current one
    _queueHooks: function( elem, type ) {
        var key = type + "queueHooks";
        return data_priv.get( elem, key ) || data_priv.access( elem, key, {
            empty: jQuery.Callbacks("once memory").add(function() {
                data_priv.remove( elem, [ type + "queue", key ] );
            })
        });
    }
});

jQuery.fn.extend({
    queue: function( type, data ) {
        var setter = 2;

        if ( typeof type !== "string" ) {
            data = type;
            type = "fx";
            setter--;
        }

        if ( arguments.length < setter ) {
            return jQuery.queue( this[0], type );
        }

        return data === undefined ?
            this :
            this.each(function() {
                var queue = jQuery.queue( this, type, data );

                // ensure a hooks for this queue
                jQuery._queueHooks( this, type );

                if ( type === "fx" && queue[0] !== "inprogress" ) {
                    jQuery.dequeue( this, type );
                }
            });
    },
    dequeue: function( type ) {
        return this.each(function() {
            jQuery.dequeue( this, type );
        });
    },
    // Based off of the plugin by Clint Helfers, with permission.
    // http://blindsignals.com/index.php/2009/07/jquery-delay/
    delay: function( time, type ) {
        time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
        type = type || "fx";

        return this.queue( type, function( next, hooks ) {
            var timeout = setTimeout( next, time );
            hooks.stop = function() {
                clearTimeout( timeout );
            };
        });
    },
    clearQueue: function( type ) {
        return this.queue( type || "fx", [] );
    },
    // Get a promise resolved when queues of a certain type
    // are emptied (fx is the type by default)
    promise: function( type, obj ) {
        var tmp,
            count = 1,
            defer = jQuery.Deferred(),
            elements = this,
            i = this.length,
            resolve = function() {
                if ( !( --count ) ) {
                    defer.resolveWith( elements, [ elements ] );
                }
            };

        if ( typeof type !== "string" ) {
            obj = type;
            type = undefined;
        }
        type = type || "fx";

        while( i-- ) {
            tmp = data_priv.get( elements[ i ], type + "queueHooks" );
            if ( tmp && tmp.empty ) {
                count++;
                tmp.empty.add( resolve );
            }
        }
        resolve();
        return defer.promise( obj );
    }
});
var nodeHook, boolHook,
    rclass = /[\t\r\n\f]/g,
    rreturn = /\r/g,
    rfocusable = /^(?:input|select|textarea|button)$/i;

jQuery.fn.extend({
    attr: function( name, value ) {
        return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
    },

    removeAttr: function( name ) {
        return this.each(function() {
            jQuery.removeAttr( this, name );
        });
    },

    prop: function( name, value ) {
        return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
    },

    removeProp: function( name ) {
        return this.each(function() {
            delete this[ jQuery.propFix[ name ] || name ];
        });
    },

    addClass: function( value ) {
        var classes, elem, cur, clazz, j,
            i = 0,
            len = this.length,
            proceed = typeof value === "string" && value;

        if ( jQuery.isFunction( value ) ) {
            return this.each(function( j ) {
                jQuery( this ).addClass( value.call( this, j, this.className ) );
            });
        }

        if ( proceed ) {
            // The disjunction here is for better compressibility (see removeClass)
            classes = ( value || "" ).match( core_rnotwhite ) || [];

            for ( ; i < len; i++ ) {
                elem = this[ i ];
                cur = elem.nodeType === 1 && ( elem.className ?
                    ( " " + elem.className + " " ).replace( rclass, " " ) :
                    " "
                );

                if ( cur ) {
                    j = 0;
                    while ( (clazz = classes[j++]) ) {
                        if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
                            cur += clazz + " ";
                        }
                    }
                    elem.className = jQuery.trim( cur );

                }
            }
        }

        return this;
    },

    removeClass: function( value ) {
        var classes, elem, cur, clazz, j,
            i = 0,
            len = this.length,
            proceed = arguments.length === 0 || typeof value === "string" && value;

        if ( jQuery.isFunction( value ) ) {
            return this.each(function( j ) {
                jQuery( this ).removeClass( value.call( this, j, this.className ) );
            });
        }
        if ( proceed ) {
            classes = ( value || "" ).match( core_rnotwhite ) || [];

            for ( ; i < len; i++ ) {
                elem = this[ i ];
                // This expression is here for better compressibility (see addClass)
                cur = elem.nodeType === 1 && ( elem.className ?
                    ( " " + elem.className + " " ).replace( rclass, " " ) :
                    ""
                );

                if ( cur ) {
                    j = 0;
                    while ( (clazz = classes[j++]) ) {
                        // Remove *all* instances
                        while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
                            cur = cur.replace( " " + clazz + " ", " " );
                        }
                    }
                    elem.className = value ? jQuery.trim( cur ) : "";
                }
            }
        }

        return this;
    },

    toggleClass: function( value, stateVal ) {
        var type = typeof value;

        if ( typeof stateVal === "boolean" && type === "string" ) {
            return stateVal ? this.addClass( value ) : this.removeClass( value );
        }

        if ( jQuery.isFunction( value ) ) {
            return this.each(function( i ) {
                jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
            });
        }

        return this.each(function() {
            if ( type === "string" ) {
                // toggle individual class names
                var className,
                    i = 0,
                    self = jQuery( this ),
                    classNames = value.match( core_rnotwhite ) || [];

                while ( (className = classNames[ i++ ]) ) {
                    // check each className given, space separated list
                    if ( self.hasClass( className ) ) {
                        self.removeClass( className );
                    } else {
                        self.addClass( className );
                    }
                }

            // Toggle whole class name
            } else if ( type === core_strundefined || type === "boolean" ) {
                if ( this.className ) {
                    // store className if set
                    data_priv.set( this, "__className__", this.className );
                }

                // If the element has a class name or if we're passed "false",
                // then remove the whole classname (if there was one, the above saved it).
                // Otherwise bring back whatever was previously saved (if anything),
                // falling back to the empty string if nothing was stored.
                this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
            }
        });
    },

    hasClass: function( selector ) {
        var className = " " + selector + " ",
            i = 0,
            l = this.length;
        for ( ; i < l; i++ ) {
            if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
                return true;
            }
        }

        return false;
    },

    val: function( value ) {
        var hooks, ret, isFunction,
            elem = this[0];

        if ( !arguments.length ) {
            if ( elem ) {
                hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];

                if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
                    return ret;
                }

                ret = elem.value;

                return typeof ret === "string" ?
                    // handle most common string cases
                    ret.replace(rreturn, "") :
                    // handle cases where value is null/undef or number
                    ret == null ? "" : ret;
            }

            return;
        }

        isFunction = jQuery.isFunction( value );

        return this.each(function( i ) {
            var val;

            if ( this.nodeType !== 1 ) {
                return;
            }

            if ( isFunction ) {
                val = value.call( this, i, jQuery( this ).val() );
            } else {
                val = value;
            }

            // Treat null/undefined as ""; convert numbers to string
            if ( val == null ) {
                val = "";
            } else if ( typeof val === "number" ) {
                val += "";
            } else if ( jQuery.isArray( val ) ) {
                val = jQuery.map(val, function ( value ) {
                    return value == null ? "" : value + "";
                });
            }

            hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];

            // If set returns undefined, fall back to normal setting
            if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
                this.value = val;
            }
        });
    }
});

jQuery.extend({
    valHooks: {
        option: {
            get: function( elem ) {
                // attributes.value is undefined in Blackberry 4.7 but
                // uses .value. See #6932
                var val = elem.attributes.value;
                return !val || val.specified ? elem.value : elem.text;
            }
        },
        select: {
            get: function( elem ) {
                var value, option,
                    options = elem.options,
                    index = elem.selectedIndex,
                    one = elem.type === "select-one" || index < 0,
                    values = one ? null : [],
                    max = one ? index + 1 : options.length,
                    i = index < 0 ?
                        max :
                        one ? index : 0;

                // Loop through all the selected options
                for ( ; i < max; i++ ) {
                    option = options[ i ];

                    // IE6-9 doesn't update selected after form reset (#2551)
                    if ( ( option.selected || i === index ) &&
                            // Don't return options that are disabled or in a disabled optgroup
                            ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
                            ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {

                        // Get the specific value for the option
                        value = jQuery( option ).val();

                        // We don't need an array for one selects
                        if ( one ) {
                            return value;
                        }

                        // Multi-Selects return an array
                        values.push( value );
                    }
                }

                return values;
            },

            set: function( elem, value ) {
                var optionSet, option,
                    options = elem.options,
                    values = jQuery.makeArray( value ),
                    i = options.length;

                while ( i-- ) {
                    option = options[ i ];
                    if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
                        optionSet = true;
                    }
                }

                // force browsers to behave consistently when non-matching value is set
                if ( !optionSet ) {
                    elem.selectedIndex = -1;
                }
                return values;
            }
        }
    },

    attr: function( elem, name, value ) {
        var hooks, ret,
            nType = elem.nodeType;

        // don't get/set attributes on text, comment and attribute nodes
        if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
            return;
        }

        // Fallback to prop when attributes are not supported
        if ( typeof elem.getAttribute === core_strundefined ) {
            return jQuery.prop( elem, name, value );
        }

        // All attributes are lowercase
        // Grab necessary hook if one is defined
        if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
            name = name.toLowerCase();
            hooks = jQuery.attrHooks[ name ] ||
                ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
        }

        if ( value !== undefined ) {

            if ( value === null ) {
                jQuery.removeAttr( elem, name );

            } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
                return ret;

            } else {
                elem.setAttribute( name, value + "" );
                return value;
            }

        } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
            return ret;

        } else {
            ret = jQuery.find.attr( elem, name );

            // Non-existent attributes return null, we normalize to undefined
            return ret == null ?
                undefined :
                ret;
        }
    },

    removeAttr: function( elem, value ) {
        var name, propName,
            i = 0,
            attrNames = value && value.match( core_rnotwhite );

        if ( attrNames && elem.nodeType === 1 ) {
            while ( (name = attrNames[i++]) ) {
                propName = jQuery.propFix[ name ] || name;

                // Boolean attributes get special treatment (#10870)
                if ( jQuery.expr.match.bool.test( name ) ) {
                    // Set corresponding property to false
                    elem[ propName ] = false;
                }

                elem.removeAttribute( name );
            }
        }
    },

    attrHooks: {
        type: {
            set: function( elem, value ) {
                if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
                    // Setting the type on a radio button after the value resets the value in IE6-9
                    // Reset value to default in case type is set after value during creation
                    var val = elem.value;
                    elem.setAttribute( "type", value );
                    if ( val ) {
                        elem.value = val;
                    }
                    return value;
                }
            }
        }
    },

    propFix: {
        "for": "htmlFor",
        "class": "className"
    },

    prop: function( elem, name, value ) {
        var ret, hooks, notxml,
            nType = elem.nodeType;

        // don't get/set properties on text, comment and attribute nodes
        if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
            return;
        }

        notxml = nType !== 1 || !jQuery.isXMLDoc( elem );

        if ( notxml ) {
            // Fix name and attach hooks
            name = jQuery.propFix[ name ] || name;
            hooks = jQuery.propHooks[ name ];
        }

        if ( value !== undefined ) {
            return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
                ret :
                ( elem[ name ] = value );

        } else {
            return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
                ret :
                elem[ name ];
        }
    },

    propHooks: {
        tabIndex: {
            get: function( elem ) {
                return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
                    elem.tabIndex :
                    -1;
            }
        }
    }
});

// Hooks for boolean attributes
boolHook = {
    set: function( elem, value, name ) {
        if ( value === false ) {
            // Remove boolean attributes when set to false
            jQuery.removeAttr( elem, name );
        } else {
            elem.setAttribute( name, name );
        }
        return name;
    }
};
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
    var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;

    jQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) {
        var fn = jQuery.expr.attrHandle[ name ],
            ret = isXML ?
                undefined :
                
                // Temporarily disable this handler to check existence
                (jQuery.expr.attrHandle[ name ] = undefined) !=
                    getter( elem, name, isXML ) ?

                    name.toLowerCase() :
                    null;

        // Restore handler
        jQuery.expr.attrHandle[ name ] = fn;

        return ret;
    };
});

// Support: IE9+
// Selectedness for an option in an optgroup can be inaccurate
if ( !jQuery.support.optSelected ) {
    jQuery.propHooks.selected = {
        get: function( elem ) {
            var parent = elem.parentNode;
            if ( parent && parent.parentNode ) {
                parent.parentNode.selectedIndex;
            }
            return null;
        }
    };
}

jQuery.each([
    "tabIndex",
    "readOnly",
    "maxLength",
    "cellSpacing",
    "cellPadding",
    "rowSpan",
    "colSpan",
    "useMap",
    "frameBorder",
    "contentEditable"
], function() {
    jQuery.propFix[ this.toLowerCase() ] = this;
});

// Radios and checkboxes getter/setter
jQuery.each([ "radio", "checkbox" ], function() {
    jQuery.valHooks[ this ] = {
        set: function( elem, value ) {
            if ( jQuery.isArray( value ) ) {
                return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
            }
        }
    };
    if ( !jQuery.support.checkOn ) {
        jQuery.valHooks[ this ].get = function( elem ) {
            // Support: Webkit
            // "" is returned instead of "on" if a value isn't specified
            return elem.getAttribute("value") === null ? "on" : elem.value;
        };
    }
});
var rkeyEvent = /^key/,
    rmouseEvent = /^(?:mouse|contextmenu)|click/,
    rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
    rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;

function returnTrue() {
    return true;
}

function returnFalse() {
    return false;
}

function safeActiveElement() {
    try {
        return document.activeElement;
    } catch ( err ) { }
}


jQuery.event = {

    global: {},

    add: function( elem, types, handler, data, selector ) {

        var handleObjIn, eventHandle, tmp,
            events, t, handleObj,
            special, handlers, type, namespaces, origType,
            elemData = data_priv.get( elem );

        // Don't attach events to noData or text/comment nodes (but allow plain objects)
        if ( !elemData ) {
            return;
        }

        // Caller can pass in an object of custom data in lieu of the handler
        if ( handler.handler ) {
            handleObjIn = handler;
            handler = handleObjIn.handler;
            selector = handleObjIn.selector;
        }

        // Make sure that the handler has a unique ID, used to find/remove it later
        if ( !handler.guid ) {
            handler.guid = jQuery.guid++;
        }

        // Init the element's event structure and main handler, if this is the first
        if ( !(events = elemData.events) ) {
            events = elemData.events = {};
        }
        if ( !(eventHandle = elemData.handle) ) {
            eventHandle = elemData.handle = function( e ) {
                // Discard the second event of a jQuery.event.trigger() and
                // when an event is called after a page has unloaded
                return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
                    jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
                    undefined;
            };
            // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
            eventHandle.elem = elem;
        }

        // Handle multiple events separated by a space
        types = ( types || "" ).match( core_rnotwhite ) || [""];
        t = types.length;
        while ( t-- ) {
            tmp = rtypenamespace.exec( types[t] ) || [];
            type = origType = tmp[1];
            namespaces = ( tmp[2] || "" ).split( "." ).sort();

            // There *must* be a type, no attaching namespace-only handlers
            if ( !type ) {
                continue;
            }

            // If event changes its type, use the special event handlers for the changed type
            special = jQuery.event.special[ type ] || {};

            // If selector defined, determine special event api type, otherwise given type
            type = ( selector ? special.delegateType : special.bindType ) || type;

            // Update special based on newly reset type
            special = jQuery.event.special[ type ] || {};

            // handleObj is passed to all event handlers
            handleObj = jQuery.extend({
                type: type,
                origType: origType,
                data: data,
                handler: handler,
                guid: handler.guid,
                selector: selector,
                needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
                namespace: namespaces.join(".")
            }, handleObjIn );

            // Init the event handler queue if we're the first
            if ( !(handlers = events[ type ]) ) {
                handlers = events[ type ] = [];
                handlers.delegateCount = 0;

                // Only use addEventListener if the special events handler returns false
                if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
                    if ( elem.addEventListener ) {
                        elem.addEventListener( type, eventHandle, false );
                    }
                }
            }

            if ( special.add ) {
                special.add.call( elem, handleObj );

                if ( !handleObj.handler.guid ) {
                    handleObj.handler.guid = handler.guid;
                }
            }

            // Add to the element's handler list, delegates in front
            if ( selector ) {
                handlers.splice( handlers.delegateCount++, 0, handleObj );
            } else {
                handlers.push( handleObj );
            }

            // Keep track of which events have ever been used, for event optimization
            jQuery.event.global[ type ] = true;
        }

        // Nullify elem to prevent memory leaks in IE
        elem = null;
    },

    // Detach an event or set of events from an element
    remove: function( elem, types, handler, selector, mappedTypes ) {

        var j, origCount, tmp,
            events, t, handleObj,
            special, handlers, type, namespaces, origType,
            elemData = data_priv.hasData( elem ) && data_priv.get( elem );

        if ( !elemData || !(events = elemData.events) ) {
            return;
        }

        // Once for each type.namespace in types; type may be omitted
        types = ( types || "" ).match( core_rnotwhite ) || [""];
        t = types.length;
        while ( t-- ) {
            tmp = rtypenamespace.exec( types[t] ) || [];
            type = origType = tmp[1];
            namespaces = ( tmp[2] || "" ).split( "." ).sort();

            // Unbind all events (on this namespace, if provided) for the element
            if ( !type ) {
                for ( type in events ) {
                    jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
                }
                continue;
            }

            special = jQuery.event.special[ type ] || {};
            type = ( selector ? special.delegateType : special.bindType ) || type;
            handlers = events[ type ] || [];
            tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );

            // Remove matching events
            origCount = j = handlers.length;
            while ( j-- ) {
                handleObj = handlers[ j ];

                if ( ( mappedTypes || origType === handleObj.origType ) &&
                    ( !handler || handler.guid === handleObj.guid ) &&
                    ( !tmp || tmp.test( handleObj.namespace ) ) &&
                    ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
                    handlers.splice( j, 1 );

                    if ( handleObj.selector ) {
                        handlers.delegateCount--;
                    }
                    if ( special.remove ) {
                        special.remove.call( elem, handleObj );
                    }
                }
            }

            // Remove generic event handler if we removed something and no more handlers exist
            // (avoids potential for endless recursion during removal of special event handlers)
            if ( origCount && !handlers.length ) {
                if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
                    jQuery.removeEvent( elem, type, elemData.handle );
                }

                delete events[ type ];
            }
        }

        // Remove the expando if it's no longer used
        if ( jQuery.isEmptyObject( events ) ) {
            delete elemData.handle;
            data_priv.remove( elem, "events" );
        }
    },

    trigger: function( event, data, elem, onlyHandlers ) {

        var i, cur, tmp, bubbleType, ontype, handle, special,
            eventPath = [ elem || document ],
            type = core_hasOwn.call( event, "type" ) ? event.type : event,
            namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];

        cur = tmp = elem = elem || document;

        // Don't do events on text and comment nodes
        if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
            return;
        }

        // focus/blur morphs to focusin/out; ensure we're not firing them right now
        if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
            return;
        }

        if ( type.indexOf(".") >= 0 ) {
            // Namespaced trigger; create a regexp to match event type in handle()
            namespaces = type.split(".");
            type = namespaces.shift();
            namespaces.sort();
        }
        ontype = type.indexOf(":") < 0 && "on" + type;

        // Caller can pass in a jQuery.Event object, Object, or just an event type string
        event = event[ jQuery.expando ] ?
            event :
            new jQuery.Event( type, typeof event === "object" && event );

        // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
        event.isTrigger = onlyHandlers ? 2 : 3;
        event.namespace = namespaces.join(".");
        event.namespace_re = event.namespace ?
            new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
            null;

        // Clean up the event in case it is being reused
        event.result = undefined;
        if ( !event.target ) {
            event.target = elem;
        }

        // Clone any incoming data and prepend the event, creating the handler arg list
        data = data == null ?
            [ event ] :
            jQuery.makeArray( data, [ event ] );

        // Allow special events to draw outside the lines
        special = jQuery.event.special[ type ] || {};
        if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
            return;
        }

        // Determine event propagation path in advance, per W3C events spec (#9951)
        // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
        if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {

            bubbleType = special.delegateType || type;
            if ( !rfocusMorph.test( bubbleType + type ) ) {
                cur = cur.parentNode;
            }
            for ( ; cur; cur = cur.parentNode ) {
                eventPath.push( cur );
                tmp = cur;
            }

            // Only add window if we got to document (e.g., not plain obj or detached DOM)
            if ( tmp === (elem.ownerDocument || document) ) {
                eventPath.push( tmp.defaultView || tmp.parentWindow || window );
            }
        }

        // Fire handlers on the event path
        i = 0;
        while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {

            event.type = i > 1 ?
                bubbleType :
                special.bindType || type;

            // jQuery handler
            handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
            if ( handle ) {
                handle.apply( cur, data );
            }

            // Native handler
            handle = ontype && cur[ ontype ];
            if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
                event.preventDefault();
            }
        }
        event.type = type;

        // If nobody prevented the default action, do it now
        if ( !onlyHandlers && !event.isDefaultPrevented() ) {

            if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
                jQuery.acceptData( elem ) ) {

                // Call a native DOM method on the target with the same name name as the event.
                // Don't do default actions on window, that's where global variables be (#6170)
                if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {

                    // Don't re-trigger an onFOO event when we call its FOO() method
                    tmp = elem[ ontype ];

                    if ( tmp ) {
                        elem[ ontype ] = null;
                    }

                    // Prevent re-triggering of the same event, since we already bubbled it above
                    jQuery.event.triggered = type;
                    elem[ type ]();
                    jQuery.event.triggered = undefined;

                    if ( tmp ) {
                        elem[ ontype ] = tmp;
                    }
                }
            }
        }

        return event.result;
    },

    dispatch: function( event ) {

        // Make a writable jQuery.Event from the native event object
        event = jQuery.event.fix( event );

        var i, j, ret, matched, handleObj,
            handlerQueue = [],
            args = core_slice.call( arguments ),
            handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
            special = jQuery.event.special[ event.type ] || {};

        // Use the fix-ed jQuery.Event rather than the (read-only) native event
        args[0] = event;
        event.delegateTarget = this;

        // Call the preDispatch hook for the mapped type, and let it bail if desired
        if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
            return;
        }

        // Determine handlers
        handlerQueue = jQuery.event.handlers.call( this, event, handlers );

        // Run delegates first; they may want to stop propagation beneath us
        i = 0;
        while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
            event.currentTarget = matched.elem;

            j = 0;
            while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {

                // Triggered event must either 1) have no namespace, or
                // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
                if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {

                    event.handleObj = handleObj;
                    event.data = handleObj.data;

                    ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
                            .apply( matched.elem, args );

                    if ( ret !== undefined ) {
                        if ( (event.result = ret) === false ) {
                            event.preventDefault();
                            event.stopPropagation();
                        }
                    }
                }
            }
        }

        // Call the postDispatch hook for the mapped type
        if ( special.postDispatch ) {
            special.postDispatch.call( this, event );
        }

        return event.result;
    },

    handlers: function( event, handlers ) {
        var i, matches, sel, handleObj,
            handlerQueue = [],
            delegateCount = handlers.delegateCount,
            cur = event.target;

        // Find delegate handlers
        // Black-hole SVG <use> instance trees (#13180)
        // Avoid non-left-click bubbling in Firefox (#3861)
        if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {

            for ( ; cur !== this; cur = cur.parentNode || this ) {

                // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
                if ( cur.disabled !== true || event.type !== "click" ) {
                    matches = [];
                    for ( i = 0; i < delegateCount; i++ ) {
                        handleObj = handlers[ i ];

                        // Don't conflict with Object.prototype properties (#13203)
                        sel = handleObj.selector + " ";

                        if ( matches[ sel ] === undefined ) {
                            matches[ sel ] = handleObj.needsContext ?
                                jQuery( sel, this ).index( cur ) >= 0 :
                                jQuery.find( sel, this, null, [ cur ] ).length;
                        }
                        if ( matches[ sel ] ) {
                            matches.push( handleObj );
                        }
                    }
                    if ( matches.length ) {
                        handlerQueue.push({ elem: cur, handlers: matches });
                    }
                }
            }
        }

        // Add the remaining (directly-bound) handlers
        if ( delegateCount < handlers.length ) {
            handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
        }

        return handlerQueue;
    },

    // Includes some event props shared by KeyEvent and MouseEvent
    props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),

    fixHooks: {},

    keyHooks: {
        props: "char charCode key keyCode".split(" "),
        filter: function( event, original ) {

            // Add which for key events
            if ( event.which == null ) {
                event.which = original.charCode != null ? original.charCode : original.keyCode;
            }

            return event;
        }
    },

    mouseHooks: {
        props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
        filter: function( event, original ) {
            var eventDoc, doc, body,
                button = original.button;

            // Calculate pageX/Y if missing and clientX/Y available
            if ( event.pageX == null && original.clientX != null ) {
                eventDoc = event.target.ownerDocument || document;
                doc = eventDoc.documentElement;
                body = eventDoc.body;

                event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
                event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
            }

            // Add which for click: 1 === left; 2 === middle; 3 === right
            // Note: button is not normalized, so don't use it
            if ( !event.which && button !== undefined ) {
                event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
            }

            return event;
        }
    },

    fix: function( event ) {
        if ( event[ jQuery.expando ] ) {
            return event;
        }

        // Create a writable copy of the event object and normalize some properties
        var i, prop, copy,
            type = event.type,
            originalEvent = event,
            fixHook = this.fixHooks[ type ];

        if ( !fixHook ) {
            this.fixHooks[ type ] = fixHook =
                rmouseEvent.test( type ) ? this.mouseHooks :
                rkeyEvent.test( type ) ? this.keyHooks :
                {};
        }
        copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;

        event = new jQuery.Event( originalEvent );

        i = copy.length;
        while ( i-- ) {
            prop = copy[ i ];
            event[ prop ] = originalEvent[ prop ];
        }

        // Support: Cordova 2.5 (WebKit) (#13255)
        // All events should have a target; Cordova deviceready doesn't
        if ( !event.target ) {
            event.target = document;
        }

        // Support: Safari 6.0+, Chrome < 28
        // Target should not be a text node (#504, #13143)
        if ( event.target.nodeType === 3 ) {
            event.target = event.target.parentNode;
        }

        return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
    },

    special: {
        load: {
            // Prevent triggered image.load events from bubbling to window.load
            noBubble: true
        },
        focus: {
            // Fire native event if possible so blur/focus sequence is correct
            trigger: function() {
                if ( this !== safeActiveElement() && this.focus ) {
                    this.focus();
                    return false;
                }
            },
            delegateType: "focusin"
        },
        blur: {
            trigger: function() {
                if ( this === safeActiveElement() && this.blur ) {
                    this.blur();
                    return false;
                }
            },
            delegateType: "focusout"
        },
        click: {
            // For checkbox, fire native event so checked state will be right
            trigger: function() {
                if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
                    this.click();
                    return false;
                }
            },

            // For cross-browser consistency, don't fire native .click() on links
            _default: function( event ) {
                return jQuery.nodeName( event.target, "a" );
            }
        },

        beforeunload: {
            postDispatch: function( event ) {

                // Support: Firefox 20+
                // Firefox doesn't alert if the returnValue field is not set.
                if ( event.result !== undefined ) {
                    event.originalEvent.returnValue = event.result;
                }
            }
        }
    },

    simulate: function( type, elem, event, bubble ) {
        // Piggyback on a donor event to simulate a different one.
        // Fake originalEvent to avoid donor's stopPropagation, but if the
        // simulated event prevents default then we do the same on the donor.
        var e = jQuery.extend(
            new jQuery.Event(),
            event,
            {
                type: type,
                isSimulated: true,
                originalEvent: {}
            }
        );
        if ( bubble ) {
            jQuery.event.trigger( e, null, elem );
        } else {
            jQuery.event.dispatch.call( elem, e );
        }
        if ( e.isDefaultPrevented() ) {
            event.preventDefault();
        }
    }
};

jQuery.removeEvent = function( elem, type, handle ) {
    if ( elem.removeEventListener ) {
        elem.removeEventListener( type, handle, false );
    }
};

jQuery.Event = function( src, props ) {
    // Allow instantiation without the 'new' keyword
    if ( !(this instanceof jQuery.Event) ) {
        return new jQuery.Event( src, props );
    }

    // Event object
    if ( src && src.type ) {
        this.originalEvent = src;
        this.type = src.type;

        // Events bubbling up the document may have been marked as prevented
        // by a handler lower down the tree; reflect the correct value.
        this.isDefaultPrevented = ( src.defaultPrevented ||
            src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;

    // Event type
    } else {
        this.type = src;
    }

    // Put explicitly provided properties onto the event object
    if ( props ) {
        jQuery.extend( this, props );
    }

    // Create a timestamp if incoming event doesn't have one
    this.timeStamp = src && src.timeStamp || jQuery.now();

    // Mark it as fixed
    this[ jQuery.expando ] = true;
};

// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
    isDefaultPrevented: returnFalse,
    isPropagationStopped: returnFalse,
    isImmediatePropagationStopped: returnFalse,

    preventDefault: function() {
        var e = this.originalEvent;

        this.isDefaultPrevented = returnTrue;

        if ( e && e.preventDefault ) {
            e.preventDefault();
        }
    },
    stopPropagation: function() {
        var e = this.originalEvent;

        this.isPropagationStopped = returnTrue;

        if ( e && e.stopPropagation ) {
            e.stopPropagation();
        }
    },
    stopImmediatePropagation: function() {
        this.isImmediatePropagationStopped = returnTrue;
        this.stopPropagation();
    }
};

// Create mouseenter/leave events using mouseover/out and event-time checks
// Support: Chrome 15+
jQuery.each({
    mouseenter: "mouseover",
    mouseleave: "mouseout"
}, function( orig, fix ) {
    jQuery.event.special[ orig ] = {
        delegateType: fix,
        bindType: fix,

        handle: function( event ) {
            var ret,
                target = this,
                related = event.relatedTarget,
                handleObj = event.handleObj;

            // For mousenter/leave call the handler if related is outside the target.
            // NB: No relatedTarget if the mouse left/entered the browser window
            if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
                event.type = handleObj.origType;
                ret = handleObj.handler.apply( this, arguments );
                event.type = fix;
            }
            return ret;
        }
    };
});

// Create "bubbling" focus and blur events
// Support: Firefox, Chrome, Safari
if ( !jQuery.support.focusinBubbles ) {
    jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {

        // Attach a single capturing handler while someone wants focusin/focusout
        var attaches = 0,
            handler = function( event ) {
                jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
            };

        jQuery.event.special[ fix ] = {
            setup: function() {
                if ( attaches++ === 0 ) {
                    document.addEventListener( orig, handler, true );
                }
            },
            teardown: function() {
                if ( --attaches === 0 ) {
                    document.removeEventListener( orig, handler, true );
                }
            }
        };
    });
}

jQuery.fn.extend({

    on: function( types, selector, data, fn,  one ) {
        var origFn, type;

        // Types can be a map of types/handlers
        if ( typeof types === "object" ) {
            // ( types-Object, selector, data )
            if ( typeof selector !== "string" ) {
                // ( types-Object, data )
                data = data || selector;
                selector = undefined;
            }
            for ( type in types ) {
                this.on( type, selector, data, types[ type ], one );
            }
            return this;
        }

        if ( data == null && fn == null ) {
            // ( types, fn )
            fn = selector;
            data = selector = undefined;
        } else if ( fn == null ) {
            if ( typeof selector === "string" ) {
                // ( types, selector, fn )
                fn = data;
                data = undefined;
            } else {
                // ( types, data, fn )
                fn = data;
                data = selector;
                selector = undefined;
            }
        }
        if ( fn === false ) {
            fn = returnFalse;
        } else if ( !fn ) {
            return this;
        }

        if ( one === 1 ) {
            origFn = fn;
            fn = function( event ) {
                // Can use an empty set, since event contains the info
                jQuery().off( event );
                return origFn.apply( this, arguments );
            };
            // Use same guid so caller can remove using origFn
            fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
        }
        return this.each( function() {
            jQuery.event.add( this, types, fn, data, selector );
        });
    },
    one: function( types, selector, data, fn ) {
        return this.on( types, selector, data, fn, 1 );
    },
    off: function( types, selector, fn ) {
        var handleObj, type;
        if ( types && types.preventDefault && types.handleObj ) {
            // ( event )  dispatched jQuery.Event
            handleObj = types.handleObj;
            jQuery( types.delegateTarget ).off(
                handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
                handleObj.selector,
                handleObj.handler
            );
            return this;
        }
        if ( typeof types === "object" ) {
            // ( types-object [, selector] )
            for ( type in types ) {
                this.off( type, selector, types[ type ] );
            }
            return this;
        }
        if ( selector === false || typeof selector === "function" ) {
            // ( types [, fn] )
            fn = selector;
            selector = undefined;
        }
        if ( fn === false ) {
            fn = returnFalse;
        }
        return this.each(function() {
            jQuery.event.remove( this, types, fn, selector );
        });
    },

    trigger: function( type, data ) {
        return this.each(function() {
            jQuery.event.trigger( type, data, this );
        });
    },
    triggerHandler: function( type, data ) {
        var elem = this[0];
        if ( elem ) {
            return jQuery.event.trigger( type, data, elem, true );
        }
    }
});
var isSimple = /^.[^:#\[\.,]*$/,
    rparentsprev = /^(?:parents|prev(?:Until|All))/,
    rneedsContext = jQuery.expr.match.needsContext,
    // methods guaranteed to produce a unique set when starting from a unique set
    guaranteedUnique = {
        children: true,
        contents: true,
        next: true,
        prev: true
    };

jQuery.fn.extend({
    find: function( selector ) {
        var i,
            ret = [],
            self = this,
            len = self.length;

        if ( typeof selector !== "string" ) {
            return this.pushStack( jQuery( selector ).filter(function() {
                for ( i = 0; i < len; i++ ) {
                    if ( jQuery.contains( self[ i ], this ) ) {
                        return true;
                    }
                }
            }) );
        }

        for ( i = 0; i < len; i++ ) {
            jQuery.find( selector, self[ i ], ret );
        }

        // Needed because $( selector, context ) becomes $( context ).find( selector )
        ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
        ret.selector = this.selector ? this.selector + " " + selector : selector;
        return ret;
    },

    has: function( target ) {
        var targets = jQuery( target, this ),
            l = targets.length;

        return this.filter(function() {
            var i = 0;
            for ( ; i < l; i++ ) {
                if ( jQuery.contains( this, targets[i] ) ) {
                    return true;
                }
            }
        });
    },

    not: function( selector ) {
        return this.pushStack( winnow(this, selector || [], true) );
    },

    filter: function( selector ) {
        return this.pushStack( winnow(this, selector || [], false) );
    },

    is: function( selector ) {
        return !!winnow(
            this,

            // If this is a positional/relative selector, check membership in the returned set
            // so $("p:first").is("p:last") won't return true for a doc with two "p".
            typeof selector === "string" && rneedsContext.test( selector ) ?
                jQuery( selector ) :
                selector || [],
            false
        ).length;
    },

    closest: function( selectors, context ) {
        var cur,
            i = 0,
            l = this.length,
            matched = [],
            pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ?
                jQuery( selectors, context || this.context ) :
                0;

        for ( ; i < l; i++ ) {
            for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
                // Always skip document fragments
                if ( cur.nodeType < 11 && (pos ?
                    pos.index(cur) > -1 :

                    // Don't pass non-elements to Sizzle
                    cur.nodeType === 1 &&
                        jQuery.find.matchesSelector(cur, selectors)) ) {

                    cur = matched.push( cur );
                    break;
                }
            }
        }

        return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
    },

    // Determine the position of an element within
    // the matched set of elements
    index: function( elem ) {

        // No argument, return index in parent
        if ( !elem ) {
            return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
        }

        // index in selector
        if ( typeof elem === "string" ) {
            return core_indexOf.call( jQuery( elem ), this[ 0 ] );
        }

        // Locate the position of the desired element
        return core_indexOf.call( this,

            // If it receives a jQuery object, the first element is used
            elem.jquery ? elem[ 0 ] : elem
        );
    },

    add: function( selector, context ) {
        var set = typeof selector === "string" ?
                jQuery( selector, context ) :
                jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
            all = jQuery.merge( this.get(), set );

        return this.pushStack( jQuery.unique(all) );
    },

    addBack: function( selector ) {
        return this.add( selector == null ?
            this.prevObject : this.prevObject.filter(selector)
        );
    }
});

function sibling( cur, dir ) {
    while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}

    return cur;
}

jQuery.each({
    parent: function( elem ) {
        var parent = elem.parentNode;
        return parent && parent.nodeType !== 11 ? parent : null;
    },
    parents: function( elem ) {
        return jQuery.dir( elem, "parentNode" );
    },
    parentsUntil: function( elem, i, until ) {
        return jQuery.dir( elem, "parentNode", until );
    },
    next: function( elem ) {
        return sibling( elem, "nextSibling" );
    },
    prev: function( elem ) {
        return sibling( elem, "previousSibling" );
    },
    nextAll: function( elem ) {
        return jQuery.dir( elem, "nextSibling" );
    },
    prevAll: function( elem ) {
        return jQuery.dir( elem, "previousSibling" );
    },
    nextUntil: function( elem, i, until ) {
        return jQuery.dir( elem, "nextSibling", until );
    },
    prevUntil: function( elem, i, until ) {
        return jQuery.dir( elem, "previousSibling", until );
    },
    siblings: function( elem ) {
        return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
    },
    children: function( elem ) {
        return jQuery.sibling( elem.firstChild );
    },
    contents: function( elem ) {
        return elem.contentDocument || jQuery.merge( [], elem.childNodes );
    }
}, function( name, fn ) {
    jQuery.fn[ name ] = function( until, selector ) {
        var matched = jQuery.map( this, fn, until );

        if ( name.slice( -5 ) !== "Until" ) {
            selector = until;
        }

        if ( selector && typeof selector === "string" ) {
            matched = jQuery.filter( selector, matched );
        }

        if ( this.length > 1 ) {
            // Remove duplicates
            if ( !guaranteedUnique[ name ] ) {
                jQuery.unique( matched );
            }

            // Reverse order for parents* and prev-derivatives
            if ( rparentsprev.test( name ) ) {
                matched.reverse();
            }
        }

        return this.pushStack( matched );
    };
});

jQuery.extend({
    filter: function( expr, elems, not ) {
        var elem = elems[ 0 ];

        if ( not ) {
            expr = ":not(" + expr + ")";
        }

        return elems.length === 1 && elem.nodeType === 1 ?
            jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
            jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
                return elem.nodeType === 1;
            }));
    },

    dir: function( elem, dir, until ) {
        var matched = [],
            truncate = until !== undefined;

        while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
            if ( elem.nodeType === 1 ) {
                if ( truncate && jQuery( elem ).is( until ) ) {
                    break;
                }
                matched.push( elem );
            }
        }
        return matched;
    },

    sibling: function( n, elem ) {
        var matched = [];

        for ( ; n; n = n.nextSibling ) {
            if ( n.nodeType === 1 && n !== elem ) {
                matched.push( n );
            }
        }

        return matched;
    }
});

// Implement the identical functionality for filter and not
function winnow( elements, qualifier, not ) {
    if ( jQuery.isFunction( qualifier ) ) {
        return jQuery.grep( elements, function( elem, i ) {
            
            return !!qualifier.call( elem, i, elem ) !== not;
        });

    }

    if ( qualifier.nodeType ) {
        return jQuery.grep( elements, function( elem ) {
            return ( elem === qualifier ) !== not;
        });

    }

    if ( typeof qualifier === "string" ) {
        if ( isSimple.test( qualifier ) ) {
            return jQuery.filter( qualifier, elements, not );
        }

        qualifier = jQuery.filter( qualifier, elements );
    }

    return jQuery.grep( elements, function( elem ) {
        return ( core_indexOf.call( qualifier, elem ) >= 0 ) !== not;
    });
}
var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
    rtagName = /<([\w:]+)/,
    rhtml = /<|&#?\w+;/,
    rnoInnerhtml = /<(?:script|style|link)/i,
    manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
    // checked="checked" or checked
    rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
    rscriptType = /^$|\/(?:java|ecma)script/i,
    rscriptTypeMasked = /^true\/(.*)/,
    rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,

    // We have to close these tags to support XHTML (#13200)
    wrapMap = {

        // Support: IE 9
        option: [ 1, "<select multiple='multiple'>", "</select>" ],

        thead: [ 1, "<table>", "</table>" ],
        col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
        tr: [ 2, "<table><tbody>", "</tbody></table>" ],
        td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],

        _default: [ 0, "", "" ]
    };

// Support: IE 9
wrapMap.optgroup = wrapMap.option;

wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;

jQuery.fn.extend({
    text: function( value ) {
        return jQuery.access( this, function( value ) {
            return value === undefined ?
                jQuery.text( this ) :
                this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );
        }, null, value, arguments.length );
    },

    append: function() {
        return this.domManip( arguments, function( elem ) {
            if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                var target = manipulationTarget( this, elem );
                target.appendChild( elem );
            }
        });
    },

    prepend: function() {
        return this.domManip( arguments, function( elem ) {
            if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                var target = manipulationTarget( this, elem );
                target.insertBefore( elem, target.firstChild );
            }
        });
    },

    before: function() {
        return this.domManip( arguments, function( elem ) {
            if ( this.parentNode ) {
                this.parentNode.insertBefore( elem, this );
            }
        });
    },

    after: function() {
        return this.domManip( arguments, function( elem ) {
            if ( this.parentNode ) {
                this.parentNode.insertBefore( elem, this.nextSibling );
            }
        });
    },

    // keepData is for internal use only--do not document
    remove: function( selector, keepData ) {
        var elem,
            elems = selector ? jQuery.filter( selector, this ) : this,
            i = 0;

        for ( ; (elem = elems[i]) != null; i++ ) {
            if ( !keepData && elem.nodeType === 1 ) {
                jQuery.cleanData( getAll( elem ) );
            }

            if ( elem.parentNode ) {
                if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
                    setGlobalEval( getAll( elem, "script" ) );
                }
                elem.parentNode.removeChild( elem );
            }
        }

        return this;
    },

    empty: function() {
        var elem,
            i = 0;

        for ( ; (elem = this[i]) != null; i++ ) {
            if ( elem.nodeType === 1 ) {

                // Prevent memory leaks
                jQuery.cleanData( getAll( elem, false ) );

                // Remove any remaining nodes
                elem.textContent = "";
            }
        }

        return this;
    },

    clone: function( dataAndEvents, deepDataAndEvents ) {
        dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
        deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

        return this.map( function () {
            return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
        });
    },

    html: function( value ) {
        return jQuery.access( this, function( value ) {
            var elem = this[ 0 ] || {},
                i = 0,
                l = this.length;

            if ( value === undefined && elem.nodeType === 1 ) {
                return elem.innerHTML;
            }

            // See if we can take a shortcut and just use innerHTML
            if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
                !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {

                value = value.replace( rxhtmlTag, "<$1></$2>" );

                try {
                    for ( ; i < l; i++ ) {
                        elem = this[ i ] || {};

                        // Remove element nodes and prevent memory leaks
                        if ( elem.nodeType === 1 ) {
                            jQuery.cleanData( getAll( elem, false ) );
                            elem.innerHTML = value;
                        }
                    }

                    elem = 0;

                // If using innerHTML throws an exception, use the fallback method
                } catch( e ) {}
            }

            if ( elem ) {
                this.empty().append( value );
            }
        }, null, value, arguments.length );
    },

    replaceWith: function() {
        var
            // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
            args = jQuery.map( this, function( elem ) {
                return [ elem.nextSibling, elem.parentNode ];
            }),
            i = 0;

        // Make the changes, replacing each context element with the new content
        this.domManip( arguments, function( elem ) {
            var next = args[ i++ ],
                parent = args[ i++ ];

            if ( parent ) {
                // Don't use the snapshot next if it has moved (#13810)
                if ( next && next.parentNode !== parent ) {
                    next = this.nextSibling;
                }
                jQuery( this ).remove();
                parent.insertBefore( elem, next );
            }
        // Allow new content to include elements from the context set
        }, true );

        // Force removal if there was no new content (e.g., from empty arguments)
        return i ? this : this.remove();
    },

    detach: function( selector ) {
        return this.remove( selector, true );
    },

    domManip: function( args, callback, allowIntersection ) {

        // Flatten any nested arrays
        args = core_concat.apply( [], args );

        var fragment, first, scripts, hasScripts, node, doc,
            i = 0,
            l = this.length,
            set = this,
            iNoClone = l - 1,
            value = args[ 0 ],
            isFunction = jQuery.isFunction( value );

        // We can't cloneNode fragments that contain checked, in WebKit
        if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
            return this.each(function( index ) {
                var self = set.eq( index );
                if ( isFunction ) {
                    args[ 0 ] = value.call( this, index, self.html() );
                }
                self.domManip( args, callback, allowIntersection );
            });
        }

        if ( l ) {
            fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );
            first = fragment.firstChild;

            if ( fragment.childNodes.length === 1 ) {
                fragment = first;
            }

            if ( first ) {
                scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
                hasScripts = scripts.length;

                // Use the original fragment for the last item instead of the first because it can end up
                // being emptied incorrectly in certain situations (#8070).
                for ( ; i < l; i++ ) {
                    node = fragment;

                    if ( i !== iNoClone ) {
                        node = jQuery.clone( node, true, true );

                        // Keep references to cloned scripts for later restoration
                        if ( hasScripts ) {
                            // Support: QtWebKit
                            // jQuery.merge because core_push.apply(_, arraylike) throws
                            jQuery.merge( scripts, getAll( node, "script" ) );
                        }
                    }

                    callback.call( this[ i ], node, i );
                }

                if ( hasScripts ) {
                    doc = scripts[ scripts.length - 1 ].ownerDocument;

                    // Reenable scripts
                    jQuery.map( scripts, restoreScript );

                    // Evaluate executable scripts on first document insertion
                    for ( i = 0; i < hasScripts; i++ ) {
                        node = scripts[ i ];
                        if ( rscriptType.test( node.type || "" ) &&
                            !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {

                            if ( node.src ) {
                                // Hope ajax is available...
                                jQuery._evalUrl( node.src );
                            } else {
                                jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
                            }
                        }
                    }
                }
            }
        }

        return this;
    }
});

jQuery.each({
    appendTo: "append",
    prependTo: "prepend",
    insertBefore: "before",
    insertAfter: "after",
    replaceAll: "replaceWith"
}, function( name, original ) {
    jQuery.fn[ name ] = function( selector ) {
        var elems,
            ret = [],
            insert = jQuery( selector ),
            last = insert.length - 1,
            i = 0;

        for ( ; i <= last; i++ ) {
            elems = i === last ? this : this.clone( true );
            jQuery( insert[ i ] )[ original ]( elems );

            // Support: QtWebKit
            // .get() because core_push.apply(_, arraylike) throws
            core_push.apply( ret, elems.get() );
        }

        return this.pushStack( ret );
    };
});

jQuery.extend({
    clone: function( elem, dataAndEvents, deepDataAndEvents ) {
        var i, l, srcElements, destElements,
            clone = elem.cloneNode( true ),
            inPage = jQuery.contains( elem.ownerDocument, elem );

        // Support: IE >= 9
        // Fix Cloning issues
        if ( !jQuery.support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {

            // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
            destElements = getAll( clone );
            srcElements = getAll( elem );

            for ( i = 0, l = srcElements.length; i < l; i++ ) {
                fixInput( srcElements[ i ], destElements[ i ] );
            }
        }

        // Copy the events from the original to the clone
        if ( dataAndEvents ) {
            if ( deepDataAndEvents ) {
                srcElements = srcElements || getAll( elem );
                destElements = destElements || getAll( clone );

                for ( i = 0, l = srcElements.length; i < l; i++ ) {
                    cloneCopyEvent( srcElements[ i ], destElements[ i ] );
                }
            } else {
                cloneCopyEvent( elem, clone );
            }
        }

        // Preserve script evaluation history
        destElements = getAll( clone, "script" );
        if ( destElements.length > 0 ) {
            setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
        }

        // Return the cloned set
        return clone;
    },

    buildFragment: function( elems, context, scripts, selection ) {
        var elem, tmp, tag, wrap, contains, j,
            i = 0,
            l = elems.length,
            fragment = context.createDocumentFragment(),
            nodes = [];

        for ( ; i < l; i++ ) {
            elem = elems[ i ];

            if ( elem || elem === 0 ) {

                // Add nodes directly
                if ( jQuery.type( elem ) === "object" ) {
                    // Support: QtWebKit
                    // jQuery.merge because core_push.apply(_, arraylike) throws
                    jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );

                // Convert non-html into a text node
                } else if ( !rhtml.test( elem ) ) {
                    nodes.push( context.createTextNode( elem ) );

                // Convert html into DOM nodes
                } else {
                    tmp = tmp || fragment.appendChild( context.createElement("div") );

                    // Deserialize a standard representation
                    tag = ( rtagName.exec( elem ) || ["", ""] )[ 1 ].toLowerCase();
                    wrap = wrapMap[ tag ] || wrapMap._default;
                    tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];

                    // Descend through wrappers to the right content
                    j = wrap[ 0 ];
                    while ( j-- ) {
                        tmp = tmp.lastChild;
                    }

                    // Support: QtWebKit
                    // jQuery.merge because core_push.apply(_, arraylike) throws
                    jQuery.merge( nodes, tmp.childNodes );

                    // Remember the top-level container
                    tmp = fragment.firstChild;

                    // Fixes #12346
                    // Support: Webkit, IE
                    tmp.textContent = "";
                }
            }
        }

        // Remove wrapper from fragment
        fragment.textContent = "";

        i = 0;
        while ( (elem = nodes[ i++ ]) ) {

            // #4087 - If origin and destination elements are the same, and this is
            // that element, do not do anything
            if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
                continue;
            }

            contains = jQuery.contains( elem.ownerDocument, elem );

            // Append to fragment
            tmp = getAll( fragment.appendChild( elem ), "script" );

            // Preserve script evaluation history
            if ( contains ) {
                setGlobalEval( tmp );
            }

            // Capture executables
            if ( scripts ) {
                j = 0;
                while ( (elem = tmp[ j++ ]) ) {
                    if ( rscriptType.test( elem.type || "" ) ) {
                        scripts.push( elem );
                    }
                }
            }
        }

        return fragment;
    },

    cleanData: function( elems ) {
        var data, elem, events, type, key, j,
            special = jQuery.event.special,
            i = 0;

        for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
            if ( Data.accepts( elem ) ) {
                key = elem[ data_priv.expando ];

                if ( key && (data = data_priv.cache[ key ]) ) {
                    events = Object.keys( data.events || {} );
                    if ( events.length ) {
                        for ( j = 0; (type = events[j]) !== undefined; j++ ) {
                            if ( special[ type ] ) {
                                jQuery.event.remove( elem, type );

                            // This is a shortcut to avoid jQuery.event.remove's overhead
                            } else {
                                jQuery.removeEvent( elem, type, data.handle );
                            }
                        }
                    }
                    if ( data_priv.cache[ key ] ) {
                        // Discard any remaining `private` data
                        delete data_priv.cache[ key ];
                    }
                }
            }
            // Discard any remaining `user` data
            delete data_user.cache[ elem[ data_user.expando ] ];
        }
    },

    _evalUrl: function( url ) {
        return jQuery.ajax({
            url: url,
            type: "GET",
            dataType: "script",
            async: false,
            global: false,
            "throws": true
        });
    }
});

// Support: 1.x compatibility
// Manipulating tables requires a tbody
function manipulationTarget( elem, content ) {
    return jQuery.nodeName( elem, "table" ) &&
        jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ?

        elem.getElementsByTagName("tbody")[0] ||
            elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
        elem;
}

// Replace/restore the type attribute of script elements for safe DOM manipulation
function disableScript( elem ) {
    elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
    return elem;
}
function restoreScript( elem ) {
    var match = rscriptTypeMasked.exec( elem.type );

    if ( match ) {
        elem.type = match[ 1 ];
    } else {
        elem.removeAttribute("type");
    }

    return elem;
}

// Mark scripts as having already been evaluated
function setGlobalEval( elems, refElements ) {
    var l = elems.length,
        i = 0;

    for ( ; i < l; i++ ) {
        data_priv.set(
            elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
        );
    }
}

function cloneCopyEvent( src, dest ) {
    var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;

    if ( dest.nodeType !== 1 ) {
        return;
    }

    // 1. Copy private data: events, handlers, etc.
    if ( data_priv.hasData( src ) ) {
        pdataOld = data_priv.access( src );
        pdataCur = data_priv.set( dest, pdataOld );
        events = pdataOld.events;

        if ( events ) {
            delete pdataCur.handle;
            pdataCur.events = {};

            for ( type in events ) {
                for ( i = 0, l = events[ type ].length; i < l; i++ ) {
                    jQuery.event.add( dest, type, events[ type ][ i ] );
                }
            }
        }
    }

    // 2. Copy user data
    if ( data_user.hasData( src ) ) {
        udataOld = data_user.access( src );
        udataCur = jQuery.extend( {}, udataOld );

        data_user.set( dest, udataCur );
    }
}


function getAll( context, tag ) {
    var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
            context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
            [];

    return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
        jQuery.merge( [ context ], ret ) :
        ret;
}

// Support: IE >= 9
function fixInput( src, dest ) {
    var nodeName = dest.nodeName.toLowerCase();

    // Fails to persist the checked state of a cloned checkbox or radio button.
    if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
        dest.checked = src.checked;

    // Fails to return the selected option to the default selected state when cloning options
    } else if ( nodeName === "input" || nodeName === "textarea" ) {
        dest.defaultValue = src.defaultValue;
    }
}
jQuery.fn.extend({
    wrapAll: function( html ) {
        var wrap;

        if ( jQuery.isFunction( html ) ) {
            return this.each(function( i ) {
                jQuery( this ).wrapAll( html.call(this, i) );
            });
        }

        if ( this[ 0 ] ) {

            // The elements to wrap the target around
            wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );

            if ( this[ 0 ].parentNode ) {
                wrap.insertBefore( this[ 0 ] );
            }

            wrap.map(function() {
                var elem = this;

                while ( elem.firstElementChild ) {
                    elem = elem.firstElementChild;
                }

                return elem;
            }).append( this );
        }

        return this;
    },

    wrapInner: function( html ) {
        if ( jQuery.isFunction( html ) ) {
            return this.each(function( i ) {
                jQuery( this ).wrapInner( html.call(this, i) );
            });
        }

        return this.each(function() {
            var self = jQuery( this ),
                contents = self.contents();

            if ( contents.length ) {
                contents.wrapAll( html );

            } else {
                self.append( html );
            }
        });
    },

    wrap: function( html ) {
        var isFunction = jQuery.isFunction( html );

        return this.each(function( i ) {
            jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
        });
    },

    unwrap: function() {
        return this.parent().each(function() {
            if ( !jQuery.nodeName( this, "body" ) ) {
                jQuery( this ).replaceWith( this.childNodes );
            }
        }).end();
    }
});
var curCSS, iframe,
    // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
    // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
    rdisplayswap = /^(none|table(?!-c[ea]).+)/,
    rmargin = /^margin/,
    rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
    rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
    rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
    elemdisplay = { BODY: "block" },

    cssShow = { position: "absolute", visibility: "hidden", display: "block" },
    cssNormalTransform = {
        letterSpacing: 0,
        fontWeight: 400
    },

    cssExpand = [ "Top", "Right", "Bottom", "Left" ],
    cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];

// return a css property mapped to a potentially vendor prefixed property
function vendorPropName( style, name ) {

    // shortcut for names that are not vendor prefixed
    if ( name in style ) {
        return name;
    }

    // check for vendor prefixed names
    var capName = name.charAt(0).toUpperCase() + name.slice(1),
        origName = name,
        i = cssPrefixes.length;

    while ( i-- ) {
        name = cssPrefixes[ i ] + capName;
        if ( name in style ) {
            return name;
        }
    }

    return origName;
}

function isHidden( elem, el ) {
    // isHidden might be called from jQuery#filter function;
    // in that case, element will be second argument
    elem = el || elem;
    return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
}

// NOTE: we've included the "window" in window.getComputedStyle
// because jsdom on node.js will break without it.
function getStyles( elem ) {
    return window.getComputedStyle( elem, null );
}

function showHide( elements, show ) {
    var display, elem, hidden,
        values = [],
        index = 0,
        length = elements.length;

    for ( ; index < length; index++ ) {
        elem = elements[ index ];
        if ( !elem.style ) {
            continue;
        }

        values[ index ] = data_priv.get( elem, "olddisplay" );
        display = elem.style.display;
        if ( show ) {
            // Reset the inline display of this element to learn if it is
            // being hidden by cascaded rules or not
            if ( !values[ index ] && display === "none" ) {
                elem.style.display = "";
            }

            // Set elements which have been overridden with display: none
            // in a stylesheet to whatever the default browser style is
            // for such an element
            if ( elem.style.display === "" && isHidden( elem ) ) {
                values[ index ] = data_priv.access( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
            }
        } else {

            if ( !values[ index ] ) {
                hidden = isHidden( elem );

                if ( display && display !== "none" || !hidden ) {
                    data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css(elem, "display") );
                }
            }
        }
    }

    // Set the display of most of the elements in a second loop
    // to avoid the constant reflow
    for ( index = 0; index < length; index++ ) {
        elem = elements[ index ];
        if ( !elem.style ) {
            continue;
        }
        if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
            elem.style.display = show ? values[ index ] || "" : "none";
        }
    }

    return elements;
}

jQuery.fn.extend({
    css: function( name, value ) {
        return jQuery.access( this, function( elem, name, value ) {
            var styles, len,
                map = {},
                i = 0;

            if ( jQuery.isArray( name ) ) {
                styles = getStyles( elem );
                len = name.length;

                for ( ; i < len; i++ ) {
                    map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
                }

                return map;
            }

            return value !== undefined ?
                jQuery.style( elem, name, value ) :
                jQuery.css( elem, name );
        }, name, value, arguments.length > 1 );
    },
    show: function() {
        return showHide( this, true );
    },
    hide: function() {
        return showHide( this );
    },
    toggle: function( state ) {
        if ( typeof state === "boolean" ) {
            return state ? this.show() : this.hide();
        }

        return this.each(function() {
            if ( isHidden( this ) ) {
                jQuery( this ).show();
            } else {
                jQuery( this ).hide();
            }
        });
    }
});

jQuery.extend({
    // Add in style property hooks for overriding the default
    // behavior of getting and setting a style property
    cssHooks: {
        opacity: {
            get: function( elem, computed ) {
                if ( computed ) {
                    // We should always get a number back from opacity
                    var ret = curCSS( elem, "opacity" );
                    return ret === "" ? "1" : ret;
                }
            }
        }
    },

    // Don't automatically add "px" to these possibly-unitless properties
    cssNumber: {
        "columnCount": true,
        "fillOpacity": true,
        "fontWeight": true,
        "lineHeight": true,
        "opacity": true,
        "order": true,
        "orphans": true,
        "widows": true,
        "zIndex": true,
        "zoom": true
    },

    // Add in properties whose names you wish to fix before
    // setting or getting the value
    cssProps: {
        // normalize float css property
        "float": "cssFloat"
    },

    // Get and set the style property on a DOM Node
    style: function( elem, name, value, extra ) {
        // Don't set styles on text and comment nodes
        if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
            return;
        }

        // Make sure that we're working with the right name
        var ret, type, hooks,
            origName = jQuery.camelCase( name ),
            style = elem.style;

        name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );

        // gets hook for the prefixed version
        // followed by the unprefixed version
        hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

        // Check if we're setting a value
        if ( value !== undefined ) {
            type = typeof value;

            // convert relative number strings (+= or -=) to relative numbers. #7345
            if ( type === "string" && (ret = rrelNum.exec( value )) ) {
                value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
                // Fixes bug #9237
                type = "number";
            }

            // Make sure that NaN and null values aren't set. See: #7116
            if ( value == null || type === "number" && isNaN( value ) ) {
                return;
            }

            // If a number was passed in, add 'px' to the (except for certain CSS properties)
            if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
                value += "px";
            }

            // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
            // but it would mean to define eight (for every problematic property) identical functions
            if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
                style[ name ] = "inherit";
            }

            // If a hook was provided, use that value, otherwise just set the specified value
            if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
                style[ name ] = value;
            }

        } else {
            // If a hook was provided get the non-computed value from there
            if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
                return ret;
            }

            // Otherwise just get the value from the style object
            return style[ name ];
        }
    },

    css: function( elem, name, extra, styles ) {
        var val, num, hooks,
            origName = jQuery.camelCase( name );

        // Make sure that we're working with the right name
        name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );

        // gets hook for the prefixed version
        // followed by the unprefixed version
        hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

        // If a hook was provided get the computed value from there
        if ( hooks && "get" in hooks ) {
            val = hooks.get( elem, true, extra );
        }

        // Otherwise, if a way to get the computed value exists, use that
        if ( val === undefined ) {
            val = curCSS( elem, name, styles );
        }

        //convert "normal" to computed value
        if ( val === "normal" && name in cssNormalTransform ) {
            val = cssNormalTransform[ name ];
        }

        // Return, converting to number if forced or a qualifier was provided and val looks numeric
        if ( extra === "" || extra ) {
            num = parseFloat( val );
            return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
        }
        return val;
    }
});

curCSS = function( elem, name, _computed ) {
    var width, minWidth, maxWidth,
        computed = _computed || getStyles( elem ),

        // Support: IE9
        // getPropertyValue is only needed for .css('filter') in IE9, see #12537
        ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
        style = elem.style;

    if ( computed ) {

        if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
            ret = jQuery.style( elem, name );
        }

        // Support: Safari 5.1
        // A tribute to the "awesome hack by Dean Edwards"
        // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
        // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
        if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {

            // Remember the original values
            width = style.width;
            minWidth = style.minWidth;
            maxWidth = style.maxWidth;

            // Put in the new values to get a computed value out
            style.minWidth = style.maxWidth = style.width = ret;
            ret = computed.width;

            // Revert the changed values
            style.width = width;
            style.minWidth = minWidth;
            style.maxWidth = maxWidth;
        }
    }

    return ret;
};


function setPositiveNumber( elem, value, subtract ) {
    var matches = rnumsplit.exec( value );
    return matches ?
        // Guard against undefined "subtract", e.g., when used as in cssHooks
        Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
        value;
}

function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
    var i = extra === ( isBorderBox ? "border" : "content" ) ?
        // If we already have the right measurement, avoid augmentation
        4 :
        // Otherwise initialize for horizontal or vertical properties
        name === "width" ? 1 : 0,

        val = 0;

    for ( ; i < 4; i += 2 ) {
        // both box models exclude margin, so add it if we want it
        if ( extra === "margin" ) {
            val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
        }

        if ( isBorderBox ) {
            // border-box includes padding, so remove it if we want content
            if ( extra === "content" ) {
                val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
            }

            // at this point, extra isn't border nor margin, so remove border
            if ( extra !== "margin" ) {
                val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
            }
        } else {
            // at this point, extra isn't content, so add padding
            val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );

            // at this point, extra isn't content nor padding, so add border
            if ( extra !== "padding" ) {
                val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
            }
        }
    }

    return val;
}

function getWidthOrHeight( elem, name, extra ) {

    // Start with offset property, which is equivalent to the border-box value
    var valueIsBorderBox = true,
        val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
        styles = getStyles( elem ),
        isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";

    // some non-html elements return undefined for offsetWidth, so check for null/undefined
    // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
    // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
    if ( val <= 0 || val == null ) {
        // Fall back to computed then uncomputed css if necessary
        val = curCSS( elem, name, styles );
        if ( val < 0 || val == null ) {
            val = elem.style[ name ];
        }

        // Computed unit is not pixels. Stop here and return.
        if ( rnumnonpx.test(val) ) {
            return val;
        }

        // we need the check for style in case a browser which returns unreliable values
        // for getComputedStyle silently falls back to the reliable elem.style
        valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );

        // Normalize "", auto, and prepare for extra
        val = parseFloat( val ) || 0;
    }

    // use the active box-sizing model to add/subtract irrelevant styles
    return ( val +
        augmentWidthOrHeight(
            elem,
            name,
            extra || ( isBorderBox ? "border" : "content" ),
            valueIsBorderBox,
            styles
        )
    ) + "px";
}

// Try to determine the default display value of an element
function css_defaultDisplay( nodeName ) {
    var doc = document,
        display = elemdisplay[ nodeName ];

    if ( !display ) {
        display = actualDisplay( nodeName, doc );

        // If the simple way fails, read from inside an iframe
        if ( display === "none" || !display ) {
            // Use the already-created iframe if possible
            iframe = ( iframe ||
                jQuery("<iframe frameborder='0' width='0' height='0'/>")
                .css( "cssText", "display:block !important" )
            ).appendTo( doc.documentElement );

            // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
            doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
            doc.write("<!doctype html><html><body>");
            doc.close();

            display = actualDisplay( nodeName, doc );
            iframe.detach();
        }

        // Store the correct default display
        elemdisplay[ nodeName ] = display;
    }

    return display;
}

// Called ONLY from within css_defaultDisplay
function actualDisplay( name, doc ) {
    var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
        display = jQuery.css( elem[0], "display" );
    elem.remove();
    return display;
}

jQuery.each([ "height", "width" ], function( i, name ) {
    jQuery.cssHooks[ name ] = {
        get: function( elem, computed, extra ) {
            if ( computed ) {
                // certain elements can have dimension info if we invisibly show them
                // however, it must have a current display style that would benefit from this
                return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
                    jQuery.swap( elem, cssShow, function() {
                        return getWidthOrHeight( elem, name, extra );
                    }) :
                    getWidthOrHeight( elem, name, extra );
            }
        },

        set: function( elem, value, extra ) {
            var styles = extra && getStyles( elem );
            return setPositiveNumber( elem, value, extra ?
                augmentWidthOrHeight(
                    elem,
                    name,
                    extra,
                    jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
                    styles
                ) : 0
            );
        }
    };
});

// These hooks cannot be added until DOM ready because the support test
// for it is not run until after DOM ready
jQuery(function() {
    // Support: Android 2.3
    if ( !jQuery.support.reliableMarginRight ) {
        jQuery.cssHooks.marginRight = {
            get: function( elem, computed ) {
                if ( computed ) {
                    // Support: Android 2.3
                    // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
                    // Work around by temporarily setting element display to inline-block
                    return jQuery.swap( elem, { "display": "inline-block" },
                        curCSS, [ elem, "marginRight" ] );
                }
            }
        };
    }

    // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
    // getComputedStyle returns percent when specified for top/left/bottom/right
    // rather than make the css module depend on the offset module, we just check for it here
    if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
        jQuery.each( [ "top", "left" ], function( i, prop ) {
            jQuery.cssHooks[ prop ] = {
                get: function( elem, computed ) {
                    if ( computed ) {
                        computed = curCSS( elem, prop );
                        // if curCSS returns percentage, fallback to offset
                        return rnumnonpx.test( computed ) ?
                            jQuery( elem ).position()[ prop ] + "px" :
                            computed;
                    }
                }
            };
        });
    }

});

if ( jQuery.expr && jQuery.expr.filters ) {
    jQuery.expr.filters.hidden = function( elem ) {
        // Support: Opera <= 12.12
        // Opera reports offsetWidths and offsetHeights less than zero on some elements
        return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
    };

    jQuery.expr.filters.visible = function( elem ) {
        return !jQuery.expr.filters.hidden( elem );
    };
}

// These hooks are used by animate to expand properties
jQuery.each({
    margin: "",
    padding: "",
    border: "Width"
}, function( prefix, suffix ) {
    jQuery.cssHooks[ prefix + suffix ] = {
        expand: function( value ) {
            var i = 0,
                expanded = {},

                // assumes a single number if not a string
                parts = typeof value === "string" ? value.split(" ") : [ value ];

            for ( ; i < 4; i++ ) {
                expanded[ prefix + cssExpand[ i ] + suffix ] =
                    parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
            }

            return expanded;
        }
    };

    if ( !rmargin.test( prefix ) ) {
        jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
    }
});
var r20 = /%20/g,
    rbracket = /\[\]$/,
    rCRLF = /\r?\n/g,
    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
    rsubmittable = /^(?:input|select|textarea|keygen)/i;

jQuery.fn.extend({
    serialize: function() {
        return jQuery.param( this.serializeArray() );
    },
    serializeArray: function() {
        return this.map(function(){
            // Can add propHook for "elements" to filter or add form elements
            var elements = jQuery.prop( this, "elements" );
            return elements ? jQuery.makeArray( elements ) : this;
        })
        .filter(function(){
            var type = this.type;
            // Use .is(":disabled") so that fieldset[disabled] works
            return this.name && !jQuery( this ).is( ":disabled" ) &&
                rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
                ( this.checked || !manipulation_rcheckableType.test( type ) );
        })
        .map(function( i, elem ){
            var val = jQuery( this ).val();

            return val == null ?
                null :
                jQuery.isArray( val ) ?
                    jQuery.map( val, function( val ){
                        return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                    }) :
                    { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
        }).get();
    }
});

//Serialize an array of form elements or a set of
//key/values into a query string
jQuery.param = function( a, traditional ) {
    var prefix,
        s = [],
        add = function( key, value ) {
            // If value is a function, invoke it and return its value
            value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
            s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
        };

    // Set traditional to true for jQuery <= 1.3.2 behavior.
    if ( traditional === undefined ) {
        traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
    }

    // If an array was passed in, assume that it is an array of form elements.
    if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
        // Serialize the form elements
        jQuery.each( a, function() {
            add( this.name, this.value );
        });

    } else {
        // If traditional, encode the "old" way (the way 1.3.2 or older
        // did it), otherwise encode params recursively.
        for ( prefix in a ) {
            buildParams( prefix, a[ prefix ], traditional, add );
        }
    }

    // Return the resulting serialization
    return s.join( "&" ).replace( r20, "+" );
};

function buildParams( prefix, obj, traditional, add ) {
    var name;

    if ( jQuery.isArray( obj ) ) {
        // Serialize array item.
        jQuery.each( obj, function( i, v ) {
            if ( traditional || rbracket.test( prefix ) ) {
                // Treat each array item as a scalar.
                add( prefix, v );

            } else {
                // Item is non-scalar (array or object), encode its numeric index.
                buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
            }
        });

    } else if ( !traditional && jQuery.type( obj ) === "object" ) {
        // Serialize object item.
        for ( name in obj ) {
            buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
        }

    } else {
        // Serialize scalar item.
        add( prefix, obj );
    }
}
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
    "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
    "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {

    // Handle event binding
    jQuery.fn[ name ] = function( data, fn ) {
        return arguments.length > 0 ?
            this.on( name, null, data, fn ) :
            this.trigger( name );
    };
});

jQuery.fn.extend({
    hover: function( fnOver, fnOut ) {
        return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
    },

    bind: function( types, data, fn ) {
        return this.on( types, null, data, fn );
    },
    unbind: function( types, fn ) {
        return this.off( types, null, fn );
    },

    delegate: function( selector, types, data, fn ) {
        return this.on( types, selector, data, fn );
    },
    undelegate: function( selector, types, fn ) {
        // ( namespace ) or ( selector, types [, fn] )
        return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
    }
});
var
    // Document location
    ajaxLocParts,
    ajaxLocation,

    ajax_nonce = jQuery.now(),

    ajax_rquery = /\?/,
    rhash = /#.*$/,
    rts = /([?&])_=[^&]*/,
    rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
    // #7653, #8125, #8152: local protocol detection
    rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
    rnoContent = /^(?:GET|HEAD)$/,
    rprotocol = /^\/\//,
    rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,

    // Keep a copy of the old load method
    _load = jQuery.fn.load,

    
    prefilters = {},

    
    transports = {},

    // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
    allTypes = "*/".concat("*");

// #8138, IE may throw an exception when accessing
// a field from window.location if document.domain has been set
try {
    ajaxLocation = location.href;
} catch( e ) {
    // Use the href attribute of an A element
    // since IE will modify it given document.location
    ajaxLocation = document.createElement( "a" );
    ajaxLocation.href = "";
    ajaxLocation = ajaxLocation.href;
}

// Segment location into parts
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];

// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
function addToPrefiltersOrTransports( structure ) {

    // dataTypeExpression is optional and defaults to "*"
    return function( dataTypeExpression, func ) {

        if ( typeof dataTypeExpression !== "string" ) {
            func = dataTypeExpression;
            dataTypeExpression = "*";
        }

        var dataType,
            i = 0,
            dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];

        if ( jQuery.isFunction( func ) ) {
            // For each dataType in the dataTypeExpression
            while ( (dataType = dataTypes[i++]) ) {
                // Prepend if requested
                if ( dataType[0] === "+" ) {
                    dataType = dataType.slice( 1 ) || "*";
                    (structure[ dataType ] = structure[ dataType ] || []).unshift( func );

                // Otherwise append
                } else {
                    (structure[ dataType ] = structure[ dataType ] || []).push( func );
                }
            }
        }
    };
}

// Base inspection function for prefilters and transports
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {

    var inspected = {},
        seekingTransport = ( structure === transports );

    function inspect( dataType ) {
        var selected;
        inspected[ dataType ] = true;
        jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
            var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
            if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
                options.dataTypes.unshift( dataTypeOrTransport );
                inspect( dataTypeOrTransport );
                return false;
            } else if ( seekingTransport ) {
                return !( selected = dataTypeOrTransport );
            }
        });
        return selected;
    }

    return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
}

// A special extend for ajax options
// that takes "flat" options (not to be deep extended)
// Fixes #9887
function ajaxExtend( target, src ) {
    var key, deep,
        flatOptions = jQuery.ajaxSettings.flatOptions || {};

    for ( key in src ) {
        if ( src[ key ] !== undefined ) {
            ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
        }
    }
    if ( deep ) {
        jQuery.extend( true, target, deep );
    }

    return target;
}

jQuery.fn.load = function( url, params, callback ) {
    if ( typeof url !== "string" && _load ) {
        return _load.apply( this, arguments );
    }

    var selector, type, response,
        self = this,
        off = url.indexOf(" ");

    if ( off >= 0 ) {
        selector = url.slice( off );
        url = url.slice( 0, off );
    }

    // If it's a function
    if ( jQuery.isFunction( params ) ) {

        // We assume that it's the callback
        callback = params;
        params = undefined;

    // Otherwise, build a param string
    } else if ( params && typeof params === "object" ) {
        type = "POST";
    }

    // If we have elements to modify, make the request
    if ( self.length > 0 ) {
        jQuery.ajax({
            url: url,

            // if "type" variable is undefined, then "GET" method will be used
            type: type,
            dataType: "html",
            data: params
        }).done(function( responseText ) {

            // Save response for use in complete callback
            response = arguments;

            self.html( selector ?

                // If a selector was specified, locate the right elements in a dummy div
                // Exclude scripts to avoid IE 'Permission Denied' errors
                jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :

                // Otherwise use the full result
                responseText );

        }).complete( callback && function( jqXHR, status ) {
            self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
        });
    }

    return this;
};

// Attach a bunch of functions for handling common AJAX events
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
    jQuery.fn[ type ] = function( fn ){
        return this.on( type, fn );
    };
});

jQuery.extend({

    // Counter for holding the number of active queries
    active: 0,

    // Last-Modified header cache for next request
    lastModified: {},
    etag: {},

    ajaxSettings: {
        url: ajaxLocation,
        type: "GET",
        isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
        global: true,
        processData: true,
        async: true,
        contentType: "application/x-www-form-urlencoded; charset=UTF-8",
        

        accepts: {
            "*": allTypes,
            text: "text/plain",
            html: "text/html",
            xml: "application/xml, text/xml",
            json: "application/json, text/javascript"
        },

        contents: {
            xml: /xml/,
            html: /html/,
            json: /json/
        },

        responseFields: {
            xml: "responseXML",
            text: "responseText",
            json: "responseJSON"
        },

        // Data converters
        // Keys separate source (or catchall "*") and destination types with a single space
        converters: {

            // Convert anything to text
            "* text": String,

            // Text to html (true = no transformation)
            "text html": true,

            // Evaluate text as a json expression
            "text json": jQuery.parseJSON,

            // Parse text as xml
            "text xml": jQuery.parseXML
        },

        // For options that shouldn't be deep extended:
        // you can add your own custom options here if
        // and when you create one that shouldn't be
        // deep extended (see ajaxExtend)
        flatOptions: {
            url: true,
            context: true
        }
    },

    // Creates a full fledged settings object into target
    // with both ajaxSettings and settings fields.
    // If target is omitted, writes into ajaxSettings.
    ajaxSetup: function( target, settings ) {
        return settings ?

            // Building a settings object
            ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :

            // Extending ajaxSettings
            ajaxExtend( jQuery.ajaxSettings, target );
    },

    ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
    ajaxTransport: addToPrefiltersOrTransports( transports ),

    // Main method
    ajax: function( url, options ) {

        // If url is an object, simulate pre-1.5 signature
        if ( typeof url === "object" ) {
            options = url;
            url = undefined;
        }

        // Force options to be an object
        options = options || {};

        var transport,
            // URL without anti-cache param
            cacheURL,
            // Response headers
            responseHeadersString,
            responseHeaders,
            // timeout handle
            timeoutTimer,
            // Cross-domain detection vars
            parts,
            // To know if global events are to be dispatched
            fireGlobals,
            // Loop variable
            i,
            // Create the final options object
            s = jQuery.ajaxSetup( {}, options ),
            // Callbacks context
            callbackContext = s.context || s,
            // Context for global events is callbackContext if it is a DOM node or jQuery collection
            globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
                jQuery( callbackContext ) :
                jQuery.event,
            // Deferreds
            deferred = jQuery.Deferred(),
            completeDeferred = jQuery.Callbacks("once memory"),
            // Status-dependent callbacks
            statusCode = s.statusCode || {},
            // Headers (they are sent all at once)
            requestHeaders = {},
            requestHeadersNames = {},
            // The jqXHR state
            state = 0,
            // Default abort message
            strAbort = "canceled",
            // Fake xhr
            jqXHR = {
                readyState: 0,

                // Builds headers hashtable if needed
                getResponseHeader: function( key ) {
                    var match;
                    if ( state === 2 ) {
                        if ( !responseHeaders ) {
                            responseHeaders = {};
                            while ( (match = rheaders.exec( responseHeadersString )) ) {
                                responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
                            }
                        }
                        match = responseHeaders[ key.toLowerCase() ];
                    }
                    return match == null ? null : match;
                },

                // Raw string
                getAllResponseHeaders: function() {
                    return state === 2 ? responseHeadersString : null;
                },

                // Caches the header
                setRequestHeader: function( name, value ) {
                    var lname = name.toLowerCase();
                    if ( !state ) {
                        name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
                        requestHeaders[ name ] = value;
                    }
                    return this;
                },

                // Overrides response content-type header
                overrideMimeType: function( type ) {
                    if ( !state ) {
                        s.mimeType = type;
                    }
                    return this;
                },

                // Status-dependent callbacks
                statusCode: function( map ) {
                    var code;
                    if ( map ) {
                        if ( state < 2 ) {
                            for ( code in map ) {
                                // Lazy-add the new callback in a way that preserves old ones
                                statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
                            }
                        } else {
                            // Execute the appropriate callbacks
                            jqXHR.always( map[ jqXHR.status ] );
                        }
                    }
                    return this;
                },

                // Cancel the request
                abort: function( statusText ) {
                    var finalText = statusText || strAbort;
                    if ( transport ) {
                        transport.abort( finalText );
                    }
                    done( 0, finalText );
                    return this;
                }
            };

        // Attach deferreds
        deferred.promise( jqXHR ).complete = completeDeferred.add;
        jqXHR.success = jqXHR.done;
        jqXHR.error = jqXHR.fail;

        // Remove hash character (#7531: and string promotion)
        // Add protocol if not provided (prefilters might expect it)
        // Handle falsy url in the settings object (#10093: consistency with old signature)
        // We also use the url parameter if available
        s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
            .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );

        // Alias method option to type as per ticket #12004
        s.type = options.method || options.type || s.method || s.type;

        // Extract dataTypes list
        s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];

        // A cross-domain request is in order when we have a protocol:host:port mismatch
        if ( s.crossDomain == null ) {
            parts = rurl.exec( s.url.toLowerCase() );
            s.crossDomain = !!( parts &&
                ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
                    ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
                        ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
            );
        }

        // Convert data if not already a string
        if ( s.data && s.processData && typeof s.data !== "string" ) {
            s.data = jQuery.param( s.data, s.traditional );
        }

        // Apply prefilters
        inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );

        // If request was aborted inside a prefilter, stop there
        if ( state === 2 ) {
            return jqXHR;
        }

        // We can fire global events as of now if asked to
        fireGlobals = s.global;

        // Watch for a new set of requests
        if ( fireGlobals && jQuery.active++ === 0 ) {
            jQuery.event.trigger("ajaxStart");
        }

        // Uppercase the type
        s.type = s.type.toUpperCase();

        // Determine if request has content
        s.hasContent = !rnoContent.test( s.type );

        // Save the URL in case we're toying with the If-Modified-Since
        // and/or If-None-Match header later on
        cacheURL = s.url;

        // More options handling for requests with no content
        if ( !s.hasContent ) {

            // If data is available, append data to url
            if ( s.data ) {
                cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
                // #9682: remove data so that it's not used in an eventual retry
                delete s.data;
            }

            // Add anti-cache in url if needed
            if ( s.cache === false ) {
                s.url = rts.test( cacheURL ) ?

                    // If there is already a '_' parameter, set its value
                    cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :

                    // Otherwise add one to the end
                    cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
            }
        }

        // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
        if ( s.ifModified ) {
            if ( jQuery.lastModified[ cacheURL ] ) {
                jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
            }
            if ( jQuery.etag[ cacheURL ] ) {
                jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
            }
        }

        // Set the correct header, if data is being sent
        if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
            jqXHR.setRequestHeader( "Content-Type", s.contentType );
        }

        // Set the Accepts header for the server, depending on the dataType
        jqXHR.setRequestHeader(
            "Accept",
            s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
                s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
                s.accepts[ "*" ]
        );

        // Check for headers option
        for ( i in s.headers ) {
            jqXHR.setRequestHeader( i, s.headers[ i ] );
        }

        // Allow custom headers/mimetypes and early abort
        if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
            // Abort if not done already and return
            return jqXHR.abort();
        }

        // aborting is no longer a cancellation
        strAbort = "abort";

        // Install callbacks on deferreds
        for ( i in { success: 1, error: 1, complete: 1 } ) {
            jqXHR[ i ]( s[ i ] );
        }

        // Get transport
        transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );

        // If no transport, we auto-abort
        if ( !transport ) {
            done( -1, "No Transport" );
        } else {
            jqXHR.readyState = 1;

            // Send global event
            if ( fireGlobals ) {
                globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
            }
            // Timeout
            if ( s.async && s.timeout > 0 ) {
                timeoutTimer = setTimeout(function() {
                    jqXHR.abort("timeout");
                }, s.timeout );
            }

            try {
                state = 1;
                transport.send( requestHeaders, done );
            } catch ( e ) {
                // Propagate exception as error if not done
                if ( state < 2 ) {
                    done( -1, e );
                // Simply rethrow otherwise
                } else {
                    throw e;
                }
            }
        }

        // Callback for when everything is done
        function done( status, nativeStatusText, responses, headers ) {
            var isSuccess, success, error, response, modified,
                statusText = nativeStatusText;

            // Called once
            if ( state === 2 ) {
                return;
            }

            // State is "done" now
            state = 2;

            // Clear timeout if it exists
            if ( timeoutTimer ) {
                clearTimeout( timeoutTimer );
            }

            // Dereference transport for early garbage collection
            // (no matter how long the jqXHR object will be used)
            transport = undefined;

            // Cache response headers
            responseHeadersString = headers || "";

            // Set readyState
            jqXHR.readyState = status > 0 ? 4 : 0;

            // Determine if successful
            isSuccess = status >= 200 && status < 300 || status === 304;

            // Get response data
            if ( responses ) {
                response = ajaxHandleResponses( s, jqXHR, responses );
            }

            // Convert no matter what (that way responseXXX fields are always set)
            response = ajaxConvert( s, response, jqXHR, isSuccess );

            // If successful, handle type chaining
            if ( isSuccess ) {

                // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                if ( s.ifModified ) {
                    modified = jqXHR.getResponseHeader("Last-Modified");
                    if ( modified ) {
                        jQuery.lastModified[ cacheURL ] = modified;
                    }
                    modified = jqXHR.getResponseHeader("etag");
                    if ( modified ) {
                        jQuery.etag[ cacheURL ] = modified;
                    }
                }

                // if no content
                if ( status === 204 || s.type === "HEAD" ) {
                    statusText = "nocontent";

                // if not modified
                } else if ( status === 304 ) {
                    statusText = "notmodified";

                // If we have data, let's convert it
                } else {
                    statusText = response.state;
                    success = response.data;
                    error = response.error;
                    isSuccess = !error;
                }
            } else {
                // We extract error from statusText
                // then normalize statusText and status for non-aborts
                error = statusText;
                if ( status || !statusText ) {
                    statusText = "error";
                    if ( status < 0 ) {
                        status = 0;
                    }
                }
            }

            // Set data for the fake xhr object
            jqXHR.status = status;
            jqXHR.statusText = ( nativeStatusText || statusText ) + "";

            // Success/Error
            if ( isSuccess ) {
                deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
            } else {
                deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
            }

            // Status-dependent callbacks
            jqXHR.statusCode( statusCode );
            statusCode = undefined;

            if ( fireGlobals ) {
                globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
                    [ jqXHR, s, isSuccess ? success : error ] );
            }

            // Complete
            completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );

            if ( fireGlobals ) {
                globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
                // Handle the global AJAX counter
                if ( !( --jQuery.active ) ) {
                    jQuery.event.trigger("ajaxStop");
                }
            }
        }

        return jqXHR;
    },

    getJSON: function( url, data, callback ) {
        return jQuery.get( url, data, callback, "json" );
    },

    getScript: function( url, callback ) {
        return jQuery.get( url, undefined, callback, "script" );
    }
});

jQuery.each( [ "get", "post" ], function( i, method ) {
    jQuery[ method ] = function( url, data, callback, type ) {
        // shift arguments if data argument was omitted
        if ( jQuery.isFunction( data ) ) {
            type = type || callback;
            callback = data;
            data = undefined;
        }

        return jQuery.ajax({
            url: url,
            type: method,
            dataType: type,
            data: data,
            success: callback
        });
    };
});


function ajaxHandleResponses( s, jqXHR, responses ) {

    var ct, type, finalDataType, firstDataType,
        contents = s.contents,
        dataTypes = s.dataTypes;

    // Remove auto dataType and get content-type in the process
    while( dataTypes[ 0 ] === "*" ) {
        dataTypes.shift();
        if ( ct === undefined ) {
            ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
        }
    }

    // Check if we're dealing with a known content-type
    if ( ct ) {
        for ( type in contents ) {
            if ( contents[ type ] && contents[ type ].test( ct ) ) {
                dataTypes.unshift( type );
                break;
            }
        }
    }

    // Check to see if we have a response for the expected dataType
    if ( dataTypes[ 0 ] in responses ) {
        finalDataType = dataTypes[ 0 ];
    } else {
        // Try convertible dataTypes
        for ( type in responses ) {
            if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
                finalDataType = type;
                break;
            }
            if ( !firstDataType ) {
                firstDataType = type;
            }
        }
        // Or just use first one
        finalDataType = finalDataType || firstDataType;
    }

    // If we found a dataType
    // We add the dataType to the list if needed
    // and return the corresponding response
    if ( finalDataType ) {
        if ( finalDataType !== dataTypes[ 0 ] ) {
            dataTypes.unshift( finalDataType );
        }
        return responses[ finalDataType ];
    }
}


function ajaxConvert( s, response, jqXHR, isSuccess ) {
    var conv2, current, conv, tmp, prev,
        converters = {},
        // Work with a copy of dataTypes in case we need to modify it for conversion
        dataTypes = s.dataTypes.slice();

    // Create converters map with lowercased keys
    if ( dataTypes[ 1 ] ) {
        for ( conv in s.converters ) {
            converters[ conv.toLowerCase() ] = s.converters[ conv ];
        }
    }

    current = dataTypes.shift();

    // Convert to each sequential dataType
    while ( current ) {

        if ( s.responseFields[ current ] ) {
            jqXHR[ s.responseFields[ current ] ] = response;
        }

        // Apply the dataFilter if provided
        if ( !prev && isSuccess && s.dataFilter ) {
            response = s.dataFilter( response, s.dataType );
        }

        prev = current;
        current = dataTypes.shift();

        if ( current ) {

        // There's only work to do if current dataType is non-auto
            if ( current === "*" ) {

                current = prev;

            // Convert response if prev dataType is non-auto and differs from current
            } else if ( prev !== "*" && prev !== current ) {

                // Seek a direct converter
                conv = converters[ prev + " " + current ] || converters[ "* " + current ];

                // If none found, seek a pair
                if ( !conv ) {
                    for ( conv2 in converters ) {

                        // If conv2 outputs current
                        tmp = conv2.split( " " );
                        if ( tmp[ 1 ] === current ) {

                            // If prev can be converted to accepted input
                            conv = converters[ prev + " " + tmp[ 0 ] ] ||
                                converters[ "* " + tmp[ 0 ] ];
                            if ( conv ) {
                                // Condense equivalence converters
                                if ( conv === true ) {
                                    conv = converters[ conv2 ];

                                // Otherwise, insert the intermediate dataType
                                } else if ( converters[ conv2 ] !== true ) {
                                    current = tmp[ 0 ];
                                    dataTypes.unshift( tmp[ 1 ] );
                                }
                                break;
                            }
                        }
                    }
                }

                // Apply converter (if not an equivalence)
                if ( conv !== true ) {

                    // Unless errors are allowed to bubble, catch and return them
                    if ( conv && s[ "throws" ] ) {
                        response = conv( response );
                    } else {
                        try {
                            response = conv( response );
                        } catch ( e ) {
                            return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
                        }
                    }
                }
            }
        }
    }

    return { state: "success", data: response };
}
// Install script dataType
jQuery.ajaxSetup({
    accepts: {
        script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
    },
    contents: {
        script: /(?:java|ecma)script/
    },
    converters: {
        "text script": function( text ) {
            jQuery.globalEval( text );
            return text;
        }
    }
});

// Handle cache's special case and crossDomain
jQuery.ajaxPrefilter( "script", function( s ) {
    if ( s.cache === undefined ) {
        s.cache = false;
    }
    if ( s.crossDomain ) {
        s.type = "GET";
    }
});

// Bind script tag hack transport
jQuery.ajaxTransport( "script", function( s ) {
    // This transport only deals with cross domain requests
    if ( s.crossDomain ) {
        var script, callback;
        return {
            send: function( _, complete ) {
                script = jQuery("<script>").prop({
                    async: true,
                    charset: s.scriptCharset,
                    src: s.url
                }).on(
                    "load error",
                    callback = function( evt ) {
                        script.remove();
                        callback = null;
                        if ( evt ) {
                            complete( evt.type === "error" ? 404 : 200, evt.type );
                        }
                    }
                );
                document.head.appendChild( script[ 0 ] );
            },
            abort: function() {
                if ( callback ) {
                    callback();
                }
            }
        };
    }
});
var oldCallbacks = [],
    rjsonp = /(=)\?(?=&|$)|\?\?/;

// Default jsonp settings
jQuery.ajaxSetup({
    jsonp: "callback",
    jsonpCallback: function() {
        var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
        this[ callback ] = true;
        return callback;
    }
});

// Detect, normalize options and install callbacks for jsonp requests
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {

    var callbackName, overwritten, responseContainer,
        jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
            "url" :
            typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
        );

    // Handle iff the expected data type is "jsonp" or we have a parameter to set
    if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {

        // Get callback name, remembering preexisting value associated with it
        callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
            s.jsonpCallback() :
            s.jsonpCallback;

        // Insert callback into url or form data
        if ( jsonProp ) {
            s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
        } else if ( s.jsonp !== false ) {
            s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
        }

        // Use data converter to retrieve json after script execution
        s.converters["script json"] = function() {
            if ( !responseContainer ) {
                jQuery.error( callbackName + " was not called" );
            }
            return responseContainer[ 0 ];
        };

        // force json dataType
        s.dataTypes[ 0 ] = "json";

        // Install callback
        overwritten = window[ callbackName ];
        window[ callbackName ] = function() {
            responseContainer = arguments;
        };

        // Clean-up function (fires after converters)
        jqXHR.always(function() {
            // Restore preexisting value
            window[ callbackName ] = overwritten;

            // Save back as free
            if ( s[ callbackName ] ) {
                // make sure that re-using the options doesn't screw things around
                s.jsonpCallback = originalSettings.jsonpCallback;

                // save the callback name for future use
                oldCallbacks.push( callbackName );
            }

            // Call if it was a function and we have a response
            if ( responseContainer && jQuery.isFunction( overwritten ) ) {
                overwritten( responseContainer[ 0 ] );
            }

            responseContainer = overwritten = undefined;
        });

        // Delegate to script
        return "script";
    }
});
jQuery.ajaxSettings.xhr = function() {
    try {
        return new XMLHttpRequest();
    } catch( e ) {}
};

var xhrSupported = jQuery.ajaxSettings.xhr(),
    xhrSuccessStatus = {
        // file protocol always yields status code 0, assume 200
        0: 200,
        // Support: IE9
        // #1450: sometimes IE returns 1223 when it should be 204
        1223: 204
    },
    // Support: IE9
    // We need to keep track of outbound xhr and abort them manually
    // because IE is not smart enough to do it all by itself
    xhrId = 0,
    xhrCallbacks = {};

if ( window.ActiveXObject ) {
    jQuery( window ).on( "unload", function() {
        for( var key in xhrCallbacks ) {
            xhrCallbacks[ key ]();
        }
        xhrCallbacks = undefined;
    });
}

jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
jQuery.support.ajax = xhrSupported = !!xhrSupported;

jQuery.ajaxTransport(function( options ) {
    var callback;
    // Cross domain only allowed if supported through XMLHttpRequest
    if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {
        return {
            send: function( headers, complete ) {
                var i, id,
                    xhr = options.xhr();
                xhr.open( options.type, options.url, options.async, options.username, options.password );
                // Apply custom fields if provided
                if ( options.xhrFields ) {
                    for ( i in options.xhrFields ) {
                        xhr[ i ] = options.xhrFields[ i ];
                    }
                }
                // Override mime type if needed
                if ( options.mimeType && xhr.overrideMimeType ) {
                    xhr.overrideMimeType( options.mimeType );
                }
                // X-Requested-With header
                // For cross-domain requests, seeing as conditions for a preflight are
                // akin to a jigsaw puzzle, we simply never set it to be sure.
                // (it can always be set on a per-request basis or even using ajaxSetup)
                // For same-domain requests, won't change header if already provided.
                if ( !options.crossDomain && !headers["X-Requested-With"] ) {
                    headers["X-Requested-With"] = "XMLHttpRequest";
                }
                // Set headers
                for ( i in headers ) {
                    xhr.setRequestHeader( i, headers[ i ] );
                }
                // Callback
                callback = function( type ) {
                    return function() {
                        if ( callback ) {
                            delete xhrCallbacks[ id ];
                            callback = xhr.onload = xhr.onerror = null;
                            if ( type === "abort" ) {
                                xhr.abort();
                            } else if ( type === "error" ) {
                                complete(
                                    // file protocol always yields status 0, assume 404
                                    xhr.status || 404,
                                    xhr.statusText
                                );
                            } else {
                                complete(
                                    xhrSuccessStatus[ xhr.status ] || xhr.status,
                                    xhr.statusText,
                                    // Support: IE9
                                    // #11426: When requesting binary data, IE9 will throw an exception
                                    // on any attempt to access responseText
                                    typeof xhr.responseText === "string" ? {
                                        text: xhr.responseText
                                    } : undefined,
                                    xhr.getAllResponseHeaders()
                                );
                            }
                        }
                    };
                };
                // Listen to events
                xhr.onload = callback();
                xhr.onerror = callback("error");
                // Create the abort callback
                callback = xhrCallbacks[( id = xhrId++ )] = callback("abort");
                // Do send the request
                // This may raise an exception which is actually
                // handled in jQuery.ajax (so no try/catch here)
                xhr.send( options.hasContent && options.data || null );
            },
            abort: function() {
                if ( callback ) {
                    callback();
                }
            }
        };
    }
});
var fxNow, timerId,
    rfxtypes = /^(?:toggle|show|hide)$/,
    rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
    rrun = /queueHooks$/,
    animationPrefilters = [ defaultPrefilter ],
    tweeners = {
        "*": [function( prop, value ) {
            var tween = this.createTween( prop, value ),
                target = tween.cur(),
                parts = rfxnum.exec( value ),
                unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),

                // Starting value computation is required for potential unit mismatches
                start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
                    rfxnum.exec( jQuery.css( tween.elem, prop ) ),
                scale = 1,
                maxIterations = 20;

            if ( start && start[ 3 ] !== unit ) {
                // Trust units reported by jQuery.css
                unit = unit || start[ 3 ];

                // Make sure we update the tween properties later on
                parts = parts || [];

                // Iteratively approximate from a nonzero starting point
                start = +target || 1;

                do {
                    // If previous iteration zeroed out, double until we get *something*
                    // Use a string for doubling factor so we don't accidentally see scale as unchanged below
                    scale = scale || ".5";

                    // Adjust and apply
                    start = start / scale;
                    jQuery.style( tween.elem, prop, start + unit );

                // Update scale, tolerating zero or NaN from tween.cur()
                // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
                } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
            }

            // Update tween properties
            if ( parts ) {
                start = tween.start = +start || +target || 0;
                tween.unit = unit;
                // If a +=/-= token was provided, we're doing a relative animation
                tween.end = parts[ 1 ] ?
                    start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
                    +parts[ 2 ];
            }

            return tween;
        }]
    };

// Animations created synchronously will run synchronously
function createFxNow() {
    setTimeout(function() {
        fxNow = undefined;
    });
    return ( fxNow = jQuery.now() );
}

function createTween( value, prop, animation ) {
    var tween,
        collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
        index = 0,
        length = collection.length;
    for ( ; index < length; index++ ) {
        if ( (tween = collection[ index ].call( animation, prop, value )) ) {

            // we're done with this property
            return tween;
        }
    }
}

function Animation( elem, properties, options ) {
    var result,
        stopped,
        index = 0,
        length = animationPrefilters.length,
        deferred = jQuery.Deferred().always( function() {
            // don't match elem in the :animated selector
            delete tick.elem;
        }),
        tick = function() {
            if ( stopped ) {
                return false;
            }
            var currentTime = fxNow || createFxNow(),
                remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
                // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
                temp = remaining / animation.duration || 0,
                percent = 1 - temp,
                index = 0,
                length = animation.tweens.length;

            for ( ; index < length ; index++ ) {
                animation.tweens[ index ].run( percent );
            }

            deferred.notifyWith( elem, [ animation, percent, remaining ]);

            if ( percent < 1 && length ) {
                return remaining;
            } else {
                deferred.resolveWith( elem, [ animation ] );
                return false;
            }
        },
        animation = deferred.promise({
            elem: elem,
            props: jQuery.extend( {}, properties ),
            opts: jQuery.extend( true, { specialEasing: {} }, options ),
            originalProperties: properties,
            originalOptions: options,
            startTime: fxNow || createFxNow(),
            duration: options.duration,
            tweens: [],
            createTween: function( prop, end ) {
                var tween = jQuery.Tween( elem, animation.opts, prop, end,
                        animation.opts.specialEasing[ prop ] || animation.opts.easing );
                animation.tweens.push( tween );
                return tween;
            },
            stop: function( gotoEnd ) {
                var index = 0,
                    // if we are going to the end, we want to run all the tweens
                    // otherwise we skip this part
                    length = gotoEnd ? animation.tweens.length : 0;
                if ( stopped ) {
                    return this;
                }
                stopped = true;
                for ( ; index < length ; index++ ) {
                    animation.tweens[ index ].run( 1 );
                }

                // resolve when we played the last frame
                // otherwise, reject
                if ( gotoEnd ) {
                    deferred.resolveWith( elem, [ animation, gotoEnd ] );
                } else {
                    deferred.rejectWith( elem, [ animation, gotoEnd ] );
                }
                return this;
            }
        }),
        props = animation.props;

    propFilter( props, animation.opts.specialEasing );

    for ( ; index < length ; index++ ) {
        result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
        if ( result ) {
            return result;
        }
    }

    jQuery.map( props, createTween, animation );

    if ( jQuery.isFunction( animation.opts.start ) ) {
        animation.opts.start.call( elem, animation );
    }

    jQuery.fx.timer(
        jQuery.extend( tick, {
            elem: elem,
            anim: animation,
            queue: animation.opts.queue
        })
    );

    // attach callbacks from options
    return animation.progress( animation.opts.progress )
        .done( animation.opts.done, animation.opts.complete )
        .fail( animation.opts.fail )
        .always( animation.opts.always );
}

function propFilter( props, specialEasing ) {
    var index, name, easing, value, hooks;

    // camelCase, specialEasing and expand cssHook pass
    for ( index in props ) {
        name = jQuery.camelCase( index );
        easing = specialEasing[ name ];
        value = props[ index ];
        if ( jQuery.isArray( value ) ) {
            easing = value[ 1 ];
            value = props[ index ] = value[ 0 ];
        }

        if ( index !== name ) {
            props[ name ] = value;
            delete props[ index ];
        }

        hooks = jQuery.cssHooks[ name ];
        if ( hooks && "expand" in hooks ) {
            value = hooks.expand( value );
            delete props[ name ];

            // not quite $.extend, this wont overwrite keys already present.
            // also - reusing 'index' from above because we have the correct "name"
            for ( index in value ) {
                if ( !( index in props ) ) {
                    props[ index ] = value[ index ];
                    specialEasing[ index ] = easing;
                }
            }
        } else {
            specialEasing[ name ] = easing;
        }
    }
}

jQuery.Animation = jQuery.extend( Animation, {

    tweener: function( props, callback ) {
        if ( jQuery.isFunction( props ) ) {
            callback = props;
            props = [ "*" ];
        } else {
            props = props.split(" ");
        }

        var prop,
            index = 0,
            length = props.length;

        for ( ; index < length ; index++ ) {
            prop = props[ index ];
            tweeners[ prop ] = tweeners[ prop ] || [];
            tweeners[ prop ].unshift( callback );
        }
    },

    prefilter: function( callback, prepend ) {
        if ( prepend ) {
            animationPrefilters.unshift( callback );
        } else {
            animationPrefilters.push( callback );
        }
    }
});

function defaultPrefilter( elem, props, opts ) {
    
    var prop, value, toggle, tween, hooks, oldfire,
        anim = this,
        orig = {},
        style = elem.style,
        hidden = elem.nodeType && isHidden( elem ),
        dataShow = data_priv.get( elem, "fxshow" );

    // handle queue: false promises
    if ( !opts.queue ) {
        hooks = jQuery._queueHooks( elem, "fx" );
        if ( hooks.unqueued == null ) {
            hooks.unqueued = 0;
            oldfire = hooks.empty.fire;
            hooks.empty.fire = function() {
                if ( !hooks.unqueued ) {
                    oldfire();
                }
            };
        }
        hooks.unqueued++;

        anim.always(function() {
            // doing this makes sure that the complete handler will be called
            // before this completes
            anim.always(function() {
                hooks.unqueued--;
                if ( !jQuery.queue( elem, "fx" ).length ) {
                    hooks.empty.fire();
                }
            });
        });
    }

    // height/width overflow pass
    if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
        // Make sure that nothing sneaks out
        // Record all 3 overflow attributes because IE9-10 do not
        // change the overflow attribute when overflowX and
        // overflowY are set to the same value
        opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];

        // Set display property to inline-block for height/width
        // animations on inline elements that are having width/height animated
        if ( jQuery.css( elem, "display" ) === "inline" &&
                jQuery.css( elem, "float" ) === "none" ) {

            style.display = "inline-block";
        }
    }

    if ( opts.overflow ) {
        style.overflow = "hidden";
        anim.always(function() {
            style.overflow = opts.overflow[ 0 ];
            style.overflowX = opts.overflow[ 1 ];
            style.overflowY = opts.overflow[ 2 ];
        });
    }


    // show/hide pass
    for ( prop in props ) {
        value = props[ prop ];
        if ( rfxtypes.exec( value ) ) {
            delete props[ prop ];
            toggle = toggle || value === "toggle";
            if ( value === ( hidden ? "hide" : "show" ) ) {

                // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
                if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
                    hidden = true;
                } else {
                    continue;
                }
            }
            orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
        }
    }

    if ( !jQuery.isEmptyObject( orig ) ) {
        if ( dataShow ) {
            if ( "hidden" in dataShow ) {
                hidden = dataShow.hidden;
            }
        } else {
            dataShow = data_priv.access( elem, "fxshow", {} );
        }

        // store state if its toggle - enables .stop().toggle() to "reverse"
        if ( toggle ) {
            dataShow.hidden = !hidden;
        }
        if ( hidden ) {
            jQuery( elem ).show();
        } else {
            anim.done(function() {
                jQuery( elem ).hide();
            });
        }
        anim.done(function() {
            var prop;

            data_priv.remove( elem, "fxshow" );
            for ( prop in orig ) {
                jQuery.style( elem, prop, orig[ prop ] );
            }
        });
        for ( prop in orig ) {
            tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );

            if ( !( prop in dataShow ) ) {
                dataShow[ prop ] = tween.start;
                if ( hidden ) {
                    tween.end = tween.start;
                    tween.start = prop === "width" || prop === "height" ? 1 : 0;
                }
            }
        }
    }
}

function Tween( elem, options, prop, end, easing ) {
    return new Tween.prototype.init( elem, options, prop, end, easing );
}
jQuery.Tween = Tween;

Tween.prototype = {
    constructor: Tween,
    init: function( elem, options, prop, end, easing, unit ) {
        this.elem = elem;
        this.prop = prop;
        this.easing = easing || "swing";
        this.options = options;
        this.start = this.now = this.cur();
        this.end = end;
        this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
    },
    cur: function() {
        var hooks = Tween.propHooks[ this.prop ];

        return hooks && hooks.get ?
            hooks.get( this ) :
            Tween.propHooks._default.get( this );
    },
    run: function( percent ) {
        var eased,
            hooks = Tween.propHooks[ this.prop ];

        if ( this.options.duration ) {
            this.pos = eased = jQuery.easing[ this.easing ](
                percent, this.options.duration * percent, 0, 1, this.options.duration
            );
        } else {
            this.pos = eased = percent;
        }
        this.now = ( this.end - this.start ) * eased + this.start;

        if ( this.options.step ) {
            this.options.step.call( this.elem, this.now, this );
        }

        if ( hooks && hooks.set ) {
            hooks.set( this );
        } else {
            Tween.propHooks._default.set( this );
        }
        return this;
    }
};

Tween.prototype.init.prototype = Tween.prototype;

Tween.propHooks = {
    _default: {
        get: function( tween ) {
            var result;

            if ( tween.elem[ tween.prop ] != null &&
                (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
                return tween.elem[ tween.prop ];
            }

            // passing an empty string as a 3rd parameter to .css will automatically
            // attempt a parseFloat and fallback to a string if the parse fails
            // so, simple values such as "10px" are parsed to Float.
            // complex values such as "rotate(1rad)" are returned as is.
            result = jQuery.css( tween.elem, tween.prop, "" );
            // Empty strings, null, undefined and "auto" are converted to 0.
            return !result || result === "auto" ? 0 : result;
        },
        set: function( tween ) {
            // use step hook for back compat - use cssHook if its there - use .style if its
            // available and use plain properties where available
            if ( jQuery.fx.step[ tween.prop ] ) {
                jQuery.fx.step[ tween.prop ]( tween );
            } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
                jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
            } else {
                tween.elem[ tween.prop ] = tween.now;
            }
        }
    }
};

// Support: IE9
// Panic based approach to setting things on disconnected nodes

Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
    set: function( tween ) {
        if ( tween.elem.nodeType && tween.elem.parentNode ) {
            tween.elem[ tween.prop ] = tween.now;
        }
    }
};

jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
    var cssFn = jQuery.fn[ name ];
    jQuery.fn[ name ] = function( speed, easing, callback ) {
        return speed == null || typeof speed === "boolean" ?
            cssFn.apply( this, arguments ) :
            this.animate( genFx( name, true ), speed, easing, callback );
    };
});

jQuery.fn.extend({
    fadeTo: function( speed, to, easing, callback ) {

        // show any hidden elements after setting opacity to 0
        return this.filter( isHidden ).css( "opacity", 0 ).show()

            // animate to the value specified
            .end().animate({ opacity: to }, speed, easing, callback );
    },
    animate: function( prop, speed, easing, callback ) {
        var empty = jQuery.isEmptyObject( prop ),
            optall = jQuery.speed( speed, easing, callback ),
            doAnimation = function() {
                // Operate on a copy of prop so per-property easing won't be lost
                var anim = Animation( this, jQuery.extend( {}, prop ), optall );

                // Empty animations, or finishing resolves immediately
                if ( empty || data_priv.get( this, "finish" ) ) {
                    anim.stop( true );
                }
            };
            doAnimation.finish = doAnimation;

        return empty || optall.queue === false ?
            this.each( doAnimation ) :
            this.queue( optall.queue, doAnimation );
    },
    stop: function( type, clearQueue, gotoEnd ) {
        var stopQueue = function( hooks ) {
            var stop = hooks.stop;
            delete hooks.stop;
            stop( gotoEnd );
        };

        if ( typeof type !== "string" ) {
            gotoEnd = clearQueue;
            clearQueue = type;
            type = undefined;
        }
        if ( clearQueue && type !== false ) {
            this.queue( type || "fx", [] );
        }

        return this.each(function() {
            var dequeue = true,
                index = type != null && type + "queueHooks",
                timers = jQuery.timers,
                data = data_priv.get( this );

            if ( index ) {
                if ( data[ index ] && data[ index ].stop ) {
                    stopQueue( data[ index ] );
                }
            } else {
                for ( index in data ) {
                    if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
                        stopQueue( data[ index ] );
                    }
                }
            }

            for ( index = timers.length; index--; ) {
                if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
                    timers[ index ].anim.stop( gotoEnd );
                    dequeue = false;
                    timers.splice( index, 1 );
                }
            }

            // start the next in the queue if the last step wasn't forced
            // timers currently will call their complete callbacks, which will dequeue
            // but only if they were gotoEnd
            if ( dequeue || !gotoEnd ) {
                jQuery.dequeue( this, type );
            }
        });
    },
    finish: function( type ) {
        if ( type !== false ) {
            type = type || "fx";
        }
        return this.each(function() {
            var index,
                data = data_priv.get( this ),
                queue = data[ type + "queue" ],
                hooks = data[ type + "queueHooks" ],
                timers = jQuery.timers,
                length = queue ? queue.length : 0;

            // enable finishing flag on private data
            data.finish = true;

            // empty the queue first
            jQuery.queue( this, type, [] );

            if ( hooks && hooks.stop ) {
                hooks.stop.call( this, true );
            }

            // look for any active animations, and finish them
            for ( index = timers.length; index--; ) {
                if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
                    timers[ index ].anim.stop( true );
                    timers.splice( index, 1 );
                }
            }

            // look for any animations in the old queue and finish them
            for ( index = 0; index < length; index++ ) {
                if ( queue[ index ] && queue[ index ].finish ) {
                    queue[ index ].finish.call( this );
                }
            }

            // turn off finishing flag
            delete data.finish;
        });
    }
});

// Generate parameters to create a standard animation
function genFx( type, includeWidth ) {
    var which,
        attrs = { height: type },
        i = 0;

    // if we include width, step value is 1 to do all cssExpand values,
    // if we don't include width, step value is 2 to skip over Left and Right
    includeWidth = includeWidth? 1 : 0;
    for( ; i < 4 ; i += 2 - includeWidth ) {
        which = cssExpand[ i ];
        attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
    }

    if ( includeWidth ) {
        attrs.opacity = attrs.width = type;
    }

    return attrs;
}

// Generate shortcuts for custom animations
jQuery.each({
    slideDown: genFx("show"),
    slideUp: genFx("hide"),
    slideToggle: genFx("toggle"),
    fadeIn: { opacity: "show" },
    fadeOut: { opacity: "hide" },
    fadeToggle: { opacity: "toggle" }
}, function( name, props ) {
    jQuery.fn[ name ] = function( speed, easing, callback ) {
        return this.animate( props, speed, easing, callback );
    };
});

jQuery.speed = function( speed, easing, fn ) {
    var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
        complete: fn || !fn && easing ||
            jQuery.isFunction( speed ) && speed,
        duration: speed,
        easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
    };

    opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
        opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;

    // normalize opt.queue - true/undefined/null -> "fx"
    if ( opt.queue == null || opt.queue === true ) {
        opt.queue = "fx";
    }

    // Queueing
    opt.old = opt.complete;

    opt.complete = function() {
        if ( jQuery.isFunction( opt.old ) ) {
            opt.old.call( this );
        }

        if ( opt.queue ) {
            jQuery.dequeue( this, opt.queue );
        }
    };

    return opt;
};

jQuery.easing = {
    linear: function( p ) {
        return p;
    },
    swing: function( p ) {
        return 0.5 - Math.cos( p*Math.PI ) / 2;
    }
};

jQuery.timers = [];
jQuery.fx = Tween.prototype.init;
jQuery.fx.tick = function() {
    var timer,
        timers = jQuery.timers,
        i = 0;

    fxNow = jQuery.now();

    for ( ; i < timers.length; i++ ) {
        timer = timers[ i ];
        // Checks the timer has not already been removed
        if ( !timer() && timers[ i ] === timer ) {
            timers.splice( i--, 1 );
        }
    }

    if ( !timers.length ) {
        jQuery.fx.stop();
    }
    fxNow = undefined;
};

jQuery.fx.timer = function( timer ) {
    if ( timer() && jQuery.timers.push( timer ) ) {
        jQuery.fx.start();
    }
};

jQuery.fx.interval = 13;

jQuery.fx.start = function() {
    if ( !timerId ) {
        timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
    }
};

jQuery.fx.stop = function() {
    clearInterval( timerId );
    timerId = null;
};

jQuery.fx.speeds = {
    slow: 600,
    fast: 200,
    // Default speed
    _default: 400
};

// Back Compat <1.8 extension point
jQuery.fx.step = {};

if ( jQuery.expr && jQuery.expr.filters ) {
    jQuery.expr.filters.animated = function( elem ) {
        return jQuery.grep(jQuery.timers, function( fn ) {
            return elem === fn.elem;
        }).length;
    };
}
jQuery.fn.offset = function( options ) {
    if ( arguments.length ) {
        return options === undefined ?
            this :
            this.each(function( i ) {
                jQuery.offset.setOffset( this, options, i );
            });
    }

    var docElem, win,
        elem = this[ 0 ],
        box = { top: 0, left: 0 },
        doc = elem && elem.ownerDocument;

    if ( !doc ) {
        return;
    }

    docElem = doc.documentElement;

    // Make sure it's not a disconnected DOM node
    if ( !jQuery.contains( docElem, elem ) ) {
        return box;
    }

    // If we don't have gBCR, just use 0,0 rather than error
    // BlackBerry 5, iOS 3 (original iPhone)
    if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
        box = elem.getBoundingClientRect();
    }
    win = getWindow( doc );
    return {
        top: box.top + win.pageYOffset - docElem.clientTop,
        left: box.left + win.pageXOffset - docElem.clientLeft
    };
};

jQuery.offset = {

    setOffset: function( elem, options, i ) {
        var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
            position = jQuery.css( elem, "position" ),
            curElem = jQuery( elem ),
            props = {};

        // Set position first, in-case top/left are set even on static elem
        if ( position === "static" ) {
            elem.style.position = "relative";
        }

        curOffset = curElem.offset();
        curCSSTop = jQuery.css( elem, "top" );
        curCSSLeft = jQuery.css( elem, "left" );
        calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;

        // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
        if ( calculatePosition ) {
            curPosition = curElem.position();
            curTop = curPosition.top;
            curLeft = curPosition.left;

        } else {
            curTop = parseFloat( curCSSTop ) || 0;
            curLeft = parseFloat( curCSSLeft ) || 0;
        }

        if ( jQuery.isFunction( options ) ) {
            options = options.call( elem, i, curOffset );
        }

        if ( options.top != null ) {
            props.top = ( options.top - curOffset.top ) + curTop;
        }
        if ( options.left != null ) {
            props.left = ( options.left - curOffset.left ) + curLeft;
        }

        if ( "using" in options ) {
            options.using.call( elem, props );

        } else {
            curElem.css( props );
        }
    }
};


jQuery.fn.extend({

    position: function() {
        if ( !this[ 0 ] ) {
            return;
        }

        var offsetParent, offset,
            elem = this[ 0 ],
            parentOffset = { top: 0, left: 0 };

        // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
        if ( jQuery.css( elem, "position" ) === "fixed" ) {
            // We assume that getBoundingClientRect is available when computed position is fixed
            offset = elem.getBoundingClientRect();

        } else {
            // Get *real* offsetParent
            offsetParent = this.offsetParent();

            // Get correct offsets
            offset = this.offset();
            if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
                parentOffset = offsetParent.offset();
            }

            // Add offsetParent borders
            parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
            parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
        }

        // Subtract parent offsets and element margins
        return {
            top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
            left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
        };
    },

    offsetParent: function() {
        return this.map(function() {
            var offsetParent = this.offsetParent || docElem;

            while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
                offsetParent = offsetParent.offsetParent;
            }

            return offsetParent || docElem;
        });
    }
});


// Create scrollLeft and scrollTop methods
jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
    var top = "pageYOffset" === prop;

    jQuery.fn[ method ] = function( val ) {
        return jQuery.access( this, function( elem, method, val ) {
            var win = getWindow( elem );

            if ( val === undefined ) {
                return win ? win[ prop ] : elem[ method ];
            }

            if ( win ) {
                win.scrollTo(
                    !top ? val : window.pageXOffset,
                    top ? val : window.pageYOffset
                );

            } else {
                elem[ method ] = val;
            }
        }, method, val, arguments.length, null );
    };
});

function getWindow( elem ) {
    return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
}
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
    jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
        // margin is only for outerHeight, outerWidth
        jQuery.fn[ funcName ] = function( margin, value ) {
            var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
                extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );

            return jQuery.access( this, function( elem, type, value ) {
                var doc;

                if ( jQuery.isWindow( elem ) ) {
                    // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
                    // isn't a whole lot we can do. See pull request at this URL for discussion:
                    // https://github.com/jquery/jquery/pull/764
                    return elem.document.documentElement[ "client" + name ];
                }

                // Get document width or height
                if ( elem.nodeType === 9 ) {
                    doc = elem.documentElement;

                    // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
                    // whichever is greatest
                    return Math.max(
                        elem.body[ "scroll" + name ], doc[ "scroll" + name ],
                        elem.body[ "offset" + name ], doc[ "offset" + name ],
                        doc[ "client" + name ]
                    );
                }

                return value === undefined ?
                    // Get width or height on the element, requesting but not forcing parseFloat
                    jQuery.css( elem, type, extra ) :

                    // Set width or height on the element
                    jQuery.style( elem, type, value, extra );
            }, type, chainable ? margin : undefined, chainable, null );
        };
    });
});
// Limit scope pollution from any deprecated API
// (function() {

// The number of elements contained in the matched element set
jQuery.fn.size = function() {
    return this.length;
};

jQuery.fn.andSelf = jQuery.fn.addBack;

// })();
if ( typeof module === "object" && module && typeof module.exports === "object" ) {
    // Expose jQuery as module.exports in loaders that implement the Node
    // module pattern (including browserify). Do not create the global, since
    // the user will be storing it themselves locally, and globals are frowned
    // upon in the Node module world.
    module.exports = jQuery;
} else {
    // Register as a named AMD module, since jQuery can be concatenated with other
    // files that may use define, but not via a proper concatenation script that
    // understands anonymous AMD modules. A named AMD is safest and most robust
    // way to register. Lowercase jquery is used because AMD module names are
    // derived from file names, and jQuery is normally delivered in a lowercase
    // file name. Do this after creating the global so that if an AMD module wants
    // to call noConflict to hide this version of jQuery, it will work.
    if ( typeof define === "function" && define.amd ) {
        define( "jquery", [], function () { return jQuery; } );
    }
}

// If there is a window object, that at least has a document property,
// define jQuery and $ identifiers
if ( typeof window === "object" && typeof window.document === "object" ) {
    window.jQuery = window.$ = jQuery;
}

})( window );
;

// Source: yithwebclient/static/vendor/bootstrap/bootstrap.js



!function ($) {

  "use strict"; // jshint ;_;


  

  $(function () {

    $.support.transition = (function () {

      var transitionEnd = (function () {

        var el = document.createElement('bootstrap')
          , transEndEventNames = {
               'WebkitTransition' : 'webkitTransitionEnd'
            ,  'MozTransition'    : 'transitionend'
            ,  'OTransition'      : 'oTransitionEnd otransitionend'
            ,  'transition'       : 'transitionend'
            }
          , name

        for (name in transEndEventNames){
          if (el.style[name] !== undefined) {
            return transEndEventNames[name]
          }
        }

      }())

      return transitionEnd && {
        end: transitionEnd
      }

    })()

  })

}(window.jQuery);


!function ($) {

  "use strict"; // jshint ;_;


 

  var dismiss = '[data-dismiss="alert"]'
    , Alert = function (el) {
        $(el).on('click', dismiss, this.close)
      }

  Alert.prototype.close = function (e) {
    var $this = $(this)
      , selector = $this.attr('data-target')
      , $parent

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
    }

    $parent = $(selector)

    e && e.preventDefault()

    $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())

    $parent.trigger(e = $.Event('close'))

    if (e.isDefaultPrevented()) return

    $parent.removeClass('in')

    function removeElement() {
      $parent
        .trigger('closed')
        .remove()
    }

    $.support.transition && $parent.hasClass('fade') ?
      $parent.on($.support.transition.end, removeElement) :
      removeElement()
  }


 

  var old = $.fn.alert

  $.fn.alert = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('alert')
      if (!data) $this.data('alert', (data = new Alert(this)))
      if (typeof option == 'string') data[option].call($this)
    })
  }

  $.fn.alert.Constructor = Alert


 

  $.fn.alert.noConflict = function () {
    $.fn.alert = old
    return this
  }


 

  $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)

}(window.jQuery);


!function ($) {

  "use strict"; // jshint ;_;


 

  var Button = function (element, options) {
    this.$element = $(element)
    this.options = $.extend({}, $.fn.button.defaults, options)
  }

  Button.prototype.setState = function (state) {
    var d = 'disabled'
      , $el = this.$element
      , data = $el.data()
      , val = $el.is('input') ? 'val' : 'html'

    state = state + 'Text'
    data.resetText || $el.data('resetText', $el[val]())

    $el[val](data[state] || this.options[state])

    // push to event loop to allow forms to submit
    setTimeout(function () {
      state == 'loadingText' ?
        $el.addClass(d).attr(d, d) :
        $el.removeClass(d).removeAttr(d)
    }, 0)
  }

  Button.prototype.toggle = function () {
    var $parent = this.$element.closest('[data-toggle="buttons-radio"]')

    $parent && $parent
      .find('.active')
      .removeClass('active')

    this.$element.toggleClass('active')
  }


 

  var old = $.fn.button

  $.fn.button = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('button')
        , options = typeof option == 'object' && option
      if (!data) $this.data('button', (data = new Button(this, options)))
      if (option == 'toggle') data.toggle()
      else if (option) data.setState(option)
    })
  }

  $.fn.button.defaults = {
    loadingText: 'loading...'
  }

  $.fn.button.Constructor = Button


 

  $.fn.button.noConflict = function () {
    $.fn.button = old
    return this
  }


 

  $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
    var $btn = $(e.target)
    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
    $btn.button('toggle')
  })

}(window.jQuery);


!function ($) {

  "use strict"; // jshint ;_;


 

  var Carousel = function (element, options) {
    this.$element = $(element)
    this.$indicators = this.$element.find('.carousel-indicators')
    this.options = options
    this.options.pause == 'hover' && this.$element
      .on('mouseenter', $.proxy(this.pause, this))
      .on('mouseleave', $.proxy(this.cycle, this))
  }

  Carousel.prototype = {

    cycle: function (e) {
      if (!e) this.paused = false
      if (this.interval) clearInterval(this.interval);
      this.options.interval
        && !this.paused
        && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
      return this
    }

  , getActiveIndex: function () {
      this.$active = this.$element.find('.item.active')
      this.$items = this.$active.parent().children()
      return this.$items.index(this.$active)
    }

  , to: function (pos) {
      var activeIndex = this.getActiveIndex()
        , that = this

      if (pos > (this.$items.length - 1) || pos < 0) return

      if (this.sliding) {
        return this.$element.one('slid', function () {
          that.to(pos)
        })
      }

      if (activeIndex == pos) {
        return this.pause().cycle()
      }

      return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
    }

  , pause: function (e) {
      if (!e) this.paused = true
      if (this.$element.find('.next, .prev').length && $.support.transition.end) {
        this.$element.trigger($.support.transition.end)
        this.cycle(true)
      }
      clearInterval(this.interval)
      this.interval = null
      return this
    }

  , next: function () {
      if (this.sliding) return
      return this.slide('next')
    }

  , prev: function () {
      if (this.sliding) return
      return this.slide('prev')
    }

  , slide: function (type, next) {
      var $active = this.$element.find('.item.active')
        , $next = next || $active[type]()
        , isCycling = this.interval
        , direction = type == 'next' ? 'left' : 'right'
        , fallback  = type == 'next' ? 'first' : 'last'
        , that = this
        , e

      this.sliding = true

      isCycling && this.pause()

      $next = $next.length ? $next : this.$element.find('.item')[fallback]()

      e = $.Event('slide', {
        relatedTarget: $next[0]
      , direction: direction
      })

      if ($next.hasClass('active')) return

      if (this.$indicators.length) {
        this.$indicators.find('.active').removeClass('active')
        this.$element.one('slid', function () {
          var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
          $nextIndicator && $nextIndicator.addClass('active')
        })
      }

      if ($.support.transition && this.$element.hasClass('slide')) {
        this.$element.trigger(e)
        if (e.isDefaultPrevented()) return
        $next.addClass(type)
        $next[0].offsetWidth // force reflow
        $active.addClass(direction)
        $next.addClass(direction)
        this.$element.one($.support.transition.end, function () {
          $next.removeClass([type, direction].join(' ')).addClass('active')
          $active.removeClass(['active', direction].join(' '))
          that.sliding = false
          setTimeout(function () { that.$element.trigger('slid') }, 0)
        })
      } else {
        this.$element.trigger(e)
        if (e.isDefaultPrevented()) return
        $active.removeClass('active')
        $next.addClass('active')
        this.sliding = false
        this.$element.trigger('slid')
      }

      isCycling && this.cycle()

      return this
    }

  }


 

  var old = $.fn.carousel

  $.fn.carousel = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('carousel')
        , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
        , action = typeof option == 'string' ? option : options.slide
      if (!data) $this.data('carousel', (data = new Carousel(this, options)))
      if (typeof option == 'number') data.to(option)
      else if (action) data[action]()
      else if (options.interval) data.pause().cycle()
    })
  }

  $.fn.carousel.defaults = {
    interval: 5000
  , pause: 'hover'
  }

  $.fn.carousel.Constructor = Carousel


 

  $.fn.carousel.noConflict = function () {
    $.fn.carousel = old
    return this
  }

 

  $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
    var $this = $(this), href
      , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
      , options = $.extend({}, $target.data(), $this.data())
      , slideIndex

    $target.carousel(options)

    if (slideIndex = $this.attr('data-slide-to')) {
      $target.data('carousel').pause().to(slideIndex).cycle()
    }

    e.preventDefault()
  })

}(window.jQuery);


!function ($) {

  "use strict"; // jshint ;_;


 

  var Collapse = function (element, options) {
    this.$element = $(element)
    this.options = $.extend({}, $.fn.collapse.defaults, options)

    if (this.options.parent) {
      this.$parent = $(this.options.parent)
    }

    this.options.toggle && this.toggle()
  }

  Collapse.prototype = {

    constructor: Collapse

  , dimension: function () {
      var hasWidth = this.$element.hasClass('width')
      return hasWidth ? 'width' : 'height'
    }

  , show: function () {
      var dimension
        , scroll
        , actives
        , hasData

      if (this.transitioning || this.$element.hasClass('in')) return

      dimension = this.dimension()
      scroll = $.camelCase(['scroll', dimension].join('-'))
      actives = this.$parent && this.$parent.find('> .accordion-group > .in')

      if (actives && actives.length) {
        hasData = actives.data('collapse')
        if (hasData && hasData.transitioning) return
        actives.collapse('hide')
        hasData || actives.data('collapse', null)
      }

      this.$element[dimension](0)
      this.transition('addClass', $.Event('show'), 'shown')
      $.support.transition && this.$element[dimension](this.$element[0][scroll])
    }

  , hide: function () {
      var dimension
      if (this.transitioning || !this.$element.hasClass('in')) return
      dimension = this.dimension()
      this.reset(this.$element[dimension]())
      this.transition('removeClass', $.Event('hide'), 'hidden')
      this.$element[dimension](0)
    }

  , reset: function (size) {
      var dimension = this.dimension()

      this.$element
        .removeClass('collapse')
        [dimension](size || 'auto')
        [0].offsetWidth

      this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')

      return this
    }

  , transition: function (method, startEvent, completeEvent) {
      var that = this
        , complete = function () {
            if (startEvent.type == 'show') that.reset()
            that.transitioning = 0
            that.$element.trigger(completeEvent)
          }

      this.$element.trigger(startEvent)

      if (startEvent.isDefaultPrevented()) return

      this.transitioning = 1

      this.$element[method]('in')

      $.support.transition && this.$element.hasClass('collapse') ?
        this.$element.one($.support.transition.end, complete) :
        complete()
    }

  , toggle: function () {
      this[this.$element.hasClass('in') ? 'hide' : 'show']()
    }

  }


 

  var old = $.fn.collapse

  $.fn.collapse = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('collapse')
        , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option)
      if (!data) $this.data('collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.collapse.defaults = {
    toggle: true
  }

  $.fn.collapse.Constructor = Collapse


 

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }


 

  $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
    var $this = $(this), href
      , target = $this.attr('data-target')
        || e.preventDefault()
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
      , option = $(target).data('collapse') ? 'toggle' : $this.data()
    $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
    $(target).collapse(option)
  })

}(window.jQuery);


!function ($) {

  "use strict"; // jshint ;_;


 

  var toggle = '[data-toggle=dropdown]'
    , Dropdown = function (element) {
        var $el = $(element).on('click.dropdown.data-api', this.toggle)
        $('html').on('click.dropdown.data-api', function () {
          $el.parent().removeClass('open')
        })
      }

  Dropdown.prototype = {

    constructor: Dropdown

  , toggle: function (e) {
      var $this = $(this)
        , $parent
        , isActive

      if ($this.is('.disabled, :disabled')) return

      $parent = getParent($this)

      isActive = $parent.hasClass('open')

      clearMenus()

      if (!isActive) {
        if ('ontouchstart' in document.documentElement) {
          // if mobile we we use a backdrop because click events don't delegate
          $('<div class="dropdown-backdrop"/>').insertBefore($(this)).on('click', clearMenus)
        }
        $parent.toggleClass('open')
      }

      $this.focus()

      return false
    }

  , keydown: function (e) {
      var $this
        , $items
        , $active
        , $parent
        , isActive
        , index

      if (!/(38|40|27)/.test(e.keyCode)) return

      $this = $(this)

      e.preventDefault()
      e.stopPropagation()

      if ($this.is('.disabled, :disabled')) return

      $parent = getParent($this)

      isActive = $parent.hasClass('open')

      if (!isActive || (isActive && e.keyCode == 27)) {
        if (e.which == 27) $parent.find(toggle).focus()
        return $this.click()
      }

      $items = $('[role=menu] li:not(.divider):visible a', $parent)

      if (!$items.length) return

      index = $items.index($items.filter(':focus'))

      if (e.keyCode == 38 && index > 0) index--                                        // up
      if (e.keyCode == 40 && index < $items.length - 1) index++                        // down
      if (!~index) index = 0

      $items
        .eq(index)
        .focus()
    }

  }

  function clearMenus() {
    $('.dropdown-backdrop').remove()
    $(toggle).each(function () {
      getParent($(this)).removeClass('open')
    })
  }

  function getParent($this) {
    var selector = $this.attr('data-target')
      , $parent

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
    }

    $parent = selector && $(selector)

    if (!$parent || !$parent.length) $parent = $this.parent()

    return $parent
  }


  

  var old = $.fn.dropdown

  $.fn.dropdown = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('dropdown')
      if (!data) $this.data('dropdown', (data = new Dropdown(this)))
      if (typeof option == 'string') data[option].call($this)
    })
  }

  $.fn.dropdown.Constructor = Dropdown


 

  $.fn.dropdown.noConflict = function () {
    $.fn.dropdown = old
    return this
  }


  

  $(document)
    .on('click.dropdown.data-api', clearMenus)
    .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
    .on('click.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)
    .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)

}(window.jQuery);



!function ($) {

  "use strict"; // jshint ;_;


 

  var Modal = function (element, options) {
    this.options = options
    this.$element = $(element)
      .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
    this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
  }

  Modal.prototype = {

      constructor: Modal

    , toggle: function () {
        return this[!this.isShown ? 'show' : 'hide']()
      }

    , show: function () {
        var that = this
          , e = $.Event('show')

        this.$element.trigger(e)

        if (this.isShown || e.isDefaultPrevented()) return

        this.isShown = true

        this.escape()

        this.backdrop(function () {
          var transition = $.support.transition && that.$element.hasClass('fade')

          if (!that.$element.parent().length) {
            that.$element.appendTo(document.body) //don't move modals dom position
          }

          that.$element.show()

          if (transition) {
            that.$element[0].offsetWidth // force reflow
          }

          that.$element
            .addClass('in')
            .attr('aria-hidden', false)

          that.enforceFocus()

          transition ?
            that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
            that.$element.focus().trigger('shown')

        })
      }

    , hide: function (e) {
        e && e.preventDefault()

        var that = this

        e = $.Event('hide')

        this.$element.trigger(e)

        if (!this.isShown || e.isDefaultPrevented()) return

        this.isShown = false

        this.escape()

        $(document).off('focusin.modal')

        this.$element
          .removeClass('in')
          .attr('aria-hidden', true)

        $.support.transition && this.$element.hasClass('fade') ?
          this.hideWithTransition() :
          this.hideModal()
      }

    , enforceFocus: function () {
        var that = this
        $(document).on('focusin.modal', function (e) {
          if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
            that.$element.focus()
          }
        })
      }

    , escape: function () {
        var that = this
        if (this.isShown && this.options.keyboard) {
          this.$element.on('keyup.dismiss.modal', function ( e ) {
            e.which == 27 && that.hide()
          })
        } else if (!this.isShown) {
          this.$element.off('keyup.dismiss.modal')
        }
      }

    , hideWithTransition: function () {
        var that = this
          , timeout = setTimeout(function () {
              that.$element.off($.support.transition.end)
              that.hideModal()
            }, 500)

        this.$element.one($.support.transition.end, function () {
          clearTimeout(timeout)
          that.hideModal()
        })
      }

    , hideModal: function () {
        var that = this
        this.$element.hide()
        this.backdrop(function () {
          that.removeBackdrop()
          that.$element.trigger('hidden')
        })
      }

    , removeBackdrop: function () {
        this.$backdrop && this.$backdrop.remove()
        this.$backdrop = null
      }

    , backdrop: function (callback) {
        var that = this
          , animate = this.$element.hasClass('fade') ? 'fade' : ''

        if (this.isShown && this.options.backdrop) {
          var doAnimate = $.support.transition && animate

          this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
            .appendTo(document.body)

          this.$backdrop.click(
            this.options.backdrop == 'static' ?
              $.proxy(this.$element[0].focus, this.$element[0])
            : $.proxy(this.hide, this)
          )

          if (doAnimate) this.$backdrop[0].offsetWidth // force reflow

          this.$backdrop.addClass('in')

          if (!callback) return

          doAnimate ?
            this.$backdrop.one($.support.transition.end, callback) :
            callback()

        } else if (!this.isShown && this.$backdrop) {
          this.$backdrop.removeClass('in')

          $.support.transition && this.$element.hasClass('fade')?
            this.$backdrop.one($.support.transition.end, callback) :
            callback()

        } else if (callback) {
          callback()
        }
      }
  }


 

  var old = $.fn.modal

  $.fn.modal = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('modal')
        , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
      if (!data) $this.data('modal', (data = new Modal(this, options)))
      if (typeof option == 'string') data[option]()
      else if (options.show) data.show()
    })
  }

  $.fn.modal.defaults = {
      backdrop: true
    , keyboard: true
    , show: true
  }

  $.fn.modal.Constructor = Modal


 

  $.fn.modal.noConflict = function () {
    $.fn.modal = old
    return this
  }


 

  $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
    var $this = $(this)
      , href = $this.attr('href')
      , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
      , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())

    e.preventDefault()

    $target
      .modal(option)
      .one('hide', function () {
        $this.focus()
      })
  })

}(window.jQuery);



!function ($) {

  "use strict"; // jshint ;_;


 

  var Tooltip = function (element, options) {
    this.init('tooltip', element, options)
  }

  Tooltip.prototype = {

    constructor: Tooltip

  , init: function (type, element, options) {
      var eventIn
        , eventOut
        , triggers
        , trigger
        , i

      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true

      triggers = this.options.trigger.split(' ')

      for (i = triggers.length; i--;) {
        trigger = triggers[i]
        if (trigger == 'click') {
          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
        } else if (trigger != 'manual') {
          eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
          eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
          this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
          this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
        }
      }

      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
    }

  , getOptions: function (options) {
      options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)

      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
        }
      }

      return options
    }

  , enter: function (e) {
      var defaults = $.fn[this.type].defaults
        , options = {}
        , self

      this._options && $.each(this._options, function (key, value) {
        if (defaults[key] != value) options[key] = value
      }, this)

      self = $(e.currentTarget)[this.type](options).data(this.type)

      if (!self.options.delay || !self.options.delay.show) return self.show()

      clearTimeout(this.timeout)
      self.hoverState = 'in'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'in') self.show()
      }, self.options.delay.show)
    }

  , leave: function (e) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (this.timeout) clearTimeout(this.timeout)
      if (!self.options.delay || !self.options.delay.hide) return self.hide()

      self.hoverState = 'out'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'out') self.hide()
      }, self.options.delay.hide)
    }

  , show: function () {
      var $tip
        , pos
        , actualWidth
        , actualHeight
        , placement
        , tp
        , e = $.Event('show')

      if (this.hasContent() && this.enabled) {
        this.$element.trigger(e)
        if (e.isDefaultPrevented()) return
        $tip = this.tip()
        this.setContent()

        if (this.options.animation) {
          $tip.addClass('fade')
        }

        placement = typeof this.options.placement == 'function' ?
          this.options.placement.call(this, $tip[0], this.$element[0]) :
          this.options.placement

        $tip
          .detach()
          .css({ top: 0, left: 0, display: 'block' })

        this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

        pos = this.getPosition()

        actualWidth = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight

        switch (placement) {
          case 'bottom':
            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'top':
            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'left':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
            break
          case 'right':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
            break
        }

        this.applyPlacement(tp, placement)
        this.$element.trigger('shown')
      }
    }

  , applyPlacement: function(offset, placement){
      var $tip = this.tip()
        , width = $tip[0].offsetWidth
        , height = $tip[0].offsetHeight
        , actualWidth
        , actualHeight
        , delta
        , replace

      $tip
        .offset(offset)
        .addClass(placement)
        .addClass('in')

      actualWidth = $tip[0].offsetWidth
      actualHeight = $tip[0].offsetHeight

      if (placement == 'top' && actualHeight != height) {
        offset.top = offset.top + height - actualHeight
        replace = true
      }

      if (placement == 'bottom' || placement == 'top') {
        delta = 0

        if (offset.left < 0){
          delta = offset.left * -2
          offset.left = 0
          $tip.offset(offset)
          actualWidth = $tip[0].offsetWidth
          actualHeight = $tip[0].offsetHeight
        }

        this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
      } else {
        this.replaceArrow(actualHeight - height, actualHeight, 'top')
      }

      if (replace) $tip.offset(offset)
    }

  , replaceArrow: function(delta, dimension, position){
      this
        .arrow()
        .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
    }

  , setContent: function () {
      var $tip = this.tip()
        , title = this.getTitle()

      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
      $tip.removeClass('fade in top bottom left right')
    }

  , hide: function () {
      var that = this
        , $tip = this.tip()
        , e = $.Event('hide')

      this.$element.trigger(e)
      if (e.isDefaultPrevented()) return

      $tip.removeClass('in')

      function removeWithAnimation() {
        var timeout = setTimeout(function () {
          $tip.off($.support.transition.end).detach()
        }, 500)

        $tip.one($.support.transition.end, function () {
          clearTimeout(timeout)
          $tip.detach()
        })
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        removeWithAnimation() :
        $tip.detach()

      this.$element.trigger('hidden')

      return this
    }

  , fixTitle: function () {
      var $e = this.$element
      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
        $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
      }
    }

  , hasContent: function () {
      return this.getTitle()
    }

  , getPosition: function () {
      var el = this.$element[0]
      return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
        width: el.offsetWidth
      , height: el.offsetHeight
      }, this.$element.offset())
    }

  , getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      return title
    }

  , tip: function () {
      return this.$tip = this.$tip || $(this.options.template)
    }

  , arrow: function(){
      return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
    }

  , validate: function () {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function () {
      this.enabled = true
    }

  , disable: function () {
      this.enabled = false
    }

  , toggleEnabled: function () {
      this.enabled = !this.enabled
    }

  , toggle: function (e) {
      var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
      self.tip().hasClass('in') ? self.hide() : self.show()
    }

  , destroy: function () {
      this.hide().$element.off('.' + this.type).removeData(this.type)
    }

  }


 

  var old = $.fn.tooltip

  $.fn.tooltip = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tooltip')
        , options = typeof option == 'object' && option
      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip

  $.fn.tooltip.defaults = {
    animation: true
  , placement: 'top'
  , selector: false
  , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
  , trigger: 'hover focus'
  , title: ''
  , delay: 0
  , html: false
  , container: false
  }


 

  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }

}(window.jQuery);



!function ($) {

  "use strict"; // jshint ;_;


 

  var Popover = function (element, options) {
    this.init('popover', element, options)
  }


  

  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {

    constructor: Popover

  , setContent: function () {
      var $tip = this.tip()
        , title = this.getTitle()
        , content = this.getContent()

      $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
      $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)

      $tip.removeClass('fade top bottom left right in')
    }

  , hasContent: function () {
      return this.getTitle() || this.getContent()
    }

  , getContent: function () {
      var content
        , $e = this.$element
        , o = this.options

      content = (typeof o.content == 'function' ? o.content.call($e[0]) :  o.content)
        || $e.attr('data-content')

      return content
    }

  , tip: function () {
      if (!this.$tip) {
        this.$tip = $(this.options.template)
      }
      return this.$tip
    }

  , destroy: function () {
      this.hide().$element.off('.' + this.type).removeData(this.type)
    }

  })


 

  var old = $.fn.popover

  $.fn.popover = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('popover')
        , options = typeof option == 'object' && option
      if (!data) $this.data('popover', (data = new Popover(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.popover.Constructor = Popover

  $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
    placement: 'right'
  , trigger: 'click'
  , content: ''
  , template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  })


 

  $.fn.popover.noConflict = function () {
    $.fn.popover = old
    return this
  }

}(window.jQuery);



!function ($) {

  "use strict"; // jshint ;_;


 

  function ScrollSpy(element, options) {
    var process = $.proxy(this.process, this)
      , $element = $(element).is('body') ? $(window) : $(element)
      , href
    this.options = $.extend({}, $.fn.scrollspy.defaults, options)
    this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
    this.selector = (this.options.target
      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
      || '') + ' .nav li > a'
    this.$body = $('body')
    this.refresh()
    this.process()
  }

  ScrollSpy.prototype = {

      constructor: ScrollSpy

    , refresh: function () {
        var self = this
          , $targets

        this.offsets = $([])
        this.targets = $([])

        $targets = this.$body
          .find(this.selector)
          .map(function () {
            var $el = $(this)
              , href = $el.data('target') || $el.attr('href')
              , $href = /^#\w/.test(href) && $(href)
            return ( $href
              && $href.length
              && [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null
          })
          .sort(function (a, b) { return a[0] - b[0] })
          .each(function () {
            self.offsets.push(this[0])
            self.targets.push(this[1])
          })
      }

    , process: function () {
        var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
          , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
          , maxScroll = scrollHeight - this.$scrollElement.height()
          , offsets = this.offsets
          , targets = this.targets
          , activeTarget = this.activeTarget
          , i

        if (scrollTop >= maxScroll) {
          return activeTarget != (i = targets.last()[0])
            && this.activate ( i )
        }

        for (i = offsets.length; i--;) {
          activeTarget != targets[i]
            && scrollTop >= offsets[i]
            && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
            && this.activate( targets[i] )
        }
      }

    , activate: function (target) {
        var active
          , selector

        this.activeTarget = target

        $(this.selector)
          .parent('.active')
          .removeClass('active')

        selector = this.selector
          + '[data-target="' + target + '"],'
          + this.selector + '[href="' + target + '"]'

        active = $(selector)
          .parent('li')
          .addClass('active')

        if (active.parent('.dropdown-menu').length)  {
          active = active.closest('li.dropdown').addClass('active')
        }

        active.trigger('activate')
      }

  }


 

  var old = $.fn.scrollspy

  $.fn.scrollspy = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('scrollspy')
        , options = typeof option == 'object' && option
      if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.scrollspy.Constructor = ScrollSpy

  $.fn.scrollspy.defaults = {
    offset: 10
  }


 

  $.fn.scrollspy.noConflict = function () {
    $.fn.scrollspy = old
    return this
  }


 

  $(window).on('load', function () {
    $('[data-spy="scroll"]').each(function () {
      var $spy = $(this)
      $spy.scrollspy($spy.data())
    })
  })

}(window.jQuery);


!function ($) {

  "use strict"; // jshint ;_;


 

  var Tab = function (element) {
    this.element = $(element)
  }

  Tab.prototype = {

    constructor: Tab

  , show: function () {
      var $this = this.element
        , $ul = $this.closest('ul:not(.dropdown-menu)')
        , selector = $this.attr('data-target')
        , previous
        , $target
        , e

      if (!selector) {
        selector = $this.attr('href')
        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
      }

      if ( $this.parent('li').hasClass('active') ) return

      previous = $ul.find('.active:last a')[0]

      e = $.Event('show', {
        relatedTarget: previous
      })

      $this.trigger(e)

      if (e.isDefaultPrevented()) return

      $target = $(selector)

      this.activate($this.parent('li'), $ul)
      this.activate($target, $target.parent(), function () {
        $this.trigger({
          type: 'shown'
        , relatedTarget: previous
        })
      })
    }

  , activate: function ( element, container, callback) {
      var $active = container.find('> .active')
        , transition = callback
            && $.support.transition
            && $active.hasClass('fade')

      function next() {
        $active
          .removeClass('active')
          .find('> .dropdown-menu > .active')
          .removeClass('active')

        element.addClass('active')

        if (transition) {
          element[0].offsetWidth // reflow for transition
          element.addClass('in')
        } else {
          element.removeClass('fade')
        }

        if ( element.parent('.dropdown-menu') ) {
          element.closest('li.dropdown').addClass('active')
        }

        callback && callback()
      }

      transition ?
        $active.one($.support.transition.end, next) :
        next()

      $active.removeClass('in')
    }
  }


 

  var old = $.fn.tab

  $.fn.tab = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tab')
      if (!data) $this.data('tab', (data = new Tab(this)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tab.Constructor = Tab


 

  $.fn.tab.noConflict = function () {
    $.fn.tab = old
    return this
  }


 

  $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
    e.preventDefault()
    $(this).tab('show')
  })

}(window.jQuery);


!function($){

  "use strict"; // jshint ;_;


 

  var Typeahead = function (element, options) {
    this.$element = $(element)
    this.options = $.extend({}, $.fn.typeahead.defaults, options)
    this.matcher = this.options.matcher || this.matcher
    this.sorter = this.options.sorter || this.sorter
    this.highlighter = this.options.highlighter || this.highlighter
    this.updater = this.options.updater || this.updater
    this.source = this.options.source
    this.$menu = $(this.options.menu)
    this.shown = false
    this.listen()
  }

  Typeahead.prototype = {

    constructor: Typeahead

  , select: function () {
      var val = this.$menu.find('.active').attr('data-value')
      this.$element
        .val(this.updater(val))
        .change()
      return this.hide()
    }

  , updater: function (item) {
      return item
    }

  , show: function () {
      var pos = $.extend({}, this.$element.position(), {
        height: this.$element[0].offsetHeight
      })

      this.$menu
        .insertAfter(this.$element)
        .css({
          top: pos.top + pos.height
        , left: pos.left
        })
        .show()

      this.shown = true
      return this
    }

  , hide: function () {
      this.$menu.hide()
      this.shown = false
      return this
    }

  , lookup: function (event) {
      var items

      this.query = this.$element.val()

      if (!this.query || this.query.length < this.options.minLength) {
        return this.shown ? this.hide() : this
      }

      items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source

      return items ? this.process(items) : this
    }

  , process: function (items) {
      var that = this

      items = $.grep(items, function (item) {
        return that.matcher(item)
      })

      items = this.sorter(items)

      if (!items.length) {
        return this.shown ? this.hide() : this
      }

      return this.render(items.slice(0, this.options.items)).show()
    }

  , matcher: function (item) {
      return ~item.toLowerCase().indexOf(this.query.toLowerCase())
    }

  , sorter: function (items) {
      var beginswith = []
        , caseSensitive = []
        , caseInsensitive = []
        , item

      while (item = items.shift()) {
        if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
        else if (~item.indexOf(this.query)) caseSensitive.push(item)
        else caseInsensitive.push(item)
      }

      return beginswith.concat(caseSensitive, caseInsensitive)
    }

  , highlighter: function (item) {
      var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
      return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
        return '<strong>' + match + '</strong>'
      })
    }

  , render: function (items) {
      var that = this

      items = $(items).map(function (i, item) {
        i = $(that.options.item).attr('data-value', item)
        i.find('a').html(that.highlighter(item))
        return i[0]
      })

      items.first().addClass('active')
      this.$menu.html(items)
      return this
    }

  , next: function (event) {
      var active = this.$menu.find('.active').removeClass('active')
        , next = active.next()

      if (!next.length) {
        next = $(this.$menu.find('li')[0])
      }

      next.addClass('active')
    }

  , prev: function (event) {
      var active = this.$menu.find('.active').removeClass('active')
        , prev = active.prev()

      if (!prev.length) {
        prev = this.$menu.find('li').last()
      }

      prev.addClass('active')
    }

  , listen: function () {
      this.$element
        .on('focus',    $.proxy(this.focus, this))
        .on('blur',     $.proxy(this.blur, this))
        .on('keypress', $.proxy(this.keypress, this))
        .on('keyup',    $.proxy(this.keyup, this))

      if (this.eventSupported('keydown')) {
        this.$element.on('keydown', $.proxy(this.keydown, this))
      }

      this.$menu
        .on('click', $.proxy(this.click, this))
        .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
        .on('mouseleave', 'li', $.proxy(this.mouseleave, this))
    }

  , eventSupported: function(eventName) {
      var isSupported = eventName in this.$element
      if (!isSupported) {
        this.$element.setAttribute(eventName, 'return;')
        isSupported = typeof this.$element[eventName] === 'function'
      }
      return isSupported
    }

  , move: function (e) {
      if (!this.shown) return

      switch(e.keyCode) {
        case 9: // tab
        case 13: // enter
        case 27: // escape
          e.preventDefault()
          break

        case 38: // up arrow
          e.preventDefault()
          this.prev()
          break

        case 40: // down arrow
          e.preventDefault()
          this.next()
          break
      }

      e.stopPropagation()
    }

  , keydown: function (e) {
      this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
      this.move(e)
    }

  , keypress: function (e) {
      if (this.suppressKeyPressRepeat) return
      this.move(e)
    }

  , keyup: function (e) {
      switch(e.keyCode) {
        case 40: // down arrow
        case 38: // up arrow
        case 16: // shift
        case 17: // ctrl
        case 18: // alt
          break

        case 9: // tab
        case 13: // enter
          if (!this.shown) return
          this.select()
          break

        case 27: // escape
          if (!this.shown) return
          this.hide()
          break

        default:
          this.lookup()
      }

      e.stopPropagation()
      e.preventDefault()
  }

  , focus: function (e) {
      this.focused = true
    }

  , blur: function (e) {
      this.focused = false
      if (!this.mousedover && this.shown) this.hide()
    }

  , click: function (e) {
      e.stopPropagation()
      e.preventDefault()
      this.select()
      this.$element.focus()
    }

  , mouseenter: function (e) {
      this.mousedover = true
      this.$menu.find('.active').removeClass('active')
      $(e.currentTarget).addClass('active')
    }

  , mouseleave: function (e) {
      this.mousedover = false
      if (!this.focused && this.shown) this.hide()
    }

  }


  

  var old = $.fn.typeahead

  $.fn.typeahead = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('typeahead')
        , options = typeof option == 'object' && option
      if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.typeahead.defaults = {
    source: []
  , items: 8
  , menu: '<ul class="typeahead dropdown-menu"></ul>'
  , item: '<li><a href="#"></a></li>'
  , minLength: 1
  }

  $.fn.typeahead.Constructor = Typeahead


 

  $.fn.typeahead.noConflict = function () {
    $.fn.typeahead = old
    return this
  }


 

  $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
    var $this = $(this)
    if ($this.data('typeahead')) return
    $this.typeahead($this.data())
  })

}(window.jQuery);



!function ($) {

  "use strict"; // jshint ;_;


 

  var Affix = function (element, options) {
    this.options = $.extend({}, $.fn.affix.defaults, options)
    this.$window = $(window)
      .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
      .on('click.affix.data-api',  $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
    this.$element = $(element)
    this.checkPosition()
  }

  Affix.prototype.checkPosition = function () {
    if (!this.$element.is(':visible')) return

    var scrollHeight = $(document).height()
      , scrollTop = this.$window.scrollTop()
      , position = this.$element.offset()
      , offset = this.options.offset
      , offsetBottom = offset.bottom
      , offsetTop = offset.top
      , reset = 'affix affix-top affix-bottom'
      , affix

    if (typeof offset != 'object') offsetBottom = offsetTop = offset
    if (typeof offsetTop == 'function') offsetTop = offset.top()
    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()

    affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
      false    : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
      'bottom' : offsetTop != null && scrollTop <= offsetTop ?
      'top'    : false

    if (this.affixed === affix) return

    this.affixed = affix
    this.unpin = affix == 'bottom' ? position.top - scrollTop : null

    this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
  }


 

  var old = $.fn.affix

  $.fn.affix = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('affix')
        , options = typeof option == 'object' && option
      if (!data) $this.data('affix', (data = new Affix(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.affix.Constructor = Affix

  $.fn.affix.defaults = {
    offset: 0
  }


 

  $.fn.affix.noConflict = function () {
    $.fn.affix = old
    return this
  }


 

  $(window).on('load', function () {
    $('[data-spy="affix"]').each(function () {
      var $spy = $(this)
        , data = $spy.data()

      data.offset = data.offset || {}

      data.offsetBottom && (data.offset.bottom = data.offsetBottom)
      data.offsetTop && (data.offset.top = data.offsetTop)

      $spy.affix(data)
    })
  })


}(window.jQuery);;

// Source: yithwebclient/static/vendor/pwstrength-bootstrap/pwstrength-bootstrap-1.2.1.js


(function (jQuery) {
// Source: src/rules.js




var rulesEngine = {};

try {
    if (!jQuery && module && module.exports) {
        var jQuery = require("jquery"),
            jsdom = require("jsdom").jsdom;
        jQuery = jQuery(jsdom().parentWindow);
    }
} catch (ignore) {}

(function ($, rulesEngine) {
    "use strict";
    var validation = {};

    rulesEngine.forbiddenSequences = [
        "0123456789", "abcdefghijklmnopqrstuvwxyz", "qwertyuiop", "asdfghjkl",
        "zxcvbnm", "!@#$%^&*()_+"
    ];

    validation.wordNotEmail = function (options, word, score) {
        if (word.match(/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i)) {
            options.instances.errors.push(options.ui.spanError(options, "email_as_password"));
            return score;
        }
    };

    validation.wordLength = function (options, word, score) {
        var wordlen = word.length,
            lenScore = Math.pow(wordlen, options.rules.raisePower);
        if (wordlen < options.common.minChar) {
            lenScore = (lenScore + score);
            options.instances.errors.push(options.ui.spanError(options, "password_too_short"));
        }
        return lenScore;
    };

    validation.wordSimilarToUsername = function (options, word, score) {
        var username = $(options.common.usernameField).val();
        if (username && word.toLowerCase().match(username.toLowerCase())) {
            options.instances.errors.push(options.ui.spanError(options, "same_as_username"));
            return score;
        }
        return false;
    };

    validation.wordTwoCharacterClasses = function (options, word, score) {
        if (word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) ||
                (word.match(/([a-zA-Z])/) && word.match(/([0-9])/)) ||
                (word.match(/(.[!,@,#,$,%,\^,&,*,?,_,~])/) && word.match(/[a-zA-Z0-9_]/))) {
            return score;
        }
        options.instances.errors.push(options.ui.spanError(options, "two_character_classes"));
        return false;
    };

    validation.wordRepetitions = function (options, word, score) {
        if (word.match(/(.)\1\1/)) {
            options.instances.errors.push(options.ui.spanError(options, "repeated_character"));
            return score;
        }
        return false;
    };

    validation.wordSequences = function (options, word, score) {
        var found = false,
            j;
        if (word.length > 2) {
            $.each(rulesEngine.forbiddenSequences, function (idx, seq) {
                var sequences = [seq, seq.split('').reverse().join('')];
                $.each(sequences, function (idx, sequence) {
                    for (j = 0; j < (word.length - 2); j += 1) { // iterate the word trough a sliding window of size 3:
                        if (sequence.indexOf(word.toLowerCase().substring(j, j + 3)) > -1) {
                            found = true;
                        }
                    }
                });
            });
            if (found) {
                options.instances.errors.push(options.ui.spanError(options, "sequence_found"));
                return score;
            }
        }
        return false;
    };

    validation.wordLowercase = function (options, word, score) {
        return word.match(/[a-z]/) && score;
    };

    validation.wordUppercase = function (options, word, score) {
        return word.match(/[A-Z]/) && score;
    };

    validation.wordOneNumber = function (options, word, score) {
        return word.match(/\d+/) && score;
    };

    validation.wordThreeNumbers = function (options, word, score) {
        return word.match(/(.*[0-9].*[0-9].*[0-9])/) && score;
    };

    validation.wordOneSpecialChar = function (options, word, score) {
        return word.match(/.[!,@,#,$,%,\^,&,*,?,_,~]/) && score;
    };

    validation.wordTwoSpecialChar = function (options, word, score) {
        return word.match(/(.*[!,@,#,$,%,\^,&,*,?,_,~].*[!,@,#,$,%,\^,&,*,?,_,~])/) && score;
    };

    validation.wordUpperLowerCombo = function (options, word, score) {
        return word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) && score;
    };

    validation.wordLetterNumberCombo = function (options, word, score) {
        return word.match(/([a-zA-Z])/) && word.match(/([0-9])/) && score;
    };

    validation.wordLetterNumberCharCombo = function (options, word, score) {
        return word.match(/([a-zA-Z0-9].*[!,@,#,$,%,\^,&,*,?,_,~])|([!,@,#,$,%,\^,&,*,?,_,~].*[a-zA-Z0-9])/) && score;
    };

    rulesEngine.validation = validation;

    rulesEngine.executeRules = function (options, word) {
        var totalScore = 0;

        $.each(options.rules.activated, function (rule, active) {
            if (active) {
                var score = options.rules.scores[rule],
                    funct = rulesEngine.validation[rule],
                    result;

                if (!$.isFunction(funct)) {
                    funct = options.rules.extra[rule];
                }

                if ($.isFunction(funct)) {
                    result = funct(options, word, score);
                    if (result) {
                        totalScore += result;
                    }
                }
            }
        });

        return totalScore;
    };
}(jQuery, rulesEngine));

try {
    if (module && module.exports) {
        module.exports = rulesEngine;
    }
} catch (ignore) {}

// Source: src/options.js




var defaultOptions = {};

defaultOptions.common = {};
defaultOptions.common.minChar = 6;
defaultOptions.common.usernameField = "#username";
defaultOptions.common.userInputs = [
    // Selectors for input fields with user input
];
defaultOptions.common.onLoad = undefined;
defaultOptions.common.onKeyUp = undefined;
defaultOptions.common.zxcvbn = false;
defaultOptions.common.debug = false;

defaultOptions.rules = {};
defaultOptions.rules.extra = {};
defaultOptions.rules.scores = {
    wordNotEmail: -100,
    wordLength: -50,
    wordSimilarToUsername: -100,
    wordSequences: -50,
    wordTwoCharacterClasses: 2,
    wordRepetitions: -25,
    wordLowercase: 1,
    wordUppercase: 3,
    wordOneNumber: 3,
    wordThreeNumbers: 5,
    wordOneSpecialChar: 3,
    wordTwoSpecialChar: 5,
    wordUpperLowerCombo: 2,
    wordLetterNumberCombo: 2,
    wordLetterNumberCharCombo: 2
};
defaultOptions.rules.activated = {
    wordNotEmail: true,
    wordLength: true,
    wordSimilarToUsername: true,
    wordSequences: true,
    wordTwoCharacterClasses: false,
    wordRepetitions: false,
    wordLowercase: true,
    wordUppercase: true,
    wordOneNumber: true,
    wordThreeNumbers: true,
    wordOneSpecialChar: true,
    wordTwoSpecialChar: true,
    wordUpperLowerCombo: true,
    wordLetterNumberCombo: true,
    wordLetterNumberCharCombo: true
};
defaultOptions.rules.raisePower = 1.4;

defaultOptions.ui = {};
defaultOptions.ui.bootstrap2 = false;
defaultOptions.ui.showProgressBar = true;
defaultOptions.ui.showPopover = false;
defaultOptions.ui.showStatus = false;
defaultOptions.ui.spanError = function (options, key) {
    "use strict";
    var text = options.ui.errorMessages[key];
    return '<span style="color: #d52929">' + text + '</span>';
};
defaultOptions.ui.errorMessages = {
    password_too_short: "Your password is too short",
    email_as_password: "Do not use your email as your password",
    same_as_username: "Your password cannot contain your username",
    two_character_classes: "Use different character classes",
    repeated_character: "Too many repetitions",
    sequence_found: "Your password contains sequences"
};
defaultOptions.ui.verdicts = ["Weak", "Normal", "Medium", "Strong", "Very Strong"];
defaultOptions.ui.showVerdicts = true;
defaultOptions.ui.showVerdictsInsideProgressBar = false;
defaultOptions.ui.showErrors = false;
defaultOptions.ui.container = undefined;
defaultOptions.ui.viewports = {
    progress: undefined,
    verdict: undefined,
    errors: undefined
};
defaultOptions.ui.scores = [14, 26, 38, 50];

// Source: src/ui.js




var ui = {};

(function ($, ui) {
    "use strict";

    var barClasses = ["danger", "warning", "success"],
        statusClasses = ["error", "warning", "success"];

    ui.getContainer = function (options, $el) {
        var $container;

        $container = $(options.ui.container);
        if (!($container && $container.length === 1)) {
            $container = $el.parent();
        }
        return $container;
    };

    ui.findElement = function ($container, viewport, cssSelector) {
        if (viewport) {
            return $container.find(viewport).find(cssSelector);
        }
        return $container.find(cssSelector);
    };

    ui.getUIElements = function (options, $el) {
        var $container, result;

        if (options.instances.viewports) {
            return options.instances.viewports;
        }

        $container = ui.getContainer(options, $el);

        result = {};
        result.$progressbar = ui.findElement($container, options.ui.viewports.progress, "div.progress");
        if (options.ui.showVerdictsInsideProgressBar) {
            result.$verdict = result.$progressbar.find("span.password-verdict");
        }

        if (!options.ui.showPopover) {
            if (!options.ui.showVerdictsInsideProgressBar) {
                result.$verdict = ui.findElement($container, options.ui.viewports.verdict, "span.password-verdict");
            }
            result.$errors = ui.findElement($container, options.ui.viewports.errors, "ul.error-list");
        }

        options.instances.viewports = result;
        return result;
    };

    ui.initProgressBar = function (options, $el) {
        var $container = ui.getContainer(options, $el),
            progressbar = "<div class='progress'><div class='";

        if (!options.ui.bootstrap2) {
            progressbar += "progress-";
        }
        progressbar += "bar'>";
        if (options.ui.showVerdictsInsideProgressBar) {
            progressbar += "<span class='password-verdict'></span>";
        }
        progressbar += "</div></div>";

        if (options.ui.viewports.progress) {
            $container.find(options.ui.viewports.progress).append(progressbar);
        } else {
            $(progressbar).insertAfter($el);
        }
    };

    ui.initHelper = function (options, $el, html, viewport) {
        var $container = ui.getContainer(options, $el);
        if (viewport) {
            $container.find(viewport).append(html);
        } else {
            $(html).insertAfter($el);
        }
    };

    ui.initVerdict = function (options, $el) {
        ui.initHelper(options, $el, "<span class='password-verdict'></span>",
                        options.ui.viewports.verdict);
    };

    ui.initErrorList = function (options, $el) {
        ui.initHelper(options, $el, "<ul class='error-list'></ul>",
                        options.ui.viewports.errors);
    };

    ui.initPopover = function (options, $el) {
        $el.popover("destroy");
        $el.popover({
            html: true,
            placement: "bottom",
            trigger: "manual",
            content: " "
        });
    };

    ui.initUI = function (options, $el) {
        if (options.ui.showPopover) {
            ui.initPopover(options, $el);
        } else {
            if (options.ui.showErrors) { ui.initErrorList(options, $el); }
            if (options.ui.showVerdicts && !options.ui.showVerdictsInsideProgressBar) {
                ui.initVerdict(options, $el);
            }
        }
        if (options.ui.showProgressBar) {
            ui.initProgressBar(options, $el);
        }
    };

    ui.possibleProgressBarClasses = ["danger", "warning", "success"];

    ui.updateProgressBar = function (options, $el, cssClass, percentage) {
        var $progressbar = ui.getUIElements(options, $el).$progressbar,
            $bar = $progressbar.find(".progress-bar"),
            cssPrefix = "progress-";

        if (options.ui.bootstrap2) {
            $bar = $progressbar.find(".bar");
            cssPrefix = "";
        }

        $.each(ui.possibleProgressBarClasses, function (idx, value) {
            $bar.removeClass(cssPrefix + "bar-" + value);
        });
        $bar.addClass(cssPrefix + "bar-" + barClasses[cssClass]);
        $bar.css("width", percentage + '%');
    };

    ui.updateVerdict = function (options, $el, text) {
        var $verdict = ui.getUIElements(options, $el).$verdict;
        $verdict.text(text);
    };

    ui.updateErrors = function (options, $el) {
        var $errors = ui.getUIElements(options, $el).$errors,
            html = "";
        $.each(options.instances.errors, function (idx, err) {
            html += "<li>" + err + "</li>";
        });
        $errors.html(html);
    };

    ui.updatePopover = function (options, $el, verdictText) {
        var popover = $el.data("bs.popover"),
            html = "",
            hide = true;

        if (options.ui.showVerdicts &&
                !options.ui.showVerdictsInsideProgressBar &&
                verdictText.length > 0) {
            html = "<h5><span class='password-verdict'>" + verdictText +
                "</span></h5>";
            hide = false;
        }
        if (options.ui.showErrors) {
            html += "<div>Errors:<ul class='error-list' style='margin-bottom: 0;'>";
            $.each(options.instances.errors, function (idx, err) {
                html += "<li>" + err + "</li>";
                hide = false;
            });
            html += "</ul></div>";
        }

        if (hide) {
            $el.popover("hide");
            return;
        }

        if (options.ui.bootstrap2) { popover = $el.data("popover"); }

        if (popover.$arrow && popover.$arrow.parents("body").length > 0) {
            $el.find("+ .popover .popover-content").html(html);
        } else {
            // It's hidden
            popover.options.content = html;
            $el.popover("show");
        }
    };

    ui.updateFieldStatus = function (options, $el, cssClass) {
        var targetClass = options.ui.bootstrap2 ? ".control-group" : ".form-group",
            $container = $el.parents(targetClass).first();

        $.each(statusClasses, function (idx, css) {
            if (!options.ui.bootstrap2) { css = "has-" + css; }
            $container.removeClass(css);
        });

        cssClass = statusClasses[cssClass];
        if (!options.ui.bootstrap2) { cssClass = "has-" + cssClass; }
        $container.addClass(cssClass);
    };

    ui.percentage = function (score, maximun) {
        var result = Math.floor(100 * score / maximun);
        result = result < 0 ? 0 : result;
        result = result > 100 ? 100 : result;
        return result;
    };

    ui.getVerdictAndCssClass = function (options, score) {
        var cssClass, verdictText, level;

        if (score <= 0) {
            cssClass = 0;
            level = -1;
            verdictText = options.ui.verdicts[0];
        } else if (score < options.ui.scores[0]) {
            cssClass = 0;
            level = 0;
            verdictText = options.ui.verdicts[0];
        } else if (score < options.ui.scores[1]) {
            cssClass = 0;
            level = 1;
            verdictText = options.ui.verdicts[1];
        } else if (score < options.ui.scores[2]) {
            cssClass = 1;
            level = 2;
            verdictText = options.ui.verdicts[2];
        } else if (score < options.ui.scores[3]) {
            cssClass = 1;
            level = 3;
            verdictText = options.ui.verdicts[3];
        } else {
            cssClass = 2;
            level = 4;
            verdictText = options.ui.verdicts[4];
        }

        return [verdictText, cssClass, level];
    };

    ui.updateUI = function (options, $el, score) {
        var cssClass, barPercentage, verdictText;

        cssClass = ui.getVerdictAndCssClass(options, score);
        verdictText = cssClass[0];
        cssClass = cssClass[1];

        if (options.ui.showProgressBar) {
            barPercentage = ui.percentage(score, options.ui.scores[3]);
            ui.updateProgressBar(options, $el, cssClass, barPercentage);
            if (options.ui.showVerdictsInsideProgressBar) {
                ui.updateVerdict(options, $el, verdictText);
            }
        }

        if (options.ui.showStatus) {
            ui.updateFieldStatus(options, $el, cssClass);
        }

        if (options.ui.showPopover) {
            ui.updatePopover(options, $el, verdictText);
        } else {
            if (options.ui.showVerdicts && !options.ui.showVerdictsInsideProgressBar) {
                ui.updateVerdict(options, $el, verdictText);
            }
            if (options.ui.showErrors) {
                ui.updateErrors(options, $el);
            }
        }
    };
}(jQuery, ui));

// Source: src/methods.js




var methods = {};

(function ($, methods) {
    "use strict";
    var onKeyUp, applyToAll;

    onKeyUp = function (event) {
        var $el = $(event.target),
            options = $el.data("pwstrength-bootstrap"),
            word = $el.val(),
            userInputs,
            verdictText,
            verdictLevel,
            score;

        if (options === undefined) { return; }

        options.instances.errors = [];
        if (options.common.zxcvbn) {
            userInputs = [];
            $.each(options.common.userInputs, function (idx, selector) {
                userInputs.push($(selector).val());
            });
            userInputs.push($(options.common.usernameField).val());
            score = zxcvbn(word, userInputs).entropy;
        } else {
            score = rulesEngine.executeRules(options, word);
        }
        ui.updateUI(options, $el, score);
        verdictText = ui.getVerdictAndCssClass(options, score);
        verdictLevel = verdictText[2];
        verdictText = verdictText[0];

        if (options.common.debug) { console.log(score + ' - ' + verdictText); }

        if ($.isFunction(options.common.onKeyUp)) {
            options.common.onKeyUp(event, {
                score: score,
                verdictText: verdictText,
                verdictLevel: verdictLevel
            });
        }
    };

    methods.init = function (settings) {
        this.each(function (idx, el) {
            // Make it deep extend (first param) so it extends too the
            // rules and other inside objects
            var clonedDefaults = $.extend(true, {}, defaultOptions),
                localOptions = $.extend(true, clonedDefaults, settings),
                $el = $(el);

            localOptions.instances = {};
            $el.data("pwstrength-bootstrap", localOptions);
            $el.on("keyup", onKeyUp);
            $el.on("change", onKeyUp);
            $el.on("onpaste", onKeyUp);

            ui.initUI(localOptions, $el);
            if ($.trim($el.val())) { // Not empty, calculate the strength
                $el.trigger("keyup");
            }

            if ($.isFunction(localOptions.common.onLoad)) {
                localOptions.common.onLoad();
            }
        });

        return this;
    };

    methods.destroy = function () {
        this.each(function (idx, el) {
            var $el = $(el),
                options = $el.data("pwstrength-bootstrap"),
                elements = ui.getUIElements(options, $el);
            elements.$progressbar.remove();
            elements.$verdict.remove();
            elements.$errors.remove();
            $el.removeData("pwstrength-bootstrap");
        });
    };

    methods.forceUpdate = function () {
        this.each(function (idx, el) {
            var event = { target: el };
            onKeyUp(event);
        });
    };

    methods.addRule = function (name, method, score, active) {
        this.each(function (idx, el) {
            var options = $(el).data("pwstrength-bootstrap");

            options.rules.activated[name] = active;
            options.rules.scores[name] = score;
            options.rules.extra[name] = method;
        });
    };

    applyToAll = function (rule, prop, value) {
        this.each(function (idx, el) {
            $(el).data("pwstrength-bootstrap").rules[prop][rule] = value;
        });
    };

    methods.changeScore = function (rule, score) {
        applyToAll.call(this, rule, "scores", score);
    };

    methods.ruleActive = function (rule, active) {
        applyToAll.call(this, rule, "activated", active);
    };

    $.fn.pwstrength = function (method) {
        var result;

        if (methods[method]) {
            result = methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === "object" || !method) {
            result = methods.init.apply(this, arguments);
        } else {
            $.error("Method " +  method + " does not exist on jQuery.pwstrength-bootstrap");
        }

        return result;
    };
}(jQuery, methods));
}(jQuery));;

// Source: yithwebclient/static/vendor/handlebars/handlebars.js


var Handlebars = (function() {
// handlebars/safe-string.js
var __module4__ = (function() {
  "use strict";
  var __exports__;
  // Build out our basic SafeString type
  function SafeString(string) {
    this.string = string;
  }

  SafeString.prototype.toString = function() {
    return "" + this.string;
  };

  __exports__ = SafeString;
  return __exports__;
})();

// handlebars/utils.js
var __module3__ = (function(__dependency1__) {
  "use strict";
  var __exports__ = {};
  
  var SafeString = __dependency1__;

  var escape = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': "&quot;",
    "'": "&#x27;",
    "`": "&#x60;"
  };

  var badChars = /[&<>"'`]/g;
  var possible = /[&<>"'`]/;

  function escapeChar(chr) {
    return escape[chr] || "&amp;";
  }

  function extend(obj, value) {
    for(var key in value) {
      if(Object.prototype.hasOwnProperty.call(value, key)) {
        obj[key] = value[key];
      }
    }
  }

  __exports__.extend = extend;var toString = Object.prototype.toString;
  __exports__.toString = toString;
  // Sourced from lodash
  // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
  var isFunction = function(value) {
    return typeof value === 'function';
  };
  // fallback for older versions of Chrome and Safari
  if (isFunction(/x/)) {
    isFunction = function(value) {
      return typeof value === 'function' && toString.call(value) === '[object Function]';
    };
  }
  var isFunction;
  __exports__.isFunction = isFunction;
  var isArray = Array.isArray || function(value) {
    return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
  };
  __exports__.isArray = isArray;

  function escapeExpression(string) {
    // don't escape SafeStrings, since they're already safe
    if (string instanceof SafeString) {
      return string.toString();
    } else if (!string && string !== 0) {
      return "";
    }

    // Force a string conversion as this will be done by the append regardless and
    // the regex test will do this transparently behind the scenes, causing issues if
    // an object's to string has escaped characters in it.
    string = "" + string;

    if(!possible.test(string)) { return string; }
    return string.replace(badChars, escapeChar);
  }

  __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
    if (!value && value !== 0) {
      return true;
    } else if (isArray(value) && value.length === 0) {
      return true;
    } else {
      return false;
    }
  }

  __exports__.isEmpty = isEmpty;
  return __exports__;
})(__module4__);

// handlebars/exception.js
var __module5__ = (function() {
  "use strict";
  var __exports__;

  var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];

  function Exception(message, node) {
    var line;
    if (node && node.firstLine) {
      line = node.firstLine;

      message += ' - ' + line + ':' + node.firstColumn;
    }

    var tmp = Error.prototype.constructor.call(this, message);

    // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
    for (var idx = 0; idx < errorProps.length; idx++) {
      this[errorProps[idx]] = tmp[errorProps[idx]];
    }

    if (line) {
      this.lineNumber = line;
      this.column = node.firstColumn;
    }
  }

  Exception.prototype = new Error();

  __exports__ = Exception;
  return __exports__;
})();

// handlebars/base.js
var __module2__ = (function(__dependency1__, __dependency2__) {
  "use strict";
  var __exports__ = {};
  var Utils = __dependency1__;
  var Exception = __dependency2__;

  var VERSION = "1.3.0";
  __exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
  __exports__.COMPILER_REVISION = COMPILER_REVISION;
  var REVISION_CHANGES = {
    1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
    2: '== 1.0.0-rc.3',
    3: '== 1.0.0-rc.4',
    4: '>= 1.0.0'
  };
  __exports__.REVISION_CHANGES = REVISION_CHANGES;
  var isArray = Utils.isArray,
      isFunction = Utils.isFunction,
      toString = Utils.toString,
      objectType = '[object Object]';

  function HandlebarsEnvironment(helpers, partials) {
    this.helpers = helpers || {};
    this.partials = partials || {};

    registerDefaultHelpers(this);
  }

  __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
    constructor: HandlebarsEnvironment,

    logger: logger,
    log: log,

    registerHelper: function(name, fn, inverse) {
      if (toString.call(name) === objectType) {
        if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
        Utils.extend(this.helpers, name);
      } else {
        if (inverse) { fn.not = inverse; }
        this.helpers[name] = fn;
      }
    },

    registerPartial: function(name, str) {
      if (toString.call(name) === objectType) {
        Utils.extend(this.partials,  name);
      } else {
        this.partials[name] = str;
      }
    }
  };

  function registerDefaultHelpers(instance) {
    instance.registerHelper('helperMissing', function(arg) {
      if(arguments.length === 2) {
        return undefined;
      } else {
        throw new Exception("Missing helper: '" + arg + "'");
      }
    });

    instance.registerHelper('blockHelperMissing', function(context, options) {
      var inverse = options.inverse || function() {}, fn = options.fn;

      if (isFunction(context)) { context = context.call(this); }

      if(context === true) {
        return fn(this);
      } else if(context === false || context == null) {
        return inverse(this);
      } else if (isArray(context)) {
        if(context.length > 0) {
          return instance.helpers.each(context, options);
        } else {
          return inverse(this);
        }
      } else {
        return fn(context);
      }
    });

    instance.registerHelper('each', function(context, options) {
      var fn = options.fn, inverse = options.inverse;
      var i = 0, ret = "", data;

      if (isFunction(context)) { context = context.call(this); }

      if (options.data) {
        data = createFrame(options.data);
      }

      if(context && typeof context === 'object') {
        if (isArray(context)) {
          for(var j = context.length; i<j; i++) {
            if (data) {
              data.index = i;
              data.first = (i === 0);
              data.last  = (i === (context.length-1));
            }
            ret = ret + fn(context[i], { data: data });
          }
        } else {
          for(var key in context) {
            if(context.hasOwnProperty(key)) {
              if(data) { 
                data.key = key; 
                data.index = i;
                data.first = (i === 0);
              }
              ret = ret + fn(context[key], {data: data});
              i++;
            }
          }
        }
      }

      if(i === 0){
        ret = inverse(this);
      }

      return ret;
    });

    instance.registerHelper('if', function(conditional, options) {
      if (isFunction(conditional)) { conditional = conditional.call(this); }

      // Default behavior is to render the positive path if the value is truthy and not empty.
      // The `includeZero` option may be set to treat the condtional as purely not empty based on the
      // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
      if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
        return options.inverse(this);
      } else {
        return options.fn(this);
      }
    });

    instance.registerHelper('unless', function(conditional, options) {
      return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
    });

    instance.registerHelper('with', function(context, options) {
      if (isFunction(context)) { context = context.call(this); }

      if (!Utils.isEmpty(context)) return options.fn(context);
    });

    instance.registerHelper('log', function(context, options) {
      var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
      instance.log(level, context);
    });
  }

  var logger = {
    methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },

    // State enum
    DEBUG: 0,
    INFO: 1,
    WARN: 2,
    ERROR: 3,
    level: 3,

    // can be overridden in the host environment
    log: function(level, obj) {
      if (logger.level <= level) {
        var method = logger.methodMap[level];
        if (typeof console !== 'undefined' && console[method]) {
          console[method].call(console, obj);
        }
      }
    }
  };
  __exports__.logger = logger;
  function log(level, obj) { logger.log(level, obj); }

  __exports__.log = log;var createFrame = function(object) {
    var obj = {};
    Utils.extend(obj, object);
    return obj;
  };
  __exports__.createFrame = createFrame;
  return __exports__;
})(__module3__, __module5__);

// handlebars/runtime.js
var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
  "use strict";
  var __exports__ = {};
  var Utils = __dependency1__;
  var Exception = __dependency2__;
  var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
  var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;

  function checkRevision(compilerInfo) {
    var compilerRevision = compilerInfo && compilerInfo[0] || 1,
        currentRevision = COMPILER_REVISION;

    if (compilerRevision !== currentRevision) {
      if (compilerRevision < currentRevision) {
        var runtimeVersions = REVISION_CHANGES[currentRevision],
            compilerVersions = REVISION_CHANGES[compilerRevision];
        throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
              "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
      } else {
        // Use the embedded version info since the runtime doesn't know about this revision yet
        throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
              "Please update your runtime to a newer version ("+compilerInfo[1]+").");
      }
    }
  }

  __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial

  function template(templateSpec, env) {
    if (!env) {
      throw new Exception("No environment passed to template");
    }

    // Note: Using env.VM references rather than local var references throughout this section to allow
    // for external users to override these as psuedo-supported APIs.
    var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
      var result = env.VM.invokePartial.apply(this, arguments);
      if (result != null) { return result; }

      if (env.compile) {
        var options = { helpers: helpers, partials: partials, data: data };
        partials[name] = env.compile(partial, { data: data !== undefined }, env);
        return partials[name](context, options);
      } else {
        throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
      }
    };

    // Just add water
    var container = {
      escapeExpression: Utils.escapeExpression,
      invokePartial: invokePartialWrapper,
      programs: [],
      program: function(i, fn, data) {
        var programWrapper = this.programs[i];
        if(data) {
          programWrapper = program(i, fn, data);
        } else if (!programWrapper) {
          programWrapper = this.programs[i] = program(i, fn);
        }
        return programWrapper;
      },
      merge: function(param, common) {
        var ret = param || common;

        if (param && common && (param !== common)) {
          ret = {};
          Utils.extend(ret, common);
          Utils.extend(ret, param);
        }
        return ret;
      },
      programWithDepth: env.VM.programWithDepth,
      noop: env.VM.noop,
      compilerInfo: null
    };

    return function(context, options) {
      options = options || {};
      var namespace = options.partial ? options : env,
          helpers,
          partials;

      if (!options.partial) {
        helpers = options.helpers;
        partials = options.partials;
      }
      var result = templateSpec.call(
            container,
            namespace, context,
            helpers,
            partials,
            options.data);

      if (!options.partial) {
        env.VM.checkRevision(container.compilerInfo);
      }

      return result;
    };
  }

  __exports__.template = template;function programWithDepth(i, fn, data ) {
    var args = Array.prototype.slice.call(arguments, 3);

    var prog = function(context, options) {
      options = options || {};

      return fn.apply(this, [context, options.data || data].concat(args));
    };
    prog.program = i;
    prog.depth = args.length;
    return prog;
  }

  __exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
    var prog = function(context, options) {
      options = options || {};

      return fn(context, options.data || data);
    };
    prog.program = i;
    prog.depth = 0;
    return prog;
  }

  __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
    var options = { partial: true, helpers: helpers, partials: partials, data: data };

    if(partial === undefined) {
      throw new Exception("The partial " + name + " could not be found");
    } else if(partial instanceof Function) {
      return partial(context, options);
    }
  }

  __exports__.invokePartial = invokePartial;function noop() { return ""; }

  __exports__.noop = noop;
  return __exports__;
})(__module3__, __module5__, __module2__);

// handlebars.runtime.js
var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
  "use strict";
  var __exports__;
  
  var base = __dependency1__;

  // Each of these augment the Handlebars object. No need to setup here.
  // (This is done to easily share code between commonjs and browse envs)
  var SafeString = __dependency2__;
  var Exception = __dependency3__;
  var Utils = __dependency4__;
  var runtime = __dependency5__;

  // For compatibility and usage outside of module systems, make the Handlebars object a namespace
  var create = function() {
    var hb = new base.HandlebarsEnvironment();

    Utils.extend(hb, base);
    hb.SafeString = SafeString;
    hb.Exception = Exception;
    hb.Utils = Utils;

    hb.VM = runtime;
    hb.template = function(spec) {
      return runtime.template(spec, hb);
    };

    return hb;
  };

  var Handlebars = create();
  Handlebars.create = create;

  __exports__ = Handlebars;
  return __exports__;
})(__module2__, __module4__, __module5__, __module3__, __module6__);

// handlebars/compiler/ast.js
var __module7__ = (function(__dependency1__) {
  "use strict";
  var __exports__;
  var Exception = __dependency1__;

  function LocationInfo(locInfo){
    locInfo = locInfo || {};
    this.firstLine   = locInfo.first_line;
    this.firstColumn = locInfo.first_column;
    this.lastColumn  = locInfo.last_column;
    this.lastLine    = locInfo.last_line;
  }

  var AST = {
    ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
      var inverseLocationInfo, firstInverseNode;
      if (arguments.length === 3) {
        locInfo = inverse;
        inverse = null;
      } else if (arguments.length === 2) {
        locInfo = inverseStrip;
        inverseStrip = null;
      }

      LocationInfo.call(this, locInfo);
      this.type = "program";
      this.statements = statements;
      this.strip = {};

      if(inverse) {
        firstInverseNode = inverse[0];
        if (firstInverseNode) {
          inverseLocationInfo = {
            first_line: firstInverseNode.firstLine,
            last_line: firstInverseNode.lastLine,
            last_column: firstInverseNode.lastColumn,
            first_column: firstInverseNode.firstColumn
          };
          this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
        } else {
          this.inverse = new AST.ProgramNode(inverse, inverseStrip);
        }
        this.strip.right = inverseStrip.left;
      } else if (inverseStrip) {
        this.strip.left = inverseStrip.right;
      }
    },

    MustacheNode: function(rawParams, hash, open, strip, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "mustache";
      this.strip = strip;

      // Open may be a string parsed from the parser or a passed boolean flag
      if (open != null && open.charAt) {
        // Must use charAt to support IE pre-10
        var escapeFlag = open.charAt(3) || open.charAt(2);
        this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
      } else {
        this.escaped = !!open;
      }

      if (rawParams instanceof AST.SexprNode) {
        this.sexpr = rawParams;
      } else {
        // Support old AST API
        this.sexpr = new AST.SexprNode(rawParams, hash);
      }

      this.sexpr.isRoot = true;

      // Support old AST API that stored this info in MustacheNode
      this.id = this.sexpr.id;
      this.params = this.sexpr.params;
      this.hash = this.sexpr.hash;
      this.eligibleHelper = this.sexpr.eligibleHelper;
      this.isHelper = this.sexpr.isHelper;
    },

    SexprNode: function(rawParams, hash, locInfo) {
      LocationInfo.call(this, locInfo);

      this.type = "sexpr";
      this.hash = hash;

      var id = this.id = rawParams[0];
      var params = this.params = rawParams.slice(1);

      // a mustache is an eligible helper if:
      // * its id is simple (a single part, not `this` or `..`)
      var eligibleHelper = this.eligibleHelper = id.isSimple;

      // a mustache is definitely a helper if:
      // * it is an eligible helper, and
      // * it has at least one parameter or hash segment
      this.isHelper = eligibleHelper && (params.length || hash);

      // if a mustache is an eligible helper but not a definite
      // helper, it is ambiguous, and will be resolved in a later
      // pass or at runtime.
    },

    PartialNode: function(partialName, context, strip, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type         = "partial";
      this.partialName  = partialName;
      this.context      = context;
      this.strip = strip;
    },

    BlockNode: function(mustache, program, inverse, close, locInfo) {
      LocationInfo.call(this, locInfo);

      if(mustache.sexpr.id.original !== close.path.original) {
        throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
      }

      this.type = 'block';
      this.mustache = mustache;
      this.program  = program;
      this.inverse  = inverse;

      this.strip = {
        left: mustache.strip.left,
        right: close.strip.right
      };

      (program || inverse).strip.left = mustache.strip.right;
      (inverse || program).strip.right = close.strip.left;

      if (inverse && !program) {
        this.isInverse = true;
      }
    },

    ContentNode: function(string, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "content";
      this.string = string;
    },

    HashNode: function(pairs, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "hash";
      this.pairs = pairs;
    },

    IdNode: function(parts, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "ID";

      var original = "",
          dig = [],
          depth = 0;

      for(var i=0,l=parts.length; i<l; i++) {
        var part = parts[i].part;
        original += (parts[i].separator || '') + part;

        if (part === ".." || part === "." || part === "this") {
          if (dig.length > 0) {
            throw new Exception("Invalid path: " + original, this);
          } else if (part === "..") {
            depth++;
          } else {
            this.isScoped = true;
          }
        } else {
          dig.push(part);
        }
      }

      this.original = original;
      this.parts    = dig;
      this.string   = dig.join('.');
      this.depth    = depth;

      // an ID is simple if it only has one part, and that part is not
      // `..` or `this`.
      this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;

      this.stringModeValue = this.string;
    },

    PartialNameNode: function(name, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "PARTIAL_NAME";
      this.name = name.original;
    },

    DataNode: function(id, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "DATA";
      this.id = id;
    },

    StringNode: function(string, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "STRING";
      this.original =
        this.string =
        this.stringModeValue = string;
    },

    IntegerNode: function(integer, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "INTEGER";
      this.original =
        this.integer = integer;
      this.stringModeValue = Number(integer);
    },

    BooleanNode: function(bool, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "BOOLEAN";
      this.bool = bool;
      this.stringModeValue = bool === "true";
    },

    CommentNode: function(comment, locInfo) {
      LocationInfo.call(this, locInfo);
      this.type = "comment";
      this.comment = comment;
    }
  };

  // Must be exported as an object rather than the root of the module as the jison lexer
  // most modify the object to operate properly.
  __exports__ = AST;
  return __exports__;
})(__module5__);

// handlebars/compiler/parser.js
var __module9__ = (function() {
  "use strict";
  var __exports__;
  
  
  var handlebars = (function(){
  var parser = {trace: function trace() { },
  yy: {},
  symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
  terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
  productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
  performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {

  var $0 = $$.length - 1;
  switch (yystate) {
  case 1: return new yy.ProgramNode($$[$0-1], this._$); 
  break;
  case 2: return new yy.ProgramNode([], this._$); 
  break;
  case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
  break;
  case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
  break;
  case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
  break;
  case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
  break;
  case 7:this.$ = new yy.ProgramNode([], this._$);
  break;
  case 8:this.$ = new yy.ProgramNode([], this._$);
  break;
  case 9:this.$ = [$$[$0]];
  break;
  case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; 
  break;
  case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
  break;
  case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
  break;
  case 13:this.$ = $$[$0];
  break;
  case 14:this.$ = $$[$0];
  break;
  case 15:this.$ = new yy.ContentNode($$[$0], this._$);
  break;
  case 16:this.$ = new yy.CommentNode($$[$0], this._$);
  break;
  case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
  break;
  case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
  break;
  case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
  break;
  case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
  break;
  case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
  break;
  case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
  break;
  case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
  break;
  case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
  break;
  case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
  break;
  case 26:this.$ = $$[$0];
  break;
  case 27:this.$ = new yy.StringNode($$[$0], this._$);
  break;
  case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
  break;
  case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
  break;
  case 30:this.$ = $$[$0];
  break;
  case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
  break;
  case 32:this.$ = new yy.HashNode($$[$0], this._$);
  break;
  case 33:this.$ = [$$[$0-2], $$[$0]];
  break;
  case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
  break;
  case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
  break;
  case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
  break;
  case 37:this.$ = new yy.DataNode($$[$0], this._$);
  break;
  case 38:this.$ = new yy.IdNode($$[$0], this._$);
  break;
  case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; 
  break;
  case 40:this.$ = [{part: $$[$0]}];
  break;
  case 43:this.$ = [];
  break;
  case 44:$$[$0-1].push($$[$0]);
  break;
  case 47:this.$ = [$$[$0]];
  break;
  case 48:$$[$0-1].push($$[$0]);
  break;
  }
  },
  table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
  defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
  parseError: function parseError(str, hash) {
      throw new Error(str);
  },
  parse: function parse(input) {
      var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
      this.lexer.setInput(input);
      this.lexer.yy = this.yy;
      this.yy.lexer = this.lexer;
      this.yy.parser = this;
      if (typeof this.lexer.yylloc == "undefined")
          this.lexer.yylloc = {};
      var yyloc = this.lexer.yylloc;
      lstack.push(yyloc);
      var ranges = this.lexer.options && this.lexer.options.ranges;
      if (typeof this.yy.parseError === "function")
          this.parseError = this.yy.parseError;
      function popStack(n) {
          stack.length = stack.length - 2 * n;
          vstack.length = vstack.length - n;
          lstack.length = lstack.length - n;
      }
      function lex() {
          var token;
          token = self.lexer.lex() || 1;
          if (typeof token !== "number") {
              token = self.symbols_[token] || token;
          }
          return token;
      }
      var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
      while (true) {
          state = stack[stack.length - 1];
          if (this.defaultActions[state]) {
              action = this.defaultActions[state];
          } else {
              if (symbol === null || typeof symbol == "undefined") {
                  symbol = lex();
              }
              action = table[state] && table[state][symbol];
          }
          if (typeof action === "undefined" || !action.length || !action[0]) {
              var errStr = "";
              if (!recovering) {
                  expected = [];
                  for (p in table[state])
                      if (this.terminals_[p] && p > 2) {
                          expected.push("'" + this.terminals_[p] + "'");
                      }
                  if (this.lexer.showPosition) {
                      errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
                  } else {
                      errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
                  }
                  this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
              }
          }
          if (action[0] instanceof Array && action.length > 1) {
              throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
          }
          switch (action[0]) {
          case 1:
              stack.push(symbol);
              vstack.push(this.lexer.yytext);
              lstack.push(this.lexer.yylloc);
              stack.push(action[1]);
              symbol = null;
              if (!preErrorSymbol) {
                  yyleng = this.lexer.yyleng;
                  yytext = this.lexer.yytext;
                  yylineno = this.lexer.yylineno;
                  yyloc = this.lexer.yylloc;
                  if (recovering > 0)
                      recovering--;
              } else {
                  symbol = preErrorSymbol;
                  preErrorSymbol = null;
              }
              break;
          case 2:
              len = this.productions_[action[1]][1];
              yyval.$ = vstack[vstack.length - len];
              yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
              if (ranges) {
                  yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
              }
              r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
              if (typeof r !== "undefined") {
                  return r;
              }
              if (len) {
                  stack = stack.slice(0, -1 * len * 2);
                  vstack = vstack.slice(0, -1 * len);
                  lstack = lstack.slice(0, -1 * len);
              }
              stack.push(this.productions_[action[1]][0]);
              vstack.push(yyval.$);
              lstack.push(yyval._$);
              newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
              stack.push(newState);
              break;
          case 3:
              return true;
          }
      }
      return true;
  }
  };


  function stripFlags(open, close) {
    return {
      left: open.charAt(2) === '~',
      right: close.charAt(0) === '~' || close.charAt(1) === '~'
    };
  }

  
  var lexer = (function(){
  var lexer = ({EOF:1,
  parseError:function parseError(str, hash) {
          if (this.yy.parser) {
              this.yy.parser.parseError(str, hash);
          } else {
              throw new Error(str);
          }
      },
  setInput:function (input) {
          this._input = input;
          this._more = this._less = this.done = false;
          this.yylineno = this.yyleng = 0;
          this.yytext = this.matched = this.match = '';
          this.conditionStack = ['INITIAL'];
          this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
          if (this.options.ranges) this.yylloc.range = [0,0];
          this.offset = 0;
          return this;
      },
  input:function () {
          var ch = this._input[0];
          this.yytext += ch;
          this.yyleng++;
          this.offset++;
          this.match += ch;
          this.matched += ch;
          var lines = ch.match(/(?:\r\n?|\n).*/g);
          if (lines) {
              this.yylineno++;
              this.yylloc.last_line++;
          } else {
              this.yylloc.last_column++;
          }
          if (this.options.ranges) this.yylloc.range[1]++;

          this._input = this._input.slice(1);
          return ch;
      },
  unput:function (ch) {
          var len = ch.length;
          var lines = ch.split(/(?:\r\n?|\n)/g);

          this._input = ch + this._input;
          this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
          //this.yyleng -= len;
          this.offset -= len;
          var oldLines = this.match.split(/(?:\r\n?|\n)/g);
          this.match = this.match.substr(0, this.match.length-1);
          this.matched = this.matched.substr(0, this.matched.length-1);

          if (lines.length-1) this.yylineno -= lines.length-1;
          var r = this.yylloc.range;

          this.yylloc = {first_line: this.yylloc.first_line,
            last_line: this.yylineno+1,
            first_column: this.yylloc.first_column,
            last_column: lines ?
                (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
                this.yylloc.first_column - len
            };

          if (this.options.ranges) {
              this.yylloc.range = [r[0], r[0] + this.yyleng - len];
          }
          return this;
      },
  more:function () {
          this._more = true;
          return this;
      },
  less:function (n) {
          this.unput(this.match.slice(n));
      },
  pastInput:function () {
          var past = this.matched.substr(0, this.matched.length - this.match.length);
          return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
      },
  upcomingInput:function () {
          var next = this.match;
          if (next.length < 20) {
              next += this._input.substr(0, 20-next.length);
          }
          return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
      },
  showPosition:function () {
          var pre = this.pastInput();
          var c = new Array(pre.length + 1).join("-");
          return pre + this.upcomingInput() + "\n" + c+"^";
      },
  next:function () {
          if (this.done) {
              return this.EOF;
          }
          if (!this._input) this.done = true;

          var token,
              match,
              tempMatch,
              index,
              col,
              lines;
          if (!this._more) {
              this.yytext = '';
              this.match = '';
          }
          var rules = this._currentRules();
          for (var i=0;i < rules.length; i++) {
              tempMatch = this._input.match(this.rules[rules[i]]);
              if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
                  match = tempMatch;
                  index = i;
                  if (!this.options.flex) break;
              }
          }
          if (match) {
              lines = match[0].match(/(?:\r\n?|\n).*/g);
              if (lines) this.yylineno += lines.length;
              this.yylloc = {first_line: this.yylloc.last_line,
                             last_line: this.yylineno+1,
                             first_column: this.yylloc.last_column,
                             last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
              this.yytext += match[0];
              this.match += match[0];
              this.matches = match;
              this.yyleng = this.yytext.length;
              if (this.options.ranges) {
                  this.yylloc.range = [this.offset, this.offset += this.yyleng];
              }
              this._more = false;
              this._input = this._input.slice(match[0].length);
              this.matched += match[0];
              token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
              if (this.done && this._input) this.done = false;
              if (token) return token;
              else return;
          }
          if (this._input === "") {
              return this.EOF;
          } else {
              return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
                      {text: "", token: null, line: this.yylineno});
          }
      },
  lex:function lex() {
          var r = this.next();
          if (typeof r !== 'undefined') {
              return r;
          } else {
              return this.lex();
          }
      },
  begin:function begin(condition) {
          this.conditionStack.push(condition);
      },
  popState:function popState() {
          return this.conditionStack.pop();
      },
  _currentRules:function _currentRules() {
          return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
      },
  topState:function () {
          return this.conditionStack[this.conditionStack.length-2];
      },
  pushState:function begin(condition) {
          this.begin(condition);
      }});
  lexer.options = {};
  lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {


  function strip(start, end) {
    return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
  }


  var YYSTATE=YY_START
  switch($avoiding_name_collisions) {
  case 0:
                                     if(yy_.yytext.slice(-2) === "\\\\") {
                                       strip(0,1);
                                       this.begin("mu");
                                     } else if(yy_.yytext.slice(-1) === "\\") {
                                       strip(0,1);
                                       this.begin("emu");
                                     } else {
                                       this.begin("mu");
                                     }
                                     if(yy_.yytext) return 14;
                                   
  break;
  case 1:return 14;
  break;
  case 2:
                                     this.popState();
                                     return 14;
                                   
  break;
  case 3:strip(0,4); this.popState(); return 15;
  break;
  case 4:return 35;
  break;
  case 5:return 36;
  break;
  case 6:return 25;
  break;
  case 7:return 16;
  break;
  case 8:return 20;
  break;
  case 9:return 19;
  break;
  case 10:return 19;
  break;
  case 11:return 23;
  break;
  case 12:return 22;
  break;
  case 13:this.popState(); this.begin('com');
  break;
  case 14:strip(3,5); this.popState(); return 15;
  break;
  case 15:return 22;
  break;
  case 16:return 41;
  break;
  case 17:return 40;
  break;
  case 18:return 40;
  break;
  case 19:return 44;
  break;
  case 20:// ignore whitespace
  break;
  case 21:this.popState(); return 24;
  break;
  case 22:this.popState(); return 18;
  break;
  case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
  break;
  case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
  break;
  case 25:return 42;
  break;
  case 26:return 34;
  break;
  case 27:return 34;
  break;
  case 28:return 33;
  break;
  case 29:return 40;
  break;
  case 30:yy_.yytext = strip(1,2); return 40;
  break;
  case 31:return 'INVALID';
  break;
  case 32:return 5;
  break;
  }
  };
  lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
  lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
  return lexer;})()
  parser.lexer = lexer;
  function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
  return new Parser;
  })();__exports__ = handlebars;
  
  return __exports__;
})();

// handlebars/compiler/base.js
var __module8__ = (function(__dependency1__, __dependency2__) {
  "use strict";
  var __exports__ = {};
  var parser = __dependency1__;
  var AST = __dependency2__;

  __exports__.parser = parser;

  function parse(input) {
    // Just return if an already-compile AST was passed in.
    if(input.constructor === AST.ProgramNode) { return input; }

    parser.yy = AST;
    return parser.parse(input);
  }

  __exports__.parse = parse;
  return __exports__;
})(__module9__, __module7__);

// handlebars/compiler/compiler.js
var __module10__ = (function(__dependency1__) {
  "use strict";
  var __exports__ = {};
  var Exception = __dependency1__;

  function Compiler() {}

  __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
  // function in a context. This is necessary for mustache compatibility, which
  // requires that context functions in blocks are evaluated by blockHelperMissing,
  // and then proceed as if the resulting value was provided to blockHelperMissing.

  Compiler.prototype = {
    compiler: Compiler,

    disassemble: function() {
      var opcodes = this.opcodes, opcode, out = [], params, param;

      for (var i=0, l=opcodes.length; i<l; i++) {
        opcode = opcodes[i];

        if (opcode.opcode === 'DECLARE') {
          out.push("DECLARE " + opcode.name + "=" + opcode.value);
        } else {
          params = [];
          for (var j=0; j<opcode.args.length; j++) {
            param = opcode.args[j];
            if (typeof param === "string") {
              param = "\"" + param.replace("\n", "\\n") + "\"";
            }
            params.push(param);
          }
          out.push(opcode.opcode + " " + params.join(" "));
        }
      }

      return out.join("\n");
    },

    equals: function(other) {
      var len = this.opcodes.length;
      if (other.opcodes.length !== len) {
        return false;
      }

      for (var i = 0; i < len; i++) {
        var opcode = this.opcodes[i],
            otherOpcode = other.opcodes[i];
        if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
          return false;
        }
        for (var j = 0; j < opcode.args.length; j++) {
          if (opcode.args[j] !== otherOpcode.args[j]) {
            return false;
          }
        }
      }

      len = this.children.length;
      if (other.children.length !== len) {
        return false;
      }
      for (i = 0; i < len; i++) {
        if (!this.children[i].equals(other.children[i])) {
          return false;
        }
      }

      return true;
    },

    guid: 0,

    compile: function(program, options) {
      this.opcodes = [];
      this.children = [];
      this.depths = {list: []};
      this.options = options;

      // These changes will propagate to the other compiler components
      var knownHelpers = this.options.knownHelpers;
      this.options.knownHelpers = {
        'helperMissing': true,
        'blockHelperMissing': true,
        'each': true,
        'if': true,
        'unless': true,
        'with': true,
        'log': true
      };
      if (knownHelpers) {
        for (var name in knownHelpers) {
          this.options.knownHelpers[name] = knownHelpers[name];
        }
      }

      return this.accept(program);
    },

    accept: function(node) {
      var strip = node.strip || {},
          ret;
      if (strip.left) {
        this.opcode('strip');
      }

      ret = this[node.type](node);

      if (strip.right) {
        this.opcode('strip');
      }

      return ret;
    },

    program: function(program) {
      var statements = program.statements;

      for(var i=0, l=statements.length; i<l; i++) {
        this.accept(statements[i]);
      }
      this.isSimple = l === 1;

      this.depths.list = this.depths.list.sort(function(a, b) {
        return a - b;
      });

      return this;
    },

    compileProgram: function(program) {
      var result = new this.compiler().compile(program, this.options);
      var guid = this.guid++, depth;

      this.usePartial = this.usePartial || result.usePartial;

      this.children[guid] = result;

      for(var i=0, l=result.depths.list.length; i<l; i++) {
        depth = result.depths.list[i];

        if(depth < 2) { continue; }
        else { this.addDepth(depth - 1); }
      }

      return guid;
    },

    block: function(block) {
      var mustache = block.mustache,
          program = block.program,
          inverse = block.inverse;

      if (program) {
        program = this.compileProgram(program);
      }

      if (inverse) {
        inverse = this.compileProgram(inverse);
      }

      var sexpr = mustache.sexpr;
      var type = this.classifySexpr(sexpr);

      if (type === "helper") {
        this.helperSexpr(sexpr, program, inverse);
      } else if (type === "simple") {
        this.simpleSexpr(sexpr);

        // now that the simple mustache is resolved, we need to
        // evaluate it by executing `blockHelperMissing`
        this.opcode('pushProgram', program);
        this.opcode('pushProgram', inverse);
        this.opcode('emptyHash');
        this.opcode('blockValue');
      } else {
        this.ambiguousSexpr(sexpr, program, inverse);

        // now that the simple mustache is resolved, we need to
        // evaluate it by executing `blockHelperMissing`
        this.opcode('pushProgram', program);
        this.opcode('pushProgram', inverse);
        this.opcode('emptyHash');
        this.opcode('ambiguousBlockValue');
      }

      this.opcode('append');
    },

    hash: function(hash) {
      var pairs = hash.pairs, pair, val;

      this.opcode('pushHash');

      for(var i=0, l=pairs.length; i<l; i++) {
        pair = pairs[i];
        val  = pair[1];

        if (this.options.stringParams) {
          if(val.depth) {
            this.addDepth(val.depth);
          }
          this.opcode('getContext', val.depth || 0);
          this.opcode('pushStringParam', val.stringModeValue, val.type);

          if (val.type === 'sexpr') {
            // Subexpressions get evaluated and passed in
            // in string params mode.
            this.sexpr(val);
          }
        } else {
          this.accept(val);
        }

        this.opcode('assignToHash', pair[0]);
      }
      this.opcode('popHash');
    },

    partial: function(partial) {
      var partialName = partial.partialName;
      this.usePartial = true;

      if(partial.context) {
        this.ID(partial.context);
      } else {
        this.opcode('push', 'depth0');
      }

      this.opcode('invokePartial', partialName.name);
      this.opcode('append');
    },

    content: function(content) {
      this.opcode('appendContent', content.string);
    },

    mustache: function(mustache) {
      this.sexpr(mustache.sexpr);

      if(mustache.escaped && !this.options.noEscape) {
        this.opcode('appendEscaped');
      } else {
        this.opcode('append');
      }
    },

    ambiguousSexpr: function(sexpr, program, inverse) {
      var id = sexpr.id,
          name = id.parts[0],
          isBlock = program != null || inverse != null;

      this.opcode('getContext', id.depth);

      this.opcode('pushProgram', program);
      this.opcode('pushProgram', inverse);

      this.opcode('invokeAmbiguous', name, isBlock);
    },

    simpleSexpr: function(sexpr) {
      var id = sexpr.id;

      if (id.type === 'DATA') {
        this.DATA(id);
      } else if (id.parts.length) {
        this.ID(id);
      } else {
        // Simplified ID for `this`
        this.addDepth(id.depth);
        this.opcode('getContext', id.depth);
        this.opcode('pushContext');
      }

      this.opcode('resolvePossibleLambda');
    },

    helperSexpr: function(sexpr, program, inverse) {
      var params = this.setupFullMustacheParams(sexpr, program, inverse),
          name = sexpr.id.parts[0];

      if (this.options.knownHelpers[name]) {
        this.opcode('invokeKnownHelper', params.length, name);
      } else if (this.options.knownHelpersOnly) {
        throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
      } else {
        this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
      }
    },

    sexpr: function(sexpr) {
      var type = this.classifySexpr(sexpr);

      if (type === "simple") {
        this.simpleSexpr(sexpr);
      } else if (type === "helper") {
        this.helperSexpr(sexpr);
      } else {
        this.ambiguousSexpr(sexpr);
      }
    },

    ID: function(id) {
      this.addDepth(id.depth);
      this.opcode('getContext', id.depth);

      var name = id.parts[0];
      if (!name) {
        this.opcode('pushContext');
      } else {
        this.opcode('lookupOnContext', id.parts[0]);
      }

      for(var i=1, l=id.parts.length; i<l; i++) {
        this.opcode('lookup', id.parts[i]);
      }
    },

    DATA: function(data) {
      this.options.data = true;
      if (data.id.isScoped || data.id.depth) {
        throw new Exception('Scoped data references are not supported: ' + data.original, data);
      }

      this.opcode('lookupData');
      var parts = data.id.parts;
      for(var i=0, l=parts.length; i<l; i++) {
        this.opcode('lookup', parts[i]);
      }
    },

    STRING: function(string) {
      this.opcode('pushString', string.string);
    },

    INTEGER: function(integer) {
      this.opcode('pushLiteral', integer.integer);
    },

    BOOLEAN: function(bool) {
      this.opcode('pushLiteral', bool.bool);
    },

    comment: function() {},

    // HELPERS
    opcode: function(name) {
      this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
    },

    declare: function(name, value) {
      this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
    },

    addDepth: function(depth) {
      if(depth === 0) { return; }

      if(!this.depths[depth]) {
        this.depths[depth] = true;
        this.depths.list.push(depth);
      }
    },

    classifySexpr: function(sexpr) {
      var isHelper   = sexpr.isHelper;
      var isEligible = sexpr.eligibleHelper;
      var options    = this.options;

      // if ambiguous, we can possibly resolve the ambiguity now
      if (isEligible && !isHelper) {
        var name = sexpr.id.parts[0];

        if (options.knownHelpers[name]) {
          isHelper = true;
        } else if (options.knownHelpersOnly) {
          isEligible = false;
        }
      }

      if (isHelper) { return "helper"; }
      else if (isEligible) { return "ambiguous"; }
      else { return "simple"; }
    },

    pushParams: function(params) {
      var i = params.length, param;

      while(i--) {
        param = params[i];

        if(this.options.stringParams) {
          if(param.depth) {
            this.addDepth(param.depth);
          }

          this.opcode('getContext', param.depth || 0);
          this.opcode('pushStringParam', param.stringModeValue, param.type);

          if (param.type === 'sexpr') {
            // Subexpressions get evaluated and passed in
            // in string params mode.
            this.sexpr(param);
          }
        } else {
          this[param.type](param);
        }
      }
    },

    setupFullMustacheParams: function(sexpr, program, inverse) {
      var params = sexpr.params;
      this.pushParams(params);

      this.opcode('pushProgram', program);
      this.opcode('pushProgram', inverse);

      if (sexpr.hash) {
        this.hash(sexpr.hash);
      } else {
        this.opcode('emptyHash');
      }

      return params;
    }
  };

  function precompile(input, options, env) {
    if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
      throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
    }

    options = options || {};
    if (!('data' in options)) {
      options.data = true;
    }

    var ast = env.parse(input);
    var environment = new env.Compiler().compile(ast, options);
    return new env.JavaScriptCompiler().compile(environment, options);
  }

  __exports__.precompile = precompile;function compile(input, options, env) {
    if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
      throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
    }

    options = options || {};

    if (!('data' in options)) {
      options.data = true;
    }

    var compiled;

    function compileInput() {
      var ast = env.parse(input);
      var environment = new env.Compiler().compile(ast, options);
      var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
      return env.template(templateSpec);
    }

    // Template is only compiled on first use and cached after that point.
    return function(context, options) {
      if (!compiled) {
        compiled = compileInput();
      }
      return compiled.call(this, context, options);
    };
  }

  __exports__.compile = compile;
  return __exports__;
})(__module5__);

// handlebars/compiler/javascript-compiler.js
var __module11__ = (function(__dependency1__, __dependency2__) {
  "use strict";
  var __exports__;
  var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
  var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
  var log = __dependency1__.log;
  var Exception = __dependency2__;

  function Literal(value) {
    this.value = value;
  }

  function JavaScriptCompiler() {}

  JavaScriptCompiler.prototype = {
    // PUBLIC API: You can override these methods in a subclass to provide
    // alternative compiled forms for name lookup and buffering semantics
    nameLookup: function(parent, name ) {
      var wrap,
          ret;
      if (parent.indexOf('depth') === 0) {
        wrap = true;
      }

      if (/^[0-9]+$/.test(name)) {
        ret = parent + "[" + name + "]";
      } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
        ret = parent + "." + name;
      }
      else {
        ret = parent + "['" + name + "']";
      }

      if (wrap) {
        return '(' + parent + ' && ' + ret + ')';
      } else {
        return ret;
      }
    },

    compilerInfo: function() {
      var revision = COMPILER_REVISION,
          versions = REVISION_CHANGES[revision];
      return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
    },

    appendToBuffer: function(string) {
      if (this.environment.isSimple) {
        return "return " + string + ";";
      } else {
        return {
          appendToBuffer: true,
          content: string,
          toString: function() { return "buffer += " + string + ";"; }
        };
      }
    },

    initializeBuffer: function() {
      return this.quotedString("");
    },

    namespace: "Handlebars",
    // END PUBLIC API

    compile: function(environment, options, context, asObject) {
      this.environment = environment;
      this.options = options || {};

      log('debug', this.environment.disassemble() + "\n\n");

      this.name = this.environment.name;
      this.isChild = !!context;
      this.context = context || {
        programs: [],
        environments: [],
        aliases: { }
      };

      this.preamble();

      this.stackSlot = 0;
      this.stackVars = [];
      this.registers = { list: [] };
      this.hashes = [];
      this.compileStack = [];
      this.inlineStack = [];

      this.compileChildren(environment, options);

      var opcodes = environment.opcodes, opcode;

      this.i = 0;

      for(var l=opcodes.length; this.i<l; this.i++) {
        opcode = opcodes[this.i];

        if(opcode.opcode === 'DECLARE') {
          this[opcode.name] = opcode.value;
        } else {
          this[opcode.opcode].apply(this, opcode.args);
        }

        // Reset the stripNext flag if it was not set by this operation.
        if (opcode.opcode !== this.stripNext) {
          this.stripNext = false;
        }
      }

      // Flush any trailing content that might be pending.
      this.pushSource('');

      if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
        throw new Exception('Compile completed with content left on stack');
      }

      return this.createFunctionContext(asObject);
    },

    preamble: function() {
      var out = [];

      if (!this.isChild) {
        var namespace = this.namespace;

        var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
        if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
        if (this.options.data) { copies = copies + " data = data || {};"; }
        out.push(copies);
      } else {
        out.push('');
      }

      if (!this.environment.isSimple) {
        out.push(", buffer = " + this.initializeBuffer());
      } else {
        out.push("");
      }

      // track the last context pushed into place to allow skipping the
      // getContext opcode when it would be a noop
      this.lastContext = 0;
      this.source = out;
    },

    createFunctionContext: function(asObject) {
      var locals = this.stackVars.concat(this.registers.list);

      if(locals.length > 0) {
        this.source[1] = this.source[1] + ", " + locals.join(", ");
      }

      // Generate minimizer alias mappings
      if (!this.isChild) {
        for (var alias in this.context.aliases) {
          if (this.context.aliases.hasOwnProperty(alias)) {
            this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
          }
        }
      }

      if (this.source[1]) {
        this.source[1] = "var " + this.source[1].substring(2) + ";";
      }

      // Merge children
      if (!this.isChild) {
        this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
      }

      if (!this.environment.isSimple) {
        this.pushSource("return buffer;");
      }

      var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];

      for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
        params.push("depth" + this.environment.depths.list[i]);
      }

      // Perform a second pass over the output to merge content when possible
      var source = this.mergeSource();

      if (!this.isChild) {
        source = this.compilerInfo()+source;
      }

      if (asObject) {
        params.push(source);

        return Function.apply(this, params);
      } else {
        var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n  ' + source + '}';
        log('debug', functionSource + "\n\n");
        return functionSource;
      }
    },
    mergeSource: function() {
      // WARN: We are not handling the case where buffer is still populated as the source should
      // not have buffer append operations as their final action.
      var source = '',
          buffer;
      for (var i = 0, len = this.source.length; i < len; i++) {
        var line = this.source[i];
        if (line.appendToBuffer) {
          if (buffer) {
            buffer = buffer + '\n    + ' + line.content;
          } else {
            buffer = line.content;
          }
        } else {
          if (buffer) {
            source += 'buffer += ' + buffer + ';\n  ';
            buffer = undefined;
          }
          source += line + '\n  ';
        }
      }
      return source;
    },

    // [blockValue]
    //
    // On stack, before: hash, inverse, program, value
    // On stack, after: return value of blockHelperMissing
    //
    // The purpose of this opcode is to take a block of the form
    // `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
    // replace it on the stack with the result of properly
    // invoking blockHelperMissing.
    blockValue: function() {
      this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';

      var params = ["depth0"];
      this.setupParams(0, params);

      this.replaceStack(function(current) {
        params.splice(1, 0, current);
        return "blockHelperMissing.call(" + params.join(", ") + ")";
      });
    },

    // [ambiguousBlockValue]
    //
    // On stack, before: hash, inverse, program, value
    // Compiler value, before: lastHelper=value of last found helper, if any
    // On stack, after, if no lastHelper: same as [blockValue]
    // On stack, after, if lastHelper: value
    ambiguousBlockValue: function() {
      this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';

      var params = ["depth0"];
      this.setupParams(0, params);

      var current = this.topStack();
      params.splice(1, 0, current);

      this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
    },

    // [appendContent]
    //
    // On stack, before: ...
    // On stack, after: ...
    //
    // Appends the string value of `content` to the current buffer
    appendContent: function(content) {
      if (this.pendingContent) {
        content = this.pendingContent + content;
      }
      if (this.stripNext) {
        content = content.replace(/^\s+/, '');
      }

      this.pendingContent = content;
    },

    // [strip]
    //
    // On stack, before: ...
    // On stack, after: ...
    //
    // Removes any trailing whitespace from the prior content node and flags
    // the next operation for stripping if it is a content node.
    strip: function() {
      if (this.pendingContent) {
        this.pendingContent = this.pendingContent.replace(/\s+$/, '');
      }
      this.stripNext = 'strip';
    },

    // [append]
    //
    // On stack, before: value, ...
    // On stack, after: ...
    //
    // Coerces `value` to a String and appends it to the current buffer.
    //
    // If `value` is truthy, or 0, it is coerced into a string and appended
    // Otherwise, the empty string is appended
    append: function() {
      // Force anything that is inlined onto the stack so we don't have duplication
      // when we examine local
      this.flushInline();
      var local = this.popStack();
      this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
      if (this.environment.isSimple) {
        this.pushSource("else { " + this.appendToBuffer("''") + " }");
      }
    },

    // [appendEscaped]
    //
    // On stack, before: value, ...
    // On stack, after: ...
    //
    // Escape `value` and append it to the buffer
    appendEscaped: function() {
      this.context.aliases.escapeExpression = 'this.escapeExpression';

      this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
    },

    // [getContext]
    //
    // On stack, before: ...
    // On stack, after: ...
    // Compiler value, after: lastContext=depth
    //
    // Set the value of the `lastContext` compiler value to the depth
    getContext: function(depth) {
      if(this.lastContext !== depth) {
        this.lastContext = depth;
      }
    },

    // [lookupOnContext]
    //
    // On stack, before: ...
    // On stack, after: currentContext[name], ...
    //
    // Looks up the value of `name` on the current context and pushes
    // it onto the stack.
    lookupOnContext: function(name) {
      this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
    },

    // [pushContext]
    //
    // On stack, before: ...
    // On stack, after: currentContext, ...
    //
    // Pushes the value of the current context onto the stack.
    pushContext: function() {
      this.pushStackLiteral('depth' + this.lastContext);
    },

    // [resolvePossibleLambda]
    //
    // On stack, before: value, ...
    // On stack, after: resolved value, ...
    //
    // If the `value` is a lambda, replace it on the stack by
    // the return value of the lambda
    resolvePossibleLambda: function() {
      this.context.aliases.functionType = '"function"';

      this.replaceStack(function(current) {
        return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
      });
    },

    // [lookup]
    //
    // On stack, before: value, ...
    // On stack, after: value[name], ...
    //
    // Replace the value on the stack with the result of looking
    // up `name` on `value`
    lookup: function(name) {
      this.replaceStack(function(current) {
        return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
      });
    },

    // [lookupData]
    //
    // On stack, before: ...
    // On stack, after: data, ...
    //
    // Push the data lookup operator
    lookupData: function() {
      this.pushStackLiteral('data');
    },

    // [pushStringParam]
    //
    // On stack, before: ...
    // On stack, after: string, currentContext, ...
    //
    // This opcode is designed for use in string mode, which
    // provides the string value of a parameter along with its
    // depth rather than resolving it immediately.
    pushStringParam: function(string, type) {
      this.pushStackLiteral('depth' + this.lastContext);

      this.pushString(type);

      // If it's a subexpression, the string result
      // will be pushed after this opcode.
      if (type !== 'sexpr') {
        if (typeof string === 'string') {
          this.pushString(string);
        } else {
          this.pushStackLiteral(string);
        }
      }
    },

    emptyHash: function() {
      this.pushStackLiteral('{}');

      if (this.options.stringParams) {
        this.push('{}'); // hashContexts
        this.push('{}'); // hashTypes
      }
    },
    pushHash: function() {
      if (this.hash) {
        this.hashes.push(this.hash);
      }
      this.hash = {values: [], types: [], contexts: []};
    },
    popHash: function() {
      var hash = this.hash;
      this.hash = this.hashes.pop();

      if (this.options.stringParams) {
        this.push('{' + hash.contexts.join(',') + '}');
        this.push('{' + hash.types.join(',') + '}');
      }

      this.push('{\n    ' + hash.values.join(',\n    ') + '\n  }');
    },

    // [pushString]
    //
    // On stack, before: ...
    // On stack, after: quotedString(string), ...
    //
    // Push a quoted version of `string` onto the stack
    pushString: function(string) {
      this.pushStackLiteral(this.quotedString(string));
    },

    // [push]
    //
    // On stack, before: ...
    // On stack, after: expr, ...
    //
    // Push an expression onto the stack
    push: function(expr) {
      this.inlineStack.push(expr);
      return expr;
    },

    // [pushLiteral]
    //
    // On stack, before: ...
    // On stack, after: value, ...
    //
    // Pushes a value onto the stack. This operation prevents
    // the compiler from creating a temporary variable to hold
    // it.
    pushLiteral: function(value) {
      this.pushStackLiteral(value);
    },

    // [pushProgram]
    //
    // On stack, before: ...
    // On stack, after: program(guid), ...
    //
    // Push a program expression onto the stack. This takes
    // a compile-time guid and converts it into a runtime-accessible
    // expression.
    pushProgram: function(guid) {
      if (guid != null) {
        this.pushStackLiteral(this.programExpression(guid));
      } else {
        this.pushStackLiteral(null);
      }
    },

    // [invokeHelper]
    //
    // On stack, before: hash, inverse, program, params..., ...
    // On stack, after: result of helper invocation
    //
    // Pops off the helper's parameters, invokes the helper,
    // and pushes the helper's return value onto the stack.
    //
    // If the helper is not found, `helperMissing` is called.
    invokeHelper: function(paramSize, name, isRoot) {
      this.context.aliases.helperMissing = 'helpers.helperMissing';
      this.useRegister('helper');

      var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
      var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');

      var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
      if (helper.paramsInit) {
        lookup += ',' + helper.paramsInit;
      }

      this.push(
        '('
          + lookup
          + ',helper '
            + '? helper.call(' + helper.callParams + ') '
            + ': helperMissing.call(' + helper.helperMissingParams + '))');

      // Always flush subexpressions. This is both to prevent the compounding size issue that
      // occurs when the code has to be duplicated for inlining and also to prevent errors
      // due to the incorrect options object being passed due to the shared register.
      if (!isRoot) {
        this.flushInline();
      }
    },

    // [invokeKnownHelper]
    //
    // On stack, before: hash, inverse, program, params..., ...
    // On stack, after: result of helper invocation
    //
    // This operation is used when the helper is known to exist,
    // so a `helperMissing` fallback is not required.
    invokeKnownHelper: function(paramSize, name) {
      var helper = this.setupHelper(paramSize, name);
      this.push(helper.name + ".call(" + helper.callParams + ")");
    },

    // [invokeAmbiguous]
    //
    // On stack, before: hash, inverse, program, params..., ...
    // On stack, after: result of disambiguation
    //
    // This operation is used when an expression like `{{foo}}`
    // is provided, but we don't know at compile-time whether it
    // is a helper or a path.
    //
    // This operation emits more code than the other options,
    // and can be avoided by passing the `knownHelpers` and
    // `knownHelpersOnly` flags at compile-time.
    invokeAmbiguous: function(name, helperCall) {
      this.context.aliases.functionType = '"function"';
      this.useRegister('helper');

      this.emptyHash();
      var helper = this.setupHelper(0, name, helperCall);

      var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');

      var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
      var nextStack = this.nextStack();

      if (helper.paramsInit) {
        this.pushSource(helper.paramsInit);
      }
      this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
      this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
    },

    // [invokePartial]
    //
    // On stack, before: context, ...
    // On stack after: result of partial invocation
    //
    // This operation pops off a context, invokes a partial with that context,
    // and pushes the result of the invocation back.
    invokePartial: function(name) {
      var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];

      if (this.options.data) {
        params.push("data");
      }

      this.context.aliases.self = "this";
      this.push("self.invokePartial(" + params.join(", ") + ")");
    },

    // [assignToHash]
    //
    // On stack, before: value, hash, ...
    // On stack, after: hash, ...
    //
    // Pops a value and hash off the stack, assigns `hash[key] = value`
    // and pushes the hash back onto the stack.
    assignToHash: function(key) {
      var value = this.popStack(),
          context,
          type;

      if (this.options.stringParams) {
        type = this.popStack();
        context = this.popStack();
      }

      var hash = this.hash;
      if (context) {
        hash.contexts.push("'" + key + "': " + context);
      }
      if (type) {
        hash.types.push("'" + key + "': " + type);
      }
      hash.values.push("'" + key + "': (" + value + ")");
    },

    // HELPERS

    compiler: JavaScriptCompiler,

    compileChildren: function(environment, options) {
      var children = environment.children, child, compiler;

      for(var i=0, l=children.length; i<l; i++) {
        child = children[i];
        compiler = new this.compiler();

        var index = this.matchExistingProgram(child);

        if (index == null) {
          this.context.programs.push('');     // Placeholder to prevent name conflicts for nested children
          index = this.context.programs.length;
          child.index = index;
          child.name = 'program' + index;
          this.context.programs[index] = compiler.compile(child, options, this.context);
          this.context.environments[index] = child;
        } else {
          child.index = index;
          child.name = 'program' + index;
        }
      }
    },
    matchExistingProgram: function(child) {
      for (var i = 0, len = this.context.environments.length; i < len; i++) {
        var environment = this.context.environments[i];
        if (environment && environment.equals(child)) {
          return i;
        }
      }
    },

    programExpression: function(guid) {
      this.context.aliases.self = "this";

      if(guid == null) {
        return "self.noop";
      }

      var child = this.environment.children[guid],
          depths = child.depths.list, depth;

      var programParams = [child.index, child.name, "data"];

      for(var i=0, l = depths.length; i<l; i++) {
        depth = depths[i];

        if(depth === 1) { programParams.push("depth0"); }
        else { programParams.push("depth" + (depth - 1)); }
      }

      return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
    },

    register: function(name, val) {
      this.useRegister(name);
      this.pushSource(name + " = " + val + ";");
    },

    useRegister: function(name) {
      if(!this.registers[name]) {
        this.registers[name] = true;
        this.registers.list.push(name);
      }
    },

    pushStackLiteral: function(item) {
      return this.push(new Literal(item));
    },

    pushSource: function(source) {
      if (this.pendingContent) {
        this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
        this.pendingContent = undefined;
      }

      if (source) {
        this.source.push(source);
      }
    },

    pushStack: function(item) {
      this.flushInline();

      var stack = this.incrStack();
      if (item) {
        this.pushSource(stack + " = " + item + ";");
      }
      this.compileStack.push(stack);
      return stack;
    },

    replaceStack: function(callback) {
      var prefix = '',
          inline = this.isInline(),
          stack,
          createdStack,
          usedLiteral;

      // If we are currently inline then we want to merge the inline statement into the
      // replacement statement via ','
      if (inline) {
        var top = this.popStack(true);

        if (top instanceof Literal) {
          // Literals do not need to be inlined
          stack = top.value;
          usedLiteral = true;
        } else {
          // Get or create the current stack name for use by the inline
          createdStack = !this.stackSlot;
          var name = !createdStack ? this.topStackName() : this.incrStack();

          prefix = '(' + this.push(name) + ' = ' + top + '),';
          stack = this.topStack();
        }
      } else {
        stack = this.topStack();
      }

      var item = callback.call(this, stack);

      if (inline) {
        if (!usedLiteral) {
          this.popStack();
        }
        if (createdStack) {
          this.stackSlot--;
        }
        this.push('(' + prefix + item + ')');
      } else {
        // Prevent modification of the context depth variable. Through replaceStack
        if (!/^stack/.test(stack)) {
          stack = this.nextStack();
        }

        this.pushSource(stack + " = (" + prefix + item + ");");
      }
      return stack;
    },

    nextStack: function() {
      return this.pushStack();
    },

    incrStack: function() {
      this.stackSlot++;
      if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
      return this.topStackName();
    },
    topStackName: function() {
      return "stack" + this.stackSlot;
    },
    flushInline: function() {
      var inlineStack = this.inlineStack;
      if (inlineStack.length) {
        this.inlineStack = [];
        for (var i = 0, len = inlineStack.length; i < len; i++) {
          var entry = inlineStack[i];
          if (entry instanceof Literal) {
            this.compileStack.push(entry);
          } else {
            this.pushStack(entry);
          }
        }
      }
    },
    isInline: function() {
      return this.inlineStack.length;
    },

    popStack: function(wrapped) {
      var inline = this.isInline(),
          item = (inline ? this.inlineStack : this.compileStack).pop();

      if (!wrapped && (item instanceof Literal)) {
        return item.value;
      } else {
        if (!inline) {
          if (!this.stackSlot) {
            throw new Exception('Invalid stack pop');
          }
          this.stackSlot--;
        }
        return item;
      }
    },

    topStack: function(wrapped) {
      var stack = (this.isInline() ? this.inlineStack : this.compileStack),
          item = stack[stack.length - 1];

      if (!wrapped && (item instanceof Literal)) {
        return item.value;
      } else {
        return item;
      }
    },

    quotedString: function(str) {
      return '"' + str
        .replace(/\\/g, '\\\\')
        .replace(/"/g, '\\"')
        .replace(/\n/g, '\\n')
        .replace(/\r/g, '\\r')
        .replace(/\u2028/g, '\\u2028')   // Per Ecma-262 7.3 + 7.8.4
        .replace(/\u2029/g, '\\u2029') + '"';
    },

    setupHelper: function(paramSize, name, missingParams) {
      var params = [],
          paramsInit = this.setupParams(paramSize, params, missingParams);
      var foundHelper = this.nameLookup('helpers', name, 'helper');

      return {
        params: params,
        paramsInit: paramsInit,
        name: foundHelper,
        callParams: ["depth0"].concat(params).join(", "),
        helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
      };
    },

    setupOptions: function(paramSize, params) {
      var options = [], contexts = [], types = [], param, inverse, program;

      options.push("hash:" + this.popStack());

      if (this.options.stringParams) {
        options.push("hashTypes:" + this.popStack());
        options.push("hashContexts:" + this.popStack());
      }

      inverse = this.popStack();
      program = this.popStack();

      // Avoid setting fn and inverse if neither are set. This allows
      // helpers to do a check for `if (options.fn)`
      if (program || inverse) {
        if (!program) {
          this.context.aliases.self = "this";
          program = "self.noop";
        }

        if (!inverse) {
          this.context.aliases.self = "this";
          inverse = "self.noop";
        }

        options.push("inverse:" + inverse);
        options.push("fn:" + program);
      }

      for(var i=0; i<paramSize; i++) {
        param = this.popStack();
        params.push(param);

        if(this.options.stringParams) {
          types.push(this.popStack());
          contexts.push(this.popStack());
        }
      }

      if (this.options.stringParams) {
        options.push("contexts:[" + contexts.join(",") + "]");
        options.push("types:[" + types.join(",") + "]");
      }

      if(this.options.data) {
        options.push("data:data");
      }

      return options;
    },

    // the params and contexts arguments are passed in arrays
    // to fill in
    setupParams: function(paramSize, params, useRegister) {
      var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';

      if (useRegister) {
        this.useRegister('options');
        params.push('options');
        return 'options=' + options;
      } else {
        params.push(options);
        return '';
      }
    }
  };

  var reservedWords = (
    "break else new var" +
    " case finally return void" +
    " catch for switch while" +
    " continue function this with" +
    " default if throw" +
    " delete in try" +
    " do instanceof typeof" +
    " abstract enum int short" +
    " boolean export interface static" +
    " byte extends long super" +
    " char final native synchronized" +
    " class float package throws" +
    " const goto private transient" +
    " debugger implements protected volatile" +
    " double import public let yield"
  ).split(" ");

  var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};

  for(var i=0, l=reservedWords.length; i<l; i++) {
    compilerWords[reservedWords[i]] = true;
  }

  JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
    if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
      return true;
    }
    return false;
  };

  __exports__ = JavaScriptCompiler;
  return __exports__;
})(__module2__, __module5__);

// handlebars.js
var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
  "use strict";
  var __exports__;
  
  var Handlebars = __dependency1__;

  // Compiler imports
  var AST = __dependency2__;
  var Parser = __dependency3__.parser;
  var parse = __dependency3__.parse;
  var Compiler = __dependency4__.Compiler;
  var compile = __dependency4__.compile;
  var precompile = __dependency4__.precompile;
  var JavaScriptCompiler = __dependency5__;

  var _create = Handlebars.create;
  var create = function() {
    var hb = _create();

    hb.compile = function(input, options) {
      return compile(input, options, hb);
    };
    hb.precompile = function (input, options) {
      return precompile(input, options, hb);
    };

    hb.AST = AST;
    hb.Compiler = Compiler;
    hb.JavaScriptCompiler = JavaScriptCompiler;
    hb.Parser = Parser;
    hb.parse = parse;

    return hb;
  };

  Handlebars = create();
  Handlebars.create = create;

  __exports__ = Handlebars;
  return __exports__;
})(__module1__, __module7__, __module8__, __module10__, __module11__);

  return __module0__;
})();
;

// Source: yithwebclient/static/vendor/ember/ember.js


(function() {
var define, requireModule, require, requirejs, Ember;

(function() {
  Ember = this.Ember = this.Ember || {};
  if (typeof Ember === 'undefined') { Ember = {} };

  if (typeof Ember.__loader === 'undefined') {
    var registry = {}, seen = {};

    define = function(name, deps, callback) {
      registry[name] = { deps: deps, callback: callback };
    };

    requirejs = require = requireModule = function(name) {
      if (seen.hasOwnProperty(name)) { return seen[name]; }
      seen[name] = {};

      if (!registry[name]) {
        throw new Error("Could not find module " + name);
      }

      var mod = registry[name],
      deps = mod.deps,
      callback = mod.callback,
      reified = [],
      exports;

      for (var i=0, l=deps.length; i<l; i++) {
        if (deps[i] === 'exports') {
          reified.push(exports = {});
        } else {
          reified.push(requireModule(resolve(deps[i])));
        }
      }

      var value = callback.apply(this, reified);
      return seen[name] = exports || value;

      function resolve(child) {
        if (child.charAt(0) !== '.') { return child; }
        var parts = child.split("/");
        var parentBase = name.split("/").slice(0, -1);

        for (var i=0, l=parts.length; i<l; i++) {
          var part = parts[i];

          if (part === '..') { parentBase.pop(); }
          else if (part === '.') { continue; }
          else { parentBase.push(part); }
        }

        return parentBase.join("/");
      }
    };
    requirejs._eak_seen = registry;

    Ember.__loader = {define: define, require: require, registry: registry};
  } else {
    define = Ember.__loader.define;
    requirejs = require = requireModule = Ember.__loader.require;
  }
})();

define("backburner",
  ["backburner/utils","backburner/deferred_action_queues","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Utils = __dependency1__["default"];
    var DeferredActionQueues = __dependency2__.DeferredActionQueues;

    var slice = [].slice,
        pop = [].pop,
        each = Utils.each,
        isString = Utils.isString,
        isFunction = Utils.isFunction,
        isNumber = Utils.isNumber,
        timers = [],
        global = this,
        NUMBER = /\d+/;

    // In IE 6-8, try/finally doesn't work without a catch.
    // Unfortunately, this is impossible to test for since wrapping it in a parent try/catch doesn't trigger the bug.
    // This tests for another broken try/catch behavior that only exhibits in the same versions of IE.
    var needsIETryCatchFix = (function(e,x){
      try{ x(); }
      catch(e) { } // jshint ignore:line
      return !!e;
    })();

    function isCoercableNumber(number) {
      return isNumber(number) || NUMBER.test(number);
    }

    function Backburner(queueNames, options) {
      this.queueNames = queueNames;
      this.options = options || {};
      if (!this.options.defaultQueue) {
        this.options.defaultQueue = queueNames[0];
      }
      this.instanceStack = [];
      this._debouncees = [];
      this._throttlers = [];
    }

    Backburner.prototype = {
      queueNames: null,
      options: null,
      currentInstance: null,
      instanceStack: null,

      begin: function() {
        var options = this.options,
            onBegin = options && options.onBegin,
            previousInstance = this.currentInstance;

        if (previousInstance) {
          this.instanceStack.push(previousInstance);
        }

        this.currentInstance = new DeferredActionQueues(this.queueNames, options);
        if (onBegin) {
          onBegin(this.currentInstance, previousInstance);
        }
      },

      end: function() {
        var options = this.options,
            onEnd = options && options.onEnd,
            currentInstance = this.currentInstance,
            nextInstance = null;

        // Prevent double-finally bug in Safari 6.0.2 and iOS 6
        // This bug appears to be resolved in Safari 6.0.5 and iOS 7
        var finallyAlreadyCalled = false;
        try {
          currentInstance.flush();
        } finally {
          if (!finallyAlreadyCalled) {
            finallyAlreadyCalled = true;

            this.currentInstance = null;

            if (this.instanceStack.length) {
              nextInstance = this.instanceStack.pop();
              this.currentInstance = nextInstance;
            }

            if (onEnd) {
              onEnd(currentInstance, nextInstance);
            }
          }
        }
      },

      run: function(target, method ) {
        var onError = getOnError(this.options);

        this.begin();

        if (!method) {
          method = target;
          target = null;
        }

        if (isString(method)) {
          method = target[method];
        }

        var args = slice.call(arguments, 2);

        // guard against Safari 6's double-finally bug
        var didFinally = false;

        if (onError) {
          try {
            return method.apply(target, args);
          } catch(error) {
            onError(error);
          } finally {
            if (!didFinally) {
              didFinally = true;
              this.end();
            }
          }
        } else {
          try {
            return method.apply(target, args);
          } finally {
            if (!didFinally) {
              didFinally = true;
              this.end();
            }
          }
        }
      },

      defer: function(queueName, target, method ) {
        if (!method) {
          method = target;
          target = null;
        }

        if (isString(method)) {
          method = target[method];
        }

        var stack = this.DEBUG ? new Error() : undefined,
            args = arguments.length > 3 ? slice.call(arguments, 3) : undefined;
        if (!this.currentInstance) { createAutorun(this); }
        return this.currentInstance.schedule(queueName, target, method, args, false, stack);
      },

      deferOnce: function(queueName, target, method ) {
        if (!method) {
          method = target;
          target = null;
        }

        if (isString(method)) {
          method = target[method];
        }

        var stack = this.DEBUG ? new Error() : undefined,
            args = arguments.length > 3 ? slice.call(arguments, 3) : undefined;
        if (!this.currentInstance) { createAutorun(this); }
        return this.currentInstance.schedule(queueName, target, method, args, true, stack);
      },

      setTimeout: function() {
        var args = slice.call(arguments),
            length = args.length,
            method, wait, target,
            methodOrTarget, methodOrWait, methodOrArgs;

        if (length === 0) {
          return;
        } else if (length === 1) {
          method = args.shift();
          wait = 0;
        } else if (length === 2) {
          methodOrTarget = args[0];
          methodOrWait = args[1];

          if (isFunction(methodOrWait) || isFunction(methodOrTarget[methodOrWait])) {
            target = args.shift();
            method = args.shift();
            wait = 0;
          } else if (isCoercableNumber(methodOrWait)) {
            method = args.shift();
            wait = args.shift();
          } else {
            method = args.shift();
            wait =  0;
          }
        } else {
          var last = args[args.length - 1];

          if (isCoercableNumber(last)) {
            wait = args.pop();
          } else {
            wait = 0;
          }

          methodOrTarget = args[0];
          methodOrArgs = args[1];

          if (isFunction(methodOrArgs) || (isString(methodOrArgs) &&
                                          methodOrTarget !== null &&
                                          methodOrArgs in methodOrTarget)) {
            target = args.shift();
            method = args.shift();
          } else {
            method = args.shift();
          }
        }

        var executeAt = (+new Date()) + parseInt(wait, 10);

        if (isString(method)) {
          method = target[method];
        }

        var onError = getOnError(this.options);

        function fn() {
          if (onError) {
            try {
              method.apply(target, args);
            } catch (e) {
              onError(e);
            }
          } else {
            method.apply(target, args);
          }
        }

        // find position to insert
        var i = searchTimer(executeAt, timers);

        timers.splice(i, 0, executeAt, fn);

        updateLaterTimer(this, executeAt, wait);

        return fn;
      },

      throttle: function(target, method ) {
        var self = this,
            args = arguments,
            immediate = pop.call(args),
            wait,
            throttler,
            index,
            timer;

        if (isNumber(immediate) || isString(immediate)) {
          wait = immediate;
          immediate = true;
        } else {
          wait = pop.call(args);
        }

        wait = parseInt(wait, 10);

        index = findThrottler(target, method, this._throttlers);
        if (index > -1) { return this._throttlers[index]; } // throttled

        timer = global.setTimeout(function() {
          if (!immediate) {
            self.run.apply(self, args);
          }
          var index = findThrottler(target, method, self._throttlers);
          if (index > -1) {
            self._throttlers.splice(index, 1);
          }
        }, wait);

        if (immediate) {
          self.run.apply(self, args);
        }

        throttler = [target, method, timer];

        this._throttlers.push(throttler);

        return throttler;
      },

      debounce: function(target, method ) {
        var self = this,
            args = arguments,
            immediate = pop.call(args),
            wait,
            index,
            debouncee,
            timer;

        if (isNumber(immediate) || isString(immediate)) {
          wait = immediate;
          immediate = false;
        } else {
          wait = pop.call(args);
        }

        wait = parseInt(wait, 10);
        // Remove debouncee
        index = findDebouncee(target, method, this._debouncees);

        if (index > -1) {
          debouncee = this._debouncees[index];
          this._debouncees.splice(index, 1);
          clearTimeout(debouncee[2]);
        }

        timer = global.setTimeout(function() {
          if (!immediate) {
            self.run.apply(self, args);
          }
          var index = findDebouncee(target, method, self._debouncees);
          if (index > -1) {
            self._debouncees.splice(index, 1);
          }
        }, wait);

        if (immediate && index === -1) {
          self.run.apply(self, args);
        }

        debouncee = [target, method, timer];

        self._debouncees.push(debouncee);

        return debouncee;
      },

      cancelTimers: function() {
        var clearItems = function(item) {
          clearTimeout(item[2]);
        };

        each(this._throttlers, clearItems);
        this._throttlers = [];

        each(this._debouncees, clearItems);
        this._debouncees = [];

        if (this._laterTimer) {
          clearTimeout(this._laterTimer);
          this._laterTimer = null;
        }
        timers = [];

        if (this._autorun) {
          clearTimeout(this._autorun);
          this._autorun = null;
        }
      },

      hasTimers: function() {
        return !!timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun;
      },

      cancel: function(timer) {
        var timerType = typeof timer;

        if (timer && timerType === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce
          return timer.queue.cancel(timer);
        } else if (timerType === 'function') { // we're cancelling a setTimeout
          for (var i = 0, l = timers.length; i < l; i += 2) {
            if (timers[i + 1] === timer) {
              timers.splice(i, 2); // remove the two elements
              return true;
            }
          }
        } else if (Object.prototype.toString.call(timer) === "[object Array]"){ // we're cancelling a throttle or debounce
          return this._cancelItem(findThrottler, this._throttlers, timer) ||
                   this._cancelItem(findDebouncee, this._debouncees, timer);
        } else {
          return; // timer was null or not a timer
        }
      },

      _cancelItem: function(findMethod, array, timer){
        var item,
            index;

        if (timer.length < 3) { return false; }

        index = findMethod(timer[0], timer[1], array);

        if(index > -1) {

          item = array[index];

          if(item[2] === timer[2]){
            array.splice(index, 1);
            clearTimeout(timer[2]);
            return true;
          }
        }

        return false;
      }
    };

    Backburner.prototype.schedule = Backburner.prototype.defer;
    Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
    Backburner.prototype.later = Backburner.prototype.setTimeout;

    if (needsIETryCatchFix) {
      var originalRun = Backburner.prototype.run;
      Backburner.prototype.run = wrapInTryCatch(originalRun);

      var originalEnd = Backburner.prototype.end;
      Backburner.prototype.end = wrapInTryCatch(originalEnd);
    }

    function wrapInTryCatch(func) {
      return function () {
        try {
          return func.apply(this, arguments);
        } catch (e) {
          throw e;
        }
      };
    }

    function getOnError(options) {
      return options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]);
    }


    function createAutorun(backburner) {
      backburner.begin();
      backburner._autorun = global.setTimeout(function() {
        backburner._autorun = null;
        backburner.end();
      });
    }

    function updateLaterTimer(self, executeAt, wait) {
      if (!self._laterTimer || executeAt < self._laterTimerExpiresAt) {
        self._laterTimer = global.setTimeout(function() {
          self._laterTimer = null;
          self._laterTimerExpiresAt = null;
          executeTimers(self);
        }, wait);
        self._laterTimerExpiresAt = executeAt;
      }
    }

    function executeTimers(self) {
      var now = +new Date(),
          time, fns, i, l;

      self.run(function() {
        i = searchTimer(now, timers);

        fns = timers.splice(0, i);

        for (i = 1, l = fns.length; i < l; i += 2) {
          self.schedule(self.options.defaultQueue, null, fns[i]);
        }
      });

      if (timers.length) {
        updateLaterTimer(self, timers[0], timers[0] - now);
      }
    }

    function findDebouncee(target, method, debouncees) {
      return findItem(target, method, debouncees);
    }

    function findThrottler(target, method, throttlers) {
      return findItem(target, method, throttlers);
    }

    function findItem(target, method, collection) {
      var item,
          index = -1;

      for (var i = 0, l = collection.length; i < l; i++) {
        item = collection[i];
        if (item[0] === target && item[1] === method) {
          index = i;
          break;
        }
      }

      return index;
    }

    function searchTimer(time, timers) {
      var start = 0,
          end = timers.length - 2,
          middle, l;

      while (start < end) {
        // since timers is an array of pairs 'l' will always
        // be an integer
        l = (end - start) / 2;

        // compensate for the index in case even number
        // of pairs inside timers
        middle = start + l - (l % 2);

        if (time >= timers[middle]) {
          start = middle + 2;
        } else {
          end = middle;
        }
      }

      return (time >= timers[start]) ? start + 2 : start;
    }

    __exports__.Backburner = Backburner;
  });
define("backburner/deferred_action_queues",
  ["backburner/utils","backburner/queue","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Utils = __dependency1__["default"];
    var Queue = __dependency2__.Queue;

    var each = Utils.each,
        isString = Utils.isString;

    function DeferredActionQueues(queueNames, options) {
      var queues = this.queues = {};
      this.queueNames = queueNames = queueNames || [];

      this.options = options;

      each(queueNames, function(queueName) {
        queues[queueName] = new Queue(this, queueName, options);
      });
    }

    DeferredActionQueues.prototype = {
      queueNames: null,
      queues: null,
      options: null,

      schedule: function(queueName, target, method, args, onceFlag, stack) {
        var queues = this.queues,
            queue = queues[queueName];

        if (!queue) { throw new Error("You attempted to schedule an action in a queue (" + queueName + ") that doesn't exist"); }

        if (onceFlag) {
          return queue.pushUnique(target, method, args, stack);
        } else {
          return queue.push(target, method, args, stack);
        }
      },

      invoke: function(target, method, args, _) {
        if (args && args.length > 0) {
          method.apply(target, args);
        } else {
          method.call(target);
        }
      },

      invokeWithOnError: function(target, method, args, onError) {
        try {
          if (args && args.length > 0) {
            method.apply(target, args);
          } else {
            method.call(target);
          }
        } catch(error) {
          onError(error);
        }
      },

      flush: function() {
        var queues = this.queues,
            queueNames = this.queueNames,
            queueName, queue, queueItems, priorQueueNameIndex,
            queueNameIndex = 0, numberOfQueues = queueNames.length,
            options = this.options,
            onError = options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]),
            invoke = onError ? this.invokeWithOnError : this.invoke;

        outerloop:
        while (queueNameIndex < numberOfQueues) {
          queueName = queueNames[queueNameIndex];
          queue = queues[queueName];
          queueItems = queue._queueBeingFlushed = queue._queue.slice();
          queue._queue = [];

          var queueOptions = queue.options, // TODO: write a test for this
              before = queueOptions && queueOptions.before,
              after = queueOptions && queueOptions.after,
              target, method, args, stack,
              queueIndex = 0, numberOfQueueItems = queueItems.length;

          if (numberOfQueueItems && before) { before(); }

          while (queueIndex < numberOfQueueItems) {
            target = queueItems[queueIndex];
            method = queueItems[queueIndex+1];
            args   = queueItems[queueIndex+2];
            stack  = queueItems[queueIndex+3]; // Debugging assistance

            if (isString(method)) { method = target[method]; }

            // method could have been nullified / canceled during flush
            if (method) {
              invoke(target, method, args, onError);
            }

            queueIndex += 4;
          }

          queue._queueBeingFlushed = null;
          if (numberOfQueueItems && after) { after(); }

          if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) {
            queueNameIndex = priorQueueNameIndex;
            continue outerloop;
          }

          queueNameIndex++;
        }
      }
    };

    function indexOfPriorQueueWithActions(daq, currentQueueIndex) {
      var queueName, queue;

      for (var i = 0, l = currentQueueIndex; i <= l; i++) {
        queueName = daq.queueNames[i];
        queue = daq.queues[queueName];
        if (queue._queue.length) { return i; }
      }

      return -1;
    }

    __exports__.DeferredActionQueues = DeferredActionQueues;
  });
define("backburner/queue",
  ["exports"],
  function(__exports__) {
    "use strict";
    function Queue(daq, name, options) {
      this.daq = daq;
      this.name = name;
      this.globalOptions = options;
      this.options = options[name];
      this._queue = [];
    }

    Queue.prototype = {
      daq: null,
      name: null,
      options: null,
      onError: null,
      _queue: null,

      push: function(target, method, args, stack) {
        var queue = this._queue;
        queue.push(target, method, args, stack);
        return {queue: this, target: target, method: method};
      },

      pushUnique: function(target, method, args, stack) {
        var queue = this._queue, currentTarget, currentMethod, i, l;

        for (i = 0, l = queue.length; i < l; i += 4) {
          currentTarget = queue[i];
          currentMethod = queue[i+1];

          if (currentTarget === target && currentMethod === method) {
            queue[i+2] = args; // replace args
            queue[i+3] = stack; // replace stack
            return {queue: this, target: target, method: method};
          }
        }

        queue.push(target, method, args, stack);
        return {queue: this, target: target, method: method};
      },

      // TODO: remove me, only being used for Ember.run.sync
      flush: function() {
        var queue = this._queue,
            globalOptions = this.globalOptions,
            options = this.options,
            before = options && options.before,
            after = options && options.after,
            onError = globalOptions.onError || (globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod]),
            target, method, args, stack, i, l = queue.length;

        if (l && before) { before(); }
        for (i = 0; i < l; i += 4) {
          target = queue[i];
          method = queue[i+1];
          args   = queue[i+2];
          stack  = queue[i+3]; // Debugging assistance

          // TODO: error handling
          if (args && args.length > 0) {
            if (onError) {
              try {
                method.apply(target, args);
              } catch (e) {
                onError(e);
              }
            } else {
              method.apply(target, args);
            }
          } else {
            if (onError) {
              try {
                method.call(target);
              } catch(e) {
                onError(e);
              }
            } else {
              method.call(target);
            }
          }
        }
        if (l && after) { after(); }

        // check if new items have been added
        if (queue.length > l) {
          this._queue = queue.slice(l);
          this.flush();
        } else {
          this._queue.length = 0;
        }
      },

      cancel: function(actionToCancel) {
        var queue = this._queue, currentTarget, currentMethod, i, l;

        for (i = 0, l = queue.length; i < l; i += 4) {
          currentTarget = queue[i];
          currentMethod = queue[i+1];

          if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
            queue.splice(i, 4);
            return true;
          }
        }

        // if not found in current queue
        // could be in the queue that is being flushed
        queue = this._queueBeingFlushed;
        if (!queue) {
          return;
        }
        for (i = 0, l = queue.length; i < l; i += 4) {
          currentTarget = queue[i];
          currentMethod = queue[i+1];

          if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
            // don't mess with array during flush
            // just nullify the method
            queue[i+1] = null;
            return true;
          }
        }
      }
    };

    __exports__.Queue = Queue;
  });
define("backburner/utils",
  ["exports"],
  function(__exports__) {
    "use strict";
    __exports__["default"] = {
      each: function(collection, callback) {
        for (var i = 0; i < collection.length; i++) {
          callback(collection[i]);
        }
      },

      isString: function(suspect) {
        return typeof suspect === 'string';
      },

      isFunction: function(suspect) {
        return typeof suspect === 'function';
      },

      isNumber: function(suspect) {
        return typeof suspect === 'number';
      }
    };
  });

define("calculateVersion",
  [],
  function() {
    "use strict";
    'use strict';

    var fs   = require('fs');
    var path = require('path');

    module.exports = function () {
      var packageVersion = require('../package.json').version;
      var output         = [packageVersion];
      var gitPath        = path.join(__dirname,'..','.git');
      var headFilePath   = path.join(gitPath, 'HEAD');

      if (packageVersion.indexOf('+') > -1) {
        try {
          if (fs.existsSync(headFilePath)) {
            var headFile = fs.readFileSync(headFilePath, {encoding: 'utf8'});
            var branchName = headFile.split('/').slice(-1)[0].trim();
            var refPath = headFile.split(' ')[1];
            var branchSHA;

            if (refPath) {
              var branchPath = path.join(gitPath, refPath.trim());
              branchSHA  = fs.readFileSync(branchPath);
            } else {
              branchSHA = branchName;
            }

            output.push(branchSHA.slice(0,10));
          }
        } catch (err) {
          console.error(err.stack);
        }
        return output.join('.');
      } else {
        return packageVersion;
      }
    };
  });
define("container",
  ["container/container","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    

    
    Ember.MODEL_FACTORY_INJECTIONS = false;

    if (Ember.ENV && typeof Ember.ENV.MODEL_FACTORY_INJECTIONS !== 'undefined') {
      Ember.MODEL_FACTORY_INJECTIONS = !!Ember.ENV.MODEL_FACTORY_INJECTIONS;
    }


    var Container = __dependency1__["default"];

    __exports__["default"] = Container;
  });
define("container/container",
  ["container/inheriting_dict","ember-metal/core","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var InheritingDict = __dependency1__["default"];
    var Ember = __dependency2__["default"];
    // Ember.assert

    // A lightweight container that helps to assemble and decouple components.
    // Public api for the container is still in flux.
    // The public api, specified on the application namespace should be considered the stable api.
    function Container(parent) {
      this.parent = parent;
      this.children = [];

      this.resolver = parent && parent.resolver || function() {};

      this.registry = new InheritingDict(parent && parent.registry);
      this.cache = new InheritingDict(parent && parent.cache);
      this.factoryCache = new InheritingDict(parent && parent.factoryCache);
      this.resolveCache = new InheritingDict(parent && parent.resolveCache);
      this.typeInjections = new InheritingDict(parent && parent.typeInjections);
      this.injections = {};

      this.factoryTypeInjections = new InheritingDict(parent && parent.factoryTypeInjections);
      this.factoryInjections = {};

      this._options = new InheritingDict(parent && parent._options);
      this._typeOptions = new InheritingDict(parent && parent._typeOptions);
    }

    Container.prototype = {

      
      parent: null,

      
      children: null,

      
      resolver: null,

      
      registry: null,

      
      cache: null,

      
      typeInjections: null,

      
      injections: null,

      
      _options: null,

      
      _typeOptions: null,

      
      child: function() {
        var container = new Container(this);
        this.children.push(container);
        return container;
      },

      
      set: function(object, key, value) {
        object[key] = value;
      },

      
      register: function(fullName, factory, options) {
        Ember.assert('fullName must be a proper full name', validateFullName(fullName));

        if (factory === undefined) {
          throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`');
        }

        var normalizedName = this.normalize(fullName);

        if (this.cache.has(normalizedName)) {
          throw new Error('Cannot re-register: `' + fullName +'`, as it has already been looked up.');
        }

        this.registry.set(normalizedName, factory);
        this._options.set(normalizedName, options || {});
      },

      
      unregister: function(fullName) {
        Ember.assert('fullName must be a proper full name', validateFullName(fullName));

        var normalizedName = this.normalize(fullName);

        this.registry.remove(normalizedName);
        this.cache.remove(normalizedName);
        this.factoryCache.remove(normalizedName);
        this.resolveCache.remove(normalizedName);
        this._options.remove(normalizedName);
      },

      
      resolve: function(fullName) {
        Ember.assert('fullName must be a proper full name', validateFullName(fullName));
        return resolve(this, this.normalize(fullName));
      },

      
      describe: function(fullName) {
        return fullName;
      },

      
      normalize: function(fullName) {
        return fullName;
      },

      
      makeToString: function(factory, fullName) {
        return factory.toString();
      },

      
      lookup: function(fullName, options) {
        Ember.assert('fullName must be a proper full name', validateFullName(fullName));
        return lookup(this, this.normalize(fullName), options);
      },

      
      lookupFactory: function(fullName) {
        Ember.assert('fullName must be a proper full name', validateFullName(fullName));
        return factoryFor(this, this.normalize(fullName));
      },

      
      has: function(fullName) {
        Ember.assert('fullName must be a proper full name', validateFullName(fullName));
        return has(this, this.normalize(fullName));
      },

      
      optionsForType: function(type, options) {
        if (this.parent) { illegalChildOperation('optionsForType'); }

        this._typeOptions.set(type, options);
      },

      
      options: function(type, options) {
        this.optionsForType(type, options);
      },

      
      typeInjection: function(type, property, fullName) {
        Ember.assert('fullName must be a proper full name', validateFullName(fullName));
        if (this.parent) { illegalChildOperation('typeInjection'); }

        var fullNameType = fullName.split(':')[0];
        if(fullNameType === type) {
          throw new Error('Cannot inject a `' + fullName + '` on other ' + type + '(s). Register the `' + fullName + '` as a different type and perform the typeInjection.');
        }
        addTypeInjection(this.typeInjections, type, property, fullName);
      },

      
      injection: function(fullName, property, injectionName) {
        if (this.parent) { illegalChildOperation('injection'); }

        validateFullName(injectionName);
        var normalizedInjectionName = this.normalize(injectionName);

        if (fullName.indexOf(':') === -1) {
          return this.typeInjection(fullName, property, normalizedInjectionName);
        }

        Ember.assert('fullName must be a proper full name', validateFullName(fullName));
        var normalizedName = this.normalize(fullName);

        if (this.cache.has(normalizedName)) {
          throw new Error("Attempted to register an injection for a type that has already been looked up. ('" + normalizedName + "', '" + property + "', '" + injectionName + "')");
        }
        addInjection(this.injections, normalizedName, property, normalizedInjectionName);
      },


      
      factoryTypeInjection: function(type, property, fullName) {
        if (this.parent) { illegalChildOperation('factoryTypeInjection'); }

        addTypeInjection(this.factoryTypeInjections, type, property, this.normalize(fullName));
      },

      
      factoryInjection: function(fullName, property, injectionName) {
        if (this.parent) { illegalChildOperation('injection'); }

        var normalizedName = this.normalize(fullName);
        var normalizedInjectionName = this.normalize(injectionName);

        validateFullName(injectionName);

        if (fullName.indexOf(':') === -1) {
          return this.factoryTypeInjection(normalizedName, property, normalizedInjectionName);
        }

        Ember.assert('fullName must be a proper full name', validateFullName(fullName));

        if (this.factoryCache.has(normalizedName)) {
          throw new Error('Attempted to register a factoryInjection for a type that has already ' +
            'been looked up. (\'' + normalizedName + '\', \'' + property + '\', \'' + injectionName + '\')');
        }

        addInjection(this.factoryInjections, normalizedName, property, normalizedInjectionName);
      },

      
      destroy: function() {
        for (var i = 0, length = this.children.length; i < length; i++) {
          this.children[i].destroy();
        }

        this.children = [];

        eachDestroyable(this, function(item) {
          item.destroy();
        });

        this.parent = undefined;
        this.isDestroyed = true;
      },

      
      reset: function() {
        for (var i = 0, length = this.children.length; i < length; i++) {
          resetCache(this.children[i]);
        }

        resetCache(this);
      }
    };

    function resolve(container, normalizedName) {
      var cached = container.resolveCache.get(normalizedName);
      if (cached) { return cached; }

      var resolved = container.resolver(normalizedName) || container.registry.get(normalizedName);
      container.resolveCache.set(normalizedName, resolved);

      return resolved;
    }

    function has(container, fullName){
      if (container.cache.has(fullName)) {
        return true;
      }

      return !!container.resolve(fullName);
    }

    function lookup(container, fullName, options) {
      options = options || {};

      if (container.cache.has(fullName) && options.singleton !== false) {
        return container.cache.get(fullName);
      }

      var value = instantiate(container, fullName);

      if (value === undefined) { return; }

      if (isSingleton(container, fullName) && options.singleton !== false) {
        container.cache.set(fullName, value);
      }

      return value;
    }

    function illegalChildOperation(operation) {
      throw new Error(operation + ' is not currently supported on child containers');
    }

    function isSingleton(container, fullName) {
      var singleton = option(container, fullName, 'singleton');

      return singleton !== false;
    }

    function buildInjections(container, injections) {
      var hash = {};

      if (!injections) { return hash; }

      var injection, injectable;

      for (var i = 0, length = injections.length; i < length; i++) {
        injection = injections[i];
        injectable = lookup(container, injection.fullName);

        if (injectable !== undefined) {
          hash[injection.property] = injectable;
        } else {
          throw new Error('Attempting to inject an unknown injection: `' + injection.fullName + '`');
        }
      }

      return hash;
    }

    function option(container, fullName, optionName) {
      var options = container._options.get(fullName);

      if (options && options[optionName] !== undefined) {
        return options[optionName];
      }

      var type = fullName.split(':')[0];
      options = container._typeOptions.get(type);

      if (options) {
        return options[optionName];
      }
    }

    function factoryFor(container, fullName) {
      var cache = container.factoryCache;
      if (cache.has(fullName)) {
        return cache.get(fullName);
      }
      var factory = container.resolve(fullName);
      if (factory === undefined) { return; }

      var type = fullName.split(':')[0];
      if (!factory || typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
        // TODO: think about a 'safe' merge style extension
        // for now just fallback to create time injection
        return factory;
      } else {
        var injections = injectionsFor(container, fullName);
        var factoryInjections = factoryInjectionsFor(container, fullName);

        factoryInjections._toString = container.makeToString(factory, fullName);

        var injectedFactory = factory.extend(injections);
        injectedFactory.reopenClass(factoryInjections);

        cache.set(fullName, injectedFactory);

        return injectedFactory;
      }
    }

    function injectionsFor(container, fullName) {
      var splitName = fullName.split(':'),
        type = splitName[0],
        injections = [];

      injections = injections.concat(container.typeInjections.get(type) || []);
      injections = injections.concat(container.injections[fullName] || []);

      injections = buildInjections(container, injections);
      injections._debugContainerKey = fullName;
      injections.container = container;

      return injections;
    }

    function factoryInjectionsFor(container, fullName) {
      var splitName = fullName.split(':'),
        type = splitName[0],
        factoryInjections = [];

      factoryInjections = factoryInjections.concat(container.factoryTypeInjections.get(type) || []);
      factoryInjections = factoryInjections.concat(container.factoryInjections[fullName] || []);

      factoryInjections = buildInjections(container, factoryInjections);
      factoryInjections._debugContainerKey = fullName;

      return factoryInjections;
    }

    function instantiate(container, fullName) {
      var factory = factoryFor(container, fullName);

      if (option(container, fullName, 'instantiate') === false) {
        return factory;
      }

      if (factory) {
        if (typeof factory.create !== 'function') {
          throw new Error('Failed to create an instance of \'' + fullName + '\'. ' +
            'Most likely an improperly defined class or an invalid module export.');
        }

        if (typeof factory.extend === 'function') {
          // assume the factory was extendable and is already injected
          return factory.create();
        } else {
          // assume the factory was extendable
          // to create time injections
          // TODO: support new'ing for instantiation and merge injections for pure JS Functions
          return factory.create(injectionsFor(container, fullName));
        }
      }
    }

    function eachDestroyable(container, callback) {
      container.cache.eachLocal(function(key, value) {
        if (option(container, key, 'instantiate') === false) { return; }
        callback(value);
      });
    }

    function resetCache(container) {
      container.cache.eachLocal(function(key, value) {
        if (option(container, key, 'instantiate') === false) { return; }
        value.destroy();
      });
      container.cache.dict = {};
    }

    function addTypeInjection(rules, type, property, fullName) {
      var injections = rules.get(type);

      if (!injections) {
        injections = [];
        rules.set(type, injections);
      }

      injections.push({
        property: property,
        fullName: fullName
      });
    }

    var VALID_FULL_NAME_REGEXP = /^[^:]+.+:[^:]+$/;
    function validateFullName(fullName) {
      if (!VALID_FULL_NAME_REGEXP.test(fullName)) {
        throw new TypeError('Invalid Fullname, expected: `type:name` got: ' + fullName);
      }
      return true;
    }

    function addInjection(rules, factoryName, property, injectionName) {
      var injections = rules[factoryName] = rules[factoryName] || [];
      injections.push({ property: property, fullName: injectionName });
    }

    __exports__["default"] = Container;
  });
define("container/inheriting_dict",
  ["exports"],
  function(__exports__) {
    "use strict";
    // A safe and simple inheriting object.
    function InheritingDict(parent) {
      this.parent = parent;
      this.dict = {};
    }

    InheritingDict.prototype = {

      

      parent: null,

      
      dict: null,

      
      get: function(key) {
        var dict = this.dict;

        if (dict.hasOwnProperty(key)) {
          return dict[key];
        }

        if (this.parent) {
          return this.parent.get(key);
        }
      },

      
      set: function(key, value) {
        this.dict[key] = value;
      },

      
      remove: function(key) {
        delete this.dict[key];
      },

      
      has: function(key) {
        var dict = this.dict;

        if (dict.hasOwnProperty(key)) {
          return true;
        }

        if (this.parent) {
          return this.parent.has(key);
        }

        return false;
      },

      
      eachLocal: function(callback, binding) {
        var dict = this.dict;

        for (var prop in dict) {
          if (dict.hasOwnProperty(prop)) {
            callback.call(binding, prop, dict[prop]);
          }
        }
      }
    };

    __exports__["default"] = InheritingDict;
  });
define("ember-application",
  ["ember-metal/core","ember-runtime/system/lazy_load","ember-application/system/dag","ember-application/system/resolver","ember-application/system/application","ember-application/ext/controller"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var runLoadHooks = __dependency2__.runLoadHooks;

    

    var DAG = __dependency3__["default"];
    var Resolver = __dependency4__.Resolver;
    var DefaultResolver = __dependency4__["default"];
    var Application = __dependency5__["default"];
    // side effect of extending ControllerMixin

    Ember.Application = Application;
    Ember.DAG = DAG;
    Ember.Resolver = Resolver;
    Ember.DefaultResolver = DefaultResolver;

    runLoadHooks('Ember.Application', Application);
  });
define("ember-application/ext/controller",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/error","ember-metal/utils","ember-metal/computed","ember-runtime/mixins/controller","ember-routing/system/controller_for","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.assert
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var EmberError = __dependency4__["default"];
    var inspect = __dependency5__.inspect;
    var computed = __dependency6__.computed;
    var ControllerMixin = __dependency7__["default"];
    var meta = __dependency5__.meta;
    var controllerFor = __dependency8__["default"];

    function verifyNeedsDependencies(controller, container, needs) {
      var dependency, i, l, missing = [];

      for (i=0, l=needs.length; i<l; i++) {
        dependency = needs[i];

        Ember.assert(inspect(controller) + "#needs must not specify dependencies with periods in their names (" + dependency + ")", dependency.indexOf('.') === -1);

        if (dependency.indexOf(':') === -1) {
          dependency = "controller:" + dependency;
        }

        // Structure assert to still do verification but not string concat in production
        if (!container.has(dependency)) {
          missing.push(dependency);
        }
      }
      if (missing.length) {
        throw new EmberError(inspect(controller) + " needs [ " + missing.join(', ') + " ] but " + (missing.length > 1 ? 'they' : 'it') + " could not be found");
      }
    }

    var defaultControllersComputedProperty = computed(function() {
      var controller = this;

      return {
        needs: get(controller, 'needs'),
        container: get(controller, 'container'),
        unknownProperty: function(controllerName) {
          var needs = this.needs,
            dependency, i, l;
          for (i=0, l=needs.length; i<l; i++) {
            dependency = needs[i];
            if (dependency === controllerName) {
              return this.container.lookup('controller:' + controllerName);
            }
          }

          var errorMessage = inspect(controller) + '#needs does not include `' + controllerName + '`. To access the ' + controllerName + ' controller from ' + inspect(controller) + ', ' + inspect(controller) + ' should have a `needs` property that is an array of the controllers it has access to.';
          throw new ReferenceError(errorMessage);
        },
        setUnknownProperty: function (key, value) {
          throw new Error("You cannot overwrite the value of `controllers." + key + "` of " + inspect(controller));
        }
      };
    });

    
    ControllerMixin.reopen({
      concatenatedProperties: ['needs'],

      
      needs: [],

      init: function() {
        var needs = get(this, 'needs');
        var length = get(needs, 'length');

        if (length > 0) {
          Ember.assert(' `' + inspect(this) + ' specifies `needs`, but does ' +
                       "not have a container. Please ensure this controller was " +
                       "instantiated with a container.",
                       this.container || meta(this, false).descs.controllers !== defaultControllersComputedProperty);

          if (this.container) {
            verifyNeedsDependencies(this, this.container, needs);
          }

          // if needs then initialize controllers proxy
          get(this, 'controllers');
        }

        this._super.apply(this, arguments);
      },

      
      controllerFor: function(controllerName) {
        Ember.deprecate("Controller#controllerFor is deprecated, please use Controller#needs instead");
        return controllerFor(get(this, 'container'), controllerName);
      },

      
      controllers: defaultControllersComputedProperty
    });

    __exports__["default"] = ControllerMixin;
  });
define("ember-application/system/application",
  ["ember-metal","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/lazy_load","ember-application/system/dag","ember-runtime/system/namespace","ember-runtime/mixins/deferred","ember-application/system/resolver","ember-metal/platform","ember-metal/run_loop","ember-metal/utils","container/container","ember-runtime/controllers/controller","ember-metal/enumerable_utils","ember-runtime/controllers/object_controller","ember-runtime/controllers/array_controller","ember-views/system/event_dispatcher","ember-views/system/jquery","ember-routing/system/route","ember-routing/system/router","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/location/none_location","ember-routing/system/cache","ember-metal/core","ember-handlebars-compiler","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __dependency27__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.FEATURES, Ember.deprecate, Ember.assert, Ember.libraries, LOG_VERSION, Namespace, BOOTED
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var runLoadHooks = __dependency4__.runLoadHooks;
    var DAG = __dependency5__["default"];
    var Namespace = __dependency6__["default"];
    var DeferredMixin = __dependency7__["default"];
    var DefaultResolver = __dependency8__["default"];
    var create = __dependency9__.create;
    var run = __dependency10__["default"];
    var canInvoke = __dependency11__.canInvoke;
    var Container = __dependency12__["default"];
    var Controller = __dependency13__["default"];
    var EnumerableUtils = __dependency14__["default"];
    var ObjectController = __dependency15__["default"];
    var ArrayController = __dependency16__["default"];
    var EventDispatcher = __dependency17__["default"];
    //import ContainerDebugAdapter from "ember-extension-support/container_debug_adapter";
    var jQuery = __dependency18__["default"];
    var Route = __dependency19__["default"];
    var Router = __dependency20__["default"];
    var HashLocation = __dependency21__["default"];
    var HistoryLocation = __dependency22__["default"];
    var AutoLocation = __dependency23__["default"];
    var NoneLocation = __dependency24__["default"];
    var BucketCache = __dependency25__["default"];

    var K = __dependency26__.K;
    var EmberHandlebars = __dependency27__["default"];

    var ContainerDebugAdapter;

    

    var Application = Namespace.extend(DeferredMixin, {
      _suppressDeferredDeprecation: true,

      
      rootElement: 'body',

      
      eventDispatcher: null,

      
      customEvents: null,

      // Start off the number of deferrals at 1. This will be
      // decremented by the Application's own `initialize` method.
      _readinessDeferrals: 1,

      init: function() {
        if (!this.$) { this.$ = jQuery; }
        this.__container__ = this.buildContainer();

        this.Router = this.defaultRouter();

        this._super();

        this.scheduleInitialize();

        Ember.libraries.registerCoreLibrary('Handlebars', EmberHandlebars.VERSION);
        Ember.libraries.registerCoreLibrary('jQuery', jQuery().jquery);

        if ( Ember.LOG_VERSION ) {
          Ember.LOG_VERSION = false; // we only need to see this once per Application#init

          var nameLengths = EnumerableUtils.map(Ember.libraries, function(item) {
            return get(item, "name.length");
          });

          var maxNameLength = Math.max.apply(this, nameLengths);

          Ember.debug('-------------------------------');
          Ember.libraries.each(function(name, version) {
            var spaces = new Array(maxNameLength - name.length + 1).join(" ");
            Ember.debug([name, spaces, ' : ', version].join(""));
          });
          Ember.debug('-------------------------------');
        }
      },

      
      buildContainer: function() {
        var container = this.__container__ = Application.buildContainer(this);

        return container;
      },

      

      defaultRouter: function() {
        if (this.Router === false) { return; }
        var container = this.__container__;

        if (this.Router) {
          container.unregister('router:main');
          container.register('router:main', this.Router);
        }

        return container.lookupFactory('router:main');
      },

      
      scheduleInitialize: function() {
        var self = this;

        if (!this.$ || this.$.isReady) {
          run.schedule('actions', self, '_initialize');
        } else {
          this.$().ready(function runInitialize() {
            run(self, '_initialize');
          });
        }
      },

      
      deferReadiness: function() {
        Ember.assert("You must call deferReadiness on an instance of Ember.Application", this instanceof Application);
        Ember.assert("You cannot defer readiness since the `ready()` hook has already been called.", this._readinessDeferrals > 0);
        this._readinessDeferrals++;
      },

      
      advanceReadiness: function() {
        Ember.assert("You must call advanceReadiness on an instance of Ember.Application", this instanceof Application);
        this._readinessDeferrals--;

        if (this._readinessDeferrals === 0) {
          run.once(this, this.didBecomeReady);
        }
      },

      
      register: function() {
        var container = this.__container__;
        container.register.apply(container, arguments);
      },

      
      inject: function() {
        var container = this.__container__;
        container.injection.apply(container, arguments);
      },

      
      initialize: function() {
        Ember.deprecate('Calling initialize manually is not supported. Please see Ember.Application#advanceReadiness and Ember.Application#deferReadiness');
      },

      
      _initialize: function() {
        if (this.isDestroyed) { return; }

        // At this point, the App.Router must already be assigned
        if (this.Router) {
          var container = this.__container__;
          container.unregister('router:main');
          container.register('router:main', this.Router);
        }

        this.runInitializers();
        runLoadHooks('application', this);

        // At this point, any initializers or load hooks that would have wanted
        // to defer readiness have fired. In general, advancing readiness here
        // will proceed to didBecomeReady.
        this.advanceReadiness();

        return this;
      },

      
      reset: function() {
        this._readinessDeferrals = 1;

        function handleReset() {
          var router = this.__container__.lookup('router:main');
          router.reset();

          run(this.__container__, 'destroy');

          this.buildContainer();

          run.schedule('actions', this, function() {
            this._initialize();
          });
        }

        run.join(this, handleReset);
      },

      
      runInitializers: function() {
        var initializers = get(this.constructor, 'initializers');
        var container = this.__container__;
        var graph = new DAG();
        var namespace = this;
        var name, initializer;

        for (name in initializers) {
          initializer = initializers[name];
          graph.addEdges(initializer.name, initializer.initialize, initializer.before, initializer.after);
        }

        graph.topsort(function (vertex) {
          var initializer = vertex.value;
          Ember.assert("No application initializer named '"+vertex.name+"'", initializer);
          initializer(container, namespace);
        });
      },

      
      didBecomeReady: function() {
        this.setupEventDispatcher();
        this.ready(); // user hook
        this.startRouting();

        if (!Ember.testing) {
          // Eagerly name all classes that are already loaded
          Ember.Namespace.processAll();
          Ember.BOOTED = true;
        }

        this.resolve(this);
      },

      
      setupEventDispatcher: function() {
        var customEvents = get(this, 'customEvents');
        var rootElement = get(this, 'rootElement');
        var dispatcher = this.__container__.lookup('event_dispatcher:main');

        set(this, 'eventDispatcher', dispatcher);
        dispatcher.setup(customEvents, rootElement);
      },

      
      startRouting: function() {
        var router = this.__container__.lookup('router:main');
        if (!router) { return; }

        router.startRouting();
      },

      handleURL: function(url) {
        var router = this.__container__.lookup('router:main');

        router.handleURL(url);
      },

      
      ready: K,

      
      resolver: null,

      
      Resolver: null,

      willDestroy: function() {
        Ember.BOOTED = false;
        // Ensure deactivation of routes before objects are destroyed
        this.__container__.lookup('router:main').reset();

        this.__container__.destroy();
      },

      initializer: function(options) {
        this.constructor.initializer(options);
      },

      
      then: function() {
        Ember.deprecate('Do not use `.then` on an instance of Ember.Application.  Please use the `.ready` hook instead.');

        this._super.apply(this, arguments);
      }
    });

    Application.reopenClass({
      initializers: {},

      
      initializer: function(initializer) {
        // If this is the first initializer being added to a subclass, we are going to reopen the class
        // to make sure we have a new `initializers` object, which extends from the parent class' using
        // prototypal inheritance. Without this, attempting to add initializers to the subclass would
        // pollute the parent class as well as other subclasses.
        if (this.superclass.initializers !== undefined && this.superclass.initializers === this.initializers) {
          this.reopenClass({
            initializers: create(this.initializers)
          });
        }

        Ember.assert("The initializer '" + initializer.name + "' has already been registered", !this.initializers[initializer.name]);
        Ember.assert("An initializer cannot be registered without an initialize function", canInvoke(initializer, 'initialize'));

        this.initializers[initializer.name] = initializer;
      },

      
      buildContainer: function(namespace) {
        var container = new Container();

        container.set = set;
        container.resolver  = resolverFor(namespace);
        container.normalize = container.resolver.normalize;
        container.describe  = container.resolver.describe;
        container.makeToString = container.resolver.makeToString;

        container.optionsForType('component', { singleton: false });
        container.optionsForType('view', { singleton: false });
        container.optionsForType('template', { instantiate: false });
        container.optionsForType('helper', { instantiate: false });

        container.register('application:main', namespace, { instantiate: false });

        container.register('controller:basic', Controller, { instantiate: false });
        container.register('controller:object', ObjectController, { instantiate: false });
        container.register('controller:array', ArrayController, { instantiate: false });
        container.register('route:basic', Route, { instantiate: false });
        container.register('event_dispatcher:main', EventDispatcher);

        container.register('router:main',  Router);
        container.injection('router:main', 'namespace', 'application:main');

        container.register('location:auto', AutoLocation);
        container.register('location:hash', HashLocation);
        container.register('location:history', HistoryLocation);
        container.register('location:none', NoneLocation);

        container.injection('controller', 'target', 'router:main');
        container.injection('controller', 'namespace', 'application:main');

        container.register('-bucket-cache:main', BucketCache);
        container.injection('router', '_bucketCache', '-bucket-cache:main');
        container.injection('route',  '_bucketCache', '-bucket-cache:main');
        container.injection('controller',  '_bucketCache', '-bucket-cache:main');

        container.injection('route', 'router', 'router:main');
        container.injection('location', 'rootURL', '-location-setting:root-url');

        // DEBUGGING
        container.register('resolver-for-debugging:main', container.resolver.__resolver__, { instantiate: false });
        container.injection('container-debug-adapter:main', 'resolver', 'resolver-for-debugging:main');
        container.injection('data-adapter:main', 'containerDebugAdapter', 'container-debug-adapter:main');
        // Custom resolver authors may want to register their own ContainerDebugAdapter with this key

        // ES6TODO: resolve this via import once ember-application package is ES6'ed
        if (!ContainerDebugAdapter) { ContainerDebugAdapter = requireModule('ember-extension-support/container_debug_adapter')['default']; }
        container.register('container-debug-adapter:main', ContainerDebugAdapter);

        return container;
      }
    });

    
    function resolverFor(namespace) {
      if (namespace.get('resolver')) {
        Ember.deprecate('Application.resolver is deprecated in favor of Application.Resolver', false);
      }

      var ResolverClass = namespace.get('resolver') || namespace.get('Resolver') || DefaultResolver;
      var resolver = ResolverClass.create({
        namespace: namespace
      });

      function resolve(fullName) {
        return resolver.resolve(fullName);
      }

      resolve.describe = function(fullName) {
        return resolver.lookupDescription(fullName);
      };

      resolve.makeToString = function(factory, fullName) {
        return resolver.makeToString(factory, fullName);
      };

      resolve.normalize = function(fullName) {
        if (resolver.normalize) {
          return resolver.normalize(fullName);
        } else {
          Ember.deprecate('The Resolver should now provide a \'normalize\' function', false);
          return fullName;
        }
      };

      resolve.__resolver__ = resolver;

      return resolve;
    }

    __exports__["default"] = Application;
  });
define("ember-application/system/dag",
  ["ember-metal/error","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var EmberError = __dependency1__["default"];

    function visit(vertex, fn, visited, path) {
      var name = vertex.name;
      var vertices = vertex.incoming;
      var names = vertex.incomingNames;
      var len = names.length;
      var i;

      if (!visited) {
        visited = {};
      }
      if (!path) {
        path = [];
      }
      if (visited.hasOwnProperty(name)) {
        return;
      }
      path.push(name);
      visited[name] = true;
      for (i = 0; i < len; i++) {
        visit(vertices[names[i]], fn, visited, path);
      }
      fn(vertex, path);
      path.pop();
    }


    
    function DAG() {
      this.names = [];
      this.vertices = {};
    }

    
    DAG.prototype.add = function(name) {
      if (!name) { return; }
      if (this.vertices.hasOwnProperty(name)) {
        return this.vertices[name];
      }
      var vertex = {
        name: name, incoming: {}, incomingNames: [], hasOutgoing: false, value: null
      };
      this.vertices[name] = vertex;
      this.names.push(name);
      return vertex;
    };

    
    DAG.prototype.map = function(name, value) {
      this.add(name).value = value;
    };

    
    DAG.prototype.addEdge = function(fromName, toName) {
      if (!fromName || !toName || fromName === toName) {
        return;
      }
      var from = this.add(fromName), to = this.add(toName);
      if (to.incoming.hasOwnProperty(fromName)) {
        return;
      }
      function checkCycle(vertex, path) {
        if (vertex.name === toName) {
          throw new EmberError("cycle detected: " + toName + " <- " + path.join(" <- "));
        }
      }
      visit(from, checkCycle);
      from.hasOutgoing = true;
      to.incoming[fromName] = from;
      to.incomingNames.push(fromName);
    };

    
    DAG.prototype.topsort = function(fn) {
      var visited = {};
      var vertices = this.vertices;
      var names = this.names;
      var len = names.length;
      var i, vertex;

      for (i = 0; i < len; i++) {
        vertex = vertices[names[i]];
        if (!vertex.hasOutgoing) {
          visit(vertex, fn, visited);
        }
      }
    };

    
    DAG.prototype.addEdges = function(name, value, before, after) {
      var i;
      this.map(name, value);
      if (before) {
        if (typeof before === 'string') {
          this.addEdge(name, before);
        } else {
          for (i = 0; i < before.length; i++) {
            this.addEdge(name, before[i]);
          }
        }
      }
      if (after) {
        if (typeof after === 'string') {
          this.addEdge(after, name);
        } else {
          for (i = 0; i < after.length; i++) {
            this.addEdge(after[i], name);
          }
        }
      }
    };

    __exports__["default"] = DAG;
  });
define("ember-application/system/resolver",
  ["ember-metal/core","ember-metal/property_get","ember-metal/logger","ember-runtime/system/string","ember-runtime/system/object","ember-runtime/system/namespace","ember-handlebars","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.TEMPLATES, Ember.assert
    var get = __dependency2__.get;
    var Logger = __dependency3__["default"];
    var classify = __dependency4__.classify;
    var capitalize = __dependency4__.capitalize;
    var decamelize = __dependency4__.decamelize;
    var EmberObject = __dependency5__["default"];
    var Namespace = __dependency6__["default"];
    var EmberHandlebars = __dependency7__["default"];

    var Resolver = EmberObject.extend({
      
      namespace: null,
      normalize:         Ember.required(Function),
      resolve:           Ember.required(Function),
      parseName:         Ember.required(Function),
      lookupDescription: Ember.required(Function),
      makeToString:      Ember.required(Function),
      resolveOther:      Ember.required(Function),
      _logLookup:        Ember.required(Function)
    });
    __exports__.Resolver = Resolver;
    

    __exports__["default"] = EmberObject.extend({
      
      namespace: null,

      normalize: function(fullName) {
        var split = fullName.split(':', 2),
            type = split[0],
            name = split[1];

        Ember.assert("Tried to normalize a container name without a colon (:) in it. You probably tried to lookup a name that did not contain a type, a colon, and a name. A proper lookup name would be `view:post`.", split.length === 2);

        if (type !== 'template') {
          var result = name;

          if (result.indexOf('.') > -1) {
            result = result.replace(/\.(.)/g, function(m) { return m.charAt(1).toUpperCase(); });
          }

          if (name.indexOf('_') > -1) {
            result = result.replace(/_(.)/g, function(m) { return m.charAt(1).toUpperCase(); });
          }

          return type + ':' + result;
        } else {
          return fullName;
        }
      },


      
      resolve: function(fullName) {
        var parsedName = this.parseName(fullName),
            resolveMethodName = parsedName.resolveMethodName,
            resolved;

        if (!(parsedName.name && parsedName.type)) {
          throw new TypeError('Invalid fullName: `' + fullName + '`, must be of the form `type:name` ');
        }

        if (this[resolveMethodName]) {
          resolved = this[resolveMethodName](parsedName);
        }

        if (!resolved) {
          resolved = this.resolveOther(parsedName);
        }

        if (parsedName.root && parsedName.root.LOG_RESOLVER) {
          this._logLookup(resolved, parsedName);
        }

        return resolved;
      },
      
      parseName: function(fullName) {
        var nameParts = fullName.split(':'),
            type = nameParts[0], fullNameWithoutType = nameParts[1],
            name = fullNameWithoutType,
            namespace = get(this, 'namespace'),
            root = namespace;

        if (type !== 'template' && name.indexOf('/') !== -1) {
          var parts = name.split('/');
          name = parts[parts.length - 1];
          var namespaceName = capitalize(parts.slice(0, -1).join('.'));
          root = Namespace.byName(namespaceName);

          Ember.assert('You are looking for a ' + name + ' ' + type + ' in the ' + namespaceName + ' namespace, but the namespace could not be found', root);
        }

        return {
          fullName: fullName,
          type: type,
          fullNameWithoutType: fullNameWithoutType,
          name: name,
          root: root,
          resolveMethodName: 'resolve' + classify(type)
        };
      },

      
      lookupDescription: function(fullName) {
        var parsedName = this.parseName(fullName);

        if (parsedName.type === 'template') {
          return 'template at ' + parsedName.fullNameWithoutType.replace(/\./g, '/');
        }

        var description = parsedName.root + '.' + classify(parsedName.name);
        if (parsedName.type !== 'model') { description += classify(parsedName.type); }

        return description;
      },

      makeToString: function(factory, fullName) {
        return factory.toString();
      },
      
      useRouterNaming: function(parsedName) {
        parsedName.name = parsedName.name.replace(/\./g, '_');
        if (parsedName.name === 'basic') {
          parsedName.name = '';
        }
      },
      
      resolveTemplate: function(parsedName) {
        var templateName = parsedName.fullNameWithoutType.replace(/\./g, '/');

        if (Ember.TEMPLATES[templateName]) {
          return Ember.TEMPLATES[templateName];
        }

        templateName = decamelize(templateName);
        if (Ember.TEMPLATES[templateName]) {
          return Ember.TEMPLATES[templateName];
        }
      },
      
      resolveView: function(parsedName) {
        this.useRouterNaming(parsedName);
        return this.resolveOther(parsedName);
      },
      
      resolveController: function(parsedName) {
        this.useRouterNaming(parsedName);
        return this.resolveOther(parsedName);
      },
      
      resolveRoute: function(parsedName) {
        this.useRouterNaming(parsedName);
        return this.resolveOther(parsedName);
      },

      
      resolveModel: function(parsedName) {
        var className = classify(parsedName.name);
        var factory = get(parsedName.root, className);

         if (factory) { return factory; }
      },
      
      resolveHelper: function(parsedName) {
        return this.resolveOther(parsedName) || EmberHandlebars.helpers[parsedName.fullNameWithoutType];
      },
      
      resolveOther: function(parsedName) {
        var className = classify(parsedName.name) + classify(parsedName.type);
        var factory = get(parsedName.root, className);
        if (factory) { return factory; }
      },

      
      _logLookup: function(found, parsedName) {
        var symbol, padding;

        if (found) { symbol = '[✓]'; }
        else       { symbol = '[ ]'; }

        if (parsedName.fullName.length > 60) {
          padding = '.';
        } else {
          padding = new Array(60 - parsedName.fullName.length).join('.');
        }

        Logger.info(symbol, parsedName.fullName, padding, this.lookupDescription(parsedName.fullName));
      }
    });
  });
define("ember-debug",
  ["ember-metal/core","ember-metal/error","ember-metal/logger"],
  function(__dependency1__, __dependency2__, __dependency3__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    var EmberError = __dependency2__["default"];
    var Logger = __dependency3__["default"];

    

    

    
    Ember.assert = function(desc, test) {
      if (!test) {
        throw new EmberError("Assertion Failed: " + desc);
      }
    };


    
    Ember.warn = function(message, test) {
      if (!test) {
        Logger.warn("WARNING: "+message);
        if ('trace' in Logger) Logger.trace();
      }
    };

    
    Ember.debug = function(message) {
      Logger.debug("DEBUG: "+message);
    };

    
    Ember.deprecate = function(message, test) {
      if (test) { return; }

      if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new EmberError(message); }

      var error;

      // When using new Error, we can't do the arguments check for Chrome. Alternatives are welcome
      try { __fail__.fail(); } catch (e) { error = e; }

      if (Ember.LOG_STACKTRACE_ON_DEPRECATION && error.stack) {
        var stack, stackStr = '';
        if (error['arguments']) {
          // Chrome
          stack = error.stack.replace(/^\s+at\s+/gm, '').
                              replace(/^([^\(]+?)([\n$])/gm, '{anonymous}($1)$2').
                              replace(/^Object.<anonymous>\s*\(([^\)]+)\)/gm, '{anonymous}($1)').split('\n');
          stack.shift();
        } else {
          // Firefox
          stack = error.stack.replace(/(?:\n@:0)?\s+$/m, '').
                              replace(/^\(/gm, '{anonymous}(').split('\n');
        }

        stackStr = "\n    " + stack.slice(2).join("\n    ");
        message = message + stackStr;
      }

      Logger.warn("DEPRECATION: "+message);
    };



    
    Ember.deprecateFunc = function(message, func) {
      return function() {
        Ember.deprecate(message);
        return func.apply(this, arguments);
      };
    };


    
    Ember.runInDebug = function(func) {
      func();
    };

    // Inform the developer about the Ember Inspector if not installed.
    if (!Ember.testing) {
      var isFirefox = typeof InstallTrigger !== 'undefined';
      var isChrome = !!window.chrome && !window.opera;

      if (typeof window !== 'undefined' && (isFirefox || isChrome) && window.addEventListener) {
        window.addEventListener("load", function() {
          if (document.documentElement && document.documentElement.dataset && !document.documentElement.dataset.emberExtension) {
            var downloadURL;

            if(isChrome) {
              downloadURL = 'https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi';
            } else if(isFirefox) {
              downloadURL = 'https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/';
            }

            Ember.debug('For more advanced debugging, install the Ember Inspector from ' + downloadURL);
          }
        }, false);
      }
    }
  });
define("ember-extension-support",
  ["ember-metal/core","ember-extension-support/data_adapter","ember-extension-support/container_debug_adapter"],
  function(__dependency1__, __dependency2__, __dependency3__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    var DataAdapter = __dependency2__["default"];
    var ContainerDebugAdapter = __dependency3__["default"];

    Ember.DataAdapter = DataAdapter;
    Ember.ContainerDebugAdapter = ContainerDebugAdapter;
  });
define("ember-extension-support/container_debug_adapter",
  ["ember-metal/core","ember-runtime/system/native_array","ember-metal/utils","ember-runtime/system/string","ember-runtime/system/namespace","ember-runtime/system/object","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var emberA = __dependency2__.A;
    var typeOf = __dependency3__.typeOf;
    var dasherize = __dependency4__.dasherize;
    var classify = __dependency4__.classify;
    var Namespace = __dependency5__["default"];
    var EmberObject = __dependency6__["default"];

    

    
    __exports__["default"] = EmberObject.extend({
      
      container: null,

      
      resolver: null,

      
      canCatalogEntriesByType: function(type) {
        if (type === 'model' || type === 'template') return false;
        return true;
      },

      
      catalogEntriesByType: function(type) {
        var namespaces = emberA(Namespace.NAMESPACES), types = emberA(), self = this;
        var typeSuffixRegex = new RegExp(classify(type) + "$");

        namespaces.forEach(function(namespace) {
          if (namespace !== Ember) {
            for (var key in namespace) {
              if (!namespace.hasOwnProperty(key)) { continue; }
              if (typeSuffixRegex.test(key)) {
                var klass = namespace[key];
                if (typeOf(klass) === 'class') {
                  types.push(dasherize(key.replace(typeSuffixRegex, '')));
                }
              }
            }
          }
        });
        return types;
      }
    });
  });
define("ember-extension-support/data_adapter",
  ["ember-metal/core","ember-metal/property_get","ember-metal/run_loop","ember-runtime/system/string","ember-runtime/system/namespace","ember-runtime/system/object","ember-runtime/system/native_array","ember-application/system/application","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var get = __dependency2__.get;
    var run = __dependency3__["default"];
    var dasherize = __dependency4__.dasherize;
    var Namespace = __dependency5__["default"];
    var EmberObject = __dependency6__["default"];
    var emberA = __dependency7__.A;
    var Application = __dependency8__["default"];

    

    
    __exports__["default"] = EmberObject.extend({
      init: function() {
        this._super();
        this.releaseMethods = emberA();
      },

      
      container: null,


      
      containerDebugAdapter: undefined,

      
      attributeLimit: 3,

      
      releaseMethods: emberA(),

      
      getFilters: function() {
        return emberA();
      },

      
      watchModelTypes: function(typesAdded, typesUpdated) {
        var modelTypes = this.getModelTypes(),
            self = this, typesToSend, releaseMethods = emberA();

        typesToSend = modelTypes.map(function(type) {
          var klass = type.klass;
          var wrapped = self.wrapModelType(klass, type.name);
          releaseMethods.push(self.observeModelType(klass, typesUpdated));
          return wrapped;
        });

        typesAdded(typesToSend);

        var release = function() {
          releaseMethods.forEach(function(fn) { fn(); });
          self.releaseMethods.removeObject(release);
        };
        this.releaseMethods.pushObject(release);
        return release;
      },

      _nameToClass: function(type) {
        if (typeof type === 'string') {
          type = this.container.lookupFactory('model:' + type);
        }
        return type;
      },

      
      watchRecords: function(type, recordsAdded, recordsUpdated, recordsRemoved) {
        var self = this, releaseMethods = emberA(), records = this.getRecords(type), release;

        var recordUpdated = function(updatedRecord) {
          recordsUpdated([updatedRecord]);
        };

        var recordsToSend = records.map(function(record) {
          releaseMethods.push(self.observeRecord(record, recordUpdated));
          return self.wrapRecord(record);
        });


        var contentDidChange = function(array, idx, removedCount, addedCount) {
          for (var i = idx; i < idx + addedCount; i++) {
            var record = array.objectAt(i);
            var wrapped = self.wrapRecord(record);
            releaseMethods.push(self.observeRecord(record, recordUpdated));
            recordsAdded([wrapped]);
          }

          if (removedCount) {
            recordsRemoved(idx, removedCount);
          }
        };

        var observer = { didChange: contentDidChange, willChange: Ember.K };
        records.addArrayObserver(self, observer);

        release = function() {
          releaseMethods.forEach(function(fn) { fn(); });
          records.removeArrayObserver(self, observer);
          self.releaseMethods.removeObject(release);
        };

        recordsAdded(recordsToSend);

        this.releaseMethods.pushObject(release);
        return release;
      },

      
      willDestroy: function() {
        this._super();
        this.releaseMethods.forEach(function(fn) {
          fn();
        });
      },

      
      detect: function(klass) {
        return false;
      },

      
      columnsForType: function(type) {
        return emberA();
      },

      

      observeModelType: function(type, typesUpdated) {
        var self = this, records = this.getRecords(type);

        var onChange = function() {
          typesUpdated([self.wrapModelType(type)]);
        };
        var observer = {
          didChange: function() {
            run.scheduleOnce('actions', this, onChange);
          },
          willChange: Ember.K
        };

        records.addArrayObserver(this, observer);

        var release = function() {
          records.removeArrayObserver(self, observer);
        };

        return release;
      },


      
      wrapModelType: function(type, name) {
        var release, records = this.getRecords(type),
            typeToSend, self = this;

        typeToSend = {
          name: name || type.toString(),
          count: get(records, 'length'),
          columns: this.columnsForType(type),
          object: type
        };


        return typeToSend;
      },


      
      getModelTypes: function() {
        var types, self = this,
            containerDebugAdapter = this.get('containerDebugAdapter');

        if (containerDebugAdapter.canCatalogEntriesByType('model')) {
          types = containerDebugAdapter.catalogEntriesByType('model');
        } else {
          types = this._getObjectsOnNamespaces();
        }

        // New adapters return strings instead of classes
        types = emberA(types).map(function(name) {
          return {
            klass: self._nameToClass(name),
            name: name
          };
        });
        types = emberA(types).filter(function(type) {
          return self.detect(type.klass);
        });

        return emberA(types);
      },

      
      _getObjectsOnNamespaces: function() {
        var namespaces = emberA(Namespace.NAMESPACES),
            types = emberA(),
            self = this;

        namespaces.forEach(function(namespace) {
          for (var key in namespace) {
            if (!namespace.hasOwnProperty(key)) { continue; }
            // Even though we will filter again in `getModelTypes`,
            // we should not call `lookupContainer` on non-models
            // (especially when `Ember.MODEL_FACTORY_INJECTIONS` is `true`)
            if (!self.detect(namespace[key])) { continue; }
            var name = dasherize(key);
            if (!(namespace instanceof Application) && namespace.toString()) {
              name = namespace + '/' + name;
            }
            types.push(name);
          }
        });
        return types;
      },

      
      getRecords: function(type) {
        return emberA();
      },

      
      wrapRecord: function(record) {
        var recordToSend = { object: record }, columnValues = {}, self = this;

        recordToSend.columnValues = this.getRecordColumnValues(record);
        recordToSend.searchKeywords = this.getRecordKeywords(record);
        recordToSend.filterValues = this.getRecordFilterValues(record);
        recordToSend.color = this.getRecordColor(record);

        return recordToSend;
      },

      
      getRecordColumnValues: function(record) {
        return {};
      },

      
      getRecordKeywords: function(record) {
        return emberA();
      },

      
      getRecordFilterValues: function(record) {
        return {};
      },

      
      getRecordColor: function(record) {
        return null;
      },

      
      observeRecord: function(record, recordUpdated) {
        return function(){};
      }
    });
  });
define("ember-extension-support/initializers",
  [],
  function() {
    "use strict";

  });
define("ember-handlebars-compiler",
  ["ember-metal/core","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    

    

    var Ember = __dependency1__["default"];

    // ES6Todo: you'll need to import debugger once debugger is es6'd.
    if (typeof Ember.assert === 'undefined')   { Ember.assert = function(){}; }
    if (typeof Ember.FEATURES === 'undefined') { Ember.FEATURES = { isEnabled: function(){} }; }

    var objectCreate = Object.create || function(parent) {
      function F() {}
      F.prototype = parent;
      return new F();
    };

    // set up for circular references later
    var View, Component;

    // ES6Todo: when ember-debug is es6'ed import this.
    // var emberAssert = Ember.assert;
    var Handlebars = (Ember.imports && Ember.imports.Handlebars) || (this && this.Handlebars);
    if (!Handlebars && typeof require === 'function') {
      Handlebars = require('handlebars');
    }

    Ember.assert("Ember Handlebars requires Handlebars version 1.0 or 1.1. Include " +
                 "a SCRIPT tag in the HTML HEAD linking to the Handlebars file " +
                 "before you link to Ember.", Handlebars);

    Ember.assert("Ember Handlebars requires Handlebars version 1.0 or 1.1, " +
                 "COMPILER_REVISION expected: 4, got: " +  Handlebars.COMPILER_REVISION +
                 " - Please note: Builds of master may have other COMPILER_REVISION values.",
                 Handlebars.COMPILER_REVISION === 4);

    
    var EmberHandlebars = Ember.Handlebars = objectCreate(Handlebars);

    
    EmberHandlebars.helper = function(name, value) {
      if (!View) { View = requireModule('ember-views/views/view')['default']; } // ES6TODO: stupid circular dep
      if (!Component) { Component = requireModule('ember-views/views/component')['default']; } // ES6TODO: stupid circular dep

      Ember.assert("You tried to register a component named '" + name + "', but component names must include a '-'", !Component.detect(value) || name.match(/-/));

      if (View.detect(value)) {
        EmberHandlebars.registerHelper(name, EmberHandlebars.makeViewHelper(value));
      } else {
        EmberHandlebars.registerBoundHelper.apply(null, arguments);
      }
    };

    
    EmberHandlebars.makeViewHelper = function(ViewClass) {
      return function(options) {
        Ember.assert("You can only pass attributes (such as name=value) not bare values to a helper for a View found in '" + ViewClass.toString() + "'", arguments.length < 2);
        return EmberHandlebars.helpers.view.call(this, ViewClass, options);
      };
    };

    
    EmberHandlebars.helpers = objectCreate(Handlebars.helpers);

    
    EmberHandlebars.Compiler = function() {};

    // Handlebars.Compiler doesn't exist in runtime-only
    if (Handlebars.Compiler) {
      EmberHandlebars.Compiler.prototype = objectCreate(Handlebars.Compiler.prototype);
    }

    EmberHandlebars.Compiler.prototype.compiler = EmberHandlebars.Compiler;

    
    EmberHandlebars.JavaScriptCompiler = function() {};

    // Handlebars.JavaScriptCompiler doesn't exist in runtime-only
    if (Handlebars.JavaScriptCompiler) {
      EmberHandlebars.JavaScriptCompiler.prototype = objectCreate(Handlebars.JavaScriptCompiler.prototype);
      EmberHandlebars.JavaScriptCompiler.prototype.compiler = EmberHandlebars.JavaScriptCompiler;
    }


    EmberHandlebars.JavaScriptCompiler.prototype.namespace = "Ember.Handlebars";

    EmberHandlebars.JavaScriptCompiler.prototype.initializeBuffer = function() {
      return "''";
    };

    
    EmberHandlebars.JavaScriptCompiler.prototype.appendToBuffer = function(string) {
      return "data.buffer.push("+string+");";
    };

    // Hacks ahead:
    // Handlebars presently has a bug where the `blockHelperMissing` hook
    // doesn't get passed the name of the missing helper name, but rather
    // gets passed the value of that missing helper evaluated on the current
    // context, which is most likely `undefined` and totally useless.
    //
    // So we alter the compiled template function to pass the name of the helper
    // instead, as expected.
    //
    // This can go away once the following is closed:
    // https://github.com/wycats/handlebars.js/issues/634

    var DOT_LOOKUP_REGEX = /helpers\.(.*?)\)/,
        BRACKET_STRING_LOOKUP_REGEX = /helpers\['(.*?)'/,
        INVOCATION_SPLITTING_REGEX = /(.*blockHelperMissing\.call\(.*)(stack[0-9]+)(,.*)/;

    EmberHandlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation = function(source) {
      var helperInvocation = source[source.length - 1],
          helperName = (DOT_LOOKUP_REGEX.exec(helperInvocation) || BRACKET_STRING_LOOKUP_REGEX.exec(helperInvocation))[1],
          matches = INVOCATION_SPLITTING_REGEX.exec(helperInvocation);

      source[source.length - 1] = matches[1] + "'" + helperName + "'" + matches[3];
    };

    var stringifyBlockHelperMissing = EmberHandlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation;

    var originalBlockValue = EmberHandlebars.JavaScriptCompiler.prototype.blockValue;
    EmberHandlebars.JavaScriptCompiler.prototype.blockValue = function() {
      originalBlockValue.apply(this, arguments);
      stringifyBlockHelperMissing(this.source);
    };

    var originalAmbiguousBlockValue = EmberHandlebars.JavaScriptCompiler.prototype.ambiguousBlockValue;
    EmberHandlebars.JavaScriptCompiler.prototype.ambiguousBlockValue = function() {
      originalAmbiguousBlockValue.apply(this, arguments);
      stringifyBlockHelperMissing(this.source);
    };

    
    EmberHandlebars.Compiler.prototype.mustache = function(mustache) {
      if (!(mustache.params.length || mustache.hash)) {
        var id = new Handlebars.AST.IdNode([{ part: '_triageMustache' }]);

        // Update the mustache node to include a hash value indicating whether the original node
        // was escaped. This will allow us to properly escape values when the underlying value
        // changes and we need to re-render the value.
        if (!mustache.escaped) {
          mustache.hash = mustache.hash || new Handlebars.AST.HashNode([]);
          mustache.hash.pairs.push(["unescaped", new Handlebars.AST.StringNode("true")]);
        }
        mustache = new Handlebars.AST.MustacheNode([id].concat([mustache.id]), mustache.hash, !mustache.escaped);
      }

      return Handlebars.Compiler.prototype.mustache.call(this, mustache);
    };

    
    EmberHandlebars.precompile = function(string, asObject) {
      var ast = Handlebars.parse(string);

      var options = {
        knownHelpers: {
          action: true,
          unbound: true,
          'bind-attr': true,
          template: true,
          view: true,
          _triageMustache: true
        },
        data: true,
        stringParams: true
      };

      asObject = asObject === undefined ? true : asObject;

      var environment = new EmberHandlebars.Compiler().compile(ast, options);
      return new EmberHandlebars.JavaScriptCompiler().compile(environment, options, undefined, asObject);
    };

    // We don't support this for Handlebars runtime-only
    if (Handlebars.compile) {
      
      EmberHandlebars.compile = function(string) {
        var ast = Handlebars.parse(string);
        var options = { data: true, stringParams: true };
        var environment = new EmberHandlebars.Compiler().compile(ast, options);
        var templateSpec = new EmberHandlebars.JavaScriptCompiler().compile(environment, options, undefined, true);

        var template = EmberHandlebars.template(templateSpec);
        template.isMethod = false; //Make sure we don't wrap templates with ._super

        return template;
      };
    }

    __exports__["default"] = EmberHandlebars;
  });
define("ember-handlebars",
  ["ember-handlebars-compiler","ember-metal/core","ember-runtime/system/lazy_load","ember-handlebars/loader","ember-handlebars/ext","ember-handlebars/string","ember-handlebars/helpers/shared","ember-handlebars/helpers/binding","ember-handlebars/helpers/collection","ember-handlebars/helpers/view","ember-handlebars/helpers/unbound","ember-handlebars/helpers/debug","ember-handlebars/helpers/each","ember-handlebars/helpers/template","ember-handlebars/helpers/partial","ember-handlebars/helpers/yield","ember-handlebars/helpers/loc","ember-handlebars/controls/checkbox","ember-handlebars/controls/select","ember-handlebars/controls/text_area","ember-handlebars/controls/text_field","ember-handlebars/controls/text_support","ember-handlebars/controls","ember-handlebars/component_lookup","ember-handlebars/views/handlebars_bound_view","ember-handlebars/views/metamorph_view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __exports__) {
    "use strict";
    var EmberHandlebars = __dependency1__["default"];
    var Ember = __dependency2__["default"];
    // to add to globals

    var runLoadHooks = __dependency3__.runLoadHooks;
    var bootstrap = __dependency4__["default"];

    var normalizePath = __dependency5__.normalizePath;
    var template = __dependency5__.template;
    var makeBoundHelper = __dependency5__.makeBoundHelper;
    var registerBoundHelper = __dependency5__.registerBoundHelper;
    var resolveHash = __dependency5__.resolveHash;
    var resolveParams = __dependency5__.resolveParams;
    var getEscaped = __dependency5__.getEscaped;
    var handlebarsGet = __dependency5__.handlebarsGet;
    var evaluateUnboundHelper = __dependency5__.evaluateUnboundHelper;
    var helperMissingHelper = __dependency5__.helperMissingHelper;
    var blockHelperMissingHelper = __dependency5__.blockHelperMissingHelper;


    // side effect of extending StringUtils of htmlSafe

    var resolvePaths = __dependency7__["default"];
    var bind = __dependency8__.bind;
    var _triageMustacheHelper = __dependency8__._triageMustacheHelper;
    var resolveHelper = __dependency8__.resolveHelper;
    var bindHelper = __dependency8__.bindHelper;
    var boundIfHelper = __dependency8__.boundIfHelper;
    var unboundIfHelper = __dependency8__.unboundIfHelper;
    var withHelper = __dependency8__.withHelper;
    var ifHelper = __dependency8__.ifHelper;
    var unlessHelper = __dependency8__.unlessHelper;
    var bindAttrHelper = __dependency8__.bindAttrHelper;
    var bindAttrHelperDeprecated = __dependency8__.bindAttrHelperDeprecated;
    var bindClasses = __dependency8__.bindClasses;

    var collectionHelper = __dependency9__["default"];
    var ViewHelper = __dependency10__.ViewHelper;
    var viewHelper = __dependency10__.viewHelper;
    var unboundHelper = __dependency11__["default"];
    var logHelper = __dependency12__.logHelper;
    var debuggerHelper = __dependency12__.debuggerHelper;
    var EachView = __dependency13__.EachView;
    var GroupedEach = __dependency13__.GroupedEach;
    var eachHelper = __dependency13__.eachHelper;
    var templateHelper = __dependency14__["default"];
    var partialHelper = __dependency15__["default"];
    var yieldHelper = __dependency16__["default"];
    var locHelper = __dependency17__["default"];


    var Checkbox = __dependency18__["default"];
    var Select = __dependency19__.Select;
    var SelectOption = __dependency19__.SelectOption;
    var SelectOptgroup = __dependency19__.SelectOptgroup;
    var TextArea = __dependency20__["default"];
    var TextField = __dependency21__["default"];
    var TextSupport = __dependency22__["default"];
    var inputHelper = __dependency23__.inputHelper;
    var textareaHelper = __dependency23__.textareaHelper;


    var ComponentLookup = __dependency24__["default"];
    var _HandlebarsBoundView = __dependency25__._HandlebarsBoundView;
    var SimpleHandlebarsView = __dependency25__.SimpleHandlebarsView;
    var _wrapMap = __dependency26__._wrapMap;
    var _SimpleMetamorphView = __dependency26__._SimpleMetamorphView;
    var _MetamorphView = __dependency26__._MetamorphView;
    var _Metamorph = __dependency26__._Metamorph;


    

    // Ember.Handlebars.Globals
    EmberHandlebars.bootstrap = bootstrap;
    EmberHandlebars.template = template;
    EmberHandlebars.makeBoundHelper = makeBoundHelper;
    EmberHandlebars.registerBoundHelper = registerBoundHelper;
    EmberHandlebars.resolveHash = resolveHash;
    EmberHandlebars.resolveParams = resolveParams;
    EmberHandlebars.resolveHelper = resolveHelper;
    EmberHandlebars.get = handlebarsGet;
    EmberHandlebars.getEscaped = getEscaped;
    EmberHandlebars.evaluateUnboundHelper = evaluateUnboundHelper;
    EmberHandlebars.bind = bind;
    EmberHandlebars.bindClasses = bindClasses;
    EmberHandlebars.EachView = EachView;
    EmberHandlebars.GroupedEach = GroupedEach;
    EmberHandlebars.resolvePaths = resolvePaths;
    EmberHandlebars.ViewHelper = ViewHelper;
    EmberHandlebars.normalizePath = normalizePath;


    // Ember Globals
    Ember.Handlebars = EmberHandlebars;
    Ember.ComponentLookup = ComponentLookup;
    Ember._SimpleHandlebarsView = SimpleHandlebarsView;
    Ember._HandlebarsBoundView = _HandlebarsBoundView;
    Ember._SimpleMetamorphView = _SimpleMetamorphView;
    Ember._MetamorphView = _MetamorphView;
    Ember._Metamorph = _Metamorph;
    Ember._metamorphWrapMap = _wrapMap;
    Ember.TextSupport = TextSupport;
    Ember.Checkbox = Checkbox;
    Ember.Select = Select;
    Ember.SelectOption = SelectOption;
    Ember.SelectOptgroup = SelectOptgroup;
    Ember.TextArea = TextArea;
    Ember.TextField = TextField;
    Ember.TextSupport = TextSupport;

    // register helpers
    EmberHandlebars.registerHelper('helperMissing', helperMissingHelper);
    EmberHandlebars.registerHelper('blockHelperMissing', blockHelperMissingHelper);
    EmberHandlebars.registerHelper('bind', bindHelper);
    EmberHandlebars.registerHelper('boundIf', boundIfHelper);
    EmberHandlebars.registerHelper('_triageMustache', _triageMustacheHelper);
    EmberHandlebars.registerHelper('unboundIf', unboundIfHelper);
    EmberHandlebars.registerHelper('with', withHelper);
    EmberHandlebars.registerHelper('if', ifHelper);
    EmberHandlebars.registerHelper('unless', unlessHelper);
    EmberHandlebars.registerHelper('bind-attr', bindAttrHelper);
    EmberHandlebars.registerHelper('bindAttr', bindAttrHelperDeprecated);
    EmberHandlebars.registerHelper('collection', collectionHelper);
    EmberHandlebars.registerHelper("log", logHelper);
    EmberHandlebars.registerHelper("debugger", debuggerHelper);
    EmberHandlebars.registerHelper("each", eachHelper);
    EmberHandlebars.registerHelper("loc", locHelper);
    EmberHandlebars.registerHelper("partial", partialHelper);
    EmberHandlebars.registerHelper("template", templateHelper);
    EmberHandlebars.registerHelper("yield", yieldHelper);
    EmberHandlebars.registerHelper("view", viewHelper);
    EmberHandlebars.registerHelper("unbound", unboundHelper);
    EmberHandlebars.registerHelper("input", inputHelper);
    EmberHandlebars.registerHelper("textarea", textareaHelper);

    // run load hooks
    runLoadHooks('Ember.Handlebars', EmberHandlebars);

    __exports__["default"] = EmberHandlebars;
  });
define("ember-handlebars/component_lookup",
  ["ember-runtime/system/object","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var EmberObject = __dependency1__["default"];

    var ComponentLookup = EmberObject.extend({
      lookupFactory: function(name, container) {

        container = container || this.container;

        var fullName = 'component:' + name,
            templateFullName = 'template:components/' + name,
            templateRegistered = container && container.has(templateFullName);

        if (templateRegistered) {
          container.injection(fullName, 'layout', templateFullName);
        }

        var Component = container.lookupFactory(fullName);

        // Only treat as a component if either the component
        // or a template has been registered.
        if (templateRegistered || Component) {
          if (!Component) {
            container.register(fullName, Ember.Component);
            Component = container.lookupFactory(fullName);
          }
          return Component;
        }
      }
    });

    __exports__["default"] = ComponentLookup;
  });
define("ember-handlebars/controls",
  ["ember-handlebars/controls/checkbox","ember-handlebars/controls/text_field","ember-handlebars/controls/text_area","ember-metal/core","ember-handlebars-compiler","ember-handlebars/ext","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    var Checkbox = __dependency1__["default"];
    var TextField = __dependency2__["default"];
    var TextArea = __dependency3__["default"];

    var Ember = __dependency4__["default"];
    // Ember.assert
    // var emberAssert = Ember.assert;

    var EmberHandlebars = __dependency5__["default"];
    var handlebarsGet = __dependency6__.handlebarsGet;
    var helpers = EmberHandlebars.helpers;
    

    function _resolveOption(context, options, key) {
      if (options.hashTypes[key] === "ID") {
        return handlebarsGet(context, options.hash[key], options);
      } else {
        return options.hash[key];
      }
    }

    
    function inputHelper(options) {
      Ember.assert('You can only pass attributes to the `input` helper, not arguments', arguments.length < 2);

      var hash = options.hash,
          types = options.hashTypes,
          inputType = _resolveOption(this, options, 'type'),
          onEvent = hash.on;

      delete hash.type;
      delete hash.on;

      if (inputType === 'checkbox') {
        Ember.assert("{{input type='checkbox'}} does not support setting `value=someBooleanValue`; you must use `checked=someBooleanValue` instead.", options.hashTypes.value !== 'ID');
        return helpers.view.call(this, Checkbox, options);
      } else {
        if (inputType) { hash.type = inputType; }
        hash.onEvent = onEvent || 'enter';
        return helpers.view.call(this, TextField, options);
      }
    }

    __exports__.inputHelper = inputHelper;
    function textareaHelper(options) {
      Ember.assert('You can only pass attributes to the `textarea` helper, not arguments', arguments.length < 2);

      var hash = options.hash,
          types = options.hashTypes;

      return helpers.view.call(this, TextArea, options);
    }

    __exports__.textareaHelper = textareaHelper;
  });
define("ember-handlebars/controls/checkbox",
  ["ember-metal/property_get","ember-metal/property_set","ember-views/views/view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var View = __dependency3__["default"];

    

    
    __exports__["default"] = View.extend({
      instrumentDisplay: '{{input type="checkbox"}}',

      classNames: ['ember-checkbox'],

      tagName: 'input',

      attributeBindings: [
        'type',
        'checked',
        'indeterminate',
        'disabled',
        'tabindex',
        'name',
        'autofocus',
        'required',
        'form'
      ],

      type: 'checkbox',
      checked: false,
      disabled: false,
      indeterminate: false,

      init: function() {
        this._super();
        this.on('change', this, this._updateElementValue);
      },

      didInsertElement: function() {
        this._super();
        get(this, 'element').indeterminate = !!get(this, 'indeterminate');
      },

      _updateElementValue: function() {
        set(this, 'checked', this.$().prop('checked'));
      }
    });
  });
define("ember-handlebars/controls/select",
  ["ember-handlebars-compiler","ember-metal/enumerable_utils","ember-metal/property_get","ember-metal/property_set","ember-views/views/view","ember-views/views/collection_view","ember-metal/utils","ember-metal/is_none","ember-metal/computed","ember-runtime/system/native_array","ember-metal/mixin","ember-metal/properties","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) {
    "use strict";
    

    var EmberHandlebars = __dependency1__["default"];

    var forEach = __dependency2__.forEach;
    var indexOf = __dependency2__.indexOf;
    var indexesOf = __dependency2__.indexesOf;
    var replace = __dependency2__.replace;

    var get = __dependency3__.get;
    var set = __dependency4__.set;
    var View = __dependency5__["default"];
    var CollectionView = __dependency6__["default"];
    var isArray = __dependency7__.isArray;
    var isNone = __dependency8__["default"];
    var computed = __dependency9__.computed;
    var emberA = __dependency10__.A;
    var observer = __dependency11__.observer;
    var defineProperty = __dependency12__.defineProperty;

    var precompileTemplate = EmberHandlebars.compile;

    var SelectOption = View.extend({
      instrumentDisplay: 'Ember.SelectOption',

      tagName: 'option',
      attributeBindings: ['value', 'selected'],

      defaultTemplate: function(context, options) {
        options = { data: options.data, hash: {} };
        EmberHandlebars.helpers.bind.call(context, "view.label", options);
      },

      init: function() {
        this.labelPathDidChange();
        this.valuePathDidChange();

        this._super();
      },

      selected: computed(function() {
        var content = get(this, 'content'),
            selection = get(this, 'parentView.selection');
        if (get(this, 'parentView.multiple')) {
          return selection && indexOf(selection, content.valueOf()) > -1;
        } else {
          // Primitives get passed through bindings as objects... since
          // `new Number(4) !== 4`, we use `==` below
          return content == selection; // jshint ignore:line
        }
      }).property('content', 'parentView.selection'),

      labelPathDidChange: observer('parentView.optionLabelPath', function() {
        var labelPath = get(this, 'parentView.optionLabelPath');

        if (!labelPath) { return; }

        defineProperty(this, 'label', computed(function() {
          return get(this, labelPath);
        }).property(labelPath));
      }),

      valuePathDidChange: observer('parentView.optionValuePath', function() {
        var valuePath = get(this, 'parentView.optionValuePath');

        if (!valuePath) { return; }

        defineProperty(this, 'value', computed(function() {
          return get(this, valuePath);
        }).property(valuePath));
      })
    });

    var SelectOptgroup = CollectionView.extend({
      instrumentDisplay: 'Ember.SelectOptgroup',

      tagName: 'optgroup',
      attributeBindings: ['label'],

      selectionBinding: 'parentView.selection',
      multipleBinding: 'parentView.multiple',
      optionLabelPathBinding: 'parentView.optionLabelPath',
      optionValuePathBinding: 'parentView.optionValuePath',

      itemViewClassBinding: 'parentView.optionView'
    });

    
    var Select = View.extend({
      instrumentDisplay: 'Ember.Select',

      tagName: 'select',
      classNames: ['ember-select'],
      defaultTemplate: Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
    this.compilerInfo = [4,'>= 1.0.0'];
    helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
      var buffer = '', stack1, escapeExpression=this.escapeExpression, self=this;

    function program1(depth0,data) {
      
      var buffer = '', stack1;
      data.buffer.push("<option value=\"\">");
      stack1 = helpers._triageMustache.call(depth0, "view.prompt", {hash:{},hashTypes:{},hashContexts:{},contexts:[depth0],types:["ID"],data:data});
      if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
      data.buffer.push("</option>");
      return buffer;
      }

    function program3(depth0,data) {
      
      var stack1;
      stack1 = helpers.each.call(depth0, "view.groupedContent", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(4, program4, data),contexts:[depth0],types:["ID"],data:data});
      if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
      else { data.buffer.push(''); }
      }
    function program4(depth0,data) {
      
      
      data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.groupView", {hash:{
        'content': ("content"),
        'label': ("label")
      },hashTypes:{'content': "ID",'label': "ID"},hashContexts:{'content': depth0,'label': depth0},contexts:[depth0],types:["ID"],data:data})));
      }

    function program6(depth0,data) {
      
      var stack1;
      stack1 = helpers.each.call(depth0, "view.content", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(7, program7, data),contexts:[depth0],types:["ID"],data:data});
      if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
      else { data.buffer.push(''); }
      }
    function program7(depth0,data) {
      
      
      data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.optionView", {hash:{
        'content': ("")
      },hashTypes:{'content': "ID"},hashContexts:{'content': depth0},contexts:[depth0],types:["ID"],data:data})));
      }

      stack1 = helpers['if'].call(depth0, "view.prompt", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:["ID"],data:data});
      if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
      stack1 = helpers['if'].call(depth0, "view.optionGroupPath", {hash:{},hashTypes:{},hashContexts:{},inverse:self.program(6, program6, data),fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],data:data});
      if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
      return buffer;
      
    }),
      attributeBindings: ['multiple', 'disabled', 'tabindex', 'name', 'required', 'autofocus',
                          'form', 'size'],

      
      multiple: false,

      
      disabled: false,

      
      required: false,

      
      content: null,

      
      selection: null,

      
      value: computed(function(key, value) {
        if (arguments.length === 2) { return value; }
        var valuePath = get(this, 'optionValuePath').replace(/^content\.?/, '');
        return valuePath ? get(this, 'selection.' + valuePath) : get(this, 'selection');
      }).property('selection'),

      
      prompt: null,

      
      optionLabelPath: 'content',

      
      optionValuePath: 'content',

      
      optionGroupPath: null,

      
      groupView: SelectOptgroup,

      groupedContent: computed(function() {
        var groupPath = get(this, 'optionGroupPath');
        var groupedContent = emberA();
        var content = get(this, 'content') || [];

        forEach(content, function(item) {
          var label = get(item, groupPath);

          if (get(groupedContent, 'lastObject.label') !== label) {
            groupedContent.pushObject({
              label: label,
              content: emberA()
            });
          }

          get(groupedContent, 'lastObject.content').push(item);
        });

        return groupedContent;
      }).property('optionGroupPath', 'content.@each'),

      
      optionView: SelectOption,

      _change: function() {
        if (get(this, 'multiple')) {
          this._changeMultiple();
        } else {
          this._changeSingle();
        }
      },

      selectionDidChange: observer('selection.@each', function() {
        var selection = get(this, 'selection');
        if (get(this, 'multiple')) {
          if (!isArray(selection)) {
            set(this, 'selection', emberA([selection]));
            return;
          }
          this._selectionDidChangeMultiple();
        } else {
          this._selectionDidChangeSingle();
        }
      }),

      valueDidChange: observer('value', function() {
        var content = get(this, 'content'),
            value = get(this, 'value'),
            valuePath = get(this, 'optionValuePath').replace(/^content\.?/, ''),
            selectedValue = (valuePath ? get(this, 'selection.' + valuePath) : get(this, 'selection')),
            selection;

        if (value !== selectedValue) {
          selection = content ? content.find(function(obj) {
            return value === (valuePath ? get(obj, valuePath) : obj);
          }) : null;

          this.set('selection', selection);
        }
      }),


      _triggerChange: function() {
        var selection = get(this, 'selection');
        var value = get(this, 'value');

        if (!isNone(selection)) { this.selectionDidChange(); }
        if (!isNone(value)) { this.valueDidChange(); }

        this._change();
      },

      _changeSingle: function() {
        var selectedIndex = this.$()[0].selectedIndex,
            content = get(this, 'content'),
            prompt = get(this, 'prompt');

        if (!content || !get(content, 'length')) { return; }
        if (prompt && selectedIndex === 0) { set(this, 'selection', null); return; }

        if (prompt) { selectedIndex -= 1; }
        set(this, 'selection', content.objectAt(selectedIndex));
      },


      _changeMultiple: function() {
        var options = this.$('option:selected'),
            prompt = get(this, 'prompt'),
            offset = prompt ? 1 : 0,
            content = get(this, 'content'),
            selection = get(this, 'selection');

        if (!content) { return; }
        if (options) {
          var selectedIndexes = options.map(function() {
            return this.index - offset;
          }).toArray();
          var newSelection = content.objectsAt(selectedIndexes);

          if (isArray(selection)) {
            replace(selection, 0, get(selection, 'length'), newSelection);
          } else {
            set(this, 'selection', newSelection);
          }
        }
      },

      _selectionDidChangeSingle: function() {
        var el = this.get('element');
        if (!el) { return; }

        var content = get(this, 'content'),
            selection = get(this, 'selection'),
            selectionIndex = content ? indexOf(content, selection) : -1,
            prompt = get(this, 'prompt');

        if (prompt) { selectionIndex += 1; }
        if (el) { el.selectedIndex = selectionIndex; }
      },

      _selectionDidChangeMultiple: function() {
        var content = get(this, 'content'),
            selection = get(this, 'selection'),
            selectedIndexes = content ? indexesOf(content, selection) : [-1],
            prompt = get(this, 'prompt'),
            offset = prompt ? 1 : 0,
            options = this.$('option'),
            adjusted;

        if (options) {
          options.each(function() {
            adjusted = this.index > -1 ? this.index - offset : -1;
            this.selected = indexOf(selectedIndexes, adjusted) > -1;
          });
        }
      },

      init: function() {
        this._super();
        this.on("didInsertElement", this, this._triggerChange);
        this.on("change", this, this._change);
      }
    });

    __exports__["default"] = Select;
    __exports__.Select = Select;
    __exports__.SelectOption = SelectOption;
    __exports__.SelectOptgroup = SelectOptgroup;
  });
define("ember-handlebars/controls/text_area",
  ["ember-metal/property_get","ember-views/views/component","ember-handlebars/controls/text_support","ember-metal/mixin","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";

    
    var get = __dependency1__.get;
    var Component = __dependency2__["default"];
    var TextSupport = __dependency3__["default"];
    var observer = __dependency4__.observer;

    
    __exports__["default"] = Component.extend(TextSupport, {
      instrumentDisplay: '{{textarea}}',

      classNames: ['ember-text-area'],

      tagName: "textarea",
      attributeBindings: ['rows', 'cols', 'name', 'selectionEnd', 'selectionStart', 'wrap'],
      rows: null,
      cols: null,

      _updateElementValue: observer('value', function() {
        // We do this check so cursor position doesn't get affected in IE
        var value = get(this, 'value'),
            $el = this.$();
        if ($el && value !== $el.val()) {
          $el.val(value);
        }
      }),

      init: function() {
        this._super();
        this.on("didInsertElement", this, this._updateElementValue);
      }
    });
  });
define("ember-handlebars/controls/text_field",
  ["ember-metal/property_get","ember-metal/property_set","ember-views/views/component","ember-handlebars/controls/text_support","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    

    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var Component = __dependency3__["default"];
    var TextSupport = __dependency4__["default"];

    
    __exports__["default"] = Component.extend(TextSupport, {
      instrumentDisplay: '{{input type="text"}}',

      classNames: ['ember-text-field'],
      tagName: "input",
      attributeBindings: ['type', 'value', 'size', 'pattern', 'name', 'min', 'max',
                          'accept', 'autocomplete', 'autosave', 'formaction',
                          'formenctype', 'formmethod', 'formnovalidate', 'formtarget',
                          'height', 'inputmode', 'list', 'multiple', 'step',
                          'width'],

      
      value: "",

      
      type: "text",

      
      size: null,

      
      pattern: null,

      
      min: null,

      
      max: null
    });
  });
define("ember-handlebars/controls/text_support",
  ["ember-metal/property_get","ember-metal/property_set","ember-metal/mixin","ember-runtime/mixins/target_action_support","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    

    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var Mixin = __dependency3__.Mixin;
    var TargetActionSupport = __dependency4__["default"];

    
    var TextSupport = Mixin.create(TargetActionSupport, {
      value: "",

      attributeBindings: ['placeholder', 'disabled', 'maxlength', 'tabindex', 'readonly',
                          'autofocus', 'form', 'selectionDirection', 'spellcheck', 'required',
                          'title', 'autocapitalize', 'autocorrect'],
      placeholder: null,
      disabled: false,
      maxlength: null,

      init: function() {
        this._super();
        this.on("focusOut", this, this._elementValueDidChange);
        this.on("change", this, this._elementValueDidChange);
        this.on("paste", this, this._elementValueDidChange);
        this.on("cut", this, this._elementValueDidChange);
        this.on("input", this, this._elementValueDidChange);
        this.on("keyUp", this, this.interpretKeyEvents);
      },

      
      action: null,

      
      onEvent: 'enter',

      
      bubbles: false,

      interpretKeyEvents: function(event) {
        var map = TextSupport.KEY_EVENTS;
        var method = map[event.keyCode];

        this._elementValueDidChange();
        if (method) { return this[method](event); }
      },

      _elementValueDidChange: function() {
        set(this, 'value', this.$().val());
      },

      
      insertNewline: function(event) {
        sendAction('enter', this, event);
        sendAction('insert-newline', this, event);
      },

      
      cancel: function(event) {
        sendAction('escape-press', this, event);
      },

      
      focusIn: function(event) {
        sendAction('focus-in', this, event);
      },

      
      focusOut: function(event) {
        sendAction('focus-out', this, event);
      },

      
      keyPress: function(event) {
        sendAction('key-press', this, event);
      }

    });

    TextSupport.KEY_EVENTS = {
      13: 'insertNewline',
      27: 'cancel'
    };

    // In principle, this shouldn't be necessary, but the legacy
    // sendAction semantics for TextField are different from
    // the component semantics so this method normalizes them.
    function sendAction(eventName, view, event) {
      var action = get(view, eventName),
          on = get(view, 'onEvent'),
          value = get(view, 'value');

      // back-compat support for keyPress as an event name even though
      // it's also a method name that consumes the event (and therefore
      // incompatible with sendAction semantics).
      if (on === eventName || (on === 'keyPress' && eventName === 'key-press')) {
        view.sendAction('action', value);
      }

      view.sendAction(eventName, value);

      if (action || on === eventName) {
        if(!get(view, 'bubbles')) {
          event.stopPropagation();
        }
      }
    }

    __exports__["default"] = TextSupport;
  });
define("ember-handlebars/ext",
  ["ember-metal/core","ember-runtime/system/string","ember-handlebars-compiler","ember-metal/property_get","ember-metal/binding","ember-metal/error","ember-metal/mixin","ember-metal/is_empty","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.FEATURES, Ember.assert, Ember.Handlebars, Ember.lookup
    // var emberAssert = Ember.assert;

    var fmt = __dependency2__.fmt;

    var EmberHandlebars = __dependency3__["default"];
    var helpers = EmberHandlebars.helpers;

    var get = __dependency4__.get;
    var isGlobalPath = __dependency5__.isGlobalPath;
    var EmberError = __dependency6__["default"];
    var IS_BINDING = __dependency7__.IS_BINDING;

    // late bound via requireModule because of circular dependencies.
    var resolveHelper,
        SimpleHandlebarsView;

    var isEmpty = __dependency8__["default"];

    var slice = [].slice, originalTemplate = EmberHandlebars.template;

    
    function normalizePath(root, path, data) {
      var keywords = (data && data.keywords) || {},
          keyword, isKeyword;

      // Get the first segment of the path. For example, if the
      // path is "foo.bar.baz", returns "foo".
      keyword = path.split('.', 1)[0];

      // Test to see if the first path is a keyword that has been
      // passed along in the view's data hash. If so, we will treat
      // that object as the new root.
      if (keywords.hasOwnProperty(keyword)) {
        // Look up the value in the template's data hash.
        root = keywords[keyword];
        isKeyword = true;

        // Handle cases where the entire path is the reserved
        // word. In that case, return the object itself.
        if (path === keyword) {
          path = '';
        } else {
          // Strip the keyword from the path and look up
          // the remainder from the newly found root.
          path = path.substr(keyword.length+1);
        }
      }

      return { root: root, path: path, isKeyword: isKeyword };
    }


    
    function handlebarsGet(root, path, options) {
      var data = options && options.data,
          normalizedPath = normalizePath(root, path, data),
          value;

      
        root = normalizedPath.root;
        path = normalizedPath.path;

        value = get(root, path);

        if (value === undefined && root !== Ember.lookup && isGlobalPath(path)) {
          value = get(Ember.lookup, path);
        }
      

      return value;
    }

    
    function getEscaped(root, path, options) {
      var result = handlebarsGet(root, path, options);

      if (result === null || result === undefined) {
        result = "";
      } else if (!(result instanceof Handlebars.SafeString)) {
        result = String(result);
      }
      if (!options.hash.unescaped){
        result = Handlebars.Utils.escapeExpression(result);
      }

      return result;
    }

    __exports__.getEscaped = getEscaped;function resolveParams(context, params, options) {
      var resolvedParams = [], types = options.types, param, type;

      for (var i=0, l=params.length; i<l; i++) {
        param = params[i];
        type = types[i];

        if (type === 'ID') {
          resolvedParams.push(handlebarsGet(context, param, options));
        } else {
          resolvedParams.push(param);
        }
      }

      return resolvedParams;
    }

    __exports__.resolveParams = resolveParams;function resolveHash(context, hash, options) {
      var resolvedHash = {}, types = options.hashTypes, type;

      for (var key in hash) {
        if (!hash.hasOwnProperty(key)) { continue; }

        type = types[key];

        if (type === 'ID') {
          resolvedHash[key] = handlebarsGet(context, hash[key], options);
        } else {
          resolvedHash[key] = hash[key];
        }
      }

      return resolvedHash;
    }

    __exports__.resolveHash = resolveHash;
    function helperMissingHelper(path) {
      if (!resolveHelper) { resolveHelper = requireModule('ember-handlebars/helpers/binding')['resolveHelper']; } // ES6TODO: stupid circular dep

      var error, view = "";

      var options = arguments[arguments.length - 1];

      var helper = resolveHelper(options.data.view.container, path);

      if (helper) {
        return helper.apply(this, slice.call(arguments, 1));
      }

      error = "%@ Handlebars error: Could not find property '%@' on object %@.";
      if (options.data) {
        view = options.data.view;
      }
      throw new EmberError(fmt(error, [view, path, this]));
    }

    __exports__.helperMissingHelper = helperMissingHelper;
    function blockHelperMissingHelper(path) {
      if (!resolveHelper) { resolveHelper = requireModule('ember-handlebars/helpers/binding')['resolveHelper']; } // ES6TODO: stupid circular dep

      var options = arguments[arguments.length - 1];

      Ember.assert("`blockHelperMissing` was invoked without a helper name, which " +
                   "is most likely due to a mismatch between the version of " +
                   "Ember.js you're running now and the one used to precompile your " +
                   "templates. Please make sure the version of " +
                   "`ember-handlebars-compiler` you're using is up to date.", path);

      var helper = resolveHelper(options.data.view.container, path);

      if (helper) {
        return helper.apply(this, slice.call(arguments, 1));
      } else {
        return helpers.helperMissing.call(this, path);
      }
    }

    __exports__.blockHelperMissingHelper = blockHelperMissingHelper;
    function registerBoundHelper(name, fn) {
      var boundHelperArgs = slice.call(arguments, 1),
          boundFn = makeBoundHelper.apply(this, boundHelperArgs);
      EmberHandlebars.registerHelper(name, boundFn);
    }

    __exports__.registerBoundHelper = registerBoundHelper;
    function makeBoundHelper(fn) {
      if (!SimpleHandlebarsView) { SimpleHandlebarsView = requireModule('ember-handlebars/views/handlebars_bound_view')['SimpleHandlebarsView']; } // ES6TODO: stupid circular dep

      var dependentKeys = slice.call(arguments, 1);

      function helper() {
        var properties = slice.call(arguments, 0, -1),
          numProperties = properties.length,
          options = arguments[arguments.length - 1],
          normalizedProperties = [],
          data = options.data,
          types = data.isUnbound ? slice.call(options.types, 1) : options.types,
          hash = options.hash,
          view = data.view,
          contexts = options.contexts,
          currentContext = (contexts && contexts.length) ? contexts[0] : this,
          prefixPathForDependentKeys = '',
          loc, len, hashOption,
          boundOption, property,
          normalizedValue = SimpleHandlebarsView.prototype.normalizedValue;
        var hashTypes = options.hashTypes;

        Ember.assert("registerBoundHelper-generated helpers do not support use with Handlebars blocks.", !options.fn);

        // Detect bound options (e.g. countBinding="otherCount")
        var boundOptions = hash.boundOptions = {};
        for (hashOption in hash) {
          if (IS_BINDING.test(hashOption)) {
            // Lop off 'Binding' suffix.
            boundOptions[hashOption.slice(0, -7)] = hash[hashOption];
          } else if (hashTypes[hashOption] === 'ID') {
            boundOptions[hashOption] = hash[hashOption];
          }
        }

        // Expose property names on data.properties object.
        var watchedProperties = [];
        data.properties = [];
        for (loc = 0; loc < numProperties; ++loc) {
          data.properties.push(properties[loc]);
          if (types[loc] === 'ID') {
            var normalizedProp = normalizePath(currentContext, properties[loc], data);
            normalizedProperties.push(normalizedProp);
            watchedProperties.push(normalizedProp);
          } else {
            if(data.isUnbound) {
              normalizedProperties.push({path: properties[loc]});
            }else {
              normalizedProperties.push(null);
            }
          }
        }

        // Handle case when helper invocation is preceded by `unbound`, e.g.
        // {{unbound myHelper foo}}
        if (data.isUnbound) {
          return evaluateUnboundHelper(this, fn, normalizedProperties, options);
        }

        var bindView = new SimpleHandlebarsView(null, null, !options.hash.unescaped, options.data);

        // Override SimpleHandlebarsView's method for generating the view's content.
        bindView.normalizedValue = function() {
          var args = [], boundOption;

          // Copy over bound hash options.
          for (boundOption in boundOptions) {
            if (!boundOptions.hasOwnProperty(boundOption)) { continue; }
            property = normalizePath(currentContext, boundOptions[boundOption], data);
            bindView.path = property.path;
            bindView.pathRoot = property.root;
            hash[boundOption] = normalizedValue.call(bindView);
          }

          for (loc = 0; loc < numProperties; ++loc) {
            property = normalizedProperties[loc];
            if (property) {
              bindView.path = property.path;
              bindView.pathRoot = property.root;
              args.push(normalizedValue.call(bindView));
            } else {
              args.push(properties[loc]);
            }
          }
          args.push(options);

          // Run the supplied helper function.
          return fn.apply(currentContext, args);
        };

        view.appendChild(bindView);

        // Assemble list of watched properties that'll re-render this helper.
        for (boundOption in boundOptions) {
          if (boundOptions.hasOwnProperty(boundOption)) {
            watchedProperties.push(normalizePath(currentContext, boundOptions[boundOption], data));
          }
        }

        // Observe each property.
        for (loc = 0, len = watchedProperties.length; loc < len; ++loc) {
          property = watchedProperties[loc];
          view.registerObserver(property.root, property.path, bindView, bindView.rerender);
        }

        if (types[0] !== 'ID' || normalizedProperties.length === 0) {
          return;
        }

        // Add dependent key observers to the first param
        var normalized = normalizedProperties[0],
            pathRoot = normalized.root,
            path = normalized.path;

        if(!isEmpty(path)) {
          prefixPathForDependentKeys = path + '.';
        }
        for (var i=0, l=dependentKeys.length; i<l; i++) {
          view.registerObserver(pathRoot, prefixPathForDependentKeys + dependentKeys[i], bindView, bindView.rerender);
        }
      }

      helper._rawFunction = fn;
      return helper;
    }

    
    function evaluateUnboundHelper(context, fn, normalizedProperties, options) {
      var args = [],
       hash = options.hash,
       boundOptions = hash.boundOptions,
       types = slice.call(options.types, 1),
       loc,
       len,
       property,
       propertyType,
       boundOption;

      for (boundOption in boundOptions) {
        if (!boundOptions.hasOwnProperty(boundOption)) { continue; }
        hash[boundOption] = handlebarsGet(context, boundOptions[boundOption], options);
      }

      for(loc = 0, len = normalizedProperties.length; loc < len; ++loc) {
        property = normalizedProperties[loc];
        propertyType = types[loc];
        if(propertyType === "ID") {
          args.push(handlebarsGet(property.root, property.path, options));
        } else {
          args.push(property.path);
        }
      }
      args.push(options);
      return fn.apply(context, args);
    }

    
    function template(spec) {
      var t = originalTemplate(spec);
      t.isTop = true;
      return t;
    }

    __exports__.template = template;__exports__.normalizePath = normalizePath;
    __exports__.makeBoundHelper = makeBoundHelper;
    __exports__.handlebarsGet = handlebarsGet;
    __exports__.evaluateUnboundHelper = evaluateUnboundHelper;
  });
define("ember-handlebars/helpers/binding",
  ["ember-metal/core","ember-handlebars-compiler","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-runtime/system/string","ember-metal/platform","ember-metal/is_none","ember-metal/enumerable_utils","ember-metal/array","ember-views/views/view","ember-metal/run_loop","ember-metal/observer","ember-metal/binding","ember-views/system/jquery","ember-handlebars/ext","ember-runtime/keys","ember-handlebars/views/handlebars_bound_view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.assert, Ember.warn, uuid
    // var emberAssert = Ember.assert, Ember.warn = Ember.warn;

    var EmberHandlebars = __dependency2__["default"];
    var get = __dependency3__.get;
    var set = __dependency4__.set;
    var apply = __dependency5__.apply;
    var uuid = __dependency5__.uuid;
    var fmt = __dependency6__.fmt;
    var o_create = __dependency7__.create;
    var isNone = __dependency8__["default"];
    var EnumerableUtils = __dependency9__["default"];
    var forEach = __dependency10__.forEach;
    var View = __dependency11__["default"];
    var run = __dependency12__["default"];
    var removeObserver = __dependency13__.removeObserver;
    var isGlobalPath = __dependency14__.isGlobalPath;
    var emberBind = __dependency14__.bind;
    var jQuery = __dependency15__["default"];
    var isArray = __dependency5__.isArray;
    var handlebarsGetEscaped = __dependency16__.getEscaped;
    var keys = __dependency17__["default"];

    var _HandlebarsBoundView = __dependency18__._HandlebarsBoundView;
    var SimpleHandlebarsView = __dependency18__.SimpleHandlebarsView;

    var normalizePath = __dependency16__.normalizePath;
    var handlebarsGet = __dependency16__.handlebarsGet;
    var getEscaped = __dependency16__.getEscaped;

    var guidFor = __dependency5__.guidFor;
    var typeOf = __dependency5__.typeOf;

    var helpers = EmberHandlebars.helpers;
    var SafeString = EmberHandlebars.SafeString;

    function exists(value) {
      return !isNone(value);
    }

    var WithView = _HandlebarsBoundView.extend({
      init: function() {
        var controller;

        apply(this, this._super, arguments);

        var keywords        = this.templateData.keywords;
        var keywordName     = this.templateHash.keywordName;
        var keywordPath     = this.templateHash.keywordPath;
        var controllerName  = this.templateHash.controller;
        var preserveContext = this.preserveContext;

        if (controllerName) {
          var previousContext = this.previousContext;
          controller = this.container.lookupFactory('controller:'+controllerName).create({
            parentController: previousContext,
            target: previousContext
          });

          this._generatedController = controller;

          if (!preserveContext) {
            this.set('controller', controller);

            this.valueNormalizerFunc = function(result) {
                controller.set('model', result);
                return controller;
            };
          } else {
            var controllerPath = jQuery.expando + guidFor(controller);
            keywords[controllerPath] = controller;
            emberBind(keywords, controllerPath + '.model', keywordPath);
            keywordPath = controllerPath;
          }
        }

        if (preserveContext) {
          emberBind(keywords, keywordName, keywordPath);
        }

      },
      willDestroy: function() {
        this._super();

        if (this._generatedController) {
          this._generatedController.destroy();
        }
      }
    });

    // Binds a property into the DOM. This will create a hook in DOM that the
    // KVO system will look for and update if the property changes.
    function bind(property, options, preserveContext, shouldDisplay, valueNormalizer, childProperties) {
      var data = options.data,
          fn = options.fn,
          inverse = options.inverse,
          view = data.view,
          normalized, observer, i;

      // we relied on the behavior of calling without
      // context to mean this === window, but when running
      // "use strict", it's possible for this to === undefined;
      var currentContext = this || window;

      normalized = normalizePath(currentContext, property, data);

      // Set up observers for observable objects
      if ('object' === typeof this) {
        if (data.insideGroup) {
          observer = function() {
            while (view._contextView) {
              view = view._contextView;
            }
            run.once(view, 'rerender');
          };

          var template, context, result = handlebarsGet(currentContext, property, options);

          result = valueNormalizer ? valueNormalizer(result) : result;

          context = preserveContext ? currentContext : result;
          if (shouldDisplay(result)) {
            template = fn;
          } else if (inverse) {
            template = inverse;
          }

          template(context, { data: options.data });
        } else {
          var viewClass = _HandlebarsBoundView;
          var viewOptions = {
            preserveContext: preserveContext,
            shouldDisplayFunc: shouldDisplay,
            valueNormalizerFunc: valueNormalizer,
            displayTemplate: fn,
            inverseTemplate: inverse,
            path: property,
            pathRoot: currentContext,
            previousContext: currentContext,
            isEscaped: !options.hash.unescaped,
            templateData: options.data,
            templateHash: options.hash,
            helperName: options.helperName
          };

          if (options.isWithHelper) {
            viewClass = WithView;
          }

          // Create the view that will wrap the output of this template/property
          // and add it to the nearest view's childViews array.
          // See the documentation of Ember._HandlebarsBoundView for more.
          var bindView = view.createChildView(viewClass, viewOptions);

          view.appendChild(bindView);

          observer = function() {
            run.scheduleOnce('render', bindView, 'rerenderIfNeeded');
          };
        }

        // Observes the given property on the context and
        // tells the Ember._HandlebarsBoundView to re-render. If property
        // is an empty string, we are printing the current context
        // object ({{this}}) so updating it is not our responsibility.
        if (normalized.path !== '') {
          view.registerObserver(normalized.root, normalized.path, observer);
          if (childProperties) {
            for (i=0; i<childProperties.length; i++) {
              view.registerObserver(normalized.root, normalized.path+'.'+childProperties[i], observer);
            }
          }
        }
      } else {
        // The object is not observable, so just render it out and
        // be done with it.
        data.buffer.push(handlebarsGetEscaped(currentContext, property, options));
      }
    }

    function simpleBind(currentContext, property, options) {
      var data = options.data,
          view = data.view,
          normalized, observer, pathRoot, output;

      normalized = normalizePath(currentContext, property, data);
      pathRoot = normalized.root;

      // Set up observers for observable objects
      if (pathRoot && ('object' === typeof pathRoot)) {
        if (data.insideGroup) {
          observer = function() {
            while (view._contextView) {
              view = view._contextView;
            }
            run.once(view, 'rerender');
          };

          output = handlebarsGetEscaped(currentContext, property, options);

          data.buffer.push(output);
        } else {
          var bindView = new SimpleHandlebarsView(
            property, currentContext, !options.hash.unescaped, options.data
          );

          bindView._parentView = view;
          view.appendChild(bindView);

          observer = function() {
            run.scheduleOnce('render', bindView, 'rerender');
          };
        }

        // Observes the given property on the context and
        // tells the Ember._HandlebarsBoundView to re-render. If property
        // is an empty string, we are printing the current context
        // object ({{this}}) so updating it is not our responsibility.
        if (normalized.path !== '') {
          view.registerObserver(normalized.root, normalized.path, observer);
        }
      } else {
        // The object is not observable, so just render it out and
        // be done with it.
        output = handlebarsGetEscaped(currentContext, property, options);
        data.buffer.push(output);
      }
    }

    function shouldDisplayIfHelperContent(result) {
      var truthy = result && get(result, 'isTruthy');
      if (typeof truthy === 'boolean') { return truthy; }

      if (isArray(result)) {
        return get(result, 'length') !== 0;
      } else {
        return !!result;
      }
    }

    
    function _triageMustacheHelper(property, options) {
      Ember.assert("You cannot pass more than one argument to the _triageMustache helper", arguments.length <= 2);

      var helper = EmberHandlebars.resolveHelper(options.data.view.container, property);
      if (helper) {
        return helper.call(this, options);
      }

      return helpers.bind.call(this, property, options);
    }

    
    function resolveHelper(container, name) {
      if (helpers[name]) {
        return helpers[name];
      }

      if (!container || name.indexOf('-') === -1) {
        return;
      }

      var helper = container.lookup('helper:' + name);
      if (!helper) {
        var componentLookup = container.lookup('component-lookup:main');
        Ember.assert("Could not find 'component-lookup:main' on the provided container, which is necessary for performing component lookups", componentLookup);

        var Component = componentLookup.lookupFactory(name, container);
        if (Component) {
          helper = EmberHandlebars.makeViewHelper(Component);
          container.register('helper:' + name, helper);
        }
      }
      return helper;
    }


    
    function bindHelper(property, options) {
      Ember.assert("You cannot pass more than one argument to the bind helper", arguments.length <= 2);

      var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this;

      if (!options.fn) {
        return simpleBind(context, property, options);
      }

      options.helperName = 'bind';

      return bind.call(context, property, options, false, exists);
    }

    
    function boundIfHelper(property, fn) {
      var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this;

      fn.helperName = fn.helperName || 'boundIf';

      return bind.call(context, property, fn, true, shouldDisplayIfHelperContent, shouldDisplayIfHelperContent, ['isTruthy', 'length']);
    }


    
    function unboundIfHelper(property, fn) {
      var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this,
          data = fn.data,
          template = fn.fn,
          inverse = fn.inverse,
          normalized, propertyValue, result;

      normalized = normalizePath(context, property, data);
      propertyValue = handlebarsGet(context, property, fn);

      if (!shouldDisplayIfHelperContent(propertyValue)) {
        template = inverse;
      }

      template(context, { data: data });
    }

    
    function withHelper(context, options) {
      var bindContext, preserveContext, controller, helperName = 'with';

      if (arguments.length === 4) {
        var keywordName, path, rootPath, normalized, contextPath;

        Ember.assert("If you pass more than one argument to the with helper, it must be in the form #with foo as bar", arguments[1] === "as");
        options = arguments[3];
        keywordName = arguments[2];
        path = arguments[0];

        if (path) {
          helperName += ' ' + path + ' as ' + keywordName;
        }

        Ember.assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop);

        var localizedOptions = o_create(options);
        localizedOptions.data = o_create(options.data);
        localizedOptions.data.keywords = o_create(options.data.keywords || {});

        if (isGlobalPath(path)) {
          contextPath = path;
        } else {
          normalized = normalizePath(this, path, options.data);
          path = normalized.path;
          rootPath = normalized.root;

          // This is a workaround for the fact that you cannot bind separate objects
          // together. When we implement that functionality, we should use it here.
          var contextKey = jQuery.expando + guidFor(rootPath);
          localizedOptions.data.keywords[contextKey] = rootPath;
          // if the path is '' ("this"), just bind directly to the current context
          contextPath = path ? contextKey + '.' + path : contextKey;
        }

        localizedOptions.hash.keywordName = keywordName;
        localizedOptions.hash.keywordPath = contextPath;

        bindContext = this;
        context = contextPath;
        options = localizedOptions;
        preserveContext = true;
      } else {
        Ember.assert("You must pass exactly one argument to the with helper", arguments.length === 2);
        Ember.assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop);

        helperName += ' ' + context;
        bindContext = options.contexts[0];
        preserveContext = false;
      }

      options.helperName = helperName;
      options.isWithHelper = true;

      return bind.call(bindContext, context, options, preserveContext, exists);
    }
    
    function ifHelper(context, options) {
      Ember.assert("You must pass exactly one argument to the if helper", arguments.length === 2);
      Ember.assert("You must pass a block to the if helper", options.fn && options.fn !== Handlebars.VM.noop);

      options.helperName = options.helperName || ('if ' + context);

      if (options.data.isUnbound) {
        return helpers.unboundIf.call(options.contexts[0], context, options);
      } else {
        return helpers.boundIf.call(options.contexts[0], context, options);
      }
    }

    
    function unlessHelper(context, options) {
      Ember.assert("You must pass exactly one argument to the unless helper", arguments.length === 2);
      Ember.assert("You must pass a block to the unless helper", options.fn && options.fn !== Handlebars.VM.noop);

      var fn = options.fn, inverse = options.inverse, helperName = 'unless';

      if (context) {
        helperName += ' ' + context;
      }

      options.fn = inverse;
      options.inverse = fn;

      options.helperName = options.helperName || helperName;

      if (options.data.isUnbound) {
        return helpers.unboundIf.call(options.contexts[0], context, options);
      } else {
        return helpers.boundIf.call(options.contexts[0], context, options);
      }
    }

    
    function bindAttrHelper(options) {
      var attrs = options.hash;

      Ember.assert("You must specify at least one hash argument to bind-attr", !!keys(attrs).length);

      var view = options.data.view;
      var ret = [];

      // we relied on the behavior of calling without
      // context to mean this === window, but when running
      // "use strict", it's possible for this to === undefined;
      var ctx = this || window;

      // Generate a unique id for this element. This will be added as a
      // data attribute to the element so it can be looked up when
      // the bound property changes.
      var dataId = uuid();

      // Handle classes differently, as we can bind multiple classes
      var classBindings = attrs['class'];
      if (classBindings != null) {
        var classResults = bindClasses(ctx, classBindings, view, dataId, options);

        ret.push('class="' + Handlebars.Utils.escapeExpression(classResults.join(' ')) + '"');
        delete attrs['class'];
      }

      var attrKeys = keys(attrs);

      // For each attribute passed, create an observer and emit the
      // current value of the property as an attribute.
      forEach.call(attrKeys, function(attr) {
        var path = attrs[attr],
            normalized;

        Ember.assert(fmt("You must provide an expression as the value of bound attribute. You specified: %@=%@", [attr, path]), typeof path === 'string');

        normalized = normalizePath(ctx, path, options.data);

        var value = (path === 'this') ? normalized.root : handlebarsGet(ctx, path, options),
            type = typeOf(value);

        Ember.assert(fmt("Attributes must be numbers, strings or booleans, not %@", [value]), value === null || value === undefined || type === 'number' || type === 'string' || type === 'boolean');

        var observer;

        observer = function observer() {
          var result = handlebarsGet(ctx, path, options);

          Ember.assert(fmt("Attributes must be numbers, strings or booleans, not %@", [result]),
                       result === null || result === undefined || typeof result === 'number' ||
                         typeof result === 'string' || typeof result === 'boolean');

          var elem = view.$("[data-bindattr-" + dataId + "='" + dataId + "']");

          // If we aren't able to find the element, it means the element
          // to which we were bound has been removed from the view.
          // In that case, we can assume the template has been re-rendered
          // and we need to clean up the observer.
          if (!elem || elem.length === 0) {
            removeObserver(normalized.root, normalized.path, observer);
            return;
          }

          View.applyAttributeBindings(elem, attr, result);
        };

        // Add an observer to the view for when the property changes.
        // When the observer fires, find the element using the
        // unique data id and update the attribute to the new value.
        // Note: don't add observer when path is 'this' or path
        // is whole keyword e.g. {{#each x in list}} ... {{bind-attr attr="x"}}
        if (path !== 'this' && !(normalized.isKeyword && normalized.path === '' )) {
          view.registerObserver(normalized.root, normalized.path, observer);
        }

        // if this changes, also change the logic in ember-views/lib/views/view.js
        if ((type === 'string' || (type === 'number' && !isNaN(value)))) {
          ret.push(attr + '="' + Handlebars.Utils.escapeExpression(value) + '"');
        } else if (value && type === 'boolean') {
          // The developer controls the attr name, so it should always be safe
          ret.push(attr + '="' + attr + '"');
        }
      }, this);

      // Add the unique identifier
      // NOTE: We use all lower-case since Firefox has problems with mixed case in SVG
      ret.push('data-bindattr-' + dataId + '="' + dataId + '"');
      return new SafeString(ret.join(' '));
    }

    
    function bindAttrHelperDeprecated() {
      Ember.warn("The 'bindAttr' view helper is deprecated in favor of 'bind-attr'");
      return helpers['bind-attr'].apply(this, arguments);
    }

    
    function bindClasses(context, classBindings, view, bindAttrId, options) {
      var ret = [], newClass, value, elem;

      // Helper method to retrieve the property from the context and
      // determine which class string to return, based on whether it is
      // a Boolean or not.
      var classStringForPath = function(root, parsedPath, options) {
        var val,
            path = parsedPath.path;

        if (path === 'this') {
          val = root;
        } else if (path === '') {
          val = true;
        } else {
          val = handlebarsGet(root, path, options);
        }

        return View._classStringForValue(path, val, parsedPath.className, parsedPath.falsyClassName);
      };

      // For each property passed, loop through and setup
      // an observer.
      forEach.call(classBindings.split(' '), function(binding) {

        // Variable in which the old class value is saved. The observer function
        // closes over this variable, so it knows which string to remove when
        // the property changes.
        var oldClass;

        var observer;

        var parsedPath = View._parsePropertyPath(binding),
            path = parsedPath.path,
            pathRoot = context,
            normalized;

        if (path !== '' && path !== 'this') {
          normalized = normalizePath(context, path, options.data);

          pathRoot = normalized.root;
          path = normalized.path;
        }

        // Set up an observer on the context. If the property changes, toggle the
        // class name.
        observer = function() {
          // Get the current value of the property
          newClass = classStringForPath(context, parsedPath, options);
          elem = bindAttrId ? view.$("[data-bindattr-" + bindAttrId + "='" + bindAttrId + "']") : view.$();

          // If we can't find the element anymore, a parent template has been
          // re-rendered and we've been nuked. Remove the observer.
          if (!elem || elem.length === 0) {
            removeObserver(pathRoot, path, observer);
          } else {
            // If we had previously added a class to the element, remove it.
            if (oldClass) {
              elem.removeClass(oldClass);
            }

            // If necessary, add a new class. Make sure we keep track of it so
            // it can be removed in the future.
            if (newClass) {
              elem.addClass(newClass);
              oldClass = newClass;
            } else {
              oldClass = null;
            }
          }
        };

        if (path !== '' && path !== 'this') {
          view.registerObserver(pathRoot, path, observer);
        }

        // We've already setup the observer; now we just need to figure out the
        // correct behavior right now on the first pass through.
        value = classStringForPath(context, parsedPath, options);

        if (value) {
          ret.push(value);

          // Make sure we save the current value so that it can be removed if the
          // observer fires.
          oldClass = value;
        }
      });

      return ret;
    }

    __exports__.bind = bind;
    __exports__._triageMustacheHelper = _triageMustacheHelper;
    __exports__.resolveHelper = resolveHelper;
    __exports__.bindHelper = bindHelper;
    __exports__.boundIfHelper = boundIfHelper;
    __exports__.unboundIfHelper = unboundIfHelper;
    __exports__.withHelper = withHelper;
    __exports__.ifHelper = ifHelper;
    __exports__.unlessHelper = unlessHelper;
    __exports__.bindAttrHelper = bindAttrHelper;
    __exports__.bindAttrHelperDeprecated = bindAttrHelperDeprecated;
    __exports__.bindClasses = bindClasses;
  });
define("ember-handlebars/helpers/collection",
  ["ember-metal/core","ember-metal/utils","ember-handlebars-compiler","ember-runtime/system/string","ember-metal/property_get","ember-handlebars/ext","ember-handlebars/helpers/view","ember-metal/computed","ember-views/views/collection_view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.assert, Ember.deprecate
    var inspect = __dependency2__.inspect;

    // var emberAssert = Ember.assert;
        // emberDeprecate = Ember.deprecate;

    var EmberHandlebars = __dependency3__["default"];
    var helpers = EmberHandlebars.helpers;

    var fmt = __dependency4__.fmt;
    var get = __dependency5__.get;
    var handlebarsGet = __dependency6__.handlebarsGet;
    var ViewHelper = __dependency7__.ViewHelper;
    var computed = __dependency8__.computed;
    var CollectionView = __dependency9__["default"];

    var alias = computed.alias;
    
    function collectionHelper(path, options) {
      Ember.deprecate("Using the {{collection}} helper without specifying a class has been deprecated as the {{each}} helper now supports the same functionality.", path !== 'collection');

      // If no path is provided, treat path param as options.
      if (path && path.data && path.data.isRenderData) {
        options = path;
        path = undefined;
        Ember.assert("You cannot pass more than one argument to the collection helper", arguments.length === 1);
      } else {
        Ember.assert("You cannot pass more than one argument to the collection helper", arguments.length === 2);
      }

      var fn = options.fn;
      var data = options.data;
      var inverse = options.inverse;
      var view = options.data.view;


      var controller, container;
      // If passed a path string, convert that into an object.
      // Otherwise, just default to the standard class.
      var collectionClass;
      if (path) {
        controller = data.keywords.controller;
        container = controller && controller.container;
        collectionClass = handlebarsGet(this, path, options) || container.lookupFactory('view:' + path);
        Ember.assert(fmt("%@ #collection: Could not find collection class %@", [data.view, path]), !!collectionClass);
      }
      else {
        collectionClass = CollectionView;
      }

      var hash = options.hash, itemHash = {}, match;

      // Extract item view class if provided else default to the standard class
      var collectionPrototype = collectionClass.proto(), itemViewClass;

      if (hash.itemView) {
        controller = data.keywords.controller;
        Ember.assert('You specified an itemView, but the current context has no ' +
                     'container to look the itemView up in. This probably means ' +
                     'that you created a view manually, instead of through the ' +
                     'container. Instead, use container.lookup("view:viewName"), ' +
                     'which will properly instantiate your view.',
                     controller && controller.container);
        container = controller.container;
        itemViewClass = container.lookupFactory('view:' + hash.itemView);
        Ember.assert('You specified the itemView ' + hash.itemView + ", but it was " +
                     "not found at " + container.describe("view:" + hash.itemView) +
                     " (and it was not registered in the container)", !!itemViewClass);
      } else if (hash.itemViewClass) {
        itemViewClass = handlebarsGet(collectionPrototype, hash.itemViewClass, options);
      } else {
        itemViewClass = collectionPrototype.itemViewClass;
      }

      Ember.assert(fmt("%@ #collection: Could not find itemViewClass %@", [data.view, itemViewClass]), !!itemViewClass);

      delete hash.itemViewClass;
      delete hash.itemView;

      // Go through options passed to the {{collection}} helper and extract options
      // that configure item views instead of the collection itself.
      for (var prop in hash) {
        if (hash.hasOwnProperty(prop)) {
          match = prop.match(/^item(.)(.*)$/);

          if (match && prop !== 'itemController') {
            // Convert itemShouldFoo -> shouldFoo
            itemHash[match[1].toLowerCase() + match[2]] = hash[prop];
            // Delete from hash as this will end up getting passed to the
            // {{view}} helper method.
            delete hash[prop];
          }
        }
      }

      if (fn) {
        itemHash.template = fn;
        delete options.fn;
      }

      var emptyViewClass;
      if (inverse && inverse !== EmberHandlebars.VM.noop) {
        emptyViewClass = get(collectionPrototype, 'emptyViewClass');
        emptyViewClass = emptyViewClass.extend({
              template: inverse,
              tagName: itemHash.tagName
        });
      } else if (hash.emptyViewClass) {
        emptyViewClass = handlebarsGet(this, hash.emptyViewClass, options);
      }
      if (emptyViewClass) { hash.emptyView = emptyViewClass; }

      if (hash.keyword) {
        itemHash._context = this;
      } else {
        itemHash._context = alias('content');
      }

      var viewOptions = ViewHelper.propertiesFromHTMLOptions({ data: data, hash: itemHash }, this);
      hash.itemViewClass = itemViewClass.extend(viewOptions);

      options.helperName = options.helperName || 'collection';

      return helpers.view.call(this, collectionClass, options);
    }

    __exports__["default"] = collectionHelper;
  });
define("ember-handlebars/helpers/debug",
  ["ember-metal/core","ember-metal/utils","ember-metal/logger","ember-metal/property_get","ember-handlebars/ext","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    

    
    var Ember = __dependency1__["default"];
    // Ember.FEATURES,
    var inspect = __dependency2__.inspect;
    var Logger = __dependency3__["default"];

    var get = __dependency4__.get;
    var normalizePath = __dependency5__.normalizePath;
    var handlebarsGet = __dependency5__.handlebarsGet;

    var a_slice = [].slice;

    
    function logHelper() {
      var params = a_slice.call(arguments, 0, -1),
          options = arguments[arguments.length - 1],
          logger = Logger.log,
          values = [],
          allowPrimitives = true;

      for (var i = 0; i < params.length; i++) {
        var type = options.types[i];

        if (type === 'ID' || !allowPrimitives) {
          var context = (options.contexts && options.contexts[i]) || this,
              normalized = normalizePath(context, params[i], options.data);

          if (normalized.path === 'this') {
            values.push(normalized.root);
          } else {
            values.push(handlebarsGet(normalized.root, normalized.path, options));
          }
        } else {
          values.push(params[i]);
        }
      }

      logger.apply(logger, values);
    }

    
    function debuggerHelper(options) {

      // These are helpful values you can inspect while debugging.
      var templateContext = this;
      var typeOfTemplateContext = inspect(templateContext);
      Ember.Logger.info('Use `this` to access the context of the calling template.');

      debugger;
    }

    __exports__.logHelper = logHelper;
    __exports__.debuggerHelper = debuggerHelper;
  });
define("ember-handlebars/helpers/each",
  ["ember-metal/core","ember-handlebars-compiler","ember-runtime/system/string","ember-metal/property_get","ember-metal/property_set","ember-views/views/collection_view","ember-metal/binding","ember-runtime/mixins/controller","ember-runtime/controllers/array_controller","ember-runtime/mixins/array","ember-runtime/copy","ember-metal/run_loop","ember-metal/events","ember-handlebars/ext","ember-metal/computed","ember-metal/observer","ember-handlebars/views/metamorph_view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __exports__) {
    "use strict";

    
    var Ember = __dependency1__["default"];
    // Ember.assert;, Ember.K
    // var emberAssert = Ember.assert,
    var K = Ember.K;

    var EmberHandlebars = __dependency2__["default"];
    var helpers = EmberHandlebars.helpers;

    var fmt = __dependency3__.fmt;
    var get = __dependency4__.get;
    var set = __dependency5__.set;
    var CollectionView = __dependency6__["default"];
    var Binding = __dependency7__.Binding;
    var ControllerMixin = __dependency8__["default"];
    var ArrayController = __dependency9__["default"];
    var EmberArray = __dependency10__["default"];
    var copy = __dependency11__["default"];
    var run = __dependency12__["default"];
    var on = __dependency13__.on;
    var handlebarsGet = __dependency14__.handlebarsGet;
    var computed = __dependency15__.computed;

    var addObserver = __dependency16__.addObserver;
    var removeObserver = __dependency16__.removeObserver;
    var addBeforeObserver = __dependency16__.addBeforeObserver;
    var removeBeforeObserver = __dependency16__.removeBeforeObserver;

    var _Metamorph = __dependency17__._Metamorph;
    var _MetamorphView = __dependency17__._MetamorphView;

    var EachView = CollectionView.extend(_Metamorph, {

      init: function() {
        var itemController = get(this, 'itemController');
        var binding;

        if (itemController) {
          var controller = get(this, 'controller.container').lookupFactory('controller:array').create({
            _isVirtual: true,
            parentController: get(this, 'controller'),
            itemController: itemController,
            target: get(this, 'controller'),
            _eachView: this
          });

          this.disableContentObservers(function() {
            set(this, 'content', controller);
            binding = new Binding('content', '_eachView.dataSource').oneWay();
            binding.connect(controller);
          });

          set(this, '_arrayController', controller);
        } else {
          this.disableContentObservers(function() {
            binding = new Binding('content', 'dataSource').oneWay();
            binding.connect(this);
          });
        }

        return this._super();
      },

      _assertArrayLike: function(content) {
        Ember.assert(fmt("The value that #each loops over must be an Array. You " +
                         "passed %@, but it should have been an ArrayController",
                         [content.constructor]),
                         !ControllerMixin.detect(content) ||
                           (content && content.isGenerated) ||
                           content instanceof ArrayController);
        Ember.assert(fmt("The value that #each loops over must be an Array. You passed %@", [(ControllerMixin.detect(content) && content.get('model') !== undefined) ? fmt("'%@' (wrapped in %@)", [content.get('model'), content]) : content]), EmberArray.detect(content));
      },

      disableContentObservers: function(callback) {
        removeBeforeObserver(this, 'content', null, '_contentWillChange');
        removeObserver(this, 'content', null, '_contentDidChange');

        callback.call(this);

        addBeforeObserver(this, 'content', null, '_contentWillChange');
        addObserver(this, 'content', null, '_contentDidChange');
      },

      itemViewClass: _MetamorphView,
      emptyViewClass: _MetamorphView,

      createChildView: function(view, attrs) {
        view = this._super(view, attrs);

        // At the moment, if a container view subclass wants
        // to insert keywords, it is responsible for cloning
        // the keywords hash. This will be fixed momentarily.
        var keyword = get(this, 'keyword');
        var content = get(view, 'content');

        if (keyword) {
          var data = get(view, 'templateData');

          data = copy(data);
          data.keywords = view.cloneKeywords();
          set(view, 'templateData', data);

          // In this case, we do not bind, because the `content` of
          // a #each item cannot change.
          data.keywords[keyword] = content;
        }

        // If {{#each}} is looping over an array of controllers,
        // point each child view at their respective controller.
        if (content && content.isController) {
          set(view, 'controller', content);
        }

        return view;
      },

      destroy: function() {
        if (!this._super()) { return; }

        var arrayController = get(this, '_arrayController');

        if (arrayController) {
          arrayController.destroy();
        }

        return this;
      }
    });

    // Defeatureify doesn't seem to like nested functions that need to be removed
    function _addMetamorphCheck() {
      EachView.reopen({
        _checkMetamorph: on('didInsertElement', function() {
          Ember.assert("The metamorph tags, " +
                       this.morph.start + " and " + this.morph.end +
                       ", have different parents.\nThe browser has fixed your template to output valid HTML (for example, check that you have properly closed all tags and have used a TBODY tag when creating a table with '{{#each}}')",
            document.getElementById( this.morph.start ).parentNode ===
            document.getElementById( this.morph.end ).parentNode
          );
        })
      });
    }

    // until ember-debug is es6ed
    var runInDebug = function(f){ f(); };
    runInDebug( function() {
      _addMetamorphCheck();
    });

    var GroupedEach = EmberHandlebars.GroupedEach = function(context, path, options) {
      var self = this,
          normalized = EmberHandlebars.normalizePath(context, path, options.data);

      this.context = context;
      this.path = path;
      this.options = options;
      this.template = options.fn;
      this.containingView = options.data.view;
      this.normalizedRoot = normalized.root;
      this.normalizedPath = normalized.path;
      this.content = this.lookupContent();

      this.addContentObservers();
      this.addArrayObservers();

      this.containingView.on('willClearRender', function() {
        self.destroy();
      });
    };

    GroupedEach.prototype = {
      contentWillChange: function() {
        this.removeArrayObservers();
      },

      contentDidChange: function() {
        this.content = this.lookupContent();
        this.addArrayObservers();
        this.rerenderContainingView();
      },

      contentArrayWillChange: K,

      contentArrayDidChange: function() {
        this.rerenderContainingView();
      },

      lookupContent: function() {
        return handlebarsGet(this.normalizedRoot, this.normalizedPath, this.options);
      },

      addArrayObservers: function() {
        if (!this.content) { return; }

        this.content.addArrayObserver(this, {
          willChange: 'contentArrayWillChange',
          didChange: 'contentArrayDidChange'
        });
      },

      removeArrayObservers: function() {
        if (!this.content) { return; }

        this.content.removeArrayObserver(this, {
          willChange: 'contentArrayWillChange',
          didChange: 'contentArrayDidChange'
        });
      },

      addContentObservers: function() {
        addBeforeObserver(this.normalizedRoot, this.normalizedPath, this, this.contentWillChange);
        addObserver(this.normalizedRoot, this.normalizedPath, this, this.contentDidChange);
      },

      removeContentObservers: function() {
        removeBeforeObserver(this.normalizedRoot, this.normalizedPath, this.contentWillChange);
        removeObserver(this.normalizedRoot, this.normalizedPath, this.contentDidChange);
      },

      render: function() {
        if (!this.content) { return; }

        var content = this.content,
            contentLength = get(content, 'length'),
            options = this.options,
            data = options.data,
            template = this.template;

        data.insideEach = true;
        for (var i = 0; i < contentLength; i++) {
          var context = content.objectAt(i);
          options.data.keywords[options.hash.keyword] = context;
          template(context, { data: data });
        }
      },

      rerenderContainingView: function() {
        var self = this;
        run.scheduleOnce('render', this, function() {
          // It's possible it's been destroyed after we enqueued a re-render call.
          if (!self.destroyed) {
            self.containingView.rerender();
          }
        });
      },

      destroy: function() {
        this.removeContentObservers();
        if (this.content) {
          this.removeArrayObservers();
        }
        this.destroyed = true;
      }
    };

    
    function eachHelper(path, options) {
      var ctx, helperName = 'each';

      if (arguments.length === 4) {
        Ember.assert("If you pass more than one argument to the each helper, it must be in the form #each foo in bar", arguments[1] === "in");

        var keywordName = arguments[0];


        options = arguments[3];
        path = arguments[2];

        helperName += ' ' + keywordName + ' in ' + path;

        if (path === '') { path = "this"; }

        options.hash.keyword = keywordName;

      } else if (arguments.length === 1) {
        options = path;
        path = 'this';
      } else {
        helperName += ' ' + path;
      }

      options.hash.dataSourceBinding = path;
      // Set up emptyView as a metamorph with no tag
      //options.hash.emptyViewClass = Ember._MetamorphView;

      // can't rely on this default behavior when use strict
      ctx = this || window;

      options.helperName = options.helperName || helperName;

      if (options.data.insideGroup && !options.hash.groupedRows && !options.hash.itemViewClass) {
        new GroupedEach(ctx, path, options).render();
      } else {
        // ES6TODO: figure out how to do this without global lookup.
        return helpers.collection.call(ctx, 'Ember.Handlebars.EachView', options);
      }
    }

    __exports__.EachView = EachView;
    __exports__.GroupedEach = GroupedEach;
    __exports__.eachHelper = eachHelper;
  });
define("ember-handlebars/helpers/loc",
  ["ember-runtime/system/string","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var loc = __dependency1__.loc;

    

    // ES6TODO:
    // Pretty sure this can be expressed as
    // var locHelper EmberStringUtils.loc ?

    
    __exports__["default"] = function locHelper(str) {
      return loc(str);
    }
  });
define("ember-handlebars/helpers/partial",
  ["ember-metal/core","ember-metal/is_none","ember-handlebars/ext","ember-handlebars/helpers/binding","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.assert
    // var emberAssert = Ember.assert;

    var isNone = __dependency2__.isNone;
    var handlebarsGet = __dependency3__.handlebarsGet;
    var bind = __dependency4__.bind;

    

    

    __exports__["default"] = function partialHelper(name, options) {

      var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this;

      options.helperName = options.helperName || 'partial';

      if (options.types[0] === "ID") {
        // Helper was passed a property path; we need to
        // create a binding that will re-render whenever
        // this property changes.
        options.fn = function(context, fnOptions) {
          var partialName = handlebarsGet(context, name, fnOptions);
          renderPartial(context, partialName, fnOptions);
        };

        return bind.call(context, name, options, true, exists);
      } else {
        // Render the partial right into parent template.
        renderPartial(context, name, options);
      }
    }

    function exists(value) {
      return !isNone(value);
    }

    function renderPartial(context, name, options) {
      var nameParts = name.split("/");
      var lastPart = nameParts[nameParts.length - 1];

      nameParts[nameParts.length - 1] = "_" + lastPart;

      var view = options.data.view;
      var underscoredName = nameParts.join("/");
      var template = view.templateForName(underscoredName);
      var deprecatedTemplate = !template && view.templateForName(name);

      Ember.assert("Unable to find partial with name '"+name+"'.", template || deprecatedTemplate);

      template = template || deprecatedTemplate;

      template(context, { data: options.data });
    }
  });
define("ember-handlebars/helpers/shared",
  ["ember-handlebars/ext","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var handlebarsGet = __dependency1__.handlebarsGet;

    __exports__["default"] = function resolvePaths(options) {
      var ret = [],
          contexts = options.contexts,
          roots = options.roots,
          data = options.data;

      for (var i=0, l=contexts.length; i<l; i++) {
        ret.push(handlebarsGet(roots[i], contexts[i], { data: data }));
      }

      return ret;
    }
  });
define("ember-handlebars/helpers/template",
  ["ember-metal/core","ember-handlebars-compiler","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // var emberDeprecate = Ember.deprecate;

    var EmberHandlebars = __dependency2__["default"];
    var helpers = EmberHandlebars.helpers;
    

    
    __exports__["default"] = function templateHelper(name, options) {
      Ember.deprecate("The `template` helper has been deprecated in favor of the `partial` helper. Please use `partial` instead, which will work the same way.");

      options.helperName = options.helperName || 'template';

      return helpers.partial.apply(this, arguments);
    }
  });
define("ember-handlebars/helpers/unbound",
  ["ember-handlebars-compiler","ember-handlebars/helpers/binding","ember-handlebars/ext","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    

    

    var EmberHandlebars = __dependency1__["default"];
    var helpers = EmberHandlebars.helpers;

    var resolveHelper = __dependency2__.resolveHelper;
    var handlebarsGet = __dependency3__.handlebarsGet;

    var slice = [].slice;

    
    __exports__["default"] = function unboundHelper(property, fn) {
      var options = arguments[arguments.length - 1],
          container = options.data.view.container,
          helper, context, out, ctx;

      ctx = this;
      if (arguments.length > 2) {
        // Unbound helper call.
        options.data.isUnbound = true;
        helper = resolveHelper(container, property) || helpers.helperMissing;
        out = helper.apply(ctx, slice.call(arguments, 1));
        delete options.data.isUnbound;
        return out;
      }

      context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : ctx;
      return handlebarsGet(context, property, fn);
    }
  });
define("ember-handlebars/helpers/view",
  ["ember-metal/core","ember-runtime/system/object","ember-metal/property_get","ember-metal/property_set","ember-metal/mixin","ember-views/system/jquery","ember-views/views/view","ember-metal/binding","ember-handlebars/ext","ember-runtime/system/string","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) {
    "use strict";
    

    

    var Ember = __dependency1__["default"];
    // Ember.warn, Ember.assert
    // var emberWarn = Ember.warn, emberAssert = Ember.assert;

    var EmberObject = __dependency2__["default"];
    var get = __dependency3__.get;
    var set = __dependency4__.set;
    var IS_BINDING = __dependency5__.IS_BINDING;
    var jQuery = __dependency6__["default"];
    var View = __dependency7__["default"];
    var isGlobalPath = __dependency8__.isGlobalPath;
    var normalizePath = __dependency9__.normalizePath;
    var handlebarsGet = __dependency9__.handlebarsGet;
    var EmberString = __dependency10__["default"];


    var LOWERCASE_A_Z = /^[a-z]/,
        VIEW_PREFIX = /^view\./;

    function makeBindings(thisContext, options) {
      var hash = options.hash,
          hashType = options.hashTypes;

      for (var prop in hash) {
        if (hashType[prop] === 'ID') {

          var value = hash[prop];

          if (IS_BINDING.test(prop)) {
            Ember.warn("You're attempting to render a view by passing " + prop + "=" + value + " to a view helper, but this syntax is ambiguous. You should either surround " + value + " in quotes or remove `Binding` from " + prop + ".");
          } else {
            hash[prop + 'Binding'] = value;
            hashType[prop + 'Binding'] = 'STRING';
            delete hash[prop];
            delete hashType[prop];
          }
        }
      }

      if (hash.hasOwnProperty('idBinding')) {
        // id can't be bound, so just perform one-time lookup.
        hash.id = handlebarsGet(thisContext, hash.idBinding, options);
        hashType.id = 'STRING';
        delete hash.idBinding;
        delete hashType.idBinding;
      }
    }

    var ViewHelper = EmberObject.create({

      propertiesFromHTMLOptions: function(options) {
        var hash = options.hash, data = options.data;
        var extensions = {},
            classes = hash['class'],
            dup = false;

        if (hash.id) {
          extensions.elementId = hash.id;
          dup = true;
        }

        if (hash.tag) {
          extensions.tagName = hash.tag;
          dup = true;
        }

        if (classes) {
          classes = classes.split(' ');
          extensions.classNames = classes;
          dup = true;
        }

        if (hash.classBinding) {
          extensions.classNameBindings = hash.classBinding.split(' ');
          dup = true;
        }

        if (hash.classNameBindings) {
          if (extensions.classNameBindings === undefined) extensions.classNameBindings = [];
          extensions.classNameBindings = extensions.classNameBindings.concat(hash.classNameBindings.split(' '));
          dup = true;
        }

        if (hash.attributeBindings) {
          Ember.assert("Setting 'attributeBindings' via Handlebars is not allowed. Please subclass Ember.View and set it there instead.");
          extensions.attributeBindings = null;
          dup = true;
        }

        if (dup) {
          hash = jQuery.extend({}, hash);
          delete hash.id;
          delete hash.tag;
          delete hash['class'];
          delete hash.classBinding;
        }

        // Set the proper context for all bindings passed to the helper. This applies to regular attribute bindings
        // as well as class name bindings. If the bindings are local, make them relative to the current context
        // instead of the view.
        var path;

        // Evaluate the context of regular attribute bindings:
        for (var prop in hash) {
          if (!hash.hasOwnProperty(prop)) { continue; }

          // Test if the property ends in "Binding"
          if (IS_BINDING.test(prop) && typeof hash[prop] === 'string') {
            path = this.contextualizeBindingPath(hash[prop], data);
            if (path) { hash[prop] = path; }
          }
        }

        // Evaluate the context of class name bindings:
        if (extensions.classNameBindings) {
          for (var b in extensions.classNameBindings) {
            var full = extensions.classNameBindings[b];
            if (typeof full === 'string') {
              // Contextualize the path of classNameBinding so this:
              //
              //     classNameBinding="isGreen:green"
              //
              // is converted to this:
              //
              //     classNameBinding="_parentView.context.isGreen:green"
              var parsedPath = View._parsePropertyPath(full);
              if(parsedPath.path !== '') {
                path = this.contextualizeBindingPath(parsedPath.path, data); 
                if (path) { extensions.classNameBindings[b] = path + parsedPath.classNames; }
              }
            }
          }
        }

        return jQuery.extend(hash, extensions);
      },

      // Transform bindings from the current context to a context that can be evaluated within the view.
      // Returns null if the path shouldn't be changed.
      //
      // TODO: consider the addition of a prefix that would allow this method to return `path`.
      contextualizeBindingPath: function(path, data) {
        var normalized = normalizePath(null, path, data);
        if (normalized.isKeyword) {
          return 'templateData.keywords.' + path;
        } else if (isGlobalPath(path)) {
          return null;
        } else if (path === 'this' || path === '') {
          return '_parentView.context';
        } else {
          return '_parentView.context.' + path;
        }
      },

      helper: function(thisContext, path, options) {
        var data = options.data,
            fn = options.fn,
            newView;

        makeBindings(thisContext, options);

        if ('string' === typeof path) {
          var lookup;
          // TODO: this is a lame conditional, this should likely change
          // but something along these lines will likely need to be added
          // as deprecation warnings
          //
          if (options.types[0] === 'STRING' && LOWERCASE_A_Z.test(path) && !VIEW_PREFIX.test(path)) {
            lookup = path;
          } else {
            newView = handlebarsGet(thisContext, path, options);
            if (typeof newView === 'string') {
              lookup = newView;
            }
          }

          if (lookup) {
            Ember.assert("View requires a container", !!data.view.container);
            newView = data.view.container.lookupFactory('view:' + lookup);
          }

          Ember.assert("Unable to find view at path '" + path + "'", !!newView);
        } else {
          newView = path;
        }

        Ember.assert(EmberString.fmt('You must pass a view to the #view helper, not %@ (%@)', [path, newView]), View.detect(newView) || View.detectInstance(newView));

        var viewOptions = this.propertiesFromHTMLOptions(options, thisContext);
        var currentView = data.view;
        viewOptions.templateData = data;
        var newViewProto = newView.proto ? newView.proto() : newView;

        if (fn) {
          Ember.assert("You cannot provide a template block if you also specified a templateName", !get(viewOptions, 'templateName') && !get(newViewProto, 'templateName'));
          viewOptions.template = fn;
        }

        // We only want to override the `_context` computed property if there is
        // no specified controller. See View#_context for more information.
        if (!newViewProto.controller && !newViewProto.controllerBinding && !viewOptions.controller && !viewOptions.controllerBinding) {
          viewOptions._context = thisContext;
        }

        // for instrumentation
        if (options.helperName) {
          viewOptions.helperName = options.helperName;
        }

        currentView.appendChild(newView, viewOptions);
      }
    });
    __exports__.ViewHelper = ViewHelper;
    
    function viewHelper(path, options) {
      Ember.assert("The view helper only takes a single argument", arguments.length <= 2);

      // If no path is provided, treat path param as options
      // and get an instance of the registered `view:toplevel`
      if (path && path.data && path.data.isRenderData) {
        options = path;
        Ember.assert('{{view}} helper requires parent view to have a container but none was found. This usually happens when you are manually-managing views.', !!options.data.view.container);
        path = options.data.view.container.lookupFactory('view:toplevel');
      }

      options.helperName = options.helperName || 'view';

      return ViewHelper.helper(this, path, options);
    }

    __exports__.viewHelper = viewHelper;
  });
define("ember-handlebars/helpers/yield",
  ["ember-metal/core","ember-metal/property_get","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // var emberAssert = Ember.assert;

    var get = __dependency2__.get;

    
    __exports__["default"] = function yieldHelper(options) {
      var view = options.data.view;

      while (view && !get(view, 'layout')) {
        if (view._contextView) {
          view = view._contextView;
        } else {
          view = get(view, '_parentView');
        }
      }

      Ember.assert("You called yield in a template that was not a layout", !!view);

      view._yield(this, options);
    }
  });
define("ember-handlebars/loader",
  ["ember-handlebars/component_lookup","ember-views/system/jquery","ember-metal/error","ember-runtime/system/lazy_load","ember-handlebars-compiler","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    

    var ComponentLookup = __dependency1__["default"];
    var jQuery = __dependency2__["default"];
    var EmberError = __dependency3__["default"];
    var onLoad = __dependency4__.onLoad;

    var EmberHandlebars = __dependency5__["default"];

    

    
    function bootstrap(ctx) {
      var selectors = 'script[type="text/x-handlebars"], script[type="text/x-raw-handlebars"]';

      jQuery(selectors, ctx)
        .each(function() {
        // Get a reference to the script tag
        var script = jQuery(this);

        var compile = (script.attr('type') === 'text/x-raw-handlebars') ?
                      jQuery.proxy(Handlebars.compile, Handlebars) :
                      jQuery.proxy(EmberHandlebars.compile, EmberHandlebars),
          // Get the name of the script, used by Ember.View's templateName property.
          // First look for data-template-name attribute, then fall back to its
          // id if no name is found.
          templateName = script.attr('data-template-name') || script.attr('id') || 'application',
          template = compile(script.html());

        // Check if template of same name already exists
        if (Ember.TEMPLATES[templateName] !== undefined) {
          throw new EmberError('Template named "' + templateName  + '" already exists.');
        }

        // For templates which have a name, we save them and then remove them from the DOM
        Ember.TEMPLATES[templateName] = template;

        // Remove script tag from DOM
        script.remove();
      });
    }

    function _bootstrap() {
      bootstrap( jQuery(document) );
    }

    function registerComponentLookup(container) {
      container.register('component-lookup:main', ComponentLookup);
    }

    

    onLoad('Ember.Application', function(Application) {
      Application.initializer({
        name: 'domTemplates',
        initialize: _bootstrap
      });

      Application.initializer({
        name: 'registerComponentLookup',
        after: 'domTemplates',
        initialize: registerComponentLookup
      });
    });

    __exports__["default"] = bootstrap;
  });
define("ember-handlebars/string",
  ["ember-runtime/system/string","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    // required so we can extend this object.
    var EmberStringUtils = __dependency1__["default"];

    
    function htmlSafe(str) {
      return new Handlebars.SafeString(str);
    }

    EmberStringUtils.htmlSafe = htmlSafe;
    if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {

      
      String.prototype.htmlSafe = function() {
        return htmlSafe(this);
      };
    }

    __exports__["default"] = htmlSafe;
  });
define("ember-handlebars/views/handlebars_bound_view",
  ["ember-handlebars-compiler","ember-metal/core","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-metal/merge","ember-metal/run_loop","ember-metal/computed","ember-views/views/view","ember-views/views/states","ember-handlebars/views/metamorph_view","ember-handlebars/ext","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) {
    "use strict";
    
    


    

    var EmberHandlebars = __dependency1__["default"];
    // EmberHandlebars.SafeString;
    var SafeString = EmberHandlebars.SafeString;

    var Ember = __dependency2__["default"];
    // Ember.K
    var K = Ember.K;

    var Metamorph = requireModule('metamorph');

    var EmberError = __dependency3__["default"];
    var get = __dependency4__.get;
    var set = __dependency5__.set;
    var merge = __dependency6__["default"];
    var run = __dependency7__["default"];
    var computed = __dependency8__.computed;
    var View = __dependency9__["default"];
    var cloneStates = __dependency10__.cloneStates;
    var states = __dependency10__.states;
    var viewStates = states;

    var _MetamorphView = __dependency11__["default"];
    var handlebarsGet = __dependency12__.handlebarsGet;

    function SimpleHandlebarsView(path, pathRoot, isEscaped, templateData) {
      this.path = path;
      this.pathRoot = pathRoot;
      this.isEscaped = isEscaped;
      this.templateData = templateData;

      this._lastNormalizedValue = undefined;
      this.morph = Metamorph();
      this.state = 'preRender';
      this.updateId = null;
      this._parentView = null;
      this.buffer = null;
    }

    SimpleHandlebarsView.prototype = {
      isVirtual: true,
      isView: true,

      destroy: function () {
        if (this.updateId) {
          run.cancel(this.updateId);
          this.updateId = null;
        }
        if (this._parentView) {
          this._parentView.removeChild(this);
        }
        this.morph = null;
        this.state = 'destroyed';
      },

      propertyWillChange: K,

      propertyDidChange: K,

      normalizedValue: function() {
        var path = this.path;
        var pathRoot = this.pathRoot;
        var result, templateData;

        // Use the pathRoot as the result if no path is provided. This
        // happens if the path is `this`, which gets normalized into
        // a `pathRoot` of the current Handlebars context and a path
        // of `''`.
        if (path === '') {
          result = pathRoot;
        } else {
          templateData = this.templateData;
          result = handlebarsGet(pathRoot, path, { data: templateData });
        }

        return result;
      },

      renderToBuffer: function(buffer) {
        var string = '';

        string += this.morph.startTag();
        string += this.render();
        string += this.morph.endTag();

        buffer.push(string);
      },

      render: function(value) {
        // If not invoked via a triple-mustache ({{{foo}}}), escape
        // the content of the template.
        var escape = this.isEscaped;
        var result = value || this.normalizedValue();
        this._lastNormalizedValue = result;
        if (result === null || result === undefined) {
          result = "";
        } else if (!(result instanceof SafeString)) {
          result = String(result);
        }

        if (escape) { result = Handlebars.Utils.escapeExpression(result); }
        return result;
      },

      rerender: function() {
        switch(this.state) {
          case 'preRender':
          case 'destroyed':
            break;
          case 'inBuffer':
            throw new EmberError("Something you did tried to replace an {{expression}} before it was inserted into the DOM.");
          case 'hasElement':
          case 'inDOM':
            this.updateId = run.scheduleOnce('render', this, 'update');
            break;
        }

        return this;
      },

      update: function () {
        this.updateId = null;
        var value = this.normalizedValue();
        if (value !== this._lastNormalizedValue) {
          this.morph.html(this.render(value));
        }
      },

      _transitionTo: function(state) {
        this.state = state;
      }
    };

    states = cloneStates(viewStates);

    merge(states._default, {
      rerenderIfNeeded: K
    });

    merge(states.inDOM, {
      rerenderIfNeeded: function(view) {
        if (view.normalizedValue() !== view._lastNormalizedValue) {
          view.rerender();
        }
      }
    });

    
    var _HandlebarsBoundView = _MetamorphView.extend({
      instrumentName: 'boundHandlebars',

      _states: states,

      
      shouldDisplayFunc: null,

      
      preserveContext: false,

      
      previousContext: null,

      
      displayTemplate: null,

      
      inverseTemplate: null,


      
      path: null,

      
      pathRoot: null,

      normalizedValue: function() {
        var path = get(this, 'path'),
            pathRoot  = get(this, 'pathRoot'),
            valueNormalizer = get(this, 'valueNormalizerFunc'),
            result, templateData;

        // Use the pathRoot as the result if no path is provided. This
        // happens if the path is `this`, which gets normalized into
        // a `pathRoot` of the current Handlebars context and a path
        // of `''`.
        if (path === '') {
          result = pathRoot;
        } else {
          templateData = get(this, 'templateData');
          result = handlebarsGet(pathRoot, path, { data: templateData });
        }

        return valueNormalizer ? valueNormalizer(result) : result;
      },

      rerenderIfNeeded: function() {
        this.currentState.rerenderIfNeeded(this);
      },

      
      render: function(buffer) {
        // If not invoked via a triple-mustache ({{{foo}}}), escape
        // the content of the template.
        var escape = get(this, 'isEscaped');

        var shouldDisplay = get(this, 'shouldDisplayFunc'),
            preserveContext = get(this, 'preserveContext'),
            context = get(this, 'previousContext');

        var inverseTemplate = get(this, 'inverseTemplate'),
            displayTemplate = get(this, 'displayTemplate');

        var result = this.normalizedValue();
        this._lastNormalizedValue = result;

        // First, test the conditional to see if we should
        // render the template or not.
        if (shouldDisplay(result)) {
          set(this, 'template', displayTemplate);

          // If we are preserving the context (for example, if this
          // is an #if block, call the template with the same object.
          if (preserveContext) {
            set(this, '_context', context);
          } else {
          // Otherwise, determine if this is a block bind or not.
          // If so, pass the specified object to the template
            if (displayTemplate) {
              set(this, '_context', result);
            } else {
            // This is not a bind block, just push the result of the
            // expression to the render context and return.
              if (result === null || result === undefined) {
                result = "";
              } else if (!(result instanceof SafeString)) {
                result = String(result);
              }

              if (escape) { result = Handlebars.Utils.escapeExpression(result); }
              buffer.push(result);
              return;
            }
          }
        } else if (inverseTemplate) {
          set(this, 'template', inverseTemplate);

          if (preserveContext) {
            set(this, '_context', context);
          } else {
            set(this, '_context', result);
          }
        } else {
          set(this, 'template', function() { return ''; });
        }

        return this._super(buffer);
      }
    });

    __exports__._HandlebarsBoundView = _HandlebarsBoundView;
    __exports__.SimpleHandlebarsView = SimpleHandlebarsView;
  });
define("ember-handlebars/views/metamorph_view",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","ember-metal/run_loop","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
    "use strict";
    

    
    var Ember = __dependency1__["default"];
    // Ember.deprecate
    // var emberDeprecate = Ember.deprecate;

    var get = __dependency2__.get;
    var set = __dependency3__["default"];

    var CoreView = __dependency4__["default"];
    var View = __dependency5__["default"];
    var Mixin = __dependency6__.Mixin;
    var run = __dependency7__["default"];

    

    var Metamorph = requireModule('metamorph');

    function notifyMutationListeners() {
      run.once(View, 'notifyMutationListeners');
    }

    // DOMManager should just abstract dom manipulation between jquery and metamorph
    var DOMManager = {
      remove: function(view) {
        view.morph.remove();
        notifyMutationListeners();
      },

      prepend: function(view, html) {
        view.morph.prepend(html);
        notifyMutationListeners();
      },

      after: function(view, html) {
        view.morph.after(html);
        notifyMutationListeners();
      },

      html: function(view, html) {
        view.morph.html(html);
        notifyMutationListeners();
      },

      // This is messed up.
      replace: function(view) {
        var morph = view.morph;

        view._transitionTo('preRender');

        run.schedule('render', this, function renderMetamorphView() {
          if (view.isDestroying) { return; }

          view.clearRenderedChildren();
          var buffer = view.renderToBuffer();

          view.invokeRecursively(function(view) {
            view.propertyWillChange('element');
          });
          view.triggerRecursively('willInsertElement');

          morph.replaceWith(buffer.string());
          view._transitionTo('inDOM');

          view.invokeRecursively(function(view) {
            view.propertyDidChange('element');
          });
          view.triggerRecursively('didInsertElement');

          notifyMutationListeners();
        });
      },

      empty: function(view) {
        view.morph.html("");
        notifyMutationListeners();
      }
    };

    // The `morph` and `outerHTML` properties are internal only
    // and not observable.

    
    var _Metamorph = Mixin.create({
      isVirtual: true,
      tagName: '',

      instrumentName: 'metamorph',

      init: function() {
        this._super();
        this.morph = Metamorph();
        Ember.deprecate('Supplying a tagName to Metamorph views is unreliable and is deprecated. You may be setting the tagName on a Handlebars helper that creates a Metamorph.', !this.tagName);
      },

      beforeRender: function(buffer) {
        buffer.push(this.morph.startTag());
        buffer.pushOpeningTag();
      },

      afterRender: function(buffer) {
        buffer.pushClosingTag();
        buffer.push(this.morph.endTag());
      },

      createElement: function() {
        var buffer = this.renderToBuffer();
        this.outerHTML = buffer.string();
        this.clearBuffer();
      },

      domManager: DOMManager
    });
    __exports__._Metamorph = _Metamorph;
    var _wrapMap = Metamorph._wrapMap;
    __exports__._wrapMap = _wrapMap;
    
    var _MetamorphView = View.extend(_Metamorph);
    __exports__._MetamorphView = _MetamorphView;
    
    var _SimpleMetamorphView = CoreView.extend(_Metamorph);
    __exports__._SimpleMetamorphView = _SimpleMetamorphView;__exports__["default"] = View.extend(_Metamorph);
  });
define("ember-metal",
  ["ember-metal/core","ember-metal/merge","ember-metal/instrumentation","ember-metal/utils","ember-metal/error","ember-metal/enumerable_utils","ember-metal/platform","ember-metal/array","ember-metal/logger","ember-metal/property_get","ember-metal/events","ember-metal/observer_set","ember-metal/property_events","ember-metal/properties","ember-metal/property_set","ember-metal/map","ember-metal/get_properties","ember-metal/set_properties","ember-metal/watch_key","ember-metal/chains","ember-metal/watch_path","ember-metal/watching","ember-metal/expand_properties","ember-metal/computed","ember-metal/computed_macros","ember-metal/observer","ember-metal/mixin","ember-metal/binding","ember-metal/run_loop","ember-metal/libraries","ember-metal/is_none","ember-metal/is_empty","ember-metal/is_blank","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __dependency27__, __dependency28__, __dependency29__, __dependency30__, __dependency31__, __dependency32__, __dependency33__, __exports__) {
    "use strict";
    

    // BEGIN IMPORTS
    var Ember = __dependency1__["default"];
    var merge = __dependency2__["default"];
    var instrument = __dependency3__.instrument;
    var subscribe = __dependency3__.subscribe;
    var unsubscribe = __dependency3__.unsubscribe;
    var reset = __dependency3__.reset;
    var generateGuid = __dependency4__.generateGuid;
    var GUID_KEY = __dependency4__.GUID_KEY;
    var GUID_PREFIX = __dependency4__.GUID_PREFIX;
    var guidFor = __dependency4__.guidFor;
    var META_DESC = __dependency4__.META_DESC;
    var EMPTY_META = __dependency4__.EMPTY_META;
    var meta = __dependency4__.meta;
    var getMeta = __dependency4__.getMeta;
    var setMeta = __dependency4__.setMeta;
    var metaPath = __dependency4__.metaPath;
    var inspect = __dependency4__.inspect;
    var typeOf = __dependency4__.typeOf;
    var tryCatchFinally = __dependency4__.tryCatchFinally;
    var isArray = __dependency4__.isArray;
    var makeArray = __dependency4__.makeArray;
    var canInvoke = __dependency4__.canInvoke;
    var tryInvoke = __dependency4__.tryInvoke;
    var tryFinally = __dependency4__.tryFinally;
    var wrap = __dependency4__.wrap;
    var apply = __dependency4__.apply;
    var applyStr = __dependency4__.applyStr;
    var uuid = __dependency4__.uuid;
    var EmberError = __dependency5__["default"];
    var EnumerableUtils = __dependency6__["default"];

    var create = __dependency7__.create;
    var platform = __dependency7__.platform;
    var map = __dependency8__.map;
    var forEach = __dependency8__.forEach;
    var filter = __dependency8__.filter;
    var indexOf = __dependency8__.indexOf;
    var Logger = __dependency9__["default"];

    var get = __dependency10__.get;
    var getWithDefault = __dependency10__.getWithDefault;
    var normalizeTuple = __dependency10__.normalizeTuple;
    var _getPath = __dependency10__._getPath;

    var on = __dependency11__.on;
    var addListener = __dependency11__.addListener;
    var removeListener = __dependency11__.removeListener;
    var suspendListener = __dependency11__.suspendListener;
    var suspendListeners = __dependency11__.suspendListeners;
    var sendEvent = __dependency11__.sendEvent;
    var hasListeners = __dependency11__.hasListeners;
    var watchedEvents = __dependency11__.watchedEvents;
    var listenersFor = __dependency11__.listenersFor;
    var listenersDiff = __dependency11__.listenersDiff;
    var listenersUnion = __dependency11__.listenersUnion;

    var ObserverSet = __dependency12__["default"];

    var propertyWillChange = __dependency13__.propertyWillChange;
    var propertyDidChange = __dependency13__.propertyDidChange;
    var overrideChains = __dependency13__.overrideChains;
    var beginPropertyChanges = __dependency13__.beginPropertyChanges;
    var endPropertyChanges = __dependency13__.endPropertyChanges;
    var changeProperties = __dependency13__.changeProperties;

    var Descriptor = __dependency14__.Descriptor;
    var defineProperty = __dependency14__.defineProperty;
    var set = __dependency15__.set;
    var trySet = __dependency15__.trySet;

    var OrderedSet = __dependency16__.OrderedSet;
    var Map = __dependency16__.Map;
    var MapWithDefault = __dependency16__.MapWithDefault;
    var getProperties = __dependency17__["default"];
    var setProperties = __dependency18__["default"];
    var watchKey = __dependency19__.watchKey;
    var unwatchKey = __dependency19__.unwatchKey;
    var flushPendingChains = __dependency20__.flushPendingChains;
    var removeChainWatcher = __dependency20__.removeChainWatcher;
    var ChainNode = __dependency20__.ChainNode;
    var finishChains = __dependency20__.finishChains;
    var watchPath = __dependency21__.watchPath;
    var unwatchPath = __dependency21__.unwatchPath;
    var watch = __dependency22__.watch;
    var isWatching = __dependency22__.isWatching;
    var unwatch = __dependency22__.unwatch;
    var rewatch = __dependency22__.rewatch;
    var destroy = __dependency22__.destroy;
    var expandProperties = __dependency23__["default"];
    var ComputedProperty = __dependency24__.ComputedProperty;
    var computed = __dependency24__.computed;
    var cacheFor = __dependency24__.cacheFor;

    // side effect of defining the computed.* macros

    var addObserver = __dependency26__.addObserver;
    var observersFor = __dependency26__.observersFor;
    var removeObserver = __dependency26__.removeObserver;
    var addBeforeObserver = __dependency26__.addBeforeObserver;
    var _suspendBeforeObserver = __dependency26__._suspendBeforeObserver;
    var _suspendObserver = __dependency26__._suspendObserver;
    var _suspendBeforeObservers = __dependency26__._suspendBeforeObservers;
    var _suspendObservers = __dependency26__._suspendObservers;
    var beforeObserversFor = __dependency26__.beforeObserversFor;
    var removeBeforeObserver = __dependency26__.removeBeforeObserver;
    var IS_BINDING = __dependency27__.IS_BINDING;
    var mixin = __dependency27__.mixin;
    var Mixin = __dependency27__.Mixin;
    var required = __dependency27__.required;
    var aliasMethod = __dependency27__.aliasMethod;
    var observer = __dependency27__.observer;
    var immediateObserver = __dependency27__.immediateObserver;
    var beforeObserver = __dependency27__.beforeObserver;
    var Binding = __dependency28__.Binding;
    var isGlobalPath = __dependency28__.isGlobalPath;
    var bind = __dependency28__.bind;
    var oneWay = __dependency28__.oneWay;
    var run = __dependency29__["default"];
    var libraries = __dependency30__["default"];
    var isNone = __dependency31__.isNone;
    var none = __dependency31__.none;
    var isEmpty = __dependency32__.isEmpty;
    var empty = __dependency32__.empty;
    var isBlank = __dependency33__["default"];
    // END IMPORTS

    // BEGIN EXPORTS
    var EmberInstrumentation = Ember.Instrumentation = {};
    EmberInstrumentation.instrument = instrument;
    EmberInstrumentation.subscribe = subscribe;
    EmberInstrumentation.unsubscribe = unsubscribe;
    EmberInstrumentation.reset  = reset;

    Ember.instrument = instrument;
    Ember.subscribe = subscribe;

    Ember.generateGuid    = generateGuid;
    Ember.GUID_KEY        = GUID_KEY;
    Ember.GUID_PREFIX     = GUID_PREFIX;
    Ember.create          = create;
    Ember.platform        = platform;

    var EmberArrayPolyfills = Ember.ArrayPolyfills = {};

    EmberArrayPolyfills.map = map;
    EmberArrayPolyfills.forEach = forEach;
    EmberArrayPolyfills.filter = filter;
    EmberArrayPolyfills.indexOf = indexOf;

    Ember.Error           = EmberError;
    Ember.guidFor         = guidFor;
    Ember.META_DESC       = META_DESC;
    Ember.EMPTY_META      = EMPTY_META;
    Ember.meta            = meta;
    Ember.getMeta         = getMeta;
    Ember.setMeta         = setMeta;
    Ember.metaPath        = metaPath;
    Ember.inspect         = inspect;
    Ember.typeOf          = typeOf;
    Ember.tryCatchFinally = tryCatchFinally;
    Ember.isArray         = isArray;
    Ember.makeArray       = makeArray;
    Ember.canInvoke       = canInvoke;
    Ember.tryInvoke       = tryInvoke;
    Ember.tryFinally      = tryFinally;
    Ember.wrap            = wrap;
    Ember.apply           = apply;
    Ember.applyStr        = applyStr;
    Ember.uuid            = uuid;

    Ember.Logger = Logger;

    Ember.get            = get;
    Ember.getWithDefault = getWithDefault;
    Ember.normalizeTuple = normalizeTuple;
    Ember._getPath       = _getPath;

    Ember.EnumerableUtils = EnumerableUtils;

    Ember.on                = on;
    Ember.addListener       = addListener;
    Ember.removeListener    = removeListener;
    Ember._suspendListener  = suspendListener;
    Ember._suspendListeners = suspendListeners;
    Ember.sendEvent         = sendEvent;
    Ember.hasListeners      = hasListeners;
    Ember.watchedEvents     = watchedEvents;
    Ember.listenersFor      = listenersFor;
    Ember.listenersDiff     = listenersDiff;
    Ember.listenersUnion    = listenersUnion;

    Ember._ObserverSet = ObserverSet;

    Ember.propertyWillChange = propertyWillChange;
    Ember.propertyDidChange = propertyDidChange;
    Ember.overrideChains = overrideChains;
    Ember.beginPropertyChanges = beginPropertyChanges;
    Ember.endPropertyChanges = endPropertyChanges;
    Ember.changeProperties = changeProperties;

    Ember.Descriptor     = Descriptor;
    Ember.defineProperty = defineProperty;

    Ember.set    = set;
    Ember.trySet = trySet;

    Ember.OrderedSet = OrderedSet;
    Ember.Map = Map;
    Ember.MapWithDefault = MapWithDefault;

    Ember.getProperties = getProperties;
    Ember.setProperties = setProperties;

    Ember.watchKey   = watchKey;
    Ember.unwatchKey = unwatchKey;

    Ember.flushPendingChains = flushPendingChains;
    Ember.removeChainWatcher = removeChainWatcher;
    Ember._ChainNode = ChainNode;
    Ember.finishChains = finishChains;

    Ember.watchPath = watchPath;
    Ember.unwatchPath = unwatchPath;

    Ember.watch = watch;
    Ember.isWatching = isWatching;
    Ember.unwatch = unwatch;
    Ember.rewatch = rewatch;
    Ember.destroy = destroy;

    Ember.expandProperties = expandProperties;

    Ember.ComputedProperty = ComputedProperty;
    Ember.computed = computed;
    Ember.cacheFor = cacheFor;

    Ember.addObserver = addObserver;
    Ember.observersFor = observersFor;
    Ember.removeObserver = removeObserver;
    Ember.addBeforeObserver = addBeforeObserver;
    Ember._suspendBeforeObserver = _suspendBeforeObserver;
    Ember._suspendBeforeObservers = _suspendBeforeObservers;
    Ember._suspendObserver = _suspendObserver;
    Ember._suspendObservers = _suspendObservers;
    Ember.beforeObserversFor = beforeObserversFor;
    Ember.removeBeforeObserver = removeBeforeObserver;

    Ember.IS_BINDING = IS_BINDING;
    Ember.required = required;
    Ember.aliasMethod = aliasMethod;
    Ember.observer = observer;
    Ember.immediateObserver = immediateObserver;
    Ember.beforeObserver = beforeObserver;
    Ember.mixin = mixin;
    Ember.Mixin = Mixin;

    Ember.oneWay = oneWay;
    Ember.bind = bind;
    Ember.Binding = Binding;
    Ember.isGlobalPath = isGlobalPath;

    Ember.run = run;

    Ember.libraries = libraries;
    Ember.libraries.registerCoreLibrary('Ember', Ember.VERSION);

    Ember.isNone = isNone;
    Ember.none = none;

    Ember.isEmpty = isEmpty;
    Ember.empty = empty;

    Ember.isBlank = isBlank;

    Ember.merge = merge;

    
    Ember.onerror = null;
    // END EXPORTS

    // do this for side-effects of updating Ember.assert, warn, etc when
    // ember-debug is present
    if (Ember.__loader.registry['ember-debug']) {
      requireModule('ember-debug');
    }

    __exports__["default"] = Ember;
  });
define("ember-metal/alias",
  ["ember-metal/property_get","ember-metal/property_set","ember-metal/error","ember-metal/properties","ember-metal/computed","ember-metal/platform","ember-metal/utils","ember-metal/dependent_keys","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var EmberError = __dependency3__["default"];
    var Descriptor = __dependency4__.Descriptor;
    var defineProperty = __dependency4__.defineProperty;
    var ComputedProperty = __dependency5__.ComputedProperty;
    var create = __dependency6__.create;
    var meta = __dependency7__.meta;
    var inspect = __dependency7__.inspect;
    var addDependentKeys = __dependency8__.addDependentKeys;
    var removeDependentKeys = __dependency8__.removeDependentKeys;

    function alias(altKey) {
      return new AliasedProperty(altKey);
    }

    __exports__.alias = alias;function AliasedProperty(altKey) {
      this.altKey = altKey;
      this._dependentKeys = [ altKey ];
    }

    __exports__.AliasedProperty = AliasedProperty;AliasedProperty.prototype = create(Descriptor.prototype);

    AliasedProperty.prototype.get = function AliasedProperty_get(obj, keyName) {
      return get(obj, this.altKey);
    };

    AliasedProperty.prototype.set = function AliasedProperty_set(obj, keyName, value) {
      return set(obj, this.altKey, value);
    };

    AliasedProperty.prototype.willWatch = function(obj, keyName) {
      addDependentKeys(this, obj, keyName, meta(obj));
    };

    AliasedProperty.prototype.didUnwatch = function(obj, keyName) {
      removeDependentKeys(this, obj, keyName, meta(obj));
    };

    AliasedProperty.prototype.setup = function(obj, keyName) {
      var m = meta(obj);
      if (m.watching[keyName]) {
        addDependentKeys(this, obj, keyName, m);
      }
    };

    AliasedProperty.prototype.teardown = function(obj, keyName) {
      var m = meta(obj);
      if (m.watching[keyName]) {
        removeDependentKeys(this, obj, keyName, m);
      }
    };

    AliasedProperty.prototype.readOnly = function() {
      this.set = AliasedProperty_readOnlySet;
      return this;
    };

    function AliasedProperty_readOnlySet(obj, keyName, value) {
      throw new EmberError('Cannot set read-only property "' + keyName + '" on object: ' + inspect(obj));
    }

    AliasedProperty.prototype.oneWay = function() {
      this.set = AliasedProperty_oneWaySet;
      return this;
    };

    function AliasedProperty_oneWaySet(obj, keyName, value) {
      defineProperty(obj, keyName, null);
      return set(obj, keyName, value);
    }

    // Backwards compatibility with Ember Data
    AliasedProperty.prototype._meta = undefined;
    AliasedProperty.prototype.meta = ComputedProperty.prototype.meta;
  });
define("ember-metal/array",
  ["exports"],
  function(__exports__) {
    "use strict";
    

    var ArrayPrototype = Array.prototype;

    // Testing this is not ideal, but we want to use native functions
    // if available, but not to use versions created by libraries like Prototype
    var isNativeFunc = function(func) {
      // This should probably work in all browsers likely to have ES5 array methods
      return func && Function.prototype.toString.call(func).indexOf('[native code]') > -1;
    };

    // From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map
    var map = isNativeFunc(ArrayPrototype.map) ? ArrayPrototype.map : function(fun ) {
      //"use strict";

      if (this === void 0 || this === null) {
        throw new TypeError();
      }

      var t = Object(this);
      var len = t.length >>> 0;
      if (typeof fun !== "function") {
        throw new TypeError();
      }

      var res = new Array(len);
      var thisp = arguments[1];
      for (var i = 0; i < len; i++) {
        if (i in t) {
          res[i] = fun.call(thisp, t[i], i, t);
        }
      }

      return res;
    };

    // From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
    var forEach = isNativeFunc(ArrayPrototype.forEach) ? ArrayPrototype.forEach : function(fun ) {
      //"use strict";

      if (this === void 0 || this === null) {
        throw new TypeError();
      }

      var t = Object(this);
      var len = t.length >>> 0;
      if (typeof fun !== "function") {
        throw new TypeError();
      }

      var thisp = arguments[1];
      for (var i = 0; i < len; i++) {
        if (i in t) {
          fun.call(thisp, t[i], i, t);
        }
      }
    };

    var indexOf = isNativeFunc(ArrayPrototype.indexOf) ? ArrayPrototype.indexOf : function (obj, fromIndex) {
      if (fromIndex === null || fromIndex === undefined) { fromIndex = 0; }
      else if (fromIndex < 0) { fromIndex = Math.max(0, this.length + fromIndex); }
      for (var i = fromIndex, j = this.length; i < j; i++) {
        if (this[i] === obj) { return i; }
      }
      return -1;
    };

    var filter = isNativeFunc(ArrayPrototype.filter) ? ArrayPrototype.filter : function (fn, context) {
      var i,
      value,
      result = [],
      length = this.length;

      for (i = 0; i < length; i++) {
        if (this.hasOwnProperty(i)) {
          value = this[i];
          if (fn.call(context, value, i, this)) {
            result.push(value);
          }
        }
      }
      return result;
    };


    if (Ember.SHIM_ES5) {
      if (!ArrayPrototype.map) {
        ArrayPrototype.map = map;
      }

      if (!ArrayPrototype.forEach) {
        ArrayPrototype.forEach = forEach;
      }

      if (!ArrayPrototype.filter) {
        ArrayPrototype.filter = filter;
      }

      if (!ArrayPrototype.indexOf) {
        ArrayPrototype.indexOf = indexOf;
      }
    }

    
    __exports__.map = map;
    __exports__.forEach = forEach;
    __exports__.filter = filter;
    __exports__.indexOf = indexOf;
  });
define("ember-metal/binding",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/map","ember-metal/observer","ember-metal/run_loop","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.Logger, Ember.LOG_BINDINGS, assert
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var trySet = __dependency3__.trySet;
    var guidFor = __dependency4__.guidFor;
    var Map = __dependency5__.Map;
    var addObserver = __dependency6__.addObserver;
    var removeObserver = __dependency6__.removeObserver;
    var _suspendObserver = __dependency6__._suspendObserver;
    var run = __dependency7__["default"];

    // ES6TODO: where is Ember.lookup defined?
    

    // ..........................................................
    // CONSTANTS
    //

    
    Ember.LOG_BINDINGS = false || !!Ember.ENV.LOG_BINDINGS;

    var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/;

    
    function isGlobalPath(path) {
      return IS_GLOBAL.test(path);
    }

    function getWithGlobals(obj, path) {
      return get(isGlobalPath(path) ? Ember.lookup : obj, path);
    }

    // ..........................................................
    // BINDING
    //

    function Binding(toPath, fromPath) {
      this._direction = 'fwd';
      this._from = fromPath;
      this._to   = toPath;
      this._directionMap = Map.create();
      this._readyToSync = undefined;
      this._oneWay = undefined;
    }

    

    Binding.prototype = {
      
      copy: function () {
        var copy = new Binding(this._to, this._from);
        if (this._oneWay) { copy._oneWay = true; }
        return copy;
      },

      // ..........................................................
      // CONFIG
      //

      
      from: function(path) {
        this._from = path;
        return this;
      },

      
      to: function(path) {
        this._to = path;
        return this;
      },

      
      oneWay: function() {
        this._oneWay = true;
        return this;
      },

      
      toString: function() {
        var oneWay = this._oneWay ? '[oneWay]' : '';
        return "Ember.Binding<" + guidFor(this) + ">(" + this._from + " -> " + this._to + ")" + oneWay;
      },

      // ..........................................................
      // CONNECT AND SYNC
      //

      
      connect: function(obj) {
        Ember.assert('Must pass a valid object to Ember.Binding.connect()', !!obj);

        var fromPath = this._from, toPath = this._to;
        trySet(obj, toPath, getWithGlobals(obj, fromPath));

        // add an observer on the object to be notified when the binding should be updated
        addObserver(obj, fromPath, this, this.fromDidChange);

        // if the binding is a two-way binding, also set up an observer on the target
        if (!this._oneWay) { addObserver(obj, toPath, this, this.toDidChange); }

        this._readyToSync = true;

        return this;
      },

      
      disconnect: function(obj) {
        Ember.assert('Must pass a valid object to Ember.Binding.disconnect()', !!obj);

        var twoWay = !this._oneWay;

        // remove an observer on the object so we're no longer notified of
        // changes that should update bindings.
        removeObserver(obj, this._from, this, this.fromDidChange);

        // if the binding is two-way, remove the observer from the target as well
        if (twoWay) { removeObserver(obj, this._to, this, this.toDidChange); }

        this._readyToSync = false; // disable scheduled syncs...
        return this;
      },

      // ..........................................................
      // PRIVATE
      //

      
      fromDidChange: function(target) {
        this._scheduleSync(target, 'fwd');
      },

      
      toDidChange: function(target) {
        this._scheduleSync(target, 'back');
      },

      _scheduleSync: function(obj, dir) {
        var directionMap = this._directionMap;
        var existingDir = directionMap.get(obj);

        // if we haven't scheduled the binding yet, schedule it
        if (!existingDir) {
          run.schedule('sync', this, this._sync, obj);
          directionMap.set(obj, dir);
        }

        // If both a 'back' and 'fwd' sync have been scheduled on the same object,
        // default to a 'fwd' sync so that it remains deterministic.
        if (existingDir === 'back' && dir === 'fwd') {
          directionMap.set(obj, 'fwd');
        }
      },

      _sync: function(obj) {
        var log = Ember.LOG_BINDINGS;

        // don't synchronize destroyed objects or disconnected bindings
        if (obj.isDestroyed || !this._readyToSync) { return; }

        // get the direction of the binding for the object we are
        // synchronizing from
        var directionMap = this._directionMap;
        var direction = directionMap.get(obj);

        var fromPath = this._from, toPath = this._to;

        directionMap.remove(obj);

        // if we're synchronizing from the remote object...
        if (direction === 'fwd') {
          var fromValue = getWithGlobals(obj, this._from);
          if (log) {
            Ember.Logger.log(' ', this.toString(), '->', fromValue, obj);
          }
          if (this._oneWay) {
            trySet(obj, toPath, fromValue);
          } else {
            _suspendObserver(obj, toPath, this, this.toDidChange, function () {
              trySet(obj, toPath, fromValue);
            });
          }
        // if we're synchronizing *to* the remote object
        } else if (direction === 'back') {
          var toValue = get(obj, this._to);
          if (log) {
            Ember.Logger.log(' ', this.toString(), '<-', toValue, obj);
          }
          _suspendObserver(obj, fromPath, this, this.fromDidChange, function () {
            trySet(isGlobalPath(fromPath) ? Ember.lookup : obj, fromPath, toValue);
          });
        }
      }

    };

    function mixinProperties(to, from) {
      for (var key in from) {
        if (from.hasOwnProperty(key)) {
          to[key] = from[key];
        }
      }
    }

    mixinProperties(Binding, {

      
      from: function() {
        var C = this, binding = new C();
        return binding.from.apply(binding, arguments);
      },

      
      to: function() {
        var C = this, binding = new C();
        return binding.to.apply(binding, arguments);
      },

      
      oneWay: function(from, flag) {
        var C = this, binding = new C(null, from);
        return binding.oneWay(flag);
      }

    });
    
    // Ember.Binding = Binding; ES6TODO: where to put this?


    
    function bind(obj, to, from) {
      return new Binding(to, from).connect(obj);
    }

    __exports__.bind = bind;
    function oneWay(obj, to, from) {
      return new Binding(to, from).oneWay().connect(obj);
    }

    __exports__.oneWay = oneWay;__exports__.Binding = Binding;
    __exports__.isGlobalPath = isGlobalPath;
  });
define("ember-metal/chains",
  ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/array","ember-metal/watch_key","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // warn, assert, etc;
    var get = __dependency2__.get;
    var normalizeTuple = __dependency2__.normalizeTuple;
    var meta = __dependency3__.meta;
    var META_KEY = __dependency3__.META_KEY;
    var forEach = __dependency4__.forEach;
    var watchKey = __dependency5__.watchKey;
    var unwatchKey = __dependency5__.unwatchKey;

    var metaFor = meta,
        warn = Ember.warn,
        FIRST_KEY = /^([^\.]+)/;

    function firstKey(path) {
      return path.match(FIRST_KEY)[0];
    }

    var pendingQueue = [];

    // attempts to add the pendingQueue chains again. If some of them end up
    // back in the queue and reschedule is true, schedules a timeout to try
    // again.
    function flushPendingChains() {
      if (pendingQueue.length === 0) { return; } // nothing to do

      var queue = pendingQueue;
      pendingQueue = [];

      forEach.call(queue, function(q) { q[0].add(q[1]); });

      warn('Watching an undefined global, Ember expects watched globals to be setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0);
    }

    __exports__.flushPendingChains = flushPendingChains;function addChainWatcher(obj, keyName, node) {
      if (!obj || ('object' !== typeof obj)) { return; } // nothing to do

      var m = metaFor(obj), nodes = m.chainWatchers;

      if (!m.hasOwnProperty('chainWatchers')) {
        nodes = m.chainWatchers = {};
      }

      if (!nodes[keyName]) { nodes[keyName] = []; }
      nodes[keyName].push(node);
      watchKey(obj, keyName, m);
    }

    function removeChainWatcher(obj, keyName, node) {
      if (!obj || 'object' !== typeof obj) { return; } // nothing to do

      var m = obj[META_KEY];
      if (m && !m.hasOwnProperty('chainWatchers')) { return; } // nothing to do

      var nodes = m && m.chainWatchers;

      if (nodes && nodes[keyName]) {
        nodes = nodes[keyName];
        for (var i = 0, l = nodes.length; i < l; i++) {
          if (nodes[i] === node) {
            nodes.splice(i, 1);
            break;
          }
        }
      }
      unwatchKey(obj, keyName, m);
    }

    // A ChainNode watches a single key on an object. If you provide a starting
    // value for the key then the node won't actually watch it. For a root node
    // pass null for parent and key and object for value.
    function ChainNode(parent, key, value) {
      this._parent = parent;
      this._key    = key;

      // _watching is true when calling get(this._parent, this._key) will
      // return the value of this node.
      //
      // It is false for the root of a chain (because we have no parent)
      // and for global paths (because the parent node is the object with
      // the observer on it)
      this._watching = value===undefined;

      this._value  = value;
      this._paths = {};
      if (this._watching) {
        this._object = parent.value();
        if (this._object) { addChainWatcher(this._object, this._key, this); }
      }

      // Special-case: the EachProxy relies on immediate evaluation to
      // establish its observers.
      //
      // TODO: Replace this with an efficient callback that the EachProxy
      // can implement.
      if (this._parent && this._parent._key === '@each') {
        this.value();
      }
    }

    var ChainNodePrototype = ChainNode.prototype;

    function lazyGet(obj, key) {
      if (!obj) return undefined;

      var meta = obj[META_KEY];
      // check if object meant only to be a prototype
      if (meta && meta.proto === obj) return undefined;

      if (key === "@each") return get(obj, key);

      // if a CP only return cached value
      var desc = meta && meta.descs[key];
      if (desc && desc._cacheable) {
        if (key in meta.cache) {
          return meta.cache[key];
        } else {
          return undefined;
        }
      }

      return get(obj, key);
    }

    ChainNodePrototype.value = function() {
      if (this._value === undefined && this._watching) {
        var obj = this._parent.value();
        this._value = lazyGet(obj, this._key);
      }
      return this._value;
    };

    ChainNodePrototype.destroy = function() {
      if (this._watching) {
        var obj = this._object;
        if (obj) { removeChainWatcher(obj, this._key, this); }
        this._watching = false; // so future calls do nothing
      }
    };

    // copies a top level object only
    ChainNodePrototype.copy = function(obj) {
      var ret = new ChainNode(null, null, obj),
          paths = this._paths, path;
      for (path in paths) {
        if (paths[path] <= 0) { continue; } // this check will also catch non-number vals.
        ret.add(path);
      }
      return ret;
    };

    // called on the root node of a chain to setup watchers on the specified
    // path.
    ChainNodePrototype.add = function(path) {
      var obj, tuple, key, src, paths;

      paths = this._paths;
      paths[path] = (paths[path] || 0) + 1;

      obj = this.value();
      tuple = normalizeTuple(obj, path);

      // the path was a local path
      if (tuple[0] && tuple[0] === obj) {
        path = tuple[1];
        key  = firstKey(path);
        path = path.slice(key.length+1);

      // global path, but object does not exist yet.
      // put into a queue and try to connect later.
      } else if (!tuple[0]) {
        pendingQueue.push([this, path]);
        tuple.length = 0;
        return;

      // global path, and object already exists
      } else {
        src  = tuple[0];
        key  = path.slice(0, 0-(tuple[1].length+1));
        path = tuple[1];
      }

      tuple.length = 0;
      this.chain(key, path, src);
    };

    // called on the root node of a chain to teardown watcher on the specified
    // path
    ChainNodePrototype.remove = function(path) {
      var obj, tuple, key, src, paths;

      paths = this._paths;
      if (paths[path] > 0) { paths[path]--; }

      obj = this.value();
      tuple = normalizeTuple(obj, path);
      if (tuple[0] === obj) {
        path = tuple[1];
        key  = firstKey(path);
        path = path.slice(key.length+1);
      } else {
        src  = tuple[0];
        key  = path.slice(0, 0-(tuple[1].length+1));
        path = tuple[1];
      }

      tuple.length = 0;
      this.unchain(key, path);
    };

    ChainNodePrototype.count = 0;

    ChainNodePrototype.chain = function(key, path, src) {
      var chains = this._chains, node;
      if (!chains) { chains = this._chains = {}; }

      node = chains[key];
      if (!node) { node = chains[key] = new ChainNode(this, key, src); }
      node.count++; // count chains...

      // chain rest of path if there is one
      if (path) {
        key = firstKey(path);
        path = path.slice(key.length+1);
        node.chain(key, path); // NOTE: no src means it will observe changes...
      }
    };

    ChainNodePrototype.unchain = function(key, path) {
      var chains = this._chains, node = chains[key];

      // unchain rest of path first...
      if (path && path.length>1) {
        key  = firstKey(path);
        path = path.slice(key.length+1);
        node.unchain(key, path);
      }

      // delete node if needed.
      node.count--;
      if (node.count<=0) {
        delete chains[node._key];
        node.destroy();
      }

    };

    ChainNodePrototype.willChange = function(events) {
      var chains = this._chains;
      if (chains) {
        for(var key in chains) {
          if (!chains.hasOwnProperty(key)) { continue; }
          chains[key].willChange(events);
        }
      }

      if (this._parent) { this._parent.chainWillChange(this, this._key, 1, events); }
    };

    ChainNodePrototype.chainWillChange = function(chain, path, depth, events) {
      if (this._key) { path = this._key + '.' + path; }

      if (this._parent) {
        this._parent.chainWillChange(this, path, depth+1, events);
      } else {
        if (depth > 1) {
          events.push(this.value(), path);
        }
        path = 'this.' + path;
        if (this._paths[path] > 0) {
          events.push(this.value(), path);
        }
      }
    };

    ChainNodePrototype.chainDidChange = function(chain, path, depth, events) {
      if (this._key) { path = this._key + '.' + path; }
      if (this._parent) {
        this._parent.chainDidChange(this, path, depth+1, events);
      } else {
        if (depth > 1) {
          events.push(this.value(), path);
        }
        path = 'this.' + path;
        if (this._paths[path] > 0) {
          events.push(this.value(), path);
        }
      }
    };

    ChainNodePrototype.didChange = function(events) {
      // invalidate my own value first.
      if (this._watching) {
        var obj = this._parent.value();
        if (obj !== this._object) {
          removeChainWatcher(this._object, this._key, this);
          this._object = obj;
          addChainWatcher(obj, this._key, this);
        }
        this._value  = undefined;

        // Special-case: the EachProxy relies on immediate evaluation to
        // establish its observers.
        if (this._parent && this._parent._key === '@each')
          this.value();
      }

      // then notify chains...
      var chains = this._chains;
      if (chains) {
        for(var key in chains) {
          if (!chains.hasOwnProperty(key)) { continue; }
          chains[key].didChange(events);
        }
      }

      // if no events are passed in then we only care about the above wiring update
      if (events === null) { return; }

      // and finally tell parent about my path changing...
      if (this._parent) { this._parent.chainDidChange(this, this._key, 1, events); }
    };

    function finishChains(obj) {
      // We only create meta if we really have to
      var m = obj[META_KEY], chains = m && m.chains;
      if (chains) {
        if (chains.value() !== obj) {
          metaFor(obj).chains = chains = chains.copy(obj);
        } else {
          chains.didChange(null);
        }
      }
    }

    __exports__.finishChains = finishChains;__exports__.removeChainWatcher = removeChainWatcher;
    __exports__.ChainNode = ChainNode;
  });
define("ember-metal/computed",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/expand_properties","ember-metal/error","ember-metal/properties","ember-metal/property_events","ember-metal/dependent_keys","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var meta = __dependency4__.meta;
    var META_KEY = __dependency4__.META_KEY;
    var inspect = __dependency4__.inspect;
    var expandProperties = __dependency5__["default"];
    var EmberError = __dependency6__["default"];
    var Descriptor = __dependency7__.Descriptor;
    var defineProperty = __dependency7__.defineProperty;
    var propertyWillChange = __dependency8__.propertyWillChange;
    var propertyDidChange = __dependency8__.propertyDidChange;
    var addDependentKeys = __dependency9__.addDependentKeys;
    var removeDependentKeys = __dependency9__.removeDependentKeys;

    

    Ember.warn("The CP_DEFAULT_CACHEABLE flag has been removed and computed properties are always cached by default. Use `volatile` if you don't want caching.", Ember.ENV.CP_DEFAULT_CACHEABLE !== false);


    var metaFor = meta,
        a_slice = [].slice;

    function UNDEFINED() { }

    // ..........................................................
    // COMPUTED PROPERTY
    //

    
    function ComputedProperty(func, opts) {
      func.__ember_arity__ = func.length;
      this.func = func;

      this._cacheable = (opts && opts.cacheable !== undefined) ? opts.cacheable : true;
      this._dependentKeys = opts && opts.dependentKeys;
      this._readOnly = opts && (opts.readOnly !== undefined || !!opts.readOnly) || false;
    }

    ComputedProperty.prototype = new Descriptor();

    var ComputedPropertyPrototype = ComputedProperty.prototype;
    ComputedPropertyPrototype._dependentKeys = undefined;
    ComputedPropertyPrototype._suspended = undefined;
    ComputedPropertyPrototype._meta = undefined;

    
    ComputedPropertyPrototype.cacheable = function(aFlag) {
      this._cacheable = aFlag !== false;
      return this;
    };

    
    ComputedPropertyPrototype["volatile"] = function() {
      return this.cacheable(false);
    };

    
    ComputedPropertyPrototype.readOnly = function(readOnly) {
      this._readOnly = readOnly === undefined || !!readOnly;
      return this;
    };

    
    ComputedPropertyPrototype.property = function() {
      var args;

      var addArg = function (property) {
        args.push(property);
      };

      args = [];
      for (var i = 0, l = arguments.length; i < l; i++) {
        expandProperties(arguments[i], addArg);
      }

      this._dependentKeys = args;
      return this;
    };

    

    ComputedPropertyPrototype.meta = function(meta) {
      if (arguments.length === 0) {
        return this._meta || {};
      } else {
        this._meta = meta;
        return this;
      }
    };

    
    ComputedPropertyPrototype.didChange = function(obj, keyName) {
      // _suspended is set via a CP.set to ensure we don't clear
      // the cached value set by the setter
      if (this._cacheable && this._suspended !== obj) {
        var meta = metaFor(obj);
        if (meta.cache[keyName] !== undefined) {
          meta.cache[keyName] = undefined;
          removeDependentKeys(this, obj, keyName, meta);
        }
      }
    };

    function finishChains(chainNodes)
    {
      for (var i=0, l=chainNodes.length; i<l; i++) {
        chainNodes[i].didChange(null);
      }
    }

    
    ComputedPropertyPrototype.get = function(obj, keyName) {
      var ret, cache, meta, chainNodes;
      if (this._cacheable) {
        meta = metaFor(obj);
        cache = meta.cache;

        var result = cache[keyName];

        if (result === UNDEFINED) {
          return undefined;
        }  else if (result !== undefined) {
          return result;
        }

        ret = this.func.call(obj, keyName);
        if (ret === undefined) {
          cache[keyName] = UNDEFINED;
        } else {
          cache[keyName] = ret;
        }

        chainNodes = meta.chainWatchers && meta.chainWatchers[keyName];
        if (chainNodes) { finishChains(chainNodes); }
        addDependentKeys(this, obj, keyName, meta);
      } else {
        ret = this.func.call(obj, keyName);
      }
      return ret;
    };

    
    ComputedPropertyPrototype.set = function(obj, keyName, value) {
      var cacheable = this._cacheable,
          func = this.func,
          meta = metaFor(obj, cacheable),
          oldSuspended = this._suspended,
          hadCachedValue = false,
          cache = meta.cache,
          funcArgLength, cachedValue, ret;

      if (this._readOnly) {
        throw new EmberError('Cannot set read-only property "' + keyName + '" on object: ' + inspect(obj));
      }

      this._suspended = obj;

      try {

        if (cacheable && cache[keyName] !== undefined) {
          if(cache[keyName] !== UNDEFINED) {
            cachedValue = cache[keyName];
          }

          hadCachedValue = true;
        }

        // Check if the CP has been wrapped. If it has, use the
        // length from the wrapped function.

        funcArgLength = func.wrappedFunction ? func.wrappedFunction.__ember_arity__ : func.__ember_arity__;

        // For backwards-compatibility with computed properties
        // that check for arguments.length === 2 to determine if
        // they are being get or set, only pass the old cached
        // value if the computed property opts into a third
        // argument.
        if (funcArgLength === 3) {
          ret = func.call(obj, keyName, value, cachedValue);
        } else if (funcArgLength === 2) {
          ret = func.call(obj, keyName, value);
        } else {
          defineProperty(obj, keyName, null, cachedValue);
          set(obj, keyName, value);
          return;
        }

        if (hadCachedValue && cachedValue === ret) { return; }

        var watched = meta.watching[keyName];
        if (watched) { propertyWillChange(obj, keyName); }

        if (hadCachedValue) {
          cache[keyName] = undefined;
        }

        if (cacheable) {
          if (!hadCachedValue) {
            addDependentKeys(this, obj, keyName, meta);
          }
          if (ret === undefined) {
            cache[keyName] = UNDEFINED;
          } else {
            cache[keyName] = ret;
          }
        }

        if (watched) { propertyDidChange(obj, keyName); }
      } finally {
        this._suspended = oldSuspended;
      }
      return ret;
    };

    
    ComputedPropertyPrototype.teardown = function(obj, keyName) {
      var meta = metaFor(obj);

      if (keyName in meta.cache) {
        removeDependentKeys(this, obj, keyName, meta);
      }

      if (this._cacheable) { delete meta.cache[keyName]; }

      return null; // no value to restore
    };


    
    function computed(func) {
      var args;

      if (arguments.length > 1) {
        args = a_slice.call(arguments);
        func = args.pop();
      }

      if (typeof func !== "function") {
        throw new EmberError("Computed Property declared without a property function");
      }

      var cp = new ComputedProperty(func);

      if (args) {
        cp.property.apply(cp, args);
      }

      return cp;
    }

    
    function cacheFor(obj, key) {
      var meta = obj[META_KEY],
          cache = meta && meta.cache,
          ret = cache && cache[key];

      if (ret === UNDEFINED) { return undefined; }
      return ret;
    }

    cacheFor.set = function(cache, key, value) {
      if (value === undefined) {
        cache[key] = UNDEFINED;
      } else {
        cache[key] = value;
      }
    };

    cacheFor.get = function(cache, key) {
      var ret = cache[key];
      if (ret === UNDEFINED) { return undefined; }
      return ret;
    };

    cacheFor.remove = function(cache, key) {
      cache[key] = undefined;
    };

    __exports__.ComputedProperty = ComputedProperty;
    __exports__.computed = computed;
    __exports__.cacheFor = cacheFor;
  });
define("ember-metal/computed_macros",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/is_empty","ember-metal/is_none","ember-metal/alias"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var computed = __dependency4__.computed;
    var isEmpty = __dependency5__["default"];
    var isNone = __dependency6__.isNone;
    var alias = __dependency7__.alias;

    

    var a_slice = [].slice;

    function getProperties(self, propertyNames) {
      var ret = {};
      for(var i = 0; i < propertyNames.length; i++) {
        ret[propertyNames[i]] = get(self, propertyNames[i]);
      }
      return ret;
    }

    function registerComputed(name, macro) {
      computed[name] = function(dependentKey) {
        var args = a_slice.call(arguments);
        return computed(dependentKey, function() {
          return macro.apply(this, args);
        });
      };
    }

    function registerComputedWithProperties(name, macro) {
      computed[name] = function() {
        var properties = a_slice.call(arguments);

        var computedFunc = computed(function() {
          return macro.apply(this, [getProperties(this, properties)]);
        });

        return computedFunc.property.apply(computedFunc, properties);
      };
    }

    
    computed.empty = function (dependentKey) {
      return computed(dependentKey + '.length', function () {
        return isEmpty(get(this, dependentKey));
      });
    };

    
    computed.notEmpty = function(dependentKey) {
      return computed(dependentKey + '.length', function () {
        return !isEmpty(get(this, dependentKey));
      });
    };

    
    registerComputed('none', function(dependentKey) {
      return isNone(get(this, dependentKey));
    });

    
    registerComputed('not', function(dependentKey) {
      return !get(this, dependentKey);
    });

    
    registerComputed('bool', function(dependentKey) {
      return !!get(this, dependentKey);
    });

    
    registerComputed('match', function(dependentKey, regexp) {
      var value = get(this, dependentKey);
      return typeof value === 'string' ? regexp.test(value) : false;
    });

    
    registerComputed('equal', function(dependentKey, value) {
      return get(this, dependentKey) === value;
    });

    
    registerComputed('gt', function(dependentKey, value) {
      return get(this, dependentKey) > value;
    });

    
    registerComputed('gte', function(dependentKey, value) {
      return get(this, dependentKey) >= value;
    });

    
    registerComputed('lt', function(dependentKey, value) {
      return get(this, dependentKey) < value;
    });

    
    registerComputed('lte', function(dependentKey, value) {
      return get(this, dependentKey) <= value;
    });

    
    registerComputedWithProperties('and', function(properties) {
      for (var key in properties) {
        if (properties.hasOwnProperty(key) && !properties[key]) {
          return false;
        }
      }
      return true;
    });

    
    registerComputedWithProperties('or', function(properties) {
      for (var key in properties) {
        if (properties.hasOwnProperty(key) && properties[key]) {
          return true;
        }
      }
      return false;
    });

    
    registerComputedWithProperties('any', function(properties) {
      for (var key in properties) {
        if (properties.hasOwnProperty(key) && properties[key]) {
          return properties[key];
        }
      }
      return null;
    });

    
    registerComputedWithProperties('collect', function(properties) {
      var res = [];
      for (var key in properties) {
        if (properties.hasOwnProperty(key)) {
          if (isNone(properties[key])) {
            res.push(null);
          } else {
            res.push(properties[key]);
          }
        }
      }
      return res;
    });

    
    computed.alias = alias;

    
    computed.oneWay = function(dependentKey) {
      return alias(dependentKey).oneWay();
    };

    
      
      computed.reads = computed.oneWay;
    

    
    computed.readOnly = function(dependentKey) {
      return alias(dependentKey).readOnly();
    };
    
    // ES6TODO: computed should have its own export path so you can do import {defaultTo} from computed
    computed.defaultTo = function(defaultPath) {
      return computed(function(key, newValue, cachedValue) {
        if (arguments.length === 1) {
          return get(this, defaultPath);
        }
        return newValue != null ? newValue : get(this, defaultPath);
      });
    };

    
    computed.deprecatingAlias = function(dependentKey) {
      return computed(dependentKey, function(key, value) {
        Ember.deprecate('Usage of `' + key + '` is deprecated, use `' + dependentKey + '` instead.');

        if (arguments.length > 1) {
          set(this, dependentKey, value);
          return value;
        } else {
          return get(this, dependentKey);
        }
      });
    };
  });
define("ember-metal/core",
  ["exports"],
  function(__exports__) {
    "use strict";
    

    

    

    if ('undefined' === typeof Ember) {
      // Create core object. Make it act like an instance of Ember.Namespace so that
      // objects assigned to it are given a sane string representation.
      Ember = {};
    }

    // Default imports, exports and lookup to the global object;
    var imports = Ember.imports = Ember.imports || this;
    var exports = Ember.exports = Ember.exports || this;
    var lookup  = Ember.lookup  = Ember.lookup  || this;

    // aliases needed to keep minifiers from removing the global context
    exports.Em = exports.Ember = Ember;

    // Make sure these are set whether Ember was already defined or not

    Ember.isNamespace = true;

    Ember.toString = function() { return "Ember"; };


    
    Ember.VERSION = '1.7.0';

    

    if (Ember.ENV) {
      // do nothing if Ember.ENV is already setup
    } else if ('undefined' !== typeof EmberENV) {
      Ember.ENV = EmberENV;
    } else if('undefined' !== typeof ENV) {
      Ember.ENV = ENV;
    } else {
      Ember.ENV = {};
    }

    Ember.config = Ember.config || {};

    // We disable the RANGE API by default for performance reasons
    if ('undefined' === typeof Ember.ENV.DISABLE_RANGE_API) {
      Ember.ENV.DISABLE_RANGE_API = true;
    }

    if ("undefined" === typeof MetamorphENV) {
      exports.MetamorphENV = {};
    }

    MetamorphENV.DISABLE_RANGE_API = Ember.ENV.DISABLE_RANGE_API;

    

    Ember.FEATURES = Ember.ENV.FEATURES || {};

    

    Ember.FEATURES.isEnabled = function(feature) {
      var featureValue = Ember.FEATURES[feature];

      if (Ember.ENV.ENABLE_ALL_FEATURES) {
        return true;
      } else if (featureValue === true || featureValue === false || featureValue === undefined) {
        return featureValue;
      } else if (Ember.ENV.ENABLE_OPTIONAL_FEATURES) {
        return true;
      } else {
        return false;
      }
    };

    // ..........................................................
    // BOOTSTRAP
    //

    
    Ember.EXTEND_PROTOTYPES = Ember.ENV.EXTEND_PROTOTYPES;

    if (typeof Ember.EXTEND_PROTOTYPES === 'undefined') {
      Ember.EXTEND_PROTOTYPES = true;
    }

    
    Ember.LOG_STACKTRACE_ON_DEPRECATION = (Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !== false);

    
    Ember.SHIM_ES5 = (Ember.ENV.SHIM_ES5 === false) ? false : Ember.EXTEND_PROTOTYPES;

    
    Ember.LOG_VERSION = (Ember.ENV.LOG_VERSION === false) ? false : true;

    
    var K = function() { return this; };
    var K = K;
    __exports__.K = K;Ember.K = K;
    //TODO: ES6 GLOBL TODO

    // Stub out the methods defined by the ember-debug package in case it's not loaded

    if ('undefined' === typeof Ember.assert) { Ember.assert = Ember.K; }
    if ('undefined' === typeof Ember.warn) { Ember.warn = Ember.K; }
    if ('undefined' === typeof Ember.debug) { Ember.debug = Ember.K; }
    if ('undefined' === typeof Ember.runInDebug) { Ember.runInDebug = Ember.K; }
    if ('undefined' === typeof Ember.deprecate) { Ember.deprecate = Ember.K; }
    if ('undefined' === typeof Ember.deprecateFunc) {
      Ember.deprecateFunc = function(_, func) { return func; };
    }

    __exports__["default"] = Ember;
  });
define("ember-metal/dependent_keys",
  ["ember-metal/platform","ember-metal/watching","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var create = __dependency1__.create;
    var watch = __dependency2__.watch;
    var unwatch = __dependency2__.unwatch;

    

    var o_create = create;

    // ..........................................................
    // DEPENDENT KEYS
    //

    // data structure:
    //  meta.deps = {
    //    'depKey': {
    //      'keyName': count,
    //    }
    //  }

    
    function keysForDep(depsMeta, depKey) {
      var keys = depsMeta[depKey];
      if (!keys) {
        // if there are no dependencies yet for a the given key
        // create a new empty list of dependencies for the key
        keys = depsMeta[depKey] = {};
      } else if (!depsMeta.hasOwnProperty(depKey)) {
        // otherwise if the dependency list is inherited from
        // a superclass, clone the hash
        keys = depsMeta[depKey] = o_create(keys);
      }
      return keys;
    }

    function metaForDeps(meta) {
      return keysForDep(meta, 'deps');
    }

    function addDependentKeys(desc, obj, keyName, meta) {
      // the descriptor has a list of dependent keys, so
      // add all of its dependent keys.
      var depKeys = desc._dependentKeys, depsMeta, idx, len, depKey, keys;
      if (!depKeys) return;

      depsMeta = metaForDeps(meta);

      for(idx = 0, len = depKeys.length; idx < len; idx++) {
        depKey = depKeys[idx];
        // Lookup keys meta for depKey
        keys = keysForDep(depsMeta, depKey);
        // Increment the number of times depKey depends on keyName.
        keys[keyName] = (keys[keyName] || 0) + 1;
        // Watch the depKey
        watch(obj, depKey, meta);
      }
    }

    __exports__.addDependentKeys = addDependentKeys;function removeDependentKeys(desc, obj, keyName, meta) {
      // the descriptor has a list of dependent keys, so
      // remove all of its dependent keys.
      var depKeys = desc._dependentKeys, depsMeta, idx, len, depKey, keys;
      if (!depKeys) return;

      depsMeta = metaForDeps(meta);

      for(idx = 0, len = depKeys.length; idx < len; idx++) {
        depKey = depKeys[idx];
        // Lookup keys meta for depKey
        keys = keysForDep(depsMeta, depKey);
        // Decrement the number of times depKey depends on keyName.
        keys[keyName] = (keys[keyName] || 0) - 1;
        // Unwatch the depKey
        unwatch(obj, depKey, meta);
      }
    }
    __exports__.removeDependentKeys = removeDependentKeys;
  });
define("ember-metal/enumerable_utils",
  ["ember-metal/array","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var _filter = __dependency1__.filter;
    var a_forEach = __dependency1__.forEach;
    var _indexOf = __dependency1__.indexOf;
    var _map = __dependency1__.map;

    var splice = Array.prototype.splice;

    

    
    function map(obj, callback, thisArg) {
      return obj.map ? obj.map.call(obj, callback, thisArg) : _map.call(obj, callback, thisArg);
    }

    __exports__.map = map;
    function forEach(obj, callback, thisArg) {
      return obj.forEach ? obj.forEach.call(obj, callback, thisArg) : a_forEach.call(obj, callback, thisArg);
    }

    __exports__.forEach = forEach;
    function filter(obj, callback, thisArg) {
      return obj.filter ? obj.filter.call(obj, callback, thisArg) : _filter.call(obj, callback, thisArg);
    }

    __exports__.filter = filter;
    function indexOf(obj, element, index) {
      return obj.indexOf ? obj.indexOf.call(obj, element, index) : _indexOf.call(obj, element, index);
    }

    __exports__.indexOf = indexOf;
    function indexesOf(obj, elements) {
      return elements === undefined ? [] : map(elements, function(item) {
        return indexOf(obj, item);
      });
    }

    __exports__.indexesOf = indexesOf;
    function addObject(array, item) {
      var index = indexOf(array, item);
      if (index === -1) { array.push(item); }
    }

    __exports__.addObject = addObject;
    function removeObject(array, item) {
      var index = indexOf(array, item);
      if (index !== -1) { array.splice(index, 1); }
    }

    __exports__.removeObject = removeObject;function _replace(array, idx, amt, objects) {
      var args = [].concat(objects), chunk, ret = [],
          // https://code.google.com/p/chromium/issues/detail?id=56588
          size = 60000, start = idx, ends = amt, count;

      while (args.length) {
        count = ends > size ? size : ends;
        if (count <= 0) { count = 0; }

        chunk = args.splice(0, size);
        chunk = [start, count].concat(chunk);

        start += size;
        ends -= count;

        ret = ret.concat(splice.apply(array, chunk));
      }
      return ret;
    }

    __exports__._replace = _replace;
    function replace(array, idx, amt, objects) {
      if (array.replace) {
        return array.replace(idx, amt, objects);
      } else {
        return _replace(array, idx, amt, objects);
      }
    }

    __exports__.replace = replace;
    function intersection(array1, array2) {
      var result = [];
      forEach(array1, function(element) {
        if (indexOf(array2, element) >= 0) {
          result.push(element);
        }
      });

      return result;
    }

    __exports__.intersection = intersection;// TODO: this only exists to maintain the existing api, as we move forward it
    // should only be part of the "global build" via some shim
    __exports__["default"] = {
      _replace: _replace,
      addObject: addObject,
      filter: filter,
      forEach: forEach,
      indexOf: indexOf,
      indexesOf: indexesOf,
      intersection: intersection,
      map: map,
      removeObject: removeObject,
      replace: replace
    };
  });
define("ember-metal/error",
  ["ember-metal/platform","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var create = __dependency1__.create;

    var errorProps = [
      'description',
      'fileName',
      'lineNumber',
      'message',
      'name',
      'number',
      'stack'
    ];

    
    function EmberError() {
      var tmp = Error.apply(this, arguments);

      // Adds a `stack` property to the given error object that will yield the
      // stack trace at the time captureStackTrace was called.
      // When collecting the stack trace all frames above the topmost call
      // to this function, including that call, will be left out of the
      // stack trace.
      // This is useful because we can hide Ember implementation details
      // that are not very helpful for the user.
      if (Error.captureStackTrace) {
        Error.captureStackTrace(this, Ember.Error);
      }
      // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
      for (var idx = 0; idx < errorProps.length; idx++) {
        this[errorProps[idx]] = tmp[errorProps[idx]];
      }
    }

    EmberError.prototype = create(Error.prototype);

    __exports__["default"] = EmberError;
  });
define("ember-metal/events",
  ["ember-metal/core","ember-metal/utils","ember-metal/platform","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    
    var Ember = __dependency1__["default"];
    var meta = __dependency2__.meta;
    var META_KEY = __dependency2__.META_KEY;
    var tryFinally = __dependency2__.tryFinally;
    var apply = __dependency2__.apply;
    var applyStr = __dependency2__.applyStr;
    var create = __dependency3__.create;

    var a_slice = [].slice,
        metaFor = meta,
        
        ONCE = 1, SUSPENDED = 2;


    

    function indexOf(array, target, method) {
      var index = -1;
      // hashes are added to the end of the event array
      // so it makes sense to start searching at the end
      // of the array and search in reverse
      for (var i = array.length - 3 ; i >=0; i -= 3) {
        if (target === array[i] && method === array[i + 1]) {
             index = i; break;
        }
      }
      return index;
    }

    function actionsFor(obj, eventName) {
      var meta = metaFor(obj, true),
          actions;

      if (!meta.listeners) { meta.listeners = {}; }

      if (!meta.hasOwnProperty('listeners')) {
        // setup inherited copy of the listeners object
        meta.listeners = create(meta.listeners);
      }

      actions = meta.listeners[eventName];

      // if there are actions, but the eventName doesn't exist in our listeners, then copy them from the prototype
      if (actions && !meta.listeners.hasOwnProperty(eventName)) {
        actions = meta.listeners[eventName] = meta.listeners[eventName].slice();
      } else if (!actions) {
        actions = meta.listeners[eventName] = [];
      }

      return actions;
    }

    function listenersUnion(obj, eventName, otherActions) {
      var meta = obj[META_KEY],
          actions = meta && meta.listeners && meta.listeners[eventName];

      if (!actions) { return; }
      for (var i = actions.length - 3; i >= 0; i -= 3) {
        var target = actions[i],
            method = actions[i+1],
            flags = actions[i+2],
            actionIndex = indexOf(otherActions, target, method);

        if (actionIndex === -1) {
          otherActions.push(target, method, flags);
        }
      }
    }

    __exports__.listenersUnion = listenersUnion;function listenersDiff(obj, eventName, otherActions) {
      var meta = obj[META_KEY],
          actions = meta && meta.listeners && meta.listeners[eventName],
          diffActions = [];

      if (!actions) { return; }
      for (var i = actions.length - 3; i >= 0; i -= 3) {
        var target = actions[i],
            method = actions[i+1],
            flags = actions[i+2],
            actionIndex = indexOf(otherActions, target, method);

        if (actionIndex !== -1) { continue; }

        otherActions.push(target, method, flags);
        diffActions.push(target, method, flags);
      }

      return diffActions;
    }

    __exports__.listenersDiff = listenersDiff;
    function addListener(obj, eventName, target, method, once) {
      Ember.assert("You must pass at least an object and event name to Ember.addListener", !!obj && !!eventName);

      if (!method && 'function' === typeof target) {
        method = target;
        target = null;
      }

      var actions = actionsFor(obj, eventName),
          actionIndex = indexOf(actions, target, method),
          flags = 0;

      if (once) flags |= ONCE;

      if (actionIndex !== -1) { return; }

      actions.push(target, method, flags);

      if ('function' === typeof obj.didAddListener) {
        obj.didAddListener(eventName, target, method);
      }
    }

    __exports__.addListener = addListener;
    function removeListener(obj, eventName, target, method) {
      Ember.assert("You must pass at least an object and event name to Ember.removeListener", !!obj && !!eventName);

      if (!method && 'function' === typeof target) {
        method = target;
        target = null;
      }

      function _removeListener(target, method) {
        var actions = actionsFor(obj, eventName),
            actionIndex = indexOf(actions, target, method);

        // action doesn't exist, give up silently
        if (actionIndex === -1) { return; }

        actions.splice(actionIndex, 3);

        if ('function' === typeof obj.didRemoveListener) {
          obj.didRemoveListener(eventName, target, method);
        }
      }

      if (method) {
        _removeListener(target, method);
      } else {
        var meta = obj[META_KEY],
            actions = meta && meta.listeners && meta.listeners[eventName];

        if (!actions) { return; }
        for (var i = actions.length - 3; i >= 0; i -= 3) {
          _removeListener(actions[i], actions[i+1]);
        }
      }
    }

    
    function suspendListener(obj, eventName, target, method, callback) {
      if (!method && 'function' === typeof target) {
        method = target;
        target = null;
      }

      var actions = actionsFor(obj, eventName),
          actionIndex = indexOf(actions, target, method);

      if (actionIndex !== -1) {
        actions[actionIndex+2] |= SUSPENDED; // mark the action as suspended
      }

      function tryable()   { return callback.call(target); }
      function finalizer() { if (actionIndex !== -1) { actions[actionIndex+2] &= ~SUSPENDED; } }

      return tryFinally(tryable, finalizer);
    }

    __exports__.suspendListener = suspendListener;
    function suspendListeners(obj, eventNames, target, method, callback) {
      if (!method && 'function' === typeof target) {
        method = target;
        target = null;
      }

      var suspendedActions = [],
          actionsList = [],
          eventName, actions, i, l;

      for (i=0, l=eventNames.length; i<l; i++) {
        eventName = eventNames[i];
        actions = actionsFor(obj, eventName);
        var actionIndex = indexOf(actions, target, method);

        if (actionIndex !== -1) {
          actions[actionIndex+2] |= SUSPENDED;
          suspendedActions.push(actionIndex);
          actionsList.push(actions);
        }
      }

      function tryable() { return callback.call(target); }

      function finalizer() {
        for (var i = 0, l = suspendedActions.length; i < l; i++) {
          var actionIndex = suspendedActions[i];
          actionsList[i][actionIndex+2] &= ~SUSPENDED;
        }
      }

      return tryFinally(tryable, finalizer);
    }

    __exports__.suspendListeners = suspendListeners;
    function watchedEvents(obj) {
      var listeners = obj[META_KEY].listeners, ret = [];

      if (listeners) {
        for(var eventName in listeners) {
          if (listeners[eventName]) { ret.push(eventName); }
        }
      }
      return ret;
    }

    __exports__.watchedEvents = watchedEvents;
    function sendEvent(obj, eventName, params, actions) {
      // first give object a chance to handle it
      if (obj !== Ember && 'function' === typeof obj.sendEvent) {
        obj.sendEvent(eventName, params);
      }

      if (!actions) {
        var meta = obj[META_KEY];
        actions = meta && meta.listeners && meta.listeners[eventName];
      }

      if (!actions) { return; }

      for (var i = actions.length - 3; i >= 0; i -= 3) { // looping in reverse for once listeners
        var target = actions[i], method = actions[i+1], flags = actions[i+2];
        if (!method) { continue; }
        if (flags & SUSPENDED) { continue; }
        if (flags & ONCE) { removeListener(obj, eventName, target, method); }
        if (!target) { target = obj; }
        if ('string' === typeof method) {
          if (params) {
            applyStr(target, method, params);
          } else {
            target[method]();
          }
        } else {
          if (params) {
            apply(target, method, params);
          } else {
            method.call(target);
          }
        }
      }
      return true;
    }

    __exports__.sendEvent = sendEvent;
    function hasListeners(obj, eventName) {
      var meta = obj[META_KEY],
          actions = meta && meta.listeners && meta.listeners[eventName];

      return !!(actions && actions.length);
    }

    __exports__.hasListeners = hasListeners;
    function listenersFor(obj, eventName) {
      var ret = [];
      var meta = obj[META_KEY],
          actions = meta && meta.listeners && meta.listeners[eventName];

      if (!actions) { return ret; }

      for (var i = 0, l = actions.length; i < l; i += 3) {
        var target = actions[i],
            method = actions[i+1];
        ret.push([target, method]);
      }

      return ret;
    }

    __exports__.listenersFor = listenersFor;
    function on(){
      var func = a_slice.call(arguments, -1)[0],
          events = a_slice.call(arguments, 0, -1);
      func.__ember_listens__ = events;
      return func;
    }

    __exports__.on = on;__exports__.removeListener = removeListener;
  });
define("ember-metal/expand_properties",
  ["ember-metal/error","ember-metal/enumerable_utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var EmberError = __dependency1__["default"];
    var forEach = __dependency2__.forEach;

    

    var BRACE_EXPANSION = /^((?:[^\.]*\.)*)\{(.*)\}$/;

    
    __exports__["default"] = function expandProperties(pattern, callback) {
      var match, prefix, list;

      if (pattern.indexOf(' ') > -1) {
        throw new EmberError('Brace expanded properties cannot contain spaces, ' + 
          'e.g. `user.{firstName, lastName}` should be `user.{firstName,lastName}`');
      }

      if (match = BRACE_EXPANSION.exec(pattern)) {
        prefix = match[1];
        list = match[2];

        forEach(list.split(','), function (suffix) {
            callback(prefix + suffix);
        });
      } else {
        callback(pattern);
      }
    }
  });
define("ember-metal/get_properties",
  ["ember-metal/property_get","ember-metal/utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var typeOf = __dependency2__.typeOf;

    
    __exports__["default"] = function getProperties(obj) {
      var ret = {},
          propertyNames = arguments,
          i = 1;

      if (arguments.length === 2 && typeOf(arguments[1]) === 'array') {
        i = 0;
        propertyNames = arguments[1];
      }
      for(var len = propertyNames.length; i < len; i++) {
        ret[propertyNames[i]] = get(obj, propertyNames[i]);
      }
      return ret;
    }
  });
define("ember-metal/instrumentation",
  ["ember-metal/core","ember-metal/utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var tryCatchFinally = __dependency2__.tryCatchFinally;

    
    var subscribers = [], cache = {};

    var populateListeners = function(name) {
      var listeners = [], subscriber;

      for (var i=0, l=subscribers.length; i<l; i++) {
        subscriber = subscribers[i];
        if (subscriber.regex.test(name)) {
          listeners.push(subscriber.object);
        }
      }

      cache[name] = listeners;
      return listeners;
    };

    var time = (function() {
      var perf = 'undefined' !== typeof window ? window.performance || {} : {};
      var fn = perf.now || perf.mozNow || perf.webkitNow || perf.msNow || perf.oNow;
      // fn.bind will be available in all the browsers that support the advanced window.performance... ;-)
      return fn ? fn.bind(perf) : function() { return +new Date(); };
    })();

    
    function instrument(name, payload, callback, binding) {
      var listeners = cache[name], timeName, ret;

      // ES6TODO: Docs. What is this?
      if (Ember.STRUCTURED_PROFILE) {
        timeName = name + ": " + payload.object;
        console.time(timeName);
      }

      if (!listeners) {
        listeners = populateListeners(name);
      }

      if (listeners.length === 0) {
        ret = callback.call(binding);
        if (Ember.STRUCTURED_PROFILE) { console.timeEnd(timeName); }
        return ret;
      }

      var beforeValues = [], listener, i, l;

      function tryable() {
        for (i=0, l=listeners.length; i<l; i++) {
          listener = listeners[i];
          beforeValues[i] = listener.before(name, time(), payload);
        }

        return callback.call(binding);
      }

      function catchable(e) {
        payload = payload || {};
        payload.exception = e;
      }

      function finalizer() {
        for (i=0, l=listeners.length; i<l; i++) {
          listener = listeners[i];
          listener.after(name, time(), payload, beforeValues[i]);
        }

        if (Ember.STRUCTURED_PROFILE) {
          console.timeEnd(timeName);
        }
      }

      return tryCatchFinally(tryable, catchable, finalizer);
    }

    __exports__.instrument = instrument;
    function subscribe(pattern, object) {
      var paths = pattern.split("."), path, regex = [];

      for (var i=0, l=paths.length; i<l; i++) {
        path = paths[i];
        if (path === "*") {
          regex.push("[^\\.]*");
        } else {
          regex.push(path);
        }
      }

      regex = regex.join("\\.");
      regex = regex + "(\\..*)?";

      var subscriber = {
        pattern: pattern,
        regex: new RegExp("^" + regex + "$"),
        object: object
      };

      subscribers.push(subscriber);
      cache = {};

      return subscriber;
    }

    __exports__.subscribe = subscribe;
    function unsubscribe(subscriber) {
      var index;

      for (var i=0, l=subscribers.length; i<l; i++) {
        if (subscribers[i] === subscriber) {
          index = i;
        }
      }

      subscribers.splice(index, 1);
      cache = {};
    }

    __exports__.unsubscribe = unsubscribe;
    function reset() {
      subscribers = [];
      cache = {};
    }

    __exports__.reset = reset;
  });
define("ember-metal/is_blank",
  ["ember-metal/core","ember-metal/is_empty","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // deprecateFunc
    var isEmpty = __dependency2__["default"];

    
    __exports__["default"] = function isBlank(obj) {
      return isEmpty(obj) || (typeof obj === 'string' && obj.match(/\S/) === null);
    }
  });
define("ember-metal/is_empty",
  ["ember-metal/core","ember-metal/property_get","ember-metal/is_none","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // deprecateFunc
    var get = __dependency2__.get;
    var isNone = __dependency3__["default"];

    
    function isEmpty(obj) {
      return isNone(obj) || (obj.length === 0 && typeof obj !== 'function') || (typeof obj === 'object' && get(obj, 'length') === 0);
    }

    var empty = Ember.deprecateFunc("Ember.empty is deprecated. Please use Ember.isEmpty instead.", isEmpty);
    __exports__.empty = empty;
    __exports__["default"] = isEmpty;
    __exports__.isEmpty = isEmpty;
    __exports__.empty = empty;
  });
define("ember-metal/is_none",
  ["ember-metal/core","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // deprecateFunc

    
    function isNone(obj) {
      return obj === null || obj === undefined;
    }

    var none = Ember.deprecateFunc("Ember.none is deprecated. Please use Ember.isNone instead.", isNone);
    __exports__.none = none;
    __exports__["default"] = isNone;
    __exports__.isNone = isNone;
  });
define("ember-metal/libraries",
  ["ember-metal/enumerable_utils","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    // Provides a way to register library versions with ember.
    var forEach = __dependency1__.forEach;
    var indexOf = __dependency1__.indexOf;

    var libraries = function() {
      var _libraries   = [];
      var coreLibIndex = 0;

      var getLibrary = function(name) {
        for (var i = 0; i < _libraries.length; i++) {
          if (_libraries[i].name === name) {
            return _libraries[i];
          }
        }
      };

      _libraries.register = function(name, version) {
        if (!getLibrary(name)) {
          _libraries.push({name: name, version: version});
        }
      };

      _libraries.registerCoreLibrary = function(name, version) {
        if (!getLibrary(name)) {
          _libraries.splice(coreLibIndex++, 0, {name: name, version: version});
        }
      };

      _libraries.deRegister = function(name) {
        var lib = getLibrary(name);
        if (lib) _libraries.splice(indexOf(_libraries, lib), 1);
      };

      _libraries.each = function (callback) {
        forEach(_libraries, function(lib) {
          callback(lib.name, lib.version);
        });
      };

      return _libraries;
    }();

    __exports__["default"] = libraries;
  });
define("ember-metal/logger",
  ["ember-metal/core","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var EmberError = __dependency2__["default"];

    function consoleMethod(name) {
      var consoleObj, logToConsole;
      if (Ember.imports.console) {
        consoleObj = Ember.imports.console;
      } else if (typeof console !== 'undefined') {
        consoleObj = console;
      }

      var method = typeof consoleObj === 'object' ? consoleObj[name] : null;

      if (method) {
        // Older IE doesn't support apply, but Chrome needs it
        if (typeof method.apply === 'function') {
          logToConsole = function() {
            method.apply(consoleObj, arguments);
          };
          logToConsole.displayName = 'console.' + name;
          return logToConsole;
        } else {
          return function() {
            var message = Array.prototype.join.call(arguments, ', ');
            method(message);
          };
        }
      }
    }

    function assertPolyfill(test, message) {
      if (!test) {
        try {
          // attempt to preserve the stack
          throw new EmberError("assertion failed: " + message);
        } catch(error) {
          setTimeout(function() {
            throw error;
          }, 0);
        }
      }
    }

    
    __exports__["default"] = {
      
      log:   consoleMethod('log')   || Ember.K,

      
      warn:  consoleMethod('warn')  || Ember.K,

      
      error: consoleMethod('error') || Ember.K,

      
      info:  consoleMethod('info')  || Ember.K,

      
      debug: consoleMethod('debug') || consoleMethod('info') || Ember.K,

      
      assert: consoleMethod('assert') || assertPolyfill
    };
  });
define("ember-metal/map",
  ["ember-metal/property_set","ember-metal/utils","ember-metal/array","ember-metal/platform","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    

    

    var set = __dependency1__.set;
    var guidFor = __dependency2__.guidFor;
    var indexOf = __dependency3__.indexOf;
    var create = __dependency4__.create;

    function copy(obj) {
      var output = {};

      for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) { output[prop] = obj[prop]; }
      }

      return output;
    }

    function copyMap(original, newObject) {
      var keys = original.keys.copy(),
          values = copy(original.values);

      newObject.keys = keys;
      newObject.values = values;
      newObject.length = original.length;

      return newObject;
    }

    
    function OrderedSet() {
      this.clear();
    }

    
    OrderedSet.create = function() {
      return new OrderedSet();
    };


    OrderedSet.prototype = {
      
      clear: function() {
        this.presenceSet = {};
        this.list = [];
      },

      
      add: function(obj) {
        var guid = guidFor(obj),
            presenceSet = this.presenceSet,
            list = this.list;

        if (guid in presenceSet) { return; }

        presenceSet[guid] = true;
        list.push(obj);
      },

      
      remove: function(obj) {
        var guid = guidFor(obj),
            presenceSet = this.presenceSet,
            list = this.list;

        delete presenceSet[guid];

        var index = indexOf.call(list, obj);
        if (index > -1) {
          list.splice(index, 1);
        }
      },

      
      isEmpty: function() {
        return this.list.length === 0;
      },

      
      has: function(obj) {
        var guid = guidFor(obj),
            presenceSet = this.presenceSet;

        return guid in presenceSet;
      },

      
      forEach: function(fn, self) {
        // allow mutation during iteration
        var list = this.toArray();

        for (var i = 0, j = list.length; i < j; i++) {
          fn.call(self, list[i]);
        }
      },

      
      toArray: function() {
        return this.list.slice();
      },

      
      copy: function() {
        var set = new OrderedSet();

        set.presenceSet = copy(this.presenceSet);
        set.list = this.toArray();

        return set;
      }
    };

    
    function Map() {
      this.keys = OrderedSet.create();
      this.values = {};
    }

    Ember.Map = Map;

    
    Map.create = function() {
      return new Map();
    };

    Map.prototype = {
      
      length: 0,

      
      get: function(key) {
        var values = this.values,
            guid = guidFor(key);

        return values[guid];
      },

      
      set: function(key, value) {
        var keys = this.keys,
            values = this.values,
            guid = guidFor(key);

        keys.add(key);
        values[guid] = value;
        set(this, 'length', keys.list.length);
      },

      
      remove: function(key) {
        // don't use ES6 "delete" because it will be annoying
        // to use in browsers that are not ES6 friendly;
        var keys = this.keys,
            values = this.values,
            guid = guidFor(key);

        if (values.hasOwnProperty(guid)) {
          keys.remove(key);
          delete values[guid];
          set(this, 'length', keys.list.length);
          return true;
        } else {
          return false;
        }
      },

      
      has: function(key) {
        var values = this.values,
            guid = guidFor(key);

        return values.hasOwnProperty(guid);
      },

      
      forEach: function(callback, self) {
        var keys = this.keys,
            values = this.values;

        keys.forEach(function(key) {
          var guid = guidFor(key);
          callback.call(self, key, values[guid]);
        });
      },

      
      copy: function() {
        return copyMap(this, new Map());
      }
    };

    
    function MapWithDefault(options) {
      Map.call(this);
      this.defaultValue = options.defaultValue;
    }

    
    MapWithDefault.create = function(options) {
      if (options) {
        return new MapWithDefault(options);
      } else {
        return new Map();
      }
    };

    MapWithDefault.prototype = create(Map.prototype);

    
    MapWithDefault.prototype.get = function(key) {
      var hasValue = this.has(key);

      if (hasValue) {
        return Map.prototype.get.call(this, key);
      } else {
        var defaultValue = this.defaultValue(key);
        this.set(key, defaultValue);
        return defaultValue;
      }
    };

    
    MapWithDefault.prototype.copy = function() {
      return copyMap(this, new MapWithDefault({
        defaultValue: this.defaultValue
      }));
    };

    __exports__.OrderedSet = OrderedSet;
    __exports__.Map = Map;
    __exports__.MapWithDefault = MapWithDefault;
  });
define("ember-metal/merge",
  ["exports"],
  function(__exports__) {
    "use strict";
    
    __exports__["default"] = function merge(original, updates) {
      for (var prop in updates) {
        if (!updates.hasOwnProperty(prop)) { continue; }
        original[prop] = updates[prop];
      }
      return original;
    }
  });
define("ember-metal/mixin",
  ["ember-metal/core","ember-metal/merge","ember-metal/array","ember-metal/platform","ember-metal/utils","ember-metal/expand_properties","ember-metal/properties","ember-metal/computed","ember-metal/binding","ember-metal/observer","ember-metal/events","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // warn, assert, wrap, et;
    var merge = __dependency2__["default"];
    var map = __dependency3__.map;
    var indexOf = __dependency3__.indexOf;
    var forEach = __dependency3__.forEach;
    var create = __dependency4__.create;
    var guidFor = __dependency5__.guidFor;
    var meta = __dependency5__.meta;
    var META_KEY = __dependency5__.META_KEY;
    var wrap = __dependency5__.wrap;
    var makeArray = __dependency5__.makeArray;
    var apply = __dependency5__.apply;
    var expandProperties = __dependency6__["default"];
    var Descriptor = __dependency7__.Descriptor;
    var defineProperty = __dependency7__.defineProperty;
    var ComputedProperty = __dependency8__.ComputedProperty;
    var Binding = __dependency9__.Binding;
    var addObserver = __dependency10__.addObserver;
    var removeObserver = __dependency10__.removeObserver;
    var addBeforeObserver = __dependency10__.addBeforeObserver;
    var removeBeforeObserver = __dependency10__.removeBeforeObserver;
    var addListener = __dependency11__.addListener;
    var removeListener = __dependency11__.removeListener;

    var REQUIRED,
        a_map = map,
        a_indexOf = indexOf,
        a_forEach = forEach,
        a_slice = [].slice,
        o_create = create,
        metaFor = meta;

    function superFunction(){
      var ret, func = this.__nextSuper;
      if (func) {
        this.__nextSuper = null;
        ret = apply(this, func, arguments);
        this.__nextSuper = func;
      }
      return ret;
    }

    function mixinsMeta(obj) {
      var m = metaFor(obj, true), ret = m.mixins;
      if (!ret) {
        ret = m.mixins = {};
      } else if (!m.hasOwnProperty('mixins')) {
        ret = m.mixins = o_create(ret);
      }
      return ret;
    }

    function initMixin(mixin, args) {
      if (args && args.length > 0) {
        mixin.mixins = a_map.call(args, function(x) {
          if (x instanceof Mixin) { return x; }

          // Note: Manually setup a primitive mixin here. This is the only
          // way to actually get a primitive mixin. This way normal creation
          // of mixins will give you combined mixins...
          var mixin = new Mixin();
          mixin.properties = x;
          return mixin;
        });
      }
      return mixin;
    }

    function isMethod(obj) {
      return 'function' === typeof obj &&
             obj.isMethod !== false &&
             obj !== Boolean && obj !== Object && obj !== Number && obj !== Array && obj !== Date && obj !== String;
    }

    var CONTINUE = {};

    function mixinProperties(mixinsMeta, mixin) {
      var guid;

      if (mixin instanceof Mixin) {
        guid = guidFor(mixin);
        if (mixinsMeta[guid]) { return CONTINUE; }
        mixinsMeta[guid] = mixin;
        return mixin.properties;
      } else {
        return mixin; // apply anonymous mixin properties
      }
    }

    function concatenatedMixinProperties(concatProp, props, values, base) {
      var concats;

      // reset before adding each new mixin to pickup concats from previous
      concats = values[concatProp] || base[concatProp];
      if (props[concatProp]) {
        concats = concats ? concats.concat(props[concatProp]) : props[concatProp];
      }

      return concats;
    }

    function giveDescriptorSuper(meta, key, property, values, descs) {
      var superProperty;

      // Computed properties override methods, and do not call super to them
      if (values[key] === undefined) {
        // Find the original descriptor in a parent mixin
        superProperty = descs[key];
      }

      // If we didn't find the original descriptor in a parent mixin, find
      // it on the original object.
      superProperty = superProperty || meta.descs[key];

      if (!superProperty || !(superProperty instanceof ComputedProperty)) {
        return property;
      }

      // Since multiple mixins may inherit from the same parent, we need
      // to clone the computed property so that other mixins do not receive
      // the wrapped version.
      property = o_create(property);
      property.func = wrap(property.func, superProperty.func);

      return property;
    }

    function giveMethodSuper(obj, key, method, values, descs) {
      var superMethod;

      // Methods overwrite computed properties, and do not call super to them.
      if (descs[key] === undefined) {
        // Find the original method in a parent mixin
        superMethod = values[key];
      }

      // If we didn't find the original value in a parent mixin, find it in
      // the original object
      superMethod = superMethod || obj[key];

      // Only wrap the new method if the original method was a function
      if ('function' !== typeof superMethod) {
        return method;
      }

      return wrap(method, superMethod);
    }

    function applyConcatenatedProperties(obj, key, value, values) {
      var baseValue = values[key] || obj[key];

      if (baseValue) {
        if ('function' === typeof baseValue.concat) {
          return baseValue.concat(value);
        } else {
          return makeArray(baseValue).concat(value);
        }
      } else {
        return makeArray(value);
      }
    }

    function applyMergedProperties(obj, key, value, values) {
      var baseValue = values[key] || obj[key];

      if (!baseValue) { return value; }

      var newBase = merge({}, baseValue),
          hasFunction = false;

      for (var prop in value) {
        if (!value.hasOwnProperty(prop)) { continue; }

        var propValue = value[prop];
        if (isMethod(propValue)) {
          // TODO: support for Computed Properties, etc?
          hasFunction = true;
          newBase[prop] = giveMethodSuper(obj, prop, propValue, baseValue, {});
        } else {
          newBase[prop] = propValue;
        }
      }

      if (hasFunction) {
        newBase._super = superFunction;
      }

      return newBase;
    }

    function addNormalizedProperty(base, key, value, meta, descs, values, concats, mergings) {
      if (value instanceof Descriptor) {
        if (value === REQUIRED && descs[key]) { return CONTINUE; }

        // Wrap descriptor function to implement
        // __nextSuper() if needed
        if (value.func) {
          value = giveDescriptorSuper(meta, key, value, values, descs);
        }

        descs[key]  = value;
        values[key] = undefined;
      } else {
        if ((concats && a_indexOf.call(concats, key) >= 0) ||
                    key === 'concatenatedProperties' ||
                    key === 'mergedProperties') {
          value = applyConcatenatedProperties(base, key, value, values);
        } else if ((mergings && a_indexOf.call(mergings, key) >= 0)) {
          value = applyMergedProperties(base, key, value, values);
        } else if (isMethod(value)) {
          value = giveMethodSuper(base, key, value, values, descs);
        }

        descs[key] = undefined;
        values[key] = value;
      }
    }

    function mergeMixins(mixins, m, descs, values, base, keys) {
      var mixin, props, key, concats, mergings, meta;

      function removeKeys(keyName) {
        delete descs[keyName];
        delete values[keyName];
      }

      for(var i=0, l=mixins.length; i<l; i++) {
        mixin = mixins[i];
        Ember.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(mixin),
                     typeof mixin === 'object' && mixin !== null && Object.prototype.toString.call(mixin) !== '[object Array]');

        props = mixinProperties(m, mixin);
        if (props === CONTINUE) { continue; }

        if (props) {
          meta = metaFor(base);
          if (base.willMergeMixin) { base.willMergeMixin(props); }
          concats = concatenatedMixinProperties('concatenatedProperties', props, values, base);
          mergings = concatenatedMixinProperties('mergedProperties', props, values, base);

          for (key in props) {
            if (!props.hasOwnProperty(key)) { continue; }
            keys.push(key);
            addNormalizedProperty(base, key, props[key], meta, descs, values, concats, mergings);
          }

          // manually copy toString() because some JS engines do not enumerate it
          if (props.hasOwnProperty('toString')) { base.toString = props.toString; }
        } else if (mixin.mixins) {
          mergeMixins(mixin.mixins, m, descs, values, base, keys);
          if (mixin._without) { a_forEach.call(mixin._without, removeKeys); }
        }
      }
    }

    var IS_BINDING = /^.+Binding$/;

    function detectBinding(obj, key, value, m) {
      if (IS_BINDING.test(key)) {
        var bindings = m.bindings;
        if (!bindings) {
          bindings = m.bindings = {};
        } else if (!m.hasOwnProperty('bindings')) {
          bindings = m.bindings = o_create(m.bindings);
        }
        bindings[key] = value;
      }
    }

    function connectBindings(obj, m) {
      // TODO Mixin.apply(instance) should disconnect binding if exists
      var bindings = m.bindings, key, binding, to;
      if (bindings) {
        for (key in bindings) {
          binding = bindings[key];
          if (binding) {
            to = key.slice(0, -7); // strip Binding off end
            if (binding instanceof Binding) {
              binding = binding.copy(); // copy prototypes' instance
              binding.to(to);
            } else { // binding is string path
              binding = new Binding(to, binding);
            }
            binding.connect(obj);
            obj[key] = binding;
          }
        }
        // mark as applied
        m.bindings = {};
      }
    }

    function finishPartial(obj, m) {
      connectBindings(obj, m || metaFor(obj));
      return obj;
    }

    function followAlias(obj, desc, m, descs, values) {
      var altKey = desc.methodName, value;
      if (descs[altKey] || values[altKey]) {
        value = values[altKey];
        desc  = descs[altKey];
      } else if (m.descs[altKey]) {
        desc  = m.descs[altKey];
        value = undefined;
      } else {
        desc = undefined;
        value = obj[altKey];
      }

      return { desc: desc, value: value };
    }

    function updateObserversAndListeners(obj, key, observerOrListener, pathsKey, updateMethod) {
      var paths = observerOrListener[pathsKey];

      if (paths) {
        for (var i=0, l=paths.length; i<l; i++) {
          updateMethod(obj, paths[i], null, key);
        }
      }
    }

    function replaceObserversAndListeners(obj, key, observerOrListener) {
      var prev = obj[key];

      if ('function' === typeof prev) {
        updateObserversAndListeners(obj, key, prev, '__ember_observesBefore__', removeBeforeObserver);
        updateObserversAndListeners(obj, key, prev, '__ember_observes__', removeObserver);
        updateObserversAndListeners(obj, key, prev, '__ember_listens__', removeListener);
      }

      if ('function' === typeof observerOrListener) {
        updateObserversAndListeners(obj, key, observerOrListener, '__ember_observesBefore__', addBeforeObserver);
        updateObserversAndListeners(obj, key, observerOrListener, '__ember_observes__', addObserver);
        updateObserversAndListeners(obj, key, observerOrListener, '__ember_listens__', addListener);
      }
    }

    function applyMixin(obj, mixins, partial) {
      var descs = {}, values = {}, m = metaFor(obj),
          key, value, desc, keys = [];

      obj._super = superFunction;

      // Go through all mixins and hashes passed in, and:
      //
      // * Handle concatenated properties
      // * Handle merged properties
      // * Set up _super wrapping if necessary
      // * Set up computed property descriptors
      // * Copying `toString` in broken browsers
      mergeMixins(mixins, mixinsMeta(obj), descs, values, obj, keys);

      for(var i = 0, l = keys.length; i < l; i++) {
        key = keys[i];
        if (key === 'constructor' || !values.hasOwnProperty(key)) { continue; }

        desc = descs[key];
        value = values[key];

        if (desc === REQUIRED) { continue; }

        while (desc && desc instanceof Alias) {
          var followed = followAlias(obj, desc, m, descs, values);
          desc = followed.desc;
          value = followed.value;
        }

        if (desc === undefined && value === undefined) { continue; }

        replaceObserversAndListeners(obj, key, value);
        detectBinding(obj, key, value, m);
        defineProperty(obj, key, desc, value, m);
      }

      if (!partial) { // don't apply to prototype
        finishPartial(obj, m);
      }

      return obj;
    }

    
    function mixin(obj) {
      var args = a_slice.call(arguments, 1);
      applyMixin(obj, args, false);
      return obj;
    }

    __exports__.mixin = mixin;
    __exports__["default"] = Mixin;
    function Mixin() { return initMixin(this, arguments); }
    Mixin.prototype = {
      properties: null,
      mixins: null,
      ownerConstructor: null
    };

    Mixin._apply = applyMixin;

    Mixin.applyPartial = function(obj) {
      var args = a_slice.call(arguments, 1);
      return applyMixin(obj, args, true);
    };

    Mixin.finishPartial = finishPartial;

    // ES6TODO: this relies on a global state?
    Ember.anyUnprocessedMixins = false;

    
    Mixin.create = function() {
      // ES6TODO: this relies on a global state?
      Ember.anyUnprocessedMixins = true;
      var M = this;
      return initMixin(new M(), arguments);
    };

    var MixinPrototype = Mixin.prototype;

    
    MixinPrototype.reopen = function() {
      var mixin, tmp;

      if (this.properties) {
        mixin = Mixin.create();
        mixin.properties = this.properties;
        delete this.properties;
        this.mixins = [mixin];
      } else if (!this.mixins) {
        this.mixins = [];
      }

      var len = arguments.length, mixins = this.mixins, idx;

      for(idx=0; idx < len; idx++) {
        mixin = arguments[idx];
        Ember.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(mixin),
                     typeof mixin === 'object' && mixin !== null && Object.prototype.toString.call(mixin) !== '[object Array]');

        if (mixin instanceof Mixin) {
          mixins.push(mixin);
        } else {
          tmp = Mixin.create();
          tmp.properties = mixin;
          mixins.push(tmp);
        }
      }

      return this;
    };

    
    MixinPrototype.apply = function(obj) {
      return applyMixin(obj, [this], false);
    };

    MixinPrototype.applyPartial = function(obj) {
      return applyMixin(obj, [this], true);
    };

    function _detect(curMixin, targetMixin, seen) {
      var guid = guidFor(curMixin);

      if (seen[guid]) { return false; }
      seen[guid] = true;

      if (curMixin === targetMixin) { return true; }
      var mixins = curMixin.mixins, loc = mixins ? mixins.length : 0;
      while (--loc >= 0) {
        if (_detect(mixins[loc], targetMixin, seen)) { return true; }
      }
      return false;
    }

    
    MixinPrototype.detect = function(obj) {
      if (!obj) { return false; }
      if (obj instanceof Mixin) { return _detect(obj, this, {}); }
      var m = obj[META_KEY],
          mixins = m && m.mixins;
      if (mixins) {
        return !!mixins[guidFor(this)];
      }
      return false;
    };

    MixinPrototype.without = function() {
      var ret = new Mixin(this);
      ret._without = a_slice.call(arguments);
      return ret;
    };

    function _keys(ret, mixin, seen) {
      if (seen[guidFor(mixin)]) { return; }
      seen[guidFor(mixin)] = true;

      if (mixin.properties) {
        var props = mixin.properties;
        for (var key in props) {
          if (props.hasOwnProperty(key)) { ret[key] = true; }
        }
      } else if (mixin.mixins) {
        a_forEach.call(mixin.mixins, function(x) { _keys(ret, x, seen); });
      }
    }

    MixinPrototype.keys = function() {
      var keys = {}, seen = {}, ret = [];
      _keys(keys, this, seen);
      for(var key in keys) {
        if (keys.hasOwnProperty(key)) { ret.push(key); }
      }
      return ret;
    };

    // returns the mixins currently applied to the specified object
    // TODO: Make Ember.mixin
    Mixin.mixins = function(obj) {
      var m = obj[META_KEY],
          mixins = m && m.mixins, ret = [];

      if (!mixins) { return ret; }

      for (var key in mixins) {
        var mixin = mixins[key];

        // skip primitive mixins since these are always anonymous
        if (!mixin.properties) { ret.push(mixin); }
      }

      return ret;
    };

    REQUIRED = new Descriptor();
    REQUIRED.toString = function() { return '(Required Property)'; };

    
    function required() {
      return REQUIRED;
    }

    __exports__.required = required;function Alias(methodName) {
      this.methodName = methodName;
    }

    Alias.prototype = new Descriptor();

    
    function aliasMethod(methodName) {
      return new Alias(methodName);
    }

    __exports__.aliasMethod = aliasMethod;// ..........................................................
    // OBSERVER HELPER
    //

    
    function observer() {
      var func  = a_slice.call(arguments, -1)[0];
      var paths;

      var addWatchedProperty = function (path) { paths.push(path); };
      var _paths = a_slice.call(arguments, 0, -1);

      if (typeof func !== "function") {
        // revert to old, soft-deprecated argument ordering

        func  = arguments[0];
        _paths = a_slice.call(arguments, 1);
      }

      paths = [];

      for (var i=0; i<_paths.length; ++i) {
        expandProperties(_paths[i], addWatchedProperty);
      }

      if (typeof func !== "function") {
        throw new Ember.Error("Ember.observer called without a function");
      }

      func.__ember_observes__ = paths;
      return func;
    }

    __exports__.observer = observer;
    function immediateObserver() {
      for (var i=0, l=arguments.length; i<l; i++) {
        var arg = arguments[i];
        Ember.assert("Immediate observers must observe internal properties only, not properties on other objects.", typeof arg !== "string" || arg.indexOf('.') === -1);
      }

      return observer.apply(this, arguments);
    }

    __exports__.immediateObserver = immediateObserver;
    function beforeObserver() {
      var func  = a_slice.call(arguments, -1)[0];
      var paths;

      var addWatchedProperty = function(path) { paths.push(path); };

      var _paths = a_slice.call(arguments, 0, -1);

      if (typeof func !== "function") {
        // revert to old, soft-deprecated argument ordering

        func  = arguments[0];
        _paths = a_slice.call(arguments, 1);
      }

      paths = [];

      for (var i=0; i<_paths.length; ++i) {
        expandProperties(_paths[i], addWatchedProperty);
      }

      if (typeof func !== "function") {
        throw new Ember.Error("Ember.beforeObserver called without a function");
      }

      func.__ember_observesBefore__ = paths;
      return func;
    }

    __exports__.beforeObserver = beforeObserver;__exports__.IS_BINDING = IS_BINDING;
    __exports__.Mixin = Mixin;
  });
define("ember-metal/observer",
  ["ember-metal/watching","ember-metal/array","ember-metal/events","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var watch = __dependency1__.watch;
    var unwatch = __dependency1__.unwatch;
    var map = __dependency2__.map;
    var listenersFor = __dependency3__.listenersFor;
    var addListener = __dependency3__.addListener;
    var removeListener = __dependency3__.removeListener;
    var suspendListeners = __dependency3__.suspendListeners;
    var suspendListener = __dependency3__.suspendListener;
    

    var AFTER_OBSERVERS = ':change';
    var BEFORE_OBSERVERS = ':before';

    function changeEvent(keyName) {
      return keyName + AFTER_OBSERVERS;
    }

    function beforeEvent(keyName) {
      return keyName + BEFORE_OBSERVERS;
    }

    
    function addObserver(obj, _path, target, method) {
      addListener(obj, changeEvent(_path), target, method);
      watch(obj, _path);

      return this;
    }

    __exports__.addObserver = addObserver;function observersFor(obj, path) {
      return listenersFor(obj, changeEvent(path));
    }

    __exports__.observersFor = observersFor;
    function removeObserver(obj, _path, target, method) {
      unwatch(obj, _path);
      removeListener(obj, changeEvent(_path), target, method);

      return this;
    }

    __exports__.removeObserver = removeObserver;
    function addBeforeObserver(obj, _path, target, method) {
      addListener(obj, beforeEvent(_path), target, method);
      watch(obj, _path);

      return this;
    }

    __exports__.addBeforeObserver = addBeforeObserver;// Suspend observer during callback.
    //
    // This should only be used by the target of the observer
    // while it is setting the observed path.
    function _suspendBeforeObserver(obj, path, target, method, callback) {
      return suspendListener(obj, beforeEvent(path), target, method, callback);
    }

    __exports__._suspendBeforeObserver = _suspendBeforeObserver;function _suspendObserver(obj, path, target, method, callback) {
      return suspendListener(obj, changeEvent(path), target, method, callback);
    }

    __exports__._suspendObserver = _suspendObserver;function _suspendBeforeObservers(obj, paths, target, method, callback) {
      var events = map.call(paths, beforeEvent);
      return suspendListeners(obj, events, target, method, callback);
    }

    __exports__._suspendBeforeObservers = _suspendBeforeObservers;function _suspendObservers(obj, paths, target, method, callback) {
      var events = map.call(paths, changeEvent);
      return suspendListeners(obj, events, target, method, callback);
    }

    __exports__._suspendObservers = _suspendObservers;function beforeObserversFor(obj, path) {
      return listenersFor(obj, beforeEvent(path));
    }

    __exports__.beforeObserversFor = beforeObserversFor;
    function removeBeforeObserver(obj, _path, target, method) {
      unwatch(obj, _path);
      removeListener(obj, beforeEvent(_path), target, method);

      return this;
    }

    __exports__.removeBeforeObserver = removeBeforeObserver;
  });
define("ember-metal/observer_set",
  ["ember-metal/utils","ember-metal/events","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var guidFor = __dependency1__.guidFor;
    var sendEvent = __dependency2__.sendEvent;

    
    __exports__["default"] = ObserverSet;
    function ObserverSet() {
      this.clear();
    }


    ObserverSet.prototype.add = function(sender, keyName, eventName) {
      var observerSet = this.observerSet,
          observers = this.observers,
          senderGuid = guidFor(sender),
          keySet = observerSet[senderGuid],
          index;

      if (!keySet) {
        observerSet[senderGuid] = keySet = {};
      }
      index = keySet[keyName];
      if (index === undefined) {
        index = observers.push({
          sender: sender,
          keyName: keyName,
          eventName: eventName,
          listeners: []
        }) - 1;
        keySet[keyName] = index;
      }
      return observers[index].listeners;
    };

    ObserverSet.prototype.flush = function() {
      var observers = this.observers, i, len, observer, sender;
      this.clear();
      for (i=0, len=observers.length; i < len; ++i) {
        observer = observers[i];
        sender = observer.sender;
        if (sender.isDestroying || sender.isDestroyed) { continue; }
        sendEvent(sender, observer.eventName, [sender, observer.keyName], observer.listeners);
      }
    };

    ObserverSet.prototype.clear = function() {
      this.observerSet = {};
      this.observers = [];
    };
  });
define("ember-metal/platform",
  ["ember-metal/core","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];

    

    
    // TODO remove this
    var platform = {};

    
    var create = Object.create;

    // IE8 has Object.create but it couldn't treat property descriptors.
    if (create) {
      if (create({a: 1}, {a: {value: 2}}).a !== 2) {
        create = null;
      }
    }

    // STUB_OBJECT_CREATE allows us to override other libraries that stub
    // Object.create different than we would prefer
    if (!create || Ember.ENV.STUB_OBJECT_CREATE) {
      var K = function() {};

      create = function(obj, props) {
        K.prototype = obj;
        obj = new K();
        if (props) {
          K.prototype = obj;
          for (var prop in props) {
            K.prototype[prop] = props[prop].value;
          }
          obj = new K();
        }
        K.prototype = null;

        return obj;
      };

      create.isSimulated = true;
    }

    var defineProperty = Object.defineProperty;
    var canRedefineProperties, canDefinePropertyOnDOM;

    // Catch IE8 where Object.defineProperty exists but only works on DOM elements
    if (defineProperty) {
      try {
        defineProperty({}, 'a',{get:function() {}});
      } catch (e) {
        defineProperty = null;
      }
    }

    if (defineProperty) {
      // Detects a bug in Android <3.2 where you cannot redefine a property using
      // Object.defineProperty once accessors have already been set.
      canRedefineProperties = (function() {
        var obj = {};

        defineProperty(obj, 'a', {
          configurable: true,
          enumerable: true,
          get: function() { },
          set: function() { }
        });

        defineProperty(obj, 'a', {
          configurable: true,
          enumerable: true,
          writable: true,
          value: true
        });

        return obj.a === true;
      })();

      // This is for Safari 5.0, which supports Object.defineProperty, but not
      // on DOM nodes.
      canDefinePropertyOnDOM = (function() {
        try {
          defineProperty(document.createElement('div'), 'definePropertyOnDOM', {});
          return true;
        } catch(e) { }

        return false;
      })();

      if (!canRedefineProperties) {
        defineProperty = null;
      } else if (!canDefinePropertyOnDOM) {
        defineProperty = function(obj, keyName, desc) {
          var isNode;

          if (typeof Node === "object") {
            isNode = obj instanceof Node;
          } else {
            isNode = typeof obj === "object" && typeof obj.nodeType === "number" && typeof obj.nodeName === "string";
          }

          if (isNode) {
            // TODO: Should we have a warning here?
            return (obj[keyName] = desc.value);
          } else {
            return Object.defineProperty(obj, keyName, desc);
          }
        };
      }
    }

    

    
    platform.defineProperty = defineProperty;

    
    platform.hasPropertyAccessors = true;

    if (!platform.defineProperty) {
      platform.hasPropertyAccessors = false;

      platform.defineProperty = function(obj, keyName, desc) {
        if (!desc.get) { obj[keyName] = desc.value; }
      };

      platform.defineProperty.isSimulated = true;
    }

    if (Ember.ENV.MANDATORY_SETTER && !platform.hasPropertyAccessors) {
      Ember.ENV.MANDATORY_SETTER = false;
    }

    __exports__.create = create;
    __exports__.platform = platform;
  });
define("ember-metal/properties",
  ["ember-metal/core","ember-metal/utils","ember-metal/platform","ember-metal/property_events","ember-metal/property_get","ember-metal/property_set","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    var META_KEY = __dependency2__.META_KEY;
    var meta = __dependency2__.meta;
    var platform = __dependency3__.platform;
    var overrideChains = __dependency4__.overrideChains;
    var get = __dependency5__.get;
    var set = __dependency6__.set;

    var metaFor = meta,
        objectDefineProperty = platform.defineProperty;

    var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;

    // ..........................................................
    // DESCRIPTOR
    //

    
    function Descriptor() {}

    __exports__.Descriptor = Descriptor;// ..........................................................
    // DEFINING PROPERTIES API
    //

    var MANDATORY_SETTER_FUNCTION = Ember.MANDATORY_SETTER_FUNCTION = function(value) {
      Ember.assert("You must use Ember.set() to access this property (of " + this + ")", false);
    };

    var DEFAULT_GETTER_FUNCTION = Ember.DEFAULT_GETTER_FUNCTION = function DEFAULT_GETTER_FUNCTION(name) {
      return function() {
        var meta = this[META_KEY];
        return meta && meta.values[name];
      };
    };

    
    function defineProperty(obj, keyName, desc, data, meta) {
      var descs, existingDesc, watching, value;

      if (!meta) meta = metaFor(obj);
      descs = meta.descs;
      existingDesc = meta.descs[keyName];
      watching = meta.watching[keyName] > 0;

      if (existingDesc instanceof Descriptor) {
        existingDesc.teardown(obj, keyName);
      }

      if (desc instanceof Descriptor) {
        value = desc;

        descs[keyName] = desc;
        if (MANDATORY_SETTER && watching) {
          objectDefineProperty(obj, keyName, {
            configurable: true,
            enumerable: true,
            writable: true,
            value: undefined // make enumerable
          });
        } else {
          obj[keyName] = undefined; // make enumerable
        }
        if (desc.setup) { desc.setup(obj, keyName); }
      } else {
        descs[keyName] = undefined; // shadow descriptor in proto
        if (desc == null) {
          value = data;

          if (MANDATORY_SETTER && watching) {
            meta.values[keyName] = data;
            objectDefineProperty(obj, keyName, {
              configurable: true,
              enumerable: true,
              set: MANDATORY_SETTER_FUNCTION,
              get: DEFAULT_GETTER_FUNCTION(keyName)
            });
          } else {
            obj[keyName] = data;
          }
        } else {
          value = desc;

          // compatibility with ES5
          objectDefineProperty(obj, keyName, desc);
        }
      }

      // if key is being watched, override chains that
      // were initialized with the prototype
      if (watching) { overrideChains(obj, keyName, meta); }

      // The `value` passed to the `didDefineProperty` hook is
      // either the descriptor or data, whichever was passed.
      if (obj.didDefineProperty) { obj.didDefineProperty(obj, keyName, value); }

      return this;
    }

    __exports__.defineProperty = defineProperty;

    function deprecateProperty(object, deprecatedKey, newKey) {
      function deprecate() {
        Ember.deprecate('Usage of `' + deprecatedKey + '` is deprecated, use `' + newKey + '` instead.');
      }

      if (platform.hasPropertyAccessors) {
        defineProperty(object, deprecatedKey, {
            configurable: true,
            enumerable: false,
            set: function(value) { deprecate(); set(object, newKey, value); },
            get: function() { deprecate(); return get(object, newKey); }
        });
      }
    }

    __exports__.deprecateProperty = deprecateProperty;
  });
define("ember-metal/property_events",
  ["ember-metal/utils","ember-metal/events","ember-metal/observer_set","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var META_KEY = __dependency1__.META_KEY;
    var guidFor = __dependency1__.guidFor;
    var tryFinally = __dependency1__.tryFinally;
    var sendEvent = __dependency2__.sendEvent;
    var listenersUnion = __dependency2__.listenersUnion;
    var listenersDiff = __dependency2__.listenersDiff;
    var ObserverSet = __dependency3__["default"];

    var beforeObserverSet = new ObserverSet();
    var observerSet = new ObserverSet();
    var deferred = 0;

    // ..........................................................
    // PROPERTY CHANGES
    //

    
    function propertyWillChange(obj, keyName) {
      var m = obj[META_KEY],
          watching = (m && m.watching[keyName] > 0) || keyName === 'length',
          proto = m && m.proto,
          desc = m && m.descs[keyName];

      if (!watching) { return; }
      if (proto === obj) { return; }
      if (desc && desc.willChange) { desc.willChange(obj, keyName); }
      dependentKeysWillChange(obj, keyName, m);
      chainsWillChange(obj, keyName, m);
      notifyBeforeObservers(obj, keyName);
    }

    
    function propertyDidChange(obj, keyName) {
      var m = obj[META_KEY],
          watching = (m && m.watching[keyName] > 0) || keyName === 'length',
          proto = m && m.proto,
          desc = m && m.descs[keyName];

      if (proto === obj) { return; }

      // shouldn't this mean that we're watching this key?
      if (desc && desc.didChange) { desc.didChange(obj, keyName); }
      if (!watching && keyName !== 'length') { return; }

      dependentKeysDidChange(obj, keyName, m);
      chainsDidChange(obj, keyName, m, false);
      notifyObservers(obj, keyName);
    }

    var WILL_SEEN, DID_SEEN;

    // called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...)
    function dependentKeysWillChange(obj, depKey, meta) {
      if (obj.isDestroying) { return; }

      var seen = WILL_SEEN, top = !seen;
      if (top) { seen = WILL_SEEN = {}; }
      iterDeps(propertyWillChange, obj, depKey, seen, meta);
      if (top) { WILL_SEEN = null; }
    }

    // called whenever a property has just changed to update dependent keys
    function dependentKeysDidChange(obj, depKey, meta) {
      if (obj.isDestroying) { return; }

      var seen = DID_SEEN, top = !seen;
      if (top) { seen = DID_SEEN = {}; }
      iterDeps(propertyDidChange, obj, depKey, seen, meta);
      if (top) { DID_SEEN = null; }
    }

    function iterDeps(method, obj, depKey, seen, meta) {
      var guid = guidFor(obj);
      if (!seen[guid]) seen[guid] = {};
      if (seen[guid][depKey]) return;
      seen[guid][depKey] = true;

      var deps = meta.deps;
      deps = deps && deps[depKey];
      if (deps) {
        for(var key in deps) {
          var desc = meta.descs[key];
          if (desc && desc._suspended === obj) continue;
          method(obj, key);
        }
      }
    }

    function chainsWillChange(obj, keyName, m) {
      if (!(m.hasOwnProperty('chainWatchers') &&
            m.chainWatchers[keyName])) {
        return;
      }

      var nodes = m.chainWatchers[keyName],
          events = [],
          i, l;

      for(i = 0, l = nodes.length; i < l; i++) {
        nodes[i].willChange(events);
      }

      for (i = 0, l = events.length; i < l; i += 2) {
        propertyWillChange(events[i], events[i+1]);
      }
    }

    function chainsDidChange(obj, keyName, m, suppressEvents) {
      if (!(m && m.hasOwnProperty('chainWatchers') &&
            m.chainWatchers[keyName])) {
        return;
      }

      var nodes = m.chainWatchers[keyName],
          events = suppressEvents ? null : [],
          i, l;

      for(i = 0, l = nodes.length; i < l; i++) {
        nodes[i].didChange(events);
      }

      if (suppressEvents) {
        return;
      }

      for (i = 0, l = events.length; i < l; i += 2) {
        propertyDidChange(events[i], events[i+1]);
      }
    }

    function overrideChains(obj, keyName, m) {
      chainsDidChange(obj, keyName, m, true);
    }

    
    function beginPropertyChanges() {
      deferred++;
    }

    
    function endPropertyChanges() {
      deferred--;
      if (deferred<=0) {
        beforeObserverSet.clear();
        observerSet.flush();
      }
    }

    
    function changeProperties(cb, binding) {
      beginPropertyChanges();
      tryFinally(cb, endPropertyChanges, binding);
    }

    function notifyBeforeObservers(obj, keyName) {
      if (obj.isDestroying) { return; }

      var eventName = keyName + ':before', listeners, diff;
      if (deferred) {
        listeners = beforeObserverSet.add(obj, keyName, eventName);
        diff = listenersDiff(obj, eventName, listeners);
        sendEvent(obj, eventName, [obj, keyName], diff);
      } else {
        sendEvent(obj, eventName, [obj, keyName]);
      }
    }

    function notifyObservers(obj, keyName) {
      if (obj.isDestroying) { return; }

      var eventName = keyName + ':change', listeners;
      if (deferred) {
        listeners = observerSet.add(obj, keyName, eventName);
        listenersUnion(obj, eventName, listeners);
      } else {
        sendEvent(obj, eventName, [obj, keyName]);
      }
    }

    __exports__.propertyWillChange = propertyWillChange;
    __exports__.propertyDidChange = propertyDidChange;
    __exports__.overrideChains = overrideChains;
    __exports__.beginPropertyChanges = beginPropertyChanges;
    __exports__.endPropertyChanges = endPropertyChanges;
    __exports__.changeProperties = changeProperties;
  });
define("ember-metal/property_get",
  ["ember-metal/core","ember-metal/utils","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    var META_KEY = __dependency2__.META_KEY;
    var EmberError = __dependency3__["default"];

    var get;

    var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;

    var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.]/;
    var HAS_THIS  = 'this.';
    var FIRST_KEY = /^([^\.]+)/;

    // ..........................................................
    // GET AND SET
    //
    // If we are on a platform that supports accessors we can use those.
    // Otherwise simulate accessors by looking up the property directly on the
    // object.

    
    var get = function get(obj, keyName) {
      // Helpers that operate with 'this' within an #each
      if (keyName === '') {
        return obj;
      }

      if (!keyName && 'string'===typeof obj) {
        keyName = obj;
        obj = null;
      }

      Ember.assert("Cannot call get with "+ keyName +" key.", !!keyName);
      Ember.assert("Cannot call get with '"+ keyName +"' on an undefined object.", obj !== undefined);

      if (obj === null) { return _getPath(obj, keyName);  }

      var meta = obj[META_KEY], desc = meta && meta.descs[keyName], ret;

      if (desc === undefined && keyName.indexOf('.') !== -1) {
        return _getPath(obj, keyName);
      }

      if (desc) {
        return desc.get(obj, keyName);
      } else {
        if (MANDATORY_SETTER && meta && meta.watching[keyName] > 0) {
          ret = meta.values[keyName];
        } else {
          ret = obj[keyName];
        }

        if (ret === undefined &&
            'object' === typeof obj && !(keyName in obj) && 'function' === typeof obj.unknownProperty) {
          return obj.unknownProperty(keyName);
        }

        return ret;
      }
    };

    // Currently used only by Ember Data tests
    if (Ember.config.overrideAccessors) {
      Ember.get = get;
      Ember.config.overrideAccessors();
      get = Ember.get;
    }

    
    function normalizeTuple(target, path) {
      var hasThis  = path.indexOf(HAS_THIS) === 0,
          isGlobal = !hasThis && IS_GLOBAL_PATH.test(path),
          key;

      if (!target || isGlobal) target = Ember.lookup;
      if (hasThis) path = path.slice(5);

      if (target === Ember.lookup) {
        key = path.match(FIRST_KEY)[0];
        target = get(target, key);
        path   = path.slice(key.length+1);
      }

      // must return some kind of path to be valid else other things will break.
      if (!path || path.length===0) throw new EmberError('Path cannot be empty');

      return [ target, path ];
    }

    function _getPath(root, path) {
      var hasThis, parts, tuple, idx, len;

      // If there is no root and path is a key name, return that
      // property from the global object.
      // E.g. get('Ember') -> Ember
      if (root === null && path.indexOf('.') === -1) { return get(Ember.lookup, path); }

      // detect complicated paths and normalize them
      hasThis = path.indexOf(HAS_THIS) === 0;

      if (!root || hasThis) {
        tuple = normalizeTuple(root, path);
        root = tuple[0];
        path = tuple[1];
        tuple.length = 0;
      }

      parts = path.split(".");
      len = parts.length;
      for (idx = 0; root != null && idx < len; idx++) {
        root = get(root, parts[idx], true);
        if (root && root.isDestroyed) { return undefined; }
      }
      return root;
    }

    function getWithDefault(root, key, defaultValue) {
      var value = get(root, key);

      if (value === undefined) { return defaultValue; }
      return value;
    }

    __exports__.getWithDefault = getWithDefault;__exports__["default"] = get;
    __exports__.get = get;
    __exports__.normalizeTuple = normalizeTuple;
    __exports__._getPath = _getPath;
  });
define("ember-metal/property_set",
  ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/property_events","ember-metal/properties","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var getPath = __dependency2__._getPath;
    var META_KEY = __dependency3__.META_KEY;
    var propertyWillChange = __dependency4__.propertyWillChange;
    var propertyDidChange = __dependency4__.propertyDidChange;
    var defineProperty = __dependency5__.defineProperty;
    var EmberError = __dependency6__["default"];

    var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
    var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/;

    
    var set = function set(obj, keyName, value, tolerant) {
      if (typeof obj === 'string') {
        Ember.assert("Path '" + obj + "' must be global if no obj is given.", IS_GLOBAL.test(obj));
        value = keyName;
        keyName = obj;
        obj = null;
      }

      Ember.assert("Cannot call set with "+ keyName +" key.", !!keyName);

      if (!obj) {
        return setPath(obj, keyName, value, tolerant);
      }

      var meta = obj[META_KEY], desc = meta && meta.descs[keyName],
          isUnknown, currentValue;

      if (desc === undefined && keyName.indexOf('.') !== -1) {
        return setPath(obj, keyName, value, tolerant);
      }

      Ember.assert("You need to provide an object and key to `set`.", !!obj && keyName !== undefined);
      Ember.assert('calling set on destroyed object', !obj.isDestroyed);

      if (desc !== undefined) {
        desc.set(obj, keyName, value);
      } else {

        if (typeof obj === 'object' && obj !== null && value !== undefined && obj[keyName] === value) {
          return value;
        }

        isUnknown = 'object' === typeof obj && !(keyName in obj);

        // setUnknownProperty is called if `obj` is an object,
        // the property does not already exist, and the
        // `setUnknownProperty` method exists on the object
        if (isUnknown && 'function' === typeof obj.setUnknownProperty) {
          obj.setUnknownProperty(keyName, value);
        } else if (meta && meta.watching[keyName] > 0) {
          if (MANDATORY_SETTER) {
            currentValue = meta.values[keyName];
          } else {
            currentValue = obj[keyName];
          }
          // only trigger a change if the value has changed
          if (value !== currentValue) {
            propertyWillChange(obj, keyName);
            if (MANDATORY_SETTER) {
              if ((currentValue === undefined && !(keyName in obj)) || !obj.propertyIsEnumerable(keyName)) {
                defineProperty(obj, keyName, null, value); // setup mandatory setter
              } else {
                meta.values[keyName] = value;
              }
            } else {
              obj[keyName] = value;
            }
            propertyDidChange(obj, keyName);
          }
        } else {
          obj[keyName] = value;
        }
      }
      return value;
    };

    // Currently used only by Ember Data tests
    // ES6TODO: Verify still true
    if (Ember.config.overrideAccessors) {
      Ember.set = set;
      Ember.config.overrideAccessors();
      set = Ember.set;
    }

    function setPath(root, path, value, tolerant) {
      var keyName;

      // get the last part of the path
      keyName = path.slice(path.lastIndexOf('.') + 1);

      // get the first part of the part
      path    = (path === keyName) ? keyName : path.slice(0, path.length-(keyName.length+1));

      // unless the path is this, look up the first part to
      // get the root
      if (path !== 'this') {
        root = getPath(root, path);
      }

      if (!keyName || keyName.length === 0) {
        throw new EmberError('Property set failed: You passed an empty path');
      }

      if (!root) {
        if (tolerant) { return; }
        else { throw new EmberError('Property set failed: object in path "'+path+'" could not be found or was destroyed.'); }
      }

      return set(root, keyName, value);
    }

    
    function trySet(root, path, value) {
      return set(root, path, value, true);
    }

    __exports__.trySet = trySet;__exports__.set = set;
  });
define("ember-metal/run_loop",
  ["ember-metal/core","ember-metal/utils","ember-metal/array","ember-metal/property_events","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var apply = __dependency2__.apply;
    var indexOf = __dependency3__.indexOf;
    var beginPropertyChanges = __dependency4__.beginPropertyChanges;
    var endPropertyChanges = __dependency4__.endPropertyChanges;

    function onBegin(current) {
      run.currentRunLoop = current;
    }

    function onEnd(current, next) {
      run.currentRunLoop = next;
    }

    // ES6TODO: should Backburner become es6?
    var Backburner = requireModule('backburner').Backburner;
    var backburner = new Backburner(['sync', 'actions', 'destroy'], {
      sync: {
        before: beginPropertyChanges,
        after: endPropertyChanges
      },
      defaultQueue: 'actions',
      onBegin: onBegin,
      onEnd: onEnd,
      onErrorTarget: Ember,
      onErrorMethod: 'onerror'
    });
    var slice = [].slice;
    var concat = [].concat;

    // ..........................................................
    // run - this is ideally the only public API the dev sees
    //

    
    __exports__["default"] = run;
    function run() {
      return apply(backburner, backburner.run, arguments);
    }

    
    run.join = function(target, method ) {
      if (!run.currentRunLoop) {
        return apply(Ember, run, arguments);
      }

      var args = slice.call(arguments);
      args.unshift('actions');
      apply(run, run.schedule, args);
    };

    
    run.bind = function(target, method ) {
      var args = slice.call(arguments);
      return function() {
        return apply(run, run.join, args.concat(slice.call(arguments)));
      };
    };

    run.backburner = backburner;
    run.currentRunLoop = null;
    run.queues = backburner.queueNames;

    
    run.begin = function() {
      backburner.begin();
    };

    
    run.end = function() {
      backburner.end();
    };

    

    
    run.schedule = function(queue, target, method) {
      checkAutoRun();
      apply(backburner, backburner.schedule, arguments);
    };

    // Used by global test teardown
    run.hasScheduledTimers = function() {
      return backburner.hasTimers();
    };

    // Used by global test teardown
    run.cancelTimers = function () {
      backburner.cancelTimers();
    };

    
    run.sync = function() {
      if (backburner.currentInstance) {
        backburner.currentInstance.queues.sync.flush();
      }
    };

    
    run.later = function(target, method) {
      return apply(backburner, backburner.later, arguments);
    };

    
    run.once = function(target, method) {
      checkAutoRun();
      var args = slice.call(arguments);
      args.unshift('actions');
      return apply(backburner, backburner.scheduleOnce, args);
    };

    
    run.scheduleOnce = function(queue, target, method) {
      checkAutoRun();
      return apply(backburner, backburner.scheduleOnce, arguments);
    };

    
    run.next = function() {
      var args = slice.call(arguments);
      args.push(1);
      return apply(backburner, backburner.later, args);
    };

    
    run.cancel = function(timer) {
      return backburner.cancel(timer);
    };

    
    run.debounce = function() {
      return apply(backburner, backburner.debounce, arguments);
    };

    
    run.throttle = function() {
      return apply(backburner, backburner.throttle, arguments);
    };

    // Make sure it's not an autorun during testing
    function checkAutoRun() {
      if (!run.currentRunLoop) {
        Ember.assert("You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an run", !Ember.testing);
      }
    }

    
    run._addQueue = function(name, after) {
      if (indexOf.call(run.queues, name) === -1) {
        run.queues.splice(indexOf.call(run.queues, after)+1, 0, name);
      }
    };
  });
define("ember-metal/set_properties",
  ["ember-metal/property_events","ember-metal/property_set","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var changeProperties = __dependency1__.changeProperties;
    var set = __dependency2__.set;

    
    __exports__["default"] = function setProperties(self, hash) {
      changeProperties(function() {
        for(var prop in hash) {
          if (hash.hasOwnProperty(prop)) { set(self, prop, hash[prop]); }
        }
      });
      return self;
    }
  });
define("ember-metal/utils",
  ["ember-metal/core","ember-metal/platform","ember-metal/array","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var platform = __dependency2__.platform;
    var create = __dependency2__.create;

    var forEach = __dependency3__.forEach;

    

    
    var _uuid = 0;

    
    function uuid() {
      return ++_uuid;
    }

    __exports__.uuid = uuid;
    var GUID_PREFIX = 'ember';

    var o_defineProperty = platform.defineProperty;
    var o_create = create;
    // Used for guid generation...
    var numberCache  = [];
    var stringCache  = {};
    var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;

    
    var GUID_KEY = '__ember' + (+ new Date());

    var GUID_DESC = {
      writable:    false,
      configurable: false,
      enumerable:  false,
      value: null
    };

    
    function generateGuid(obj, prefix) {
      if (!prefix) prefix = GUID_PREFIX;
      var ret = (prefix + uuid());
      if (obj) {
        if (obj[GUID_KEY] === null) {
          obj[GUID_KEY] = ret;
        } else {
          GUID_DESC.value = ret;
          o_defineProperty(obj, GUID_KEY, GUID_DESC);
        }
      }
      return ret;
    }

    __exports__.generateGuid = generateGuid;
    function guidFor(obj) {

      // special cases where we don't want to add a key to object
      if (obj === undefined) return "(undefined)";
      if (obj === null) return "(null)";

      var ret;
      var type = typeof obj;

      // Don't allow prototype changes to String etc. to change the guidFor
      switch(type) {
        case 'number':
          ret = numberCache[obj];
          if (!ret) ret = numberCache[obj] = 'nu'+obj;
          return ret;

        case 'string':
          ret = stringCache[obj];
          if (!ret) ret = stringCache[obj] = 'st' + uuid();
          return ret;

        case 'boolean':
          return obj ? '(true)' : '(false)';

        default:
          if (obj[GUID_KEY]) return obj[GUID_KEY];
          if (obj === Object) return '(Object)';
          if (obj === Array)  return '(Array)';
          ret = 'ember' + uuid();

          if (obj[GUID_KEY] === null) {
            obj[GUID_KEY] = ret;
          } else {
            GUID_DESC.value = ret;
            o_defineProperty(obj, GUID_KEY, GUID_DESC);
          }
          return ret;
      }
    }

    __exports__.guidFor = guidFor;// ..........................................................
    // META
    //

    var META_DESC = {
      writable: true,
      configurable: false,
      enumerable: false,
      value: null
    };

    
    var META_KEY = '__ember_meta__';

    var isDefinePropertySimulated = platform.defineProperty.isSimulated;

    function Meta(obj) {
      this.descs = {};
      this.watching = {};
      this.cache = {};
      this.cacheMeta = {};
      this.source = obj;
    }

    Meta.prototype = {
      descs: null,
      deps: null,
      watching: null,
      listeners: null,
      cache: null,
      cacheMeta: null,
      source: null,
      mixins: null,
      bindings: null,
      chains: null,
      chainWatchers: null,
      values: null,
      proto: null
    };

    if (isDefinePropertySimulated) {
      // on platforms that don't support enumerable false
      // make meta fail jQuery.isPlainObject() to hide from
      // jQuery.extend() by having a property that fails
      // hasOwnProperty check.
      Meta.prototype.__preventPlainObject__ = true;

      // Without non-enumerable properties, meta objects will be output in JSON
      // unless explicitly suppressed
      Meta.prototype.toJSON = function () { };
    }

    // Placeholder for non-writable metas.
    var EMPTY_META = new Meta(null);

    if (MANDATORY_SETTER) { EMPTY_META.values = {}; }

    
    function meta(obj, writable) {

      var ret = obj[META_KEY];
      if (writable===false) return ret || EMPTY_META;

      if (!ret) {
        if (!isDefinePropertySimulated) o_defineProperty(obj, META_KEY, META_DESC);

        ret = new Meta(obj);

        if (MANDATORY_SETTER) { ret.values = {}; }

        obj[META_KEY] = ret;

        // make sure we don't accidentally try to create constructor like desc
        ret.descs.constructor = null;

      } else if (ret.source !== obj) {
        if (!isDefinePropertySimulated) o_defineProperty(obj, META_KEY, META_DESC);

        ret = o_create(ret);
        ret.descs     = o_create(ret.descs);
        ret.watching  = o_create(ret.watching);
        ret.cache     = {};
        ret.cacheMeta = {};
        ret.source    = obj;

        if (MANDATORY_SETTER) { ret.values = o_create(ret.values); }

        obj[META_KEY] = ret;
      }
      return ret;
    }

    function getMeta(obj, property) {
      var _meta = meta(obj, false);
      return _meta[property];
    }

    __exports__.getMeta = getMeta;function setMeta(obj, property, value) {
      var _meta = meta(obj, true);
      _meta[property] = value;
      return value;
    }

    __exports__.setMeta = setMeta;
    function metaPath(obj, path, writable) {
      Ember.deprecate("Ember.metaPath is deprecated and will be removed from future releases.");
      var _meta = meta(obj, writable), keyName, value;

      for (var i=0, l=path.length; i<l; i++) {
        keyName = path[i];
        value = _meta[keyName];

        if (!value) {
          if (!writable) { return undefined; }
          value = _meta[keyName] = { __ember_source__: obj };
        } else if (value.__ember_source__ !== obj) {
          if (!writable) { return undefined; }
          value = _meta[keyName] = o_create(value);
          value.__ember_source__ = obj;
        }

        _meta = value;
      }

      return value;
    }

    __exports__.metaPath = metaPath;
    function wrap(func, superFunc) {
      function superWrapper() {
        var ret, sup = this && this.__nextSuper;
        if(this) { this.__nextSuper = superFunc; }
        ret = apply(this, func, arguments);
        if(this) { this.__nextSuper = sup; }
        return ret;
      }

      superWrapper.wrappedFunction = func;
      superWrapper.wrappedFunction.__ember_arity__ = func.length;
      superWrapper.__ember_observes__ = func.__ember_observes__;
      superWrapper.__ember_observesBefore__ = func.__ember_observesBefore__;
      superWrapper.__ember_listens__ = func.__ember_listens__;

      return superWrapper;
    }

    __exports__.wrap = wrap;var EmberArray;

    
    // ES6TODO: Move up to runtime? This is only use in ember-metal by concatenatedProperties
    function isArray(obj) {
      var modulePath, type;

      if (typeof EmberArray === "undefined") {
        modulePath = 'ember-runtime/mixins/array';
        if (Ember.__loader.registry[modulePath]) {
          EmberArray = Ember.__loader.require(modulePath)['default'];
        }
      }

      if (!obj || obj.setInterval) { return false; }
      if (Array.isArray && Array.isArray(obj)) { return true; }
      if (EmberArray && EmberArray.detect(obj)) { return true; }

      type = typeOf(obj);
      if ('array' === type) { return true; }
      if ((obj.length !== undefined) && 'object' === type) { return true; }
      return false;
    }

    
    function makeArray(obj) {
      if (obj === null || obj === undefined) { return []; }
      return isArray(obj) ? obj : [obj];
    }

    __exports__.makeArray = makeArray;
    function canInvoke(obj, methodName) {
      return !!(obj && typeof obj[methodName] === 'function');
    }

    
    function tryInvoke(obj, methodName, args) {
      if (canInvoke(obj, methodName)) {
        return args ? applyStr(obj, methodName, args) : applyStr(obj, methodName);
      }
    }

    __exports__.tryInvoke = tryInvoke;// https://github.com/emberjs/ember.js/pull/1617
    var needsFinallyFix = (function() {
      var count = 0;
      try{
        try { }
        finally {
          count++;
          throw new Error('needsFinallyFixTest');
        }
      } catch (e) {}

      return count !== 1;
    })();

    

    var tryFinally;
    if (needsFinallyFix) {
      tryFinally = function(tryable, finalizer, binding) {
        var result, finalResult, finalError;

        binding = binding || this;

        try {
          result = tryable.call(binding);
        } finally {
          try {
            finalResult = finalizer.call(binding);
          } catch (e) {
            finalError = e;
          }
        }

        if (finalError) { throw finalError; }

        return (finalResult === undefined) ? result : finalResult;
      };
    } else {
      tryFinally = function(tryable, finalizer, binding) {
        var result, finalResult;

        binding = binding || this;

        try {
          result = tryable.call(binding);
        } finally {
          finalResult = finalizer.call(binding);
        }

        return (finalResult === undefined) ? result : finalResult;
      };
    }

    
    var tryCatchFinally;
    if (needsFinallyFix) {
      tryCatchFinally = function(tryable, catchable, finalizer, binding) {
        var result, finalResult, finalError;

        binding = binding || this;

        try {
          result = tryable.call(binding);
        } catch(error) {
          result = catchable.call(binding, error);
        } finally {
          try {
            finalResult = finalizer.call(binding);
          } catch (e) {
            finalError = e;
          }
        }

        if (finalError) { throw finalError; }

        return (finalResult === undefined) ? result : finalResult;
      };
    } else {
      tryCatchFinally = function(tryable, catchable, finalizer, binding) {
        var result, finalResult;

        binding = binding || this;

        try {
          result = tryable.call(binding);
        } catch(error) {
          result = catchable.call(binding, error);
        } finally {
          finalResult = finalizer.call(binding);
        }

        return (finalResult === undefined) ? result : finalResult;
      };
    }

    // ........................................
    // TYPING & ARRAY MESSAGING
    //

    var TYPE_MAP = {};
    var t = "Boolean Number String Function Array Date RegExp Object".split(" ");
    forEach.call(t, function(name) {
      TYPE_MAP[ "[object " + name + "]" ] = name.toLowerCase();
    });

    var toString = Object.prototype.toString;

    var EmberObject;

    
    function typeOf(item) {
      var ret, modulePath;

      // ES6TODO: Depends on Ember.Object which is defined in runtime.
      if (typeof EmberObject === "undefined") {
        modulePath = 'ember-runtime/system/object';
        if (Ember.__loader.registry[modulePath]) {
          EmberObject = Ember.__loader.require(modulePath)['default'];
        }
      }

      ret = (item === null || item === undefined) ? String(item) : TYPE_MAP[toString.call(item)] || 'object';

      if (ret === 'function') {
        if (EmberObject && EmberObject.detect(item)) ret = 'class';
      } else if (ret === 'object') {
        if (item instanceof Error) ret = 'error';
        else if (EmberObject && item instanceof EmberObject) ret = 'instance';
        else if (item instanceof Date) ret = 'date';
      }

      return ret;
    }

    
    function inspect(obj) {
      var type = typeOf(obj);
      if (type === 'array') {
        return '[' + obj + ']';
      }
      if (type !== 'object') {
        return obj + '';
      }

      var v, ret = [];
      for(var key in obj) {
        if (obj.hasOwnProperty(key)) {
          v = obj[key];
          if (v === 'toString') { continue; } // ignore useless items
          if (typeOf(v) === 'function') { v = "function() { ... }"; }
          ret.push(key + ": " + v);
        }
      }
      return "{" + ret.join(", ") + "}";
    }

    __exports__.inspect = inspect;// The following functions are intentionally minified to keep the functions
    // below Chrome's function body size inlining limit of 600 chars.

    function apply(t , m , a ) {
      var l = a && a.length;
      if (!a || !l) { return m.call(t); }
      switch (l) {
        case 1:  return m.call(t, a[0]);
        case 2:  return m.call(t, a[0], a[1]);
        case 3:  return m.call(t, a[0], a[1], a[2]);
        case 4:  return m.call(t, a[0], a[1], a[2], a[3]);
        case 5:  return m.call(t, a[0], a[1], a[2], a[3], a[4]);
        default: return m.apply(t, a);
      }
    }

    __exports__.apply = apply;function applyStr(t , m , a ) {
      var l = a && a.length;
      if (!a || !l) { return t[m](); }
      switch (l) {
        case 1:  return t[m](a[0]);
        case 2:  return t[m](a[0], a[1]);
        case 3:  return t[m](a[0], a[1], a[2]);
        case 4:  return t[m](a[0], a[1], a[2], a[3]);
        case 5:  return t[m](a[0], a[1], a[2], a[3], a[4]);
        default: return t[m].apply(t, a);
      }
    }

    __exports__.applyStr = applyStr;__exports__.GUID_KEY = GUID_KEY;
    __exports__.GUID_PREFIX = GUID_PREFIX;
    __exports__.META_DESC = META_DESC;
    __exports__.EMPTY_META = EMPTY_META;
    __exports__.META_KEY = META_KEY;
    __exports__.meta = meta;
    __exports__.typeOf = typeOf;
    __exports__.tryCatchFinally = tryCatchFinally;
    __exports__.isArray = isArray;
    __exports__.canInvoke = canInvoke;
    __exports__.tryFinally = tryFinally;
  });
define("ember-metal/watch_key",
  ["ember-metal/core","ember-metal/utils","ember-metal/platform","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var meta = __dependency2__.meta;
    var typeOf = __dependency2__.typeOf;
    var platform = __dependency3__.platform;

    var metaFor = meta; // utils.js
    var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
    var o_defineProperty = platform.defineProperty;

    function watchKey(obj, keyName, meta) {
      // can't watch length on Array - it is special...
      if (keyName === 'length' && typeOf(obj) === 'array') { return; }

      var m = meta || metaFor(obj), watching = m.watching;

      // activate watching first time
      if (!watching[keyName]) {
        watching[keyName] = 1;

        var desc = m.descs[keyName];
        if (desc && desc.willWatch) { desc.willWatch(obj, keyName); }

        if ('function' === typeof obj.willWatchProperty) {
          obj.willWatchProperty(keyName);
        }

        if (MANDATORY_SETTER && keyName in obj) {
          m.values[keyName] = obj[keyName];
          o_defineProperty(obj, keyName, {
            configurable: true,
            enumerable: obj.propertyIsEnumerable(keyName),
            set: Ember.MANDATORY_SETTER_FUNCTION,
            get: Ember.DEFAULT_GETTER_FUNCTION(keyName)
          });
        }
      } else {
        watching[keyName] = (watching[keyName] || 0) + 1;
      }
    }

    __exports__.watchKey = watchKey;function unwatchKey(obj, keyName, meta) {
      var m = meta || metaFor(obj), watching = m.watching;

      if (watching[keyName] === 1) {
        watching[keyName] = 0;

        var desc = m.descs[keyName];
        if (desc && desc.didUnwatch) { desc.didUnwatch(obj, keyName); }

        if ('function' === typeof obj.didUnwatchProperty) {
          obj.didUnwatchProperty(keyName);
        }

        if (MANDATORY_SETTER && keyName in obj) {
          o_defineProperty(obj, keyName, {
            configurable: true,
            enumerable: obj.propertyIsEnumerable(keyName),
            set: function(val) {
              // redefine to set as enumerable
              o_defineProperty(obj, keyName, {
                configurable: true,
                writable: true,
                enumerable: true,
                value: val
              });
              delete m.values[keyName];
            },
            get: Ember.DEFAULT_GETTER_FUNCTION(keyName)
          });
        }
      } else if (watching[keyName] > 1) {
        watching[keyName]--;
      }
    }

    __exports__.unwatchKey = unwatchKey;
  });
define("ember-metal/watch_path",
  ["ember-metal/utils","ember-metal/chains","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var meta = __dependency1__.meta;
    var typeOf = __dependency1__.typeOf;
    var ChainNode = __dependency2__.ChainNode;

    var metaFor = meta;

    // get the chains for the current object. If the current object has
    // chains inherited from the proto they will be cloned and reconfigured for
    // the current object.
    function chainsFor(obj, meta) {
      var m = meta || metaFor(obj), ret = m.chains;
      if (!ret) {
        ret = m.chains = new ChainNode(null, null, obj);
      } else if (ret.value() !== obj) {
        ret = m.chains = ret.copy(obj);
      }
      return ret;
    }

    function watchPath(obj, keyPath, meta) {
      // can't watch length on Array - it is special...
      if (keyPath === 'length' && typeOf(obj) === 'array') { return; }

      var m = meta || metaFor(obj), watching = m.watching;

      if (!watching[keyPath]) { // activate watching first time
        watching[keyPath] = 1;
        chainsFor(obj, m).add(keyPath);
      } else {
        watching[keyPath] = (watching[keyPath] || 0) + 1;
      }
    }

    __exports__.watchPath = watchPath;function unwatchPath(obj, keyPath, meta) {
      var m = meta || metaFor(obj), watching = m.watching;

      if (watching[keyPath] === 1) {
        watching[keyPath] = 0;
        chainsFor(obj, m).remove(keyPath);
      } else if (watching[keyPath] > 1) {
        watching[keyPath]--;
      }
    }

    __exports__.unwatchPath = unwatchPath;
  });
define("ember-metal/watching",
  ["ember-metal/utils","ember-metal/chains","ember-metal/watch_key","ember-metal/watch_path","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    

    var meta = __dependency1__.meta;
    var META_KEY = __dependency1__.META_KEY;
    var GUID_KEY = __dependency1__.GUID_KEY;
    var typeOf = __dependency1__.typeOf;
    var generateGuid = __dependency1__.generateGuid;
    var removeChainWatcher = __dependency2__.removeChainWatcher;
    var flushPendingChains = __dependency2__.flushPendingChains;
    var watchKey = __dependency3__.watchKey;
    var unwatchKey = __dependency3__.unwatchKey;
    var watchPath = __dependency4__.watchPath;
    var unwatchPath = __dependency4__.unwatchPath;

    var metaFor = meta; // utils.js

    // returns true if the passed path is just a keyName
    function isKeyName(path) {
      return path.indexOf('.') === -1;
    }

    
    function watch(obj, _keyPath, m) {
      // can't watch length on Array - it is special...
      if (_keyPath === 'length' && typeOf(obj) === 'array') { return; }

      if (isKeyName(_keyPath)) {
        watchKey(obj, _keyPath, m);
      } else {
        watchPath(obj, _keyPath, m);
      }
    }

    __exports__.watch = watch;

    function isWatching(obj, key) {
      var meta = obj[META_KEY];
      return (meta && meta.watching[key]) > 0;
    }

    __exports__.isWatching = isWatching;watch.flushPending = flushPendingChains;

    function unwatch(obj, _keyPath, m) {
      // can't watch length on Array - it is special...
      if (_keyPath === 'length' && typeOf(obj) === 'array') { return; }

      if (isKeyName(_keyPath)) {
        unwatchKey(obj, _keyPath, m);
      } else {
        unwatchPath(obj, _keyPath, m);
      }
    }

    __exports__.unwatch = unwatch;
    function rewatch(obj) {
      var m = obj[META_KEY], chains = m && m.chains;

      // make sure the object has its own guid.
      if (GUID_KEY in obj && !obj.hasOwnProperty(GUID_KEY)) {
        generateGuid(obj);
      }

      // make sure any chained watchers update.
      if (chains && chains.value() !== obj) {
        m.chains = chains.copy(obj);
      }
    }

    __exports__.rewatch = rewatch;var NODE_STACK = [];

    
    function destroy(obj) {
      var meta = obj[META_KEY], node, nodes, key, nodeObject;
      if (meta) {
        obj[META_KEY] = null;
        // remove chainWatchers to remove circular references that would prevent GC
        node = meta.chains;
        if (node) {
          NODE_STACK.push(node);
          // process tree
          while (NODE_STACK.length > 0) {
            node = NODE_STACK.pop();
            // push children
            nodes = node._chains;
            if (nodes) {
              for (key in nodes) {
                if (nodes.hasOwnProperty(key)) {
                  NODE_STACK.push(nodes[key]);
                }
              }
            }
            // remove chainWatcher in node object
            if (node._watching) {
              nodeObject = node._object;
              if (nodeObject) {
                removeChainWatcher(nodeObject, node._key, node);
              }
            }
          }
        }
      }
    }

    __exports__.destroy = destroy;
  });
define("ember-routing-handlebars",
  ["ember-metal/core","ember-handlebars","ember-routing/system/router","ember-routing-handlebars/helpers/shared","ember-routing-handlebars/helpers/link_to","ember-routing-handlebars/helpers/outlet","ember-routing-handlebars/helpers/render","ember-routing-handlebars/helpers/action","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    var EmberHandlebars = __dependency2__["default"];
    var Router = __dependency3__["default"];

    var resolvePaths = __dependency4__.resolvePaths;
    var resolveParams = __dependency4__.resolveParams;

    var deprecatedLinkToHelper = __dependency5__.deprecatedLinkToHelper;
    var linkToHelper = __dependency5__.linkToHelper;
    var LinkView = __dependency5__.LinkView;

    var outletHelper = __dependency6__.outletHelper;
    var OutletView = __dependency6__.OutletView;

    var renderHelper = __dependency7__["default"];

    var ActionHelper = __dependency8__.ActionHelper;
    var actionHelper = __dependency8__.actionHelper;

    Router.resolveParams = resolveParams;
    Router.resolvePaths = resolvePaths;

    Ember.LinkView = LinkView;
    EmberHandlebars.ActionHelper = ActionHelper;
    EmberHandlebars.OutletView = OutletView;

    EmberHandlebars.registerHelper('render', renderHelper);
    EmberHandlebars.registerHelper('action', actionHelper);
    EmberHandlebars.registerHelper('outlet', outletHelper);
    EmberHandlebars.registerHelper('link-to', linkToHelper);
    EmberHandlebars.registerHelper('linkTo', deprecatedLinkToHelper);

    __exports__["default"] = Ember;
  });
define("ember-routing-handlebars/helpers/action",
  ["ember-metal/core","ember-metal/property_get","ember-metal/array","ember-metal/utils","ember-metal/run_loop","ember-views/system/utils","ember-routing/system/router","ember-handlebars","ember-handlebars/ext","ember-handlebars/helpers/view","ember-routing-handlebars/helpers/shared","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Handlebars, uuid, FEATURES, assert, deprecate
    var get = __dependency2__.get;
    var forEach = __dependency3__.forEach;
    var uuid = __dependency4__.uuid;
    var run = __dependency5__["default"];

    var isSimpleClick = __dependency6__.isSimpleClick;
    var EmberRouter = __dependency7__["default"];

    var EmberHandlebars = __dependency8__["default"];
    var handlebarsGet = __dependency9__.handlebarsGet;
    var viewHelper = __dependency10__.viewHelper;
    var resolveParams = __dependency11__.resolveParams;
    var resolvePath = __dependency11__.resolvePath;

    

    var SafeString = EmberHandlebars.SafeString;
    var a_slice = Array.prototype.slice;

    function args(options, actionName) {
      var ret = [];
      if (actionName) { ret.push(actionName); }

      var types = options.options.types.slice(1),
          data = options.options.data;

      return ret.concat(resolveParams(options.context, options.params, { types: types, data: data }));
    }

    var ActionHelper = {
      registeredActions: {}
    };

    __exports__.ActionHelper = ActionHelper;

    var keys = ["alt", "shift", "meta", "ctrl"];

    var POINTER_EVENT_TYPE_REGEX = /^click|mouse|touch/;

    var isAllowedEvent = function(event, allowedKeys) {
      if (typeof allowedKeys === "undefined") {
        if (POINTER_EVENT_TYPE_REGEX.test(event.type)) {
          return isSimpleClick(event);
        } else {
          allowedKeys = '';
        }
      }

      if (allowedKeys.indexOf("any") >= 0) {
        return true;
      }

      var allowed = true;

      forEach.call(keys, function(key) {
        if (event[key + "Key"] && allowedKeys.indexOf(key) === -1) {
          allowed = false;
        }
      });

      return allowed;
    };

    ActionHelper.registerAction = function(actionNameOrPath, options, allowedKeys) {
      var actionId = uuid();

      ActionHelper.registeredActions[actionId] = {
        eventName: options.eventName,
        handler: function handleRegisteredAction(event) {
          if (!isAllowedEvent(event, allowedKeys)) { return true; }

          if (options.preventDefault !== false) {
            event.preventDefault();
          }

          if (options.bubbles === false) {
            event.stopPropagation();
          }

          var target = options.target,
              parameters = options.parameters,
              actionName;

          if (target.target) {
            target = handlebarsGet(target.root, target.target, target.options);
          } else {
            target = target.root;
          }

          if (options.boundProperty) {
            actionName = resolveParams(parameters.context, [actionNameOrPath], { types: ['ID'], data: parameters.options.data })[0];

            if (typeof actionName === 'undefined' || typeof actionName === 'function') {
              Ember.deprecate("You specified a quoteless path to the {{action}} helper '" + actionNameOrPath + "' which did not resolve to an actionName. Perhaps you meant to use a quoted actionName? (e.g. {{action '" + actionNameOrPath + "'}}).");
              actionName = actionNameOrPath;
            }
          }

          if (!actionName) {
            actionName = actionNameOrPath;
          }

          run(function runRegisteredAction() {
            if (target.send) {
              target.send.apply(target, args(parameters, actionName));
            } else {
              Ember.assert("The action '" + actionName + "' did not exist on " + target, typeof target[actionName] === 'function');
              target[actionName].apply(target, args(parameters));
            }
          });
        }
      };

      options.view.on('willClearRender', function() {
        delete ActionHelper.registeredActions[actionId];
      });

      return actionId;
    };

    
    function actionHelper(actionName) {
      var options = arguments[arguments.length - 1],
          contexts = a_slice.call(arguments, 1, -1);

      var hash = options.hash,
          controller = options.data.keywords.controller;

      // create a hash to pass along to registerAction
      var action = {
        eventName: hash.on || "click",
        parameters: {
          context: this,
          options: options,
          params: contexts
        },
        view: options.data.view,
        bubbles: hash.bubbles,
        preventDefault: hash.preventDefault,
        target: { options: options },
        boundProperty: options.types[0] === "ID"
      };

      if (hash.target) {
        action.target.root = this;
        action.target.target = hash.target;
      } else if (controller) {
        action.target.root = controller;
      }

      var actionId = ActionHelper.registerAction(actionName, action, hash.allowedKeys);
      return new SafeString('data-ember-action="' + actionId + '"');
    }

    __exports__.actionHelper = actionHelper;
  });
define("ember-routing-handlebars/helpers/link_to",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/merge","ember-metal/run_loop","ember-metal/computed","ember-runtime/system/lazy_load","ember-runtime/system/string","ember-runtime/system/object","ember-runtime/keys","ember-views/system/utils","ember-views/views/component","ember-handlebars","ember-handlebars/helpers/view","ember-routing/system/router","ember-routing-handlebars/helpers/shared","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // FEATURES, Logger, Handlebars, warn, assert
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var merge = __dependency4__["default"];
    var run = __dependency5__["default"];
    var computed = __dependency6__.computed;

    var onLoad = __dependency7__.onLoad;
    var fmt = __dependency8__.fmt;
    var EmberObject = __dependency9__["default"];
    var keys = __dependency10__["default"];
    var isSimpleClick = __dependency11__.isSimpleClick;
    var EmberComponent = __dependency12__["default"];
    var EmberHandlebars = __dependency13__["default"];
    var viewHelper = __dependency14__.viewHelper;
    var EmberRouter = __dependency15__["default"];
    var resolveParams = __dependency16__.resolveParams;
    var resolvePaths = __dependency16__.resolvePaths;
    var routeArgs = __dependency16__.routeArgs;

    

    var slice = [].slice;

    requireModule('ember-handlebars');

    var numberOfContextsAcceptedByHandler = function(handler, handlerInfos) {
      var req = 0;
      for (var i = 0, l = handlerInfos.length; i < l; i++) {
        req = req + handlerInfos[i].names.length;
        if (handlerInfos[i].handler === handler)
          break;
      }

      return req;
    };

    var QueryParams = EmberObject.extend({
      values: null
    });

    function getResolvedPaths(options) {

      var types = options.options.types,
          data = options.options.data;

      return resolvePaths(options.context, options.params, { types: types, data: data });
    }

    
    var LinkView = Ember.LinkView = EmberComponent.extend({
      tagName: 'a',
      currentWhen: null,

      
      title: null,

      
      rel: null,

      
      activeClass: 'active',

      
      loadingClass: 'loading',

      
      disabledClass: 'disabled',
      _isDisabled: false,

      
      replace: false,

      
      attributeBindings: ['href', 'title', 'rel', 'tabindex'],

      
      classNameBindings: ['active', 'loading', 'disabled'],

      
      eventName: 'click',

      // this is doc'ed here so it shows up in the events
      // section of the API documentation, which is where
      // people will likely go looking for it.
      

      
      init: function() {
        this._super.apply(this, arguments);

        // Map desired event name to invoke function
        var eventName = get(this, 'eventName');
        this.on(eventName, this, this._invoke);
      },

      
      _paramsChanged: function() {
        this.notifyPropertyChange('resolvedParams');
      },

      
      _setupPathObservers: function(){
        var helperParameters = this.parameters,
            linkTextPath     = helperParameters.options.linkTextPath,
            paths = getResolvedPaths(helperParameters),
            length = paths.length,
            path, i, normalizedPath;

        if (linkTextPath) {
          normalizedPath = getNormalizedPath(linkTextPath, helperParameters);
          this.registerObserver(normalizedPath.root, normalizedPath.path, this, this.rerender);
        }

        for(i=0; i < length; i++) {
          path = paths[i];
          if (null === path) {
            // A literal value was provided, not a path, so nothing to observe.
            continue;
          }

          normalizedPath = getNormalizedPath(path, helperParameters);
          this.registerObserver(normalizedPath.root, normalizedPath.path, this, this._paramsChanged);
        }

        var queryParamsObject = this.queryParamsObject;
        if (queryParamsObject) {
          var values = queryParamsObject.values;

          // Install observers for all of the hash options
          // provided in the (query-params) subexpression.
          for (var k in values) {
            if (!values.hasOwnProperty(k)) { continue; }

            if (queryParamsObject.types[k] === 'ID') {
              normalizedPath = getNormalizedPath(values[k], helperParameters);
              this.registerObserver(normalizedPath.root, normalizedPath.path, this, this._paramsChanged);
            }
          }
        }
      },

      afterRender: function(){
        this._super.apply(this, arguments);
        this._setupPathObservers();
      },

      
      disabled: computed(function computeLinkViewDisabled(key, value) {
        if (value !== undefined) { this.set('_isDisabled', value); }

        return value ? get(this, 'disabledClass') : false;
      }),

      
      active: computed('loadedParams', function computeLinkViewActive() {
        if (get(this, 'loading')) { return false; }

        var router = get(this, 'router');
        var loadedParams = get(this, 'loadedParams');
        var contexts = loadedParams.models;
        var currentWhen = this.currentWhen;
        var isCurrentWhenSpecified = Boolean(currentWhen);
        currentWhen = currentWhen || loadedParams.targetRouteName;

        var handlers = router.router.recognizer.handlersFor(currentWhen);
        var leafName = handlers[handlers.length-1].handler;
        var maximumContexts = numberOfContextsAcceptedByHandler(currentWhen, handlers);

        // NOTE: any ugliness in the calculation of activeness is largely
        // due to the fact that we support automatic normalizing of
        // `resource` -> `resource.index`, even though there might be
        // dynamic segments / query params defined on `resource.index`
        // which complicates (and makes somewhat ambiguous) the calculation
        // of activeness for links that link to `resource` instead of
        // directly to `resource.index`.

        // if we don't have enough contexts revert back to full route name
        // this is because the leaf route will use one of the contexts
        if (contexts.length > maximumContexts) {
          currentWhen = leafName;
        }

        var args = routeArgs(currentWhen, contexts, null);
        var isActive = router.isActive.apply(router, args);
        if (!isActive) { return false; }

        
          var emptyQueryParams = Ember.isEmpty(Ember.keys(loadedParams.queryParams));

          if (!isCurrentWhenSpecified && !emptyQueryParams && isActive) {
            var visibleQueryParams = {};
            merge(visibleQueryParams, loadedParams.queryParams);
            router._prepareQueryParams(loadedParams.targetRouteName, loadedParams.models, visibleQueryParams);
            isActive = shallowEqual(visibleQueryParams, router.router.state.queryParams);
          }
        

        if (isActive) { return get(this, 'activeClass'); }
      }),

      
      loading: computed('loadedParams', function computeLinkViewLoading() {
        if (!get(this, 'loadedParams')) { return get(this, 'loadingClass'); }
      }),

      
      router: computed(function() {
        var controller = get(this, 'controller');
        if (controller && controller.container) {
          return controller.container.lookup('router:main');
        }
      }),

      
      _invoke: function(event) {
        if (!isSimpleClick(event)) { return true; }

        if (this.preventDefault !== false) {
          
            event.preventDefault();
          
        }

        if (this.bubbles === false) { event.stopPropagation(); }

        if (get(this, '_isDisabled')) { return false; }

        if (get(this, 'loading')) {
          Ember.Logger.warn("This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid.");
          return false;
        }

        var router = get(this, 'router'),
            loadedParams = get(this, 'loadedParams');

        var transition = router._doTransition(loadedParams.targetRouteName, loadedParams.models, loadedParams.queryParams);
        if (get(this, 'replace')) {
          transition.method('replace');
        }

        // Schedule eager URL update, but after we've given the transition
        // a chance to synchronously redirect.
        // We need to always generate the URL instead of using the href because
        // the href will include any rootURL set, but the router expects a URL
        // without it! Note that we don't use the first level router because it
        // calls location.formatURL(), which also would add the rootURL!
        var args = routeArgs(loadedParams.targetRouteName, loadedParams.models, transition.state.queryParams);
        var url = router.router.generate.apply(router.router, args);

        run.scheduleOnce('routerTransitions', this, this._eagerUpdateUrl, transition, url);
      },

      
      _eagerUpdateUrl: function(transition, href) {
        if (!transition.isActive || !transition.urlMethod) {
          // transition was aborted, already ran to completion,
          // or it has a null url-updated method.
          return;
        }

        if (href.indexOf('#') === 0) {
          href = href.slice(1);
        }

        // Re-use the routerjs hooks set up by the Ember router.
        var routerjs = get(this, 'router.router');
        if (transition.urlMethod === 'update') {
          routerjs.updateURL(href);
        } else if (transition.urlMethod === 'replace') {
          routerjs.replaceURL(href);
        }

        // Prevent later update url refire.
        transition.method(null);
      },

      
      resolvedParams: computed('router.url', function() {
        var parameters = this.parameters,
            options = parameters.options,
            types = options.types,
            data = options.data,
            targetRouteName, models;

        var onlyQueryParamsSupplied = (parameters.params.length === 0);
        if (onlyQueryParamsSupplied) {
          var appController = this.container.lookup('controller:application');
          targetRouteName = get(appController, 'currentRouteName');
          models = [];
        } else {
          models = resolveParams(parameters.context, parameters.params, { types: types, data: data });
          targetRouteName = models.shift();
        }

        var suppliedQueryParams = getResolvedQueryParams(this, targetRouteName);

        return {
          targetRouteName: targetRouteName,
          models: models,
          queryParams: suppliedQueryParams
        };
      }),

      
      loadedParams: computed('resolvedParams', function computeLinkViewRouteArgs() {
        var router = get(this, 'router');
        if (!router) { return; }

        var resolvedParams = get(this, 'resolvedParams'),
            namedRoute = resolvedParams.targetRouteName;

        if (!namedRoute) { return; }

        Ember.assert(fmt("The attempt to link-to route '%@' failed. " +
                         "The router did not find '%@' in its possible routes: '%@'",
                         [namedRoute, namedRoute, keys(router.router.recognizer.names).join("', '")]),
                         router.hasRoute(namedRoute));

        if (!paramsAreLoaded(resolvedParams.models)) { return; }

        return resolvedParams;
      }),

      queryParamsObject: null,

      
      href: computed('loadedParams', function computeLinkViewHref() {
        if (get(this, 'tagName') !== 'a') { return; }

        var router = get(this, 'router'),
            loadedParams = get(this, 'loadedParams');

        if (!loadedParams) {
          return get(this, 'loadingHref');
        }

        var visibleQueryParams = {};
        
          merge(visibleQueryParams, loadedParams.queryParams);
          router._prepareQueryParams(loadedParams.targetRouteName, loadedParams.models, visibleQueryParams);
        

        var args = routeArgs(loadedParams.targetRouteName, loadedParams.models, visibleQueryParams);
        var result = router.generate.apply(router, args);
        return result;
      }),

      
      loadingHref: '#'
    });

    LinkView.toString = function() { return "LinkView"; };

    
    
    function linkToHelper(name) {
      var options = slice.call(arguments, -1)[0],
          params = slice.call(arguments, 0, -1),
          hash = options.hash;

      Ember.assert("You must provide one or more parameters to the link-to helper.", params.length);

      if (params[params.length - 1] instanceof QueryParams) {
        hash.queryParamsObject = params.pop();
      }

      hash.disabledBinding = hash.disabledWhen;

      if (!options.fn) {
        var linkTitle = params.shift();
        var linkType = options.types.shift();
        var context = this;
        if (linkType === 'ID') {
          options.linkTextPath = linkTitle;
          options.fn = function() {
            return EmberHandlebars.getEscaped(context, linkTitle, options);
          };
        } else {
          options.fn = function() {
            return linkTitle;
          };
        }
      }

      hash.parameters = {
        context: this,
        options: options,
        params: params
      };

      options.helperName = options.helperName || 'link-to';

      return viewHelper.call(this, LinkView, options);
    }


    
      EmberHandlebars.registerHelper('query-params', function queryParamsHelper(options) {
        Ember.assert(fmt("The `query-params` helper only accepts hash parameters, e.g. (query-params queryParamPropertyName='%@') as opposed to just (query-params '%@')", [options, options]), arguments.length === 1);

        return QueryParams.create({
          values: options.hash,
          types: options.hashTypes
        });
      });
    

    
    function deprecatedLinkToHelper() {
      Ember.warn("The 'linkTo' view helper is deprecated in favor of 'link-to'");
      return linkToHelper.apply(this, arguments);
    }

    function getResolvedQueryParams(linkView, targetRouteName) {
      var helperParameters = linkView.parameters,
          queryParamsObject = linkView.queryParamsObject,
          resolvedQueryParams = {};

      if (!queryParamsObject) { return resolvedQueryParams; }
      var rawParams = queryParamsObject.values;

      for (var key in rawParams) {
        if (!rawParams.hasOwnProperty(key)) { continue; }

        var value = rawParams[key],
            type = queryParamsObject.types[key];

        if (type === 'ID') {
          var normalizedPath = getNormalizedPath(value, helperParameters);
          value = EmberHandlebars.get(normalizedPath.root, normalizedPath.path, helperParameters.options);
        }
        resolvedQueryParams[key] = value;
      }
      return resolvedQueryParams;
    }

    function getNormalizedPath(path, helperParameters) {
      return EmberHandlebars.normalizePath(helperParameters.context, path, helperParameters.options.data);
    }

    function paramsAreLoaded(params) {
      for (var i = 0, len = params.length; i < len; ++i) {
        var param = params[i];
        if (param === null || typeof param === 'undefined') {
          return false;
        }
      }
      return true;
    }

    function shallowEqual(a, b) {
      var k;
      for (k in a) {
        if (a.hasOwnProperty(k) && a[k] !== b[k]) { return false; }
      }
      for (k in b) {
        if (b.hasOwnProperty(k) && a[k] !== b[k]) { return false; }
      }
      return true;
    }

    __exports__.LinkView = LinkView;
    __exports__.deprecatedLinkToHelper = deprecatedLinkToHelper;
    __exports__.linkToHelper = linkToHelper;
  });
define("ember-routing-handlebars/helpers/outlet",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/lazy_load","ember-views/views/container_view","ember-handlebars/views/metamorph_view","ember-handlebars/helpers/view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // assert
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var onLoad = __dependency4__.onLoad;
    var ContainerView = __dependency5__["default"];
    var _Metamorph = __dependency6__._Metamorph;
    var viewHelper = __dependency7__.viewHelper;

    

      

    var OutletView = ContainerView.extend(_Metamorph);
    __exports__.OutletView = OutletView;
    
    function outletHelper(property, options) {
      var outletSource;
      var container;
      var viewName;
      var viewClass;
      var viewFullName;

      if (property && property.data && property.data.isRenderData) {
        options = property;
        property = 'main';
      }

      container = options.data.view.container;

      outletSource = options.data.view;
      while (!outletSource.get('template.isTop')) {
        outletSource = outletSource.get('_parentView');
      }

      // provide controller override
      viewName = options.hash.view;

      if (viewName) {
        viewFullName = 'view:' + viewName;
        Ember.assert("Using a quoteless view parameter with {{outlet}} is not supported. Please update to quoted usage '{{outlet \"" + viewName + "\"}}.", options.hashTypes.view !== 'ID');
        Ember.assert("The view name you supplied '" + viewName + "' did not resolve to a view.", container.has(viewFullName));
      }

      viewClass = viewName ? container.lookupFactory(viewFullName) : options.hash.viewClass || OutletView;

      options.data.view.set('outletSource', outletSource);
      options.hash.currentViewBinding = '_view.outletSource._outlets.' + property;

      options.helperName = options.helperName || 'outlet';

      return viewHelper.call(this, viewClass, options);
    }

    __exports__.outletHelper = outletHelper;
  });
define("ember-routing-handlebars/helpers/render",
  ["ember-metal/core","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/string","ember-routing/system/generate_controller","ember-handlebars/ext","ember-handlebars/helpers/view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // assert, deprecate
    var EmberError = __dependency2__["default"];
    var get = __dependency3__.get;
    var set = __dependency4__.set;
    var camelize = __dependency5__.camelize;
    var generateControllerFactory = __dependency6__.generateControllerFactory;
    var generateController = __dependency6__["default"];
    var handlebarsGet = __dependency7__.handlebarsGet;
    var viewHelper = __dependency8__.viewHelper;


    

    
    __exports__["default"] = function renderHelper(name, contextString, options) {
      var length = arguments.length;

      var contextProvided = length === 3,
          container, router, controller, view, context, lookupOptions;

      container = (options || contextString).data.keywords.controller.container;
      router = container.lookup('router:main');

      if (length === 2) {
        // use the singleton controller
        options = contextString;
        contextString = undefined;
        Ember.assert("You can only use the {{render}} helper once without a model object as its second argument, as in {{render \"post\" post}}.", !router || !router._lookupActiveView(name));
      } else if (length === 3) {
        // create a new controller
        context = handlebarsGet(options.contexts[1], contextString, options);
      } else {
        throw new EmberError("You must pass a templateName to render");
      }

      Ember.deprecate("Using a quoteless parameter with {{render}} is deprecated. Please update to quoted usage '{{render \"" + name + "\"}}.", options.types[0] !== 'ID');

      // # legacy namespace
      name = name.replace(/\//g, '.');
      // \ legacy slash as namespace support


      view = container.lookup('view:' + name) || container.lookup('view:default');

      // provide controller override
      var controllerName = options.hash.controller || name;
      var controllerFullName = 'controller:' + controllerName;

      if (options.hash.controller) {
        Ember.assert("The controller name you supplied '" + controllerName + "' did not resolve to a controller.", container.has(controllerFullName));
      }

      var parentController = options.data.keywords.controller;

      // choose name
      if (length > 2) {
        var factory = container.lookupFactory(controllerFullName) ||
                      generateControllerFactory(container, controllerName, context);

        controller = factory.create({
          model: context,
          parentController: parentController,
          target: parentController
        });

        view.one('willDestroyElement', function() {
          controller.destroy();
        });
      } else {
        controller = container.lookup(controllerFullName) ||
                     generateController(container, controllerName);

        controller.setProperties({
          target: parentController,
          parentController: parentController
        });
      }

      var root = options.contexts[1];

      if (root) {
        view.registerObserver(root, contextString, function() {
          controller.set('model', handlebarsGet(root, contextString, options));
        });
      }

      options.hash.viewName = camelize(name);

      var templateName = 'template:' + name;
      Ember.assert("You used `{{render '" + name + "'}}`, but '" + name + "' can not be found as either a template or a view.", container.has("view:" + name) || container.has(templateName) || options.fn);
      options.hash.template = container.lookup(templateName);

      options.hash.controller = controller;

      if (router && !context) {
        router._connectActiveView(name, view);
      }

      options.helperName = options.helperName || ('render "' + name + '"');

      viewHelper.call(this, view, options);
    }
  });
define("ember-routing-handlebars/helpers/shared",
  ["ember-metal/property_get","ember-metal/array","ember-runtime/mixins/controller","ember-handlebars/ext","ember-metal/utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var map = __dependency2__.map;
    var ControllerMixin = __dependency3__["default"];
    var handlebarsResolve = __dependency4__.resolveParams;
    var handlebarsGet = __dependency4__.handlebarsGet;
    var typeOf = __dependency5__.typeOf;
    var get = __dependency1__.get;

    function routeArgs(targetRouteName, models, queryParams) {
      var args = [];
      if (typeOf(targetRouteName) === 'string') {
        args.push('' + targetRouteName);
      }
      args.push.apply(args, models);
      args.push({ queryParams: queryParams });
      return args;
    }

    __exports__.routeArgs = routeArgs;function getActiveTargetName(router) {
      var handlerInfos = router.activeTransition ?
                         router.activeTransition.state.handlerInfos :
                         router.state.handlerInfos;
      return handlerInfos[handlerInfos.length - 1].name;
    }

    __exports__.getActiveTargetName = getActiveTargetName;function resolveParams(context, params, options) {
      return map.call(resolvePaths(context, params, options), function(path, i) {
        if (null === path) {
          // Param was string/number, not a path, so just return raw string/number.
          return params[i];
        } else {
          return handlebarsGet(context, path, options);
        }
      });
    }

    __exports__.resolveParams = resolveParams;function stashParamNames(router, handlerInfos) {
      if (handlerInfos._namesStashed) { return; }

      // This helper exists because router.js/route-recognizer.js awkwardly
      // keeps separate a handlerInfo's list of parameter names depending
      // on whether a URL transition or named transition is happening.
      // Hopefully we can remove this in the future.
      var targetRouteName = handlerInfos[handlerInfos.length-1].name;
      var recogHandlers = router.router.recognizer.handlersFor(targetRouteName);
      var dynamicParent = null;

      for (var i = 0, len = handlerInfos.length; i < len; ++i) {
        var handlerInfo = handlerInfos[i];
        var names = recogHandlers[i].names;

        if (names.length) {
          dynamicParent = handlerInfo;
        }

        handlerInfo._names = names;

        var route = handlerInfo.handler;
        route._stashNames(handlerInfo, dynamicParent);
      }

      handlerInfos._namesStashed = true;
    }

    __exports__.stashParamNames = stashParamNames;function resolvePaths(context, params, options) {
      var resolved = handlebarsResolve(context, params, options),
          types = options.types;

      return map.call(resolved, function(object, i) {
        if (types[i] === 'ID') {
          return unwrap(object, params[i]);
        } else {
          return null;
        }
      });

      function unwrap(object, path) {
        if (path === 'controller') { return path; }

        if (ControllerMixin.detect(object)) {
          return unwrap(get(object, 'model'), path ? path + '.model' : 'model');
        } else {
          return path;
        }
      }
    }

    __exports__.resolvePaths = resolvePaths;
  });
define("ember-routing",
  ["ember-handlebars","ember-metal/core","ember-routing/ext/run_loop","ember-routing/ext/controller","ember-routing/ext/view","ember-routing/location/api","ember-routing/location/none_location","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/system/generate_controller","ember-routing/system/controller_for","ember-routing/system/dsl","ember-routing/system/router","ember-routing/system/route","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) {
    "use strict";
    

    var EmberHandlebars = __dependency1__["default"];
    var Ember = __dependency2__["default"];

    // ES6TODO: Cleanup modules with side-effects below

    var EmberLocation = __dependency6__["default"];
    var NoneLocation = __dependency7__["default"];
    var HashLocation = __dependency8__["default"];
    var HistoryLocation = __dependency9__["default"];
    var AutoLocation = __dependency10__["default"];

    var generateControllerFactory = __dependency11__.generateControllerFactory;
    var generateController = __dependency11__["default"];
    var controllerFor = __dependency12__["default"];
    var RouterDSL = __dependency13__["default"];
    var Router = __dependency14__["default"];
    var Route = __dependency15__["default"];

    Ember.Location = EmberLocation;
    Ember.AutoLocation = AutoLocation;
    Ember.HashLocation = HashLocation;
    Ember.HistoryLocation = HistoryLocation;
    Ember.NoneLocation = NoneLocation;

    Ember.controllerFor = controllerFor;
    Ember.generateControllerFactory = generateControllerFactory;
    Ember.generateController = generateController;
    Ember.RouterDSL = RouterDSL;
    Ember.Router = Router;
    Ember.Route = Route;

    __exports__["default"] = Ember;
  });
define("ember-routing/ext/controller",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/utils","ember-metal/merge","ember-metal/enumerable_utils","ember-runtime/mixins/controller","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // FEATURES, deprecate
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var computed = __dependency4__.computed;
    var typeOf = __dependency5__.typeOf;
    var meta = __dependency5__.meta;
    var merge = __dependency6__["default"];
    var map = __dependency7__.map;

    var ControllerMixin = __dependency8__["default"];

    

    ControllerMixin.reopen({
      
      transitionToRoute: function() {
        // target may be either another controller or a router
        var target = get(this, 'target');
        var method = target.transitionToRoute || target.transitionTo;
        return method.apply(target, arguments);
      },

      
      transitionTo: function() {
        Ember.deprecate("transitionTo is deprecated. Please use transitionToRoute.");
        return this.transitionToRoute.apply(this, arguments);
      },

      
      replaceRoute: function() {
        // target may be either another controller or a router
        var target = get(this, 'target');
        var method = target.replaceRoute || target.replaceWith;
        return method.apply(target, arguments);
      },

      
      replaceWith: function() {
        Ember.deprecate("replaceWith is deprecated. Please use replaceRoute.");
        return this.replaceRoute.apply(this, arguments);
      }
    });

    var ALL_PERIODS_REGEX = /\./g;

    
      ControllerMixin.reopen({
        init: function() {
          this._super.apply(this, arguments);
          listenForQueryParamChanges(this);
        },

        concatenatedProperties: ['queryParams', '_pCacheMeta'],
        queryParams: null,

        _qpDelegate: null,
        _normalizedQueryParams: computed(function() {
          var m = meta(this);
          if (m.proto !== this) {
            return get(m.proto, '_normalizedQueryParams');
          }

          var queryParams = get(this, 'queryParams');
          if (queryParams._qpMap) {
            return queryParams._qpMap;
          }

          var qpMap = queryParams._qpMap = {};

          for (var i = 0, len = queryParams.length; i < len; ++i) {
            accumulateQueryParamDescriptors(queryParams[i], qpMap);
          }

          return qpMap;
        }),

        _cacheMeta: computed(function() {
          var m = meta(this);
          if (m.proto !== this) {
            return get(m.proto, '_cacheMeta');
          }

          var cacheMeta = {};
          var qpMap = get(this, '_normalizedQueryParams');
          for (var prop in qpMap) {
            if (!qpMap.hasOwnProperty(prop)) { continue; }

            var qp = qpMap[prop];
            var scope = qp.scope;
            var parts;

            if (scope === 'controller') {
              parts = [];
            }

            cacheMeta[prop] = {
              parts: parts, // provided by route if 'model' scope
              values: null, // provided by route
              scope: scope,
              prefix: "",
              def: get(this, prop)
            };
          }

          return cacheMeta;
        }),

        _updateCacheParams: function(params) {
          var cacheMeta = get(this, '_cacheMeta');
          for (var prop in cacheMeta) {
            if (!cacheMeta.hasOwnProperty(prop)) { continue; }
            var propMeta = cacheMeta[prop];
            propMeta.values = params;

            var cacheKey = this._calculateCacheKey(propMeta.prefix, propMeta.parts, propMeta.values);
            var cache = this._bucketCache;

            if (cache) {
              var value = cache.lookup(cacheKey, prop, propMeta.def);
              set(this, prop, value);
            }
          }
        },

        _qpChanged: function(controller, _prop) {
          var prop = _prop.substr(0, _prop.length-3);
          var cacheMeta = get(controller, '_cacheMeta');
          var propCache = cacheMeta[prop];
          var cacheKey = controller._calculateCacheKey(propCache.prefix || "", propCache.parts, propCache.values);
          var value = get(controller, prop);

          // 1. Update model-dep cache
          var cache = this._bucketCache;
          if (cache) {
            controller._bucketCache.stash(cacheKey, prop, value);
          }

          // 2. Notify a delegate (e.g. to fire a qp transition)
          var delegate = controller._qpDelegate;
          if (delegate) {
            delegate(controller, prop);
          }
        },

        _calculateCacheKey: function(prefix, _parts, values) {
          var parts = _parts || [], suffixes = "";
          for (var i = 0, len = parts.length; i < len; ++i) {
            var part = parts[i];
            var value = get(values, part);
            suffixes += "::" + part + ":" + value;
          }
          return prefix + suffixes.replace(ALL_PERIODS_REGEX, '-');
        }
      });
    

    function accumulateQueryParamDescriptors(_desc, accum) {
      var desc = _desc, tmp;
      if (typeOf(desc) === 'string') {
        tmp = {};
        tmp[desc] = { as: null };
        desc = tmp;
      }

      for (var key in desc) {
        if (!desc.hasOwnProperty(key)) { return; }

        var singleDesc = desc[key];
        if (typeOf(singleDesc) === 'string') {
          singleDesc = { as: singleDesc };
        }

        tmp = accum[key] || { as: null, scope: 'model' };
        merge(tmp, singleDesc);

        accum[key] = tmp;
      }
    }

    function listenForQueryParamChanges(controller) {
      var qpMap = get(controller, '_normalizedQueryParams');
      for (var prop in qpMap) {
        if (!qpMap.hasOwnProperty(prop)) { continue; }
        controller.addObserver(prop + '.[]', controller, controller._qpChanged);
      }
    }


    __exports__["default"] = ControllerMixin;
  });
define("ember-routing/ext/run_loop",
  ["ember-metal/run_loop"],
  function(__dependency1__) {
    "use strict";
    var run = __dependency1__["default"];

    

    // Add a new named queue after the 'actions' queue (where RSVP promises
    // resolve), which is used in router transitions to prevent unnecessary
    // loading state entry if all context promises resolve on the
    // 'actions' queue first.

    var queues = run.queues;
    run._addQueue('routerTransitions', 'actions');
  });
define("ember-routing/ext/view",
  ["ember-metal/property_get","ember-metal/property_set","ember-metal/run_loop","ember-views/views/view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var run = __dependency3__["default"];
    var EmberView = __dependency4__["default"];

    

    EmberView.reopen({

      
      init: function() {
        set(this, '_outlets', {});
        this._super();
      },

      
      connectOutlet: function(outletName, view) {
        if (this._pendingDisconnections) {
          delete this._pendingDisconnections[outletName];
        }

        if (this._hasEquivalentView(outletName, view)) {
          view.destroy();
          return;
        }

        var outlets = get(this, '_outlets');
        var container = get(this, 'container');
        var router = container && container.lookup('router:main');
        var renderedName = get(view, 'renderedName');

        set(outlets, outletName, view);

        if (router && renderedName) {
          router._connectActiveView(renderedName, view);
        }
      },

      
      _hasEquivalentView: function(outletName, view) {
        var existingView = get(this, '_outlets.'+outletName);
        return existingView &&
          existingView.constructor === view.constructor &&
          existingView.get('template') === view.get('template') &&
          existingView.get('context') === view.get('context');
      },

      
      disconnectOutlet: function(outletName) {
        if (!this._pendingDisconnections) {
          this._pendingDisconnections = {};
        }
        this._pendingDisconnections[outletName] = true;
        run.once(this, '_finishDisconnections');
      },

      
      _finishDisconnections: function() {
        if (this.isDestroyed) return; // _outlets will be gone anyway
        var outlets = get(this, '_outlets');
        var pendingDisconnections = this._pendingDisconnections;
        this._pendingDisconnections = null;

        for (var outletName in pendingDisconnections) {
          set(outlets, outletName, null);
        }
      }
    });

    __exports__["default"] = EmberView;
  });
define("ember-routing/location/api",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // deprecate, assert
    var get = __dependency2__.get;
    var set = __dependency3__.set;

    

    
    __exports__["default"] = {
      
      create: function(options) {
        var implementation = options && options.implementation;
        Ember.assert("Ember.Location.create: you must specify a 'implementation' option", !!implementation);

        var implementationClass = this.implementations[implementation];
        Ember.assert("Ember.Location.create: " + implementation + " is not a valid implementation", !!implementationClass);

        return implementationClass.create.apply(implementationClass, arguments);
      },

      
      registerImplementation: function(name, implementation) {
        Ember.deprecate('Using the Ember.Location.registerImplementation is no longer supported. Register your custom location implementation with the container instead.', false);

        this.implementations[name] = implementation;
      },

      implementations: {},
      _location: window.location,

      
      _getHash: function () {
        // AutoLocation has it at _location, HashLocation at .location.
        // Being nice and not changing
        var href = (this._location || this.location).href;
        var hashIndex = href.indexOf('#');

        if (hashIndex === -1) {
          return '';
        } else {
          return href.substr(hashIndex);
        }
      }
    };
  });
define("ember-routing/location/auto_location",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-routing/location/api","ember-routing/location/history_location","ember-routing/location/hash_location","ember-routing/location/none_location","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // FEATURES
    var get = __dependency2__.get;
    var set = __dependency3__.set;

    var EmberLocation = __dependency4__["default"];
    var HistoryLocation = __dependency5__["default"];
    var HashLocation = __dependency6__["default"];
    var NoneLocation = __dependency7__["default"];

    

    
    __exports__["default"] = {

      
      cancelRouterSetup: false,

      
      rootURL: '/',

      
      _window: window,

      
      _location: window.location,

      
      _history: window.history,

      
      _HistoryLocation: HistoryLocation,

      
      _HashLocation: HashLocation,

      
      _NoneLocation: NoneLocation,

      
      _getOrigin: function () {
        var location = this._location;
        var origin = location.origin;

        // Older browsers, especially IE, don't have origin
        if (!origin) {
          origin = location.protocol + '//' + location.hostname;

          if (location.port) {
            origin += ':' + location.port;
          }
        }

        return origin;
      },

      
      _getSupportsHistory: function () {
        // Boosted from Modernizr: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
        // The stock browser on Android 2.2 & 2.3 returns positive on history support
        // Unfortunately support is really buggy and there is no clean way to detect
        // these bugs, so we fall back to a user agent sniff :(
        var userAgent = this._window.navigator.userAgent;

        // We only want Android 2, stock browser, and not Chrome which identifies
        // itself as 'Mobile Safari' as well
        if (userAgent.indexOf('Android 2') !== -1 &&
            userAgent.indexOf('Mobile Safari') !== -1 &&
            userAgent.indexOf('Chrome') === -1) {
          return false;
        }

        return !!(this._history && 'pushState' in this._history);
      },

      
      _getSupportsHashChange: function () {
        var _window = this._window;
        var documentMode = _window.document.documentMode;

        return ('onhashchange' in _window && (documentMode === undefined || documentMode > 7 ));
      },

      
      _replacePath: function (path) {
        this._location.replace(this._getOrigin() + path);
      },

      
      _getRootURL: function () {
        return this.rootURL;
      },

      
      _getPath: function () {
        var pathname = this._location.pathname;
        // Various versions of IE/Opera don't always return a leading slash
        if (pathname.charAt(0) !== '/') {
          pathname = '/' + pathname;
        }

        return pathname;
      },

      
      _getHash: EmberLocation._getHash,

      
      _getQuery: function () {
        return this._location.search;
      },

      
      _getFullPath: function () {
        return this._getPath() + this._getQuery() + this._getHash();
      },

      
      _getHistoryPath: function () {
        var rootURL = this._getRootURL();
        var path = this._getPath();
        var hash = this._getHash();
        var query = this._getQuery();
        var rootURLIndex = path.indexOf(rootURL);
        var routeHash, hashParts;

        Ember.assert('Path ' + path + ' does not start with the provided rootURL ' + rootURL, rootURLIndex === 0);

        // By convention, Ember.js routes using HashLocation are required to start
        // with `#/`. Anything else should NOT be considered a route and should
        // be passed straight through, without transformation.
        if (hash.substr(0, 2) === '#/') {
          // There could be extra hash segments after the route
          hashParts = hash.substr(1).split('#');
          // The first one is always the route url
          routeHash = hashParts.shift();

          // If the path already has a trailing slash, remove the one
          // from the hashed route so we don't double up.
          if (path.slice(-1) === '/') {
              routeHash = routeHash.substr(1);
          }

          // This is the "expected" final order
          path += routeHash;
          path += query;

          if (hashParts.length) {
            path += '#' + hashParts.join('#');
          }
        } else {
          path += query;
          path += hash;
        }

        return path;
      },

      
      _getHashPath: function () {
        var rootURL = this._getRootURL();
        var path = rootURL;
        var historyPath = this._getHistoryPath();
        var routePath = historyPath.substr(rootURL.length);

        if (routePath !== '') {
          if (routePath.charAt(0) !== '/') {
            routePath = '/' + routePath;
          }

          path += '#' + routePath;
        }

        return path;
      },

      
      create: function (options) {
        if (options && options.rootURL) {
          Ember.assert('rootURL must end with a trailing forward slash e.g. "/app/"', options.rootURL.charAt(options.rootURL.length-1) === '/');
          this.rootURL = options.rootURL;
        }

        var historyPath, hashPath;
        var cancelRouterSetup = false;
        var implementationClass = this._NoneLocation;
        var currentPath = this._getFullPath();

        if (this._getSupportsHistory()) {
          historyPath = this._getHistoryPath();

          // Since we support history paths, let's be sure we're using them else
          // switch the location over to it.
          if (currentPath === historyPath) {
            implementationClass = this._HistoryLocation;
          } else {
            cancelRouterSetup = true;
            this._replacePath(historyPath);
          }

        } else if (this._getSupportsHashChange()) {
          hashPath = this._getHashPath();

          // Be sure we're using a hashed path, otherwise let's switch over it to so
          // we start off clean and consistent. We'll count an index path with no
          // hash as "good enough" as well.
          if (currentPath === hashPath || (currentPath === '/' && hashPath === '/#/')) {
            implementationClass = this._HashLocation;
          } else {
            // Our URL isn't in the expected hash-supported format, so we want to
            // cancel the router setup and replace the URL to start off clean
            cancelRouterSetup = true;
            this._replacePath(hashPath);
          }
        }

        var implementation = implementationClass.create.apply(implementationClass, arguments);

        if (cancelRouterSetup) {
          set(implementation, 'cancelRouterSetup', true);
        }

        return implementation;
      }
    };
  });
define("ember-routing/location/hash_location",
  ["ember-metal/property_get","ember-metal/property_set","ember-metal/run_loop","ember-metal/utils","ember-runtime/system/object","ember-routing/location/api","ember-views/system/jquery","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var run = __dependency3__["default"];
    var guidFor = __dependency4__.guidFor;

    var EmberObject = __dependency5__["default"];
    var EmberLocation = __dependency6__["default"];
    var jQuery = __dependency7__["default"];

    

    
    __exports__["default"] = EmberObject.extend({
      implementation: 'hash',

      init: function() {
        set(this, 'location', get(this, '_location') || window.location);
      },

      
      getHash: EmberLocation._getHash,

      
      getURL: function() {
        return this.getHash().substr(1);
      },

      
      setURL: function(path) {
        get(this, 'location').hash = path;
        set(this, 'lastSetURL', path);
      },

      
      replaceURL: function(path) {
        get(this, 'location').replace('#' + path);
        set(this, 'lastSetURL', path);
      },

      
      onUpdateURL: function(callback) {
        var self = this;
        var guid = guidFor(this);

        jQuery(window).on('hashchange.ember-location-'+guid, function() {
          run(function() {
            var path = self.getURL();
            if (get(self, 'lastSetURL') === path) { return; }

            set(self, 'lastSetURL', null);

            callback(path);
          });
        });
      },

      
      formatURL: function(url) {
        return '#' + url;
      },

      
      willDestroy: function() {
        var guid = guidFor(this);

        jQuery(window).off('hashchange.ember-location-'+guid);
      }
    });
  });
define("ember-routing/location/history_location",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-runtime/system/object","ember-views/system/jquery","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // FEATURES
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var guidFor = __dependency4__.guidFor;

    var EmberObject = __dependency5__["default"];
    var jQuery = __dependency6__["default"];

    

    var popstateFired = false;
    var supportsHistoryState = window.history && 'state' in window.history;

    
    __exports__["default"] = EmberObject.extend({
      implementation: 'history',

      init: function() {
        set(this, 'location', get(this, 'location') || window.location);
        set(this, 'baseURL', jQuery('base').attr('href') || '');
      },

      
      initState: function() {
        set(this, 'history', get(this, 'history') || window.history);
        this.replaceState(this.formatURL(this.getURL()));
      },

      
      rootURL: '/',

      
      getURL: function() {
        var rootURL = get(this, 'rootURL');
        var location = get(this, 'location');
        var path = location.pathname;
        var baseURL = get(this, 'baseURL');

        rootURL = rootURL.replace(/\/$/, '');
        baseURL = baseURL.replace(/\/$/, '');

        var url = path.replace(baseURL, '').replace(rootURL, '');

        
          var search = location.search || '';
          url += search;
        

        return url;
      },

      
      setURL: function(path) {
        var state = this.getState();
        path = this.formatURL(path);

        if (!state || state.path !== path) {
          this.pushState(path);
        }
      },

      
      replaceURL: function(path) {
        var state = this.getState();
        path = this.formatURL(path);

        if (!state || state.path !== path) {
          this.replaceState(path);
        }
      },

      
      getState: function() {
        return supportsHistoryState ? get(this, 'history').state : this._historyState;
      },

      
      pushState: function(path) {
        var state = { path: path };

        get(this, 'history').pushState(state, null, path);

        // store state if browser doesn't support `history.state`
        if (!supportsHistoryState) {
          this._historyState = state;
        }

        // used for webkit workaround
        this._previousURL = this.getURL();
      },

      
      replaceState: function(path) {
        var state = { path: path };

        get(this, 'history').replaceState(state, null, path);

        // store state if browser doesn't support `history.state`
        if (!supportsHistoryState) {
          this._historyState = state;
        }

        // used for webkit workaround
        this._previousURL = this.getURL();
      },

      
      onUpdateURL: function(callback) {
        var guid = guidFor(this);
        var self = this;

        jQuery(window).on('popstate.ember-location-'+guid, function(e) {
          // Ignore initial page load popstate event in Chrome
          if (!popstateFired) {
            popstateFired = true;
            if (self.getURL() === self._previousURL) { return; }
          }
          callback(self.getURL());
        });
      },

      
      formatURL: function(url) {
        var rootURL = get(this, 'rootURL');
        var baseURL = get(this, 'baseURL');

        if (url !== '') {
          rootURL = rootURL.replace(/\/$/, '');
          baseURL = baseURL.replace(/\/$/, '');
        } else if(baseURL.match(/^\//) && rootURL.match(/^\//)) {
          baseURL = baseURL.replace(/\/$/, '');
        }

        return baseURL + rootURL + url;
      },

      
      willDestroy: function() {
        var guid = guidFor(this);

        jQuery(window).off('popstate.ember-location-'+guid);
      }
    });
  });
define("ember-routing/location/none_location",
  ["ember-metal/property_get","ember-metal/property_set","ember-runtime/system/object","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var EmberObject = __dependency3__["default"];

    

    
    __exports__["default"] = EmberObject.extend({
      implementation: 'none',
      path: '',

      
      getURL: function() {
        return get(this, 'path');
      },

      
      setURL: function(path) {
        set(this, 'path', path);
      },

      
      onUpdateURL: function(callback) {
        this.updateCallback = callback;
      },

      
      handleURL: function(url) {
        set(this, 'path', url);
        this.updateCallback(url);
      },

      
      formatURL: function(url) {
        // The return value is not overly meaningful, but we do not want to throw
        // errors when test code renders templates containing {{action href=true}}
        // helpers.
        return url;
      }
    });
  });
define("ember-routing/system/cache",
  ["ember-runtime/system/object","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var EmberObject = __dependency1__["default"];

    __exports__["default"] = EmberObject.extend({
      init: function() {
        this.cache = {};
      },
      has: function(bucketKey) {
        return bucketKey in this.cache;
      },
      stash: function(bucketKey, key, value) {
        var bucket = this.cache[bucketKey];
        if (!bucket) {
          bucket = this.cache[bucketKey] = {};
        }
        bucket[key] = value;
      },
      lookup: function(bucketKey, prop, defaultValue) {
        var cache = this.cache;
        if (!(bucketKey in cache)) {
          return defaultValue;
        }
        var bucket = cache[bucketKey];
        if (prop in bucket) {
          return bucket[prop];
        } else {
          return defaultValue;
        }
      },
      cache: null
    });
  });
define("ember-routing/system/controller_for",
  ["exports"],
  function(__exports__) {
    "use strict";
    

    
    __exports__["default"] = function controllerFor(container, controllerName, lookupOptions) {
      return container.lookup('controller:' + controllerName, lookupOptions);
    }
  });
define("ember-routing/system/dsl",
  ["ember-metal/core","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // FEATURES, assert

    

    function DSL(name) {
      this.parent = name;
      this.matches = [];
    }
    __exports__["default"] = DSL;

    DSL.prototype = {
      route: function(name, options, callback) {
        if (arguments.length === 2 && typeof options === 'function') {
          callback = options;
          options = {};
        }

        if (arguments.length === 1) {
          options = {};
        }

        var type = options.resetNamespace === true ? 'resource' : 'route';
        Ember.assert("'basic' cannot be used as a " + type + " name.", name !== 'basic');


        if (typeof options.path !== 'string') {
          options.path = "/" + name;
        }

        if (canNest(this) && options.resetNamespace !== true) {
          name = this.parent + "." + name;
        }

        if (callback) {
          var dsl = new DSL(name);
          route(dsl, 'loading');
          route(dsl, 'error', { path: "/_unused_dummy_error_path_route_" + name + "/:error" });

          if (callback) { callback.call(dsl); }

          this.push(options.path, name, dsl.generate());
        } else {
          this.push(options.path, name, null);
        }

              },

      push: function(url, name, callback) {
        var parts = name.split('.');
        if (url === "" || url === "/" || parts[parts.length-1] === "index") { this.explicitIndex = true; }

        this.matches.push([url, name, callback]);
      },

      resource: function(name, options, callback) {
        if (arguments.length === 2 && typeof options === 'function') {
          callback = options;
          options = {};
        }

        if (arguments.length === 1) {
          options = {};
        }

        options.resetNamespace = true;
        this.route(name, options, callback);
      },

      generate: function() {
        var dslMatches = this.matches;

        if (!this.explicitIndex) {
          route(this, "index", { path: "/" });
        }

        return function(match) {
          for (var i=0, l=dslMatches.length; i<l; i++) {
            var dslMatch = dslMatches[i];
            var matchObj = match(dslMatch[0]).to(dslMatch[1], dslMatch[2]);
          }
        };
      }
    };

    function canNest(dsl) {
      return dsl.parent && dsl.parent !== 'application';
    }

    function route(dsl, name, options) {
      Ember.assert("You must use `this.resource` to nest", typeof options !== 'function');

      options = options || {};

      if (typeof options.path !== 'string') {
        options.path = "/" + name;
      }

      if (canNest(dsl) && options.resetNamespace !== true) {
        name = dsl.parent + "." + name;
      }

      dsl.push(options.path, name, null);
    }

    DSL.map = function(callback) {
      var dsl = new DSL();
      callback.call(dsl);
      return dsl;
    };
  });
define("ember-routing/system/generate_controller",
  ["ember-metal/core","ember-metal/property_get","ember-metal/utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Logger
    var get = __dependency2__.get;
    var isArray = __dependency3__.isArray;

    

    

    function generateControllerFactory(container, controllerName, context) {
      var Factory, fullName, instance, name, factoryName, controllerType;

      if (context && isArray(context)) {
        controllerType = 'array';
      } else if (context) {
        controllerType = 'object';
      } else {
        controllerType = 'basic';
      }

      factoryName = 'controller:' + controllerType;

      Factory = container.lookupFactory(factoryName).extend({
        isGenerated: true,
        toString: function() {
          return "(generated " + controllerName + " controller)";
        }
      });

      fullName = 'controller:' + controllerName;

      container.register(fullName,  Factory);

      return Factory;
    }

    __exports__.generateControllerFactory = generateControllerFactory;
    __exports__["default"] = function generateController(container, controllerName, context) {
      generateControllerFactory(container, controllerName, context);
      var fullName = 'controller:' + controllerName;
      var instance = container.lookup(fullName);

      if (get(instance, 'namespace.LOG_ACTIVE_GENERATION')) {
        Ember.Logger.info("generated -> " + fullName, { fullName: fullName });
      }

      return instance;
    }
  });
define("ember-routing/system/route",
  ["ember-metal/core","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-metal/get_properties","ember-metal/enumerable_utils","ember-metal/is_none","ember-metal/computed","ember-metal/merge","ember-metal/utils","ember-metal/run_loop","ember-runtime/keys","ember-runtime/copy","ember-runtime/system/string","ember-runtime/system/object","ember-runtime/mixins/action_handler","ember-routing/system/generate_controller","ember-routing-handlebars/helpers/shared","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // FEATURES, K, A, deprecate, assert, Logger
    var EmberError = __dependency2__["default"];
    var get = __dependency3__.get;
    var set = __dependency4__.set;
    var getProperties = __dependency5__["default"];
    var forEach = __dependency6__.forEach;
    var replace = __dependency6__.replace;
    var isNone = __dependency7__.isNone;
    var computed = __dependency8__.computed;
    var merge = __dependency9__["default"];
    var isArray = __dependency10__.isArray;
    var typeOf = __dependency10__.typeOf;
    var run = __dependency11__["default"];
    var keys = __dependency12__["default"];
    var copy = __dependency13__["default"];
    var classify = __dependency14__.classify;
    var fmt = __dependency14__.fmt;
    var EmberObject = __dependency15__["default"];
    var ActionHandler = __dependency16__["default"];
    var generateController = __dependency17__["default"];
    var stashParamNames = __dependency18__.stashParamNames;

    

    
    var Route = EmberObject.extend(ActionHandler, {

      
      exit: function() {
        this.deactivate();
        this.teardownViews();
      },

      
      _reset: function(isExiting, transition) {
        
          var controller = this.controller;
          controller._qpDelegate = get(this, '_qp.states.inactive');
          this.resetController(this.controller, isExiting, transition);
        
      },

      
      enter: function() {
        this.activate();
      },

      
      viewName: null,

      
      templateName: null,

      
      controllerName: null,

      

      

      

      

      

      _actions: {

        queryParamsDidChange: function(changed, totalPresent, removed) {
          
            var totalChanged = keys(changed).concat(keys(removed));
            for (var i = 0, len = totalChanged.length; i < len; ++i) {
              var urlKey = totalChanged[i],
                  options = get(this.queryParams, urlKey) || {};
              if (get(options, 'refreshModel')) {
                this.refresh();
              }
            }
            return true;
          
        },

        finalizeQueryParamChange: function(params, finalParams, transition) {
          
            if (this.routeName !== 'application') { return true; }

            // Transition object is absent for intermediate transitions.
            if (!transition) { return; }

            var handlerInfos = transition.state.handlerInfos;
            var router = this.router;
            var qpMeta = router._queryParamsFor(handlerInfos[handlerInfos.length-1].name);
            var changes = router._qpUpdates;
            var replaceUrl;

            stashParamNames(router, handlerInfos);

            for (var i = 0, len = qpMeta.qps.length; i < len; ++i) {
              var qp = qpMeta.qps[i];
              var route = qp.route;
              var controller = route.controller;
              var presentKey = qp.urlKey in params && qp.urlKey;

              // Do a reverse lookup to see if the changed query
              // param URL key corresponds to a QP property on
              // this controller.
              var value, svalue;
              if (changes && qp.urlKey in changes) {
                // Value updated in/before setupController
                value = get(controller, qp.prop);
                svalue = route.serializeQueryParam(value, qp.urlKey, qp.type);
              } else {
                if (presentKey) {
                  svalue = params[presentKey];
                  value = route.deserializeQueryParam(svalue, qp.urlKey, qp.type);
                } else {
                  // No QP provided; use default value.
                  svalue = qp.sdef;
                  value = copyDefaultValue(qp.def);
                }
              }

              controller._qpDelegate = get(this, '_qp.states.inactive');

              var thisQueryParamChanged = (svalue !== qp.svalue);
              if (thisQueryParamChanged) {
                var options = get(route, 'queryParams.' + qp.urlKey) || {};

                if (transition.queryParamsOnly && replaceUrl !== false) {
                  var replaceConfigValue = get(options, 'replace');
                  if (replaceConfigValue) {
                    replaceUrl = true;
                  } else if (replaceConfigValue === false) {
                    // Explicit pushState wins over any other replaceStates.
                    replaceUrl = false;
                  }
                }

                set(controller, qp.prop, value);
              }

              // Stash current serialized value of controller.
              qp.svalue = svalue;

              var thisQueryParamHasDefaultValue = (qp.sdef === svalue);
              if (!thisQueryParamHasDefaultValue) {
                finalParams.push({
                  value: svalue,
                  visible: true,
                  key: presentKey || qp.urlKey
                });
              }
            }

            if (replaceUrl) {
              transition.method('replace');
            }

            forEach(qpMeta.qps, function(qp) {
              var routeQpMeta = get(qp.route, '_qp');
              var finalizedController = qp.route.controller;
              finalizedController._qpDelegate = get(routeQpMeta, 'states.active');
            });
            router._qpUpdates = null;
          
        }
      },

      
      events: null,

      mergedProperties: ['events'],

      
      deactivate: Ember.K,

      
      activate: Ember.K,

      
      transitionTo: function(name, context) {
        var router = this.router;
        return router.transitionTo.apply(router, arguments);
      },

      
      intermediateTransitionTo: function() {
        var router = this.router;
        router.intermediateTransitionTo.apply(router, arguments);
      },

      
      refresh: function() {
        return this.router.router.refresh(this);
      },

      
      replaceWith: function() {
        var router = this.router;
        return router.replaceWith.apply(router, arguments);
      },

      
      send: function() {
        return this.router.send.apply(this.router, arguments);
      },

      
      setup: function(context, transition) {
        var controllerName = this.controllerName || this.routeName;
        var controller = this.controllerFor(controllerName, true);

        if (!controller) {
          controller =  this.generateController(controllerName, context);
        }

        // Assign the route's controller so that it can more easily be
        // referenced in action handlers
        this.controller = controller;

        if (this.setupControllers) {
          Ember.deprecate("Ember.Route.setupControllers is deprecated. Please use Ember.Route.setupController(controller, model) instead.");
          this.setupControllers(controller, context);
        } else {
          
            var states = get(this, '_qp.states');
            if (transition) {
              // Update the model dep values used to calculate cache keys.
              stashParamNames(this.router, transition.state.handlerInfos);
              controller._qpDelegate = states.changingKeys;
              controller._updateCacheParams(transition.params);
            }
            controller._qpDelegate = states.allowOverrides;

            if (transition) {
              var qpValues = getQueryParamsFor(this, transition.state);
              controller.setProperties(qpValues);
            }

            this.setupController(controller, context, transition);
                  }

        if (this.renderTemplates) {
          Ember.deprecate("Ember.Route.renderTemplates is deprecated. Please use Ember.Route.renderTemplate(controller, model) instead.");
          this.renderTemplates(context);
        } else {
          this.renderTemplate(controller, context);
        }
      },

      
      beforeModel: Ember.K,

      
      afterModel: Ember.K,

      
      redirect: Ember.K,

      
      contextDidChange: function() {
        this.currentModel = this.context;
      },

      
      model: function(params, transition) {
        var match, name, sawParams, value;

        var queryParams;
        
          queryParams = get(this, '_qp.map');
        

        for (var prop in params) {
          if (prop === 'queryParams' || (queryParams && prop in queryParams)) {
            continue;
          }

          if (match = prop.match(/^(.*)_id$/)) {
            name = match[1];
            value = params[prop];
          }
          sawParams = true;
        }

        if (!name && sawParams) { return copy(params); }
        else if (!name) {
          if (transition.resolveIndex !== transition.state.handlerInfos.length-1) { return; }

          var parentModel = transition.state.handlerInfos[transition.resolveIndex-1].context;

          return parentModel;
        }

        return this.findModel(name, value);
      },

      
      deserialize: function(params, transition) {
        
          return this.model(this.paramsFor(this.routeName), transition);
              },

      
      findModel: function(){
        var store = get(this, 'store');
        return store.find.apply(store, arguments);
      },

      
      store: computed(function(){
        var container = this.container;
        var routeName = this.routeName;
        var namespace = get(this, 'router.namespace');

        return {
          find: function(name, value) {
            var modelClass = container.lookupFactory('model:' + name);

            Ember.assert("You used the dynamic segment " + name + "_id in your route " +
                         routeName + ", but " + namespace + "." + classify(name) +
                         " did not exist and you did not override your route's `model` " +
                         "hook.", modelClass);

            if (!modelClass) { return; }

            Ember.assert(classify(name) + ' has no method `find`.', typeof modelClass.find === 'function');

            return modelClass.find(value);
          }
        };
      }),

      
      serialize: function(model, params) {
        if (params.length < 1) { return; }
        if (!model) { return; }

        var name = params[0], object = {};

        if (/_id$/.test(name) && params.length === 1) {
          object[name] = get(model, "id");
        } else {
          object = getProperties(model, params);
        }

        return object;
      },

      
      setupController: function(controller, context, transition) {
        if (controller && (context !== undefined)) {
          set(controller, 'model', context);
        }
      },

      
      controllerFor: function(name, _skipAssert) {
        var container = this.container;
        var route = container.lookup('route:'+name);
        var controller;

        if (route && route.controllerName) {
          name = route.controllerName;
        }

        controller = container.lookup('controller:' + name);

        // NOTE: We're specifically checking that skipAssert is true, because according
        //   to the old API the second parameter was model. We do not want people who
        //   passed a model to skip the assertion.
        Ember.assert("The controller named '"+name+"' could not be found. Make sure " +
                     "that this route exists and has already been entered at least " +
                     "once. If you are accessing a controller not associated with a " +
                     "route, make sure the controller class is explicitly defined.",
                     controller || _skipAssert === true);

        return controller;
      },

      
      generateController: function(name, model) {
        var container = this.container;

        model = model || this.modelFor(name);

        return generateController(container, name, model);
      },

      
      modelFor: function(name) {
        var route = this.container.lookup('route:' + name);
        var transition = this.router ? this.router.router.activeTransition : null;

        // If we are mid-transition, we want to try and look up
        // resolved parent contexts on the current transitionEvent.
        if (transition) {
          var modelLookupName = (route && route.routeName) || name;
          if (transition.resolvedModels.hasOwnProperty(modelLookupName)) {
            return transition.resolvedModels[modelLookupName];
          }
        }

        return route && route.currentModel;
      },

      
      renderTemplate: function(controller, model) {
        this.render();
      },

      
      render: function(name, options) {
        Ember.assert("The name in the given arguments is undefined", arguments.length > 0 ? !isNone(arguments[0]) : true);

        var namePassed = typeof name === 'string' && !!name;

        if (typeof name === 'object' && !options) {
          options = name;
          name = this.routeName;
        }

        options = options || {};
        options.namePassed = namePassed;

        var templateName;

        if (name) {
          name = name.replace(/\//g, '.');
          templateName = name;
        } else {
          name = this.routeName;
          templateName = this.templateName || name;
        }

        var viewName = options.view || namePassed && name || this.viewName || name;

        var container = this.container;
        var view = container.lookup('view:' + viewName);
        var template = view ? view.get('template') : null;

        if (!template) {
          template = container.lookup('template:' + templateName);
        }

        if (!view && !template) {
          Ember.assert("Could not find \"" + name + "\" template or view.", Ember.isEmpty(arguments[0]));
          if (get(this.router, 'namespace.LOG_VIEW_LOOKUPS')) {
            Ember.Logger.info("Could not find \"" + name + "\" template or view. Nothing will be rendered", { fullName: 'template:' + name });
          }
          return;
        }

        options = normalizeOptions(this, name, template, options);
        view = setupView(view, container, options);

        if (options.outlet === 'main') { this.lastRenderedTemplate = name; }

        appendView(this, view, options);
      },

      
      disconnectOutlet: function(options) {
        if (!options || typeof options === "string") {
          var outletName = options;
          options = {};
          options.outlet = outletName;
        }
        options.parentView = options.parentView ? options.parentView.replace(/\//g, '.') : parentTemplate(this);
        options.outlet = options.outlet || 'main';

        var parentView = this.router._lookupActiveView(options.parentView);
        if (parentView) { parentView.disconnectOutlet(options.outlet); }
      },

      willDestroy: function() {
        this.teardownViews();
      },

      
      teardownViews: function() {
        // Tear down the top level view
        if (this.teardownTopLevelView) { this.teardownTopLevelView(); }

        // Tear down any outlets rendered with 'into'
        var teardownOutletViews = this.teardownOutletViews || [];
        forEach(teardownOutletViews, function(teardownOutletView) {
          teardownOutletView();
        });

        delete this.teardownTopLevelView;
        delete this.teardownOutletViews;
        delete this.lastRenderedTemplate;
      }
    });

    var defaultQPMeta = {
      qps: [],
      map: {},
      states: {}
    };

    
      Route.reopen({
        
        queryParams: {},

        _qp: computed(function() {
          var controllerName = this.controllerName || this.routeName;
          var fullName = this.container.normalize('controller:' + controllerName);
          var controllerClass = this.container.lookupFactory(fullName);

          if (!controllerClass) {
            return defaultQPMeta;
          }

          var controllerProto = controllerClass.proto();
          var qpProps = get(controllerProto, '_normalizedQueryParams');
          var cacheMeta = get(controllerProto, '_cacheMeta');

          var qps = [], map = {}, self = this;
          for (var propName in qpProps) {
            if (!qpProps.hasOwnProperty(propName)) { continue; }

            var desc = qpProps[propName],
                urlKey = desc.as || this.serializeQueryParamKey(propName),
                defaultValue = get(controllerProto, propName);

            if (isArray(defaultValue)) {
              defaultValue = Ember.A(defaultValue.slice());
            }

            var type = typeOf(defaultValue),
                defaultValueSerialized = this.serializeQueryParam(defaultValue, urlKey, type),
                fprop = controllerName + ':' + propName,
                qp = {
                  def: defaultValue,
                  sdef: defaultValueSerialized,
                  type: type,
                  urlKey: urlKey,
                  prop: propName,
                  fprop: fprop,
                  ctrl: controllerName,
                  cProto: controllerProto,
                  svalue: defaultValueSerialized,
                  cacheType: desc.scope,
                  route: this,
                  cacheMeta: cacheMeta[propName]
                };

            map[propName] = map[urlKey] = map[fprop] = qp;
            qps.push(qp);
          }

          return {
            qps: qps,
            map: map,
            states: {
              active: function(controller, prop) {
                return self._activeQPChanged(controller, map[prop]);
              },
              allowOverrides: function(controller, prop) {
                return self._updatingQPChanged(controller, map[prop]);
              },
              changingKeys: function(controller, prop) {
                return self._updateSerializedQPValue(controller, map[prop]);
              }
            }
          };
        }),

        _names: null,
        _stashNames: function(_handlerInfo, dynamicParent) {
          var handlerInfo = _handlerInfo;
          if (this._names) { return; }
          var names = this._names = handlerInfo._names;

          if (!names.length) {
            handlerInfo = dynamicParent;
            names = handlerInfo && handlerInfo._names || [];
          }

          var qps = get(this, '_qp.qps');
          var len = qps.length;

          var namePaths = new Array(names.length);
          for (var a = 0, nlen = names.length; a < nlen; ++a) {
            namePaths[a] = handlerInfo.name + '.' + names[a];
          }

          for (var i = 0; i < len; ++i) {
            var qp = qps[i];
            var cacheMeta = qp.cacheMeta;
            if (cacheMeta.scope === 'model') {
              cacheMeta.parts = namePaths;
            }
            cacheMeta.prefix = qp.ctrl;
          }
        },

        _updateSerializedQPValue: function(controller, qp) {
          var value = get(controller, qp.prop);
          qp.svalue = this.serializeQueryParam(value, qp.urlKey, qp.type);
        },

        _activeQPChanged: function(controller, qp) {
          var value = get(controller, qp.prop);
          this.router._queuedQPChanges[qp.fprop] = value;
          run.once(this, this._fireQueryParamTransition);
        },

        _updatingQPChanged: function(controller, qp) {
          var router = this.router;
          if (!router._qpUpdates) {
            router._qpUpdates = {};
          }
          router._qpUpdates[qp.urlKey] = true;
        },

        mergedProperties: ['queryParams'],

        paramsFor: function(name) {
          var route = this.container.lookup('route:' + name);

          if (!route) {
            return {};
          }

          var transition = this.router.router.activeTransition;
          var state = transition ? transition.state : this.router.router.state;

          var params = {};
          merge(params, state.params[name]);
          merge(params, getQueryParamsFor(route, state));

          return params;
        },

        serializeQueryParamKey: function(controllerPropertyName) {
          return controllerPropertyName;
        },

        serializeQueryParam: function(value, urlKey, defaultValueType) {
          // urlKey isn't used here, but anyone overriding
          // can use it to provide serialization specific
          // to a certain query param.
          if (defaultValueType === 'array') {
            return JSON.stringify(value);
          }
          return '' + value;
        },

        deserializeQueryParam: function(value, urlKey, defaultValueType) {
          // urlKey isn't used here, but anyone overriding
          // can use it to provide deserialization specific
          // to a certain query param.

          // Use the defaultValueType of the default value (the initial value assigned to a
          // controller query param property), to intelligently deserialize and cast.
          if (defaultValueType === 'boolean') {
            return (value === 'true') ? true : false;
          } else if (defaultValueType === 'number') {
            return (Number(value)).valueOf();
          } else if (defaultValueType === 'array') {
            return Ember.A(JSON.parse(value));
          }
          return value;
        },


        _fireQueryParamTransition: function() {
          this.transitionTo({ queryParams: this.router._queuedQPChanges });
          this.router._queuedQPChanges = {};
        },

        
        resetController: Ember.K
      });
    

    function parentRoute(route) {
      var handlerInfo = handlerInfoFor(route, route.router.router.state.handlerInfos, -1);
      return handlerInfo && handlerInfo.handler;
    }

    function handlerInfoFor(route, handlerInfos, _offset) {
      if (!handlerInfos) { return; }

      var offset = _offset || 0, current;
      for (var i=0, l=handlerInfos.length; i<l; i++) {
        current = handlerInfos[i].handler;
        if (current === route) { return handlerInfos[i+offset]; }
      }
    }

    function parentTemplate(route) {
      var parent = parentRoute(route), template;

      if (!parent) { return; }

      if (template = parent.lastRenderedTemplate) {
        return template;
      } else {
        return parentTemplate(parent);
      }
    }

    function normalizeOptions(route, name, template, options) {
      options = options || {};
      options.into = options.into ? options.into.replace(/\//g, '.') : parentTemplate(route);
      options.outlet = options.outlet || 'main';
      options.name = name;
      options.template = template;
      options.LOG_VIEW_LOOKUPS = get(route.router, 'namespace.LOG_VIEW_LOOKUPS');

      Ember.assert("An outlet ("+options.outlet+") was specified but was not found.", options.outlet === 'main' || options.into);

      var controller = options.controller,
          model = options.model,
          namedController;

      if (options.controller) {
        controller = options.controller;
      } else if (options.namePassed) {
        controller = route.container.lookup('controller:' + name) || route.controllerName || route.routeName;
      } else {
        controller = route.controllerName || route.container.lookup('controller:' + name);
      }

      if (typeof controller === 'string') {
        var controllerName = controller;
        controller = route.container.lookup('controller:' + controllerName);
        if (!controller) {
          throw new EmberError("You passed `controller: '" + controllerName + "'` into the `render` method, but no such controller could be found.");
        }
      }

      if (model) {
        controller.set('model', model);
      }

      options.controller = controller;

      return options;
    }

    function setupView(view, container, options) {
      if (view) {
        if (options.LOG_VIEW_LOOKUPS) {
          Ember.Logger.info("Rendering " + options.name + " with " + view, { fullName: 'view:' + options.name });
        }
      } else {
        var defaultView = options.into ? 'view:default' : 'view:toplevel';
        view = container.lookup(defaultView);
        if (options.LOG_VIEW_LOOKUPS) {
          Ember.Logger.info("Rendering " + options.name + " with default view " + view, { fullName: 'view:' + options.name });
        }
      }

      if (!get(view, 'templateName')) {
        set(view, 'template', options.template);

        set(view, '_debugTemplateName', options.name);
      }

      set(view, 'renderedName', options.name);
      set(view, 'controller', options.controller);

      return view;
    }

    function appendView(route, view, options) {
      if (options.into) {
        var parentView = route.router._lookupActiveView(options.into);
        var teardownOutletView = generateOutletTeardown(parentView, options.outlet);
        if (!route.teardownOutletViews) { route.teardownOutletViews = []; }
        replace(route.teardownOutletViews, 0, 0, [teardownOutletView]);
        parentView.connectOutlet(options.outlet, view);
      } else {
        var rootElement = get(route, 'router.namespace.rootElement');
        // tear down view if one is already rendered
        if (route.teardownTopLevelView) {
          route.teardownTopLevelView();
        }
        route.router._connectActiveView(options.name, view);
        route.teardownTopLevelView = generateTopLevelTeardown(view);
        view.appendTo(rootElement);
      }
    }

    function generateTopLevelTeardown(view) {
      return function() { view.destroy(); };
    }

    function generateOutletTeardown(parentView, outlet) {
      return function() { parentView.disconnectOutlet(outlet); };
    }

    function getFullQueryParams(router, state) {
      if (state.fullQueryParams) { return state.fullQueryParams; }

      state.fullQueryParams = {};
      merge(state.fullQueryParams, state.queryParams);

      var targetRouteName = state.handlerInfos[state.handlerInfos.length-1].name;
      router._deserializeQueryParams(targetRouteName, state.fullQueryParams);
      return state.fullQueryParams;
    }

    function getQueryParamsFor(route, state) {
      state.queryParamsFor = state.queryParamsFor || {};
      var name = route.routeName;

      if (state.queryParamsFor[name]) { return state.queryParamsFor[name]; }

      var fullQueryParams = getFullQueryParams(route.router, state);

      var params = state.queryParamsFor[name] = {};

      // Copy over all the query params for this route/controller into params hash.
      var qpMeta = get(route, '_qp');
      var qps = qpMeta.qps;
      for (var i = 0, len = qps.length; i < len; ++i) {
        // Put deserialized qp on params hash.
        var qp = qps[i];

        var qpValueWasPassedIn = (qp.prop in fullQueryParams);
        params[qp.prop] = qpValueWasPassedIn ?
                          fullQueryParams[qp.prop] :
                          copyDefaultValue(qp.def);
      }

      return params;
    }

    function copyDefaultValue(value) {
      if (isArray(value)) {
        return Ember.A(value.slice());
      }
      return value;
    }

    __exports__["default"] = Route;
  });
define("ember-routing/system/router",
  ["ember-metal/core","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-metal/properties","ember-metal/computed","ember-metal/merge","ember-metal/run_loop","ember-metal/enumerable_utils","ember-runtime/system/string","ember-runtime/system/object","ember-runtime/mixins/evented","ember-routing/system/dsl","ember-views/views/view","ember-routing/location/api","ember-handlebars/views/metamorph_view","ember-routing-handlebars/helpers/shared","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // FEATURES, Logger, K, assert
    var EmberError = __dependency2__["default"];
    var get = __dependency3__.get;
    var set = __dependency4__.set;
    var defineProperty = __dependency5__.defineProperty;
    var computed = __dependency6__.computed;
    var merge = __dependency7__["default"];
    var run = __dependency8__["default"];
    var forEach = __dependency9__.forEach;

    var fmt = __dependency10__.fmt;
    var EmberObject = __dependency11__["default"];
    var Evented = __dependency12__["default"];
    var EmberRouterDSL = __dependency13__["default"];
    var EmberView = __dependency14__["default"];
    var EmberLocation = __dependency15__["default"];
    var _MetamorphView = __dependency16__["default"];
    var routeArgs = __dependency17__.routeArgs;
    var getActiveTargetName = __dependency17__.getActiveTargetName;
    var stashParamNames = __dependency17__.stashParamNames;

    // requireModule("ember-handlebars");
    // requireModule("ember-runtime");
    // requireModule("ember-views");

    

    // // side effect of loading some Ember globals, for now
    // requireModule("ember-handlebars");
    // requireModule("ember-runtime");
    // requireModule("ember-views");

    var Router = requireModule("router")['default'];
    var Transition = requireModule("router/transition").Transition;

    var slice = [].slice;

    
    var EmberRouter = EmberObject.extend(Evented, {
      
      location: 'hash',

      
      rootURL: '/',

      init: function() {
        this.router = this.constructor.router || this.constructor.map(Ember.K);
        this._activeViews = {};
        this._setupLocation();
        this._qpCache = {};
        this._queuedQPChanges = {};

        if (get(this, 'namespace.LOG_TRANSITIONS_INTERNAL')) {
          this.router.log = Ember.Logger.debug;
        }
      },

      
      url: computed(function() {
        return get(this, 'location').getURL();
      }),

      
      startRouting: function() {
        this.router = this.router || this.constructor.map(Ember.K);

        var router = this.router;
        var location = get(this, 'location');
        var container = this.container;
        var self = this;
        var initialURL = get(this, 'initialURL');

        // Allow the Location class to cancel the router setup while it refreshes
        // the page
        if (get(location, 'cancelRouterSetup')) {
          return;
        }

        this._setupRouter(router, location);

        container.register('view:default', _MetamorphView);
        container.register('view:toplevel', EmberView.extend());

        location.onUpdateURL(function(url) {
          self.handleURL(url);
        });

        if (typeof initialURL === "undefined") {
          initialURL = location.getURL();
        }

        this.handleURL(initialURL);
      },

      
      didTransition: function(infos) {
        updatePaths(this);

        this._cancelLoadingEvent();

        this.notifyPropertyChange('url');

        // Put this in the runloop so url will be accurate. Seems
        // less surprising than didTransition being out of sync.
        run.once(this, this.trigger, 'didTransition');

        if (get(this, 'namespace').LOG_TRANSITIONS) {
          Ember.Logger.log("Transitioned into '" + EmberRouter._routePath(infos) + "'");
        }
      },

      handleURL: function(url) {
        return this._doURLTransition('handleURL', url);
      },

      _doURLTransition: function(routerJsMethod, url) {
        var transition = this.router[routerJsMethod](url || '/');
        listenForTransitionErrors(transition);
        return transition;
      },

      transitionTo: function() {
        var args = slice.call(arguments), queryParams;
        if (resemblesURL(args[0])) {
          return this._doURLTransition('transitionTo', args[0]);
        }

        var possibleQueryParams = args[args.length-1];
        if (possibleQueryParams && possibleQueryParams.hasOwnProperty('queryParams')) {
          queryParams = args.pop().queryParams;
        } else {
          queryParams = {};
        }

        var targetRouteName = args.shift();
        return this._doTransition(targetRouteName, args, queryParams);
      },

      intermediateTransitionTo: function() {
        this.router.intermediateTransitionTo.apply(this.router, arguments);

        updatePaths(this);

        var infos = this.router.currentHandlerInfos;
        if (get(this, 'namespace').LOG_TRANSITIONS) {
          Ember.Logger.log("Intermediate-transitioned into '" + EmberRouter._routePath(infos) + "'");
        }
      },

      replaceWith: function() {
        return this.transitionTo.apply(this, arguments).method('replace');
      },

      generate: function() {
        var url = this.router.generate.apply(this.router, arguments);
        return this.location.formatURL(url);
      },

      
      isActive: function(routeName) {
        var router = this.router;
        return router.isActive.apply(router, arguments);
      },

      
      isActiveIntent: function(routeName, models, queryParams) {
        var router = this.router;
        return router.isActive.apply(router, arguments);
      },

      send: function(name, context) {
        this.router.trigger.apply(this.router, arguments);
      },

      
      hasRoute: function(route) {
        return this.router.hasRoute(route);
      },

      
      reset: function() {
        this.router.reset();
      },

      _lookupActiveView: function(templateName) {
        var active = this._activeViews[templateName];
        return active && active[0];
      },

      _connectActiveView: function(templateName, view) {
        var existing = this._activeViews[templateName];

        if (existing) {
          existing[0].off('willDestroyElement', this, existing[1]);
        }

        function disconnectActiveView() {
          delete this._activeViews[templateName];
        }

        this._activeViews[templateName] = [view, disconnectActiveView];
        view.one('willDestroyElement', this, disconnectActiveView);
      },

      _setupLocation: function() {
        var location = get(this, 'location');
        var rootURL = get(this, 'rootURL');

        if (rootURL && this.container && !this.container.has('-location-setting:root-url')) {
          this.container.register('-location-setting:root-url', rootURL, { instantiate: false });
        }

        if ('string' === typeof location && this.container) {
          var resolvedLocation = this.container.lookup('location:' + location);

          if ('undefined' !== typeof resolvedLocation) {
            location = set(this, 'location', resolvedLocation);
          } else {
            // Allow for deprecated registration of custom location API's
            var options = {implementation: location};

            location = set(this, 'location', EmberLocation.create(options));
          }
        }

        if (rootURL && typeof rootURL === 'string') {
          location.rootURL = rootURL;
        }

        // ensure that initState is called AFTER the rootURL is set on
        // the location instance
        if (typeof location.initState === 'function') { location.initState(); }
      },

      _getHandlerFunction: function() {
        var seen = {}, container = this.container;
        var DefaultRoute = container.lookupFactory('route:basic');
        var self = this;

        return function(name) {
          var routeName = 'route:' + name;
          var handler = container.lookup(routeName);

          if (seen[name]) { return handler; }

          seen[name] = true;

          if (!handler) {
            container.register(routeName, DefaultRoute.extend());
            handler = container.lookup(routeName);

            if (get(self, 'namespace.LOG_ACTIVE_GENERATION')) {
              Ember.Logger.info("generated -> " + routeName, { fullName: routeName });
            }
          }

          handler.routeName = name;
          return handler;
        };
      },

      _setupRouter: function(router, location) {
        var lastURL, emberRouter = this;

        router.getHandler = this._getHandlerFunction();

        var doUpdateURL = function() {
          location.setURL(lastURL);
        };

        router.updateURL = function(path) {
          lastURL = path;
          run.once(doUpdateURL);
        };

        if (location.replaceURL) {
          var doReplaceURL = function() {
            location.replaceURL(lastURL);
          };

          router.replaceURL = function(path) {
            lastURL = path;
            run.once(doReplaceURL);
          };
        }

        router.didTransition = function(infos) {
          emberRouter.didTransition(infos);
        };
      },

      _serializeQueryParams: function(targetRouteName, queryParams) {
        var groupedByUrlKey = {};

        forEachQueryParam(this, targetRouteName, queryParams, function(key, value, qp) {
          var urlKey = qp.urlKey;
          if (!groupedByUrlKey[urlKey]) {
            groupedByUrlKey[urlKey] = [];
          }
          groupedByUrlKey[urlKey].push({
            qp: qp,
            value: value
          });
          delete queryParams[key];
        });

        for (var key in groupedByUrlKey) {
          var qps = groupedByUrlKey[key];
          if (qps.length > 1) {
            var qp0 = qps[0].qp, qp1=qps[1].qp;
            Ember.assert(fmt("You're not allowed to have more than one controller property map to the same query param key, but both `%@` and `%@` map to `%@`. You can fix this by mapping one of the controller properties to a different query param key via the `as` config option, e.g. `%@: { as: 'other-%@' }`", [qp0.fprop, qp1.fprop, qp0.urlKey, qp0.prop, qp0.prop]), false);
          }
          var qp = qps[0].qp;
          queryParams[qp.urlKey] = qp.route.serializeQueryParam(qps[0].value, qp.urlKey, qp.type);
        }
      },

      _deserializeQueryParams: function(targetRouteName, queryParams) {
        forEachQueryParam(this, targetRouteName, queryParams, function(key, value, qp) {
          delete queryParams[key];
          queryParams[qp.prop] = qp.route.deserializeQueryParam(value, qp.urlKey, qp.type);
        });
      },

      _pruneDefaultQueryParamValues: function(targetRouteName, queryParams) {
        var qps = this._queryParamsFor(targetRouteName);
        for (var key in queryParams) {
          var qp = qps.map[key];
          if (qp && qp.sdef === queryParams[key]) {
            delete queryParams[key];
          }
        }
      },

      _doTransition: function(_targetRouteName, models, _queryParams) {
        var targetRouteName = _targetRouteName || getActiveTargetName(this.router);
        Ember.assert("The route " + targetRouteName + " was not found", targetRouteName && this.router.hasRoute(targetRouteName));

        var queryParams = {};
        
          merge(queryParams, _queryParams);
          this._prepareQueryParams(targetRouteName, models, queryParams);
        

        var transitionArgs = routeArgs(targetRouteName, models, queryParams);
        var transitionPromise = this.router.transitionTo.apply(this.router, transitionArgs);

        listenForTransitionErrors(transitionPromise);

        return transitionPromise;
      },

      _prepareQueryParams: function(targetRouteName, models, queryParams) {
        this._hydrateUnsuppliedQueryParams(targetRouteName, models, queryParams);
        this._serializeQueryParams(targetRouteName, queryParams);
        this._pruneDefaultQueryParamValues(targetRouteName, queryParams);
      },

      
      _queryParamsFor: function(leafRouteName) {
        if (this._qpCache[leafRouteName]) {
          return this._qpCache[leafRouteName];
        }

        var map = {}, qps = [], qpCache = this._qpCache[leafRouteName] = {
          map: map,
          qps: qps
        };

        var routerjs = this.router,
            recogHandlerInfos = routerjs.recognizer.handlersFor(leafRouteName);

        for (var i = 0, len = recogHandlerInfos.length; i < len; ++i) {
          var recogHandler = recogHandlerInfos[i];
          var route = routerjs.getHandler(recogHandler.handler);
          var qpMeta = get(route, '_qp');

          if (!qpMeta) { continue; }

          merge(map, qpMeta.map);
          qps.push.apply(qps, qpMeta.qps);
        }

        return {
          qps: qps,
          map: map
        };
      },

      

      _hydrateUnsuppliedQueryParams: function(leafRouteName, contexts, queryParams) {
        var state = calculatePostTransitionState(this, leafRouteName, contexts);
        var handlerInfos = state.handlerInfos;
        var appCache = this._bucketCache;

        stashParamNames(this, handlerInfos);

        for (var i = 0, len = handlerInfos.length; i < len; ++i) {
          var route = handlerInfos[i].handler;
          var qpMeta = get(route, '_qp');

          for (var j = 0, qpLen = qpMeta.qps.length; j < qpLen; ++j) {
            var qp = qpMeta.qps[j];
            var presentProp = qp.prop in queryParams  && qp.prop ||
                              qp.fprop in queryParams && qp.fprop;

            if (presentProp) {
              if (presentProp !== qp.fprop) {
                queryParams[qp.fprop] = queryParams[presentProp];
                delete queryParams[presentProp];
              }
            } else {
              var controllerProto = qp.cProto;
              var cacheMeta = get(controllerProto, '_cacheMeta');

              var cacheKey = controllerProto._calculateCacheKey(qp.ctrl, cacheMeta[qp.prop].parts, state.params);
              queryParams[qp.fprop] = appCache.lookup(cacheKey, qp.prop, qp.def);
            }
          }
        }
      },

      _scheduleLoadingEvent: function(transition, originRoute) {
        this._cancelLoadingEvent();
        this._loadingStateTimer = run.scheduleOnce('routerTransitions', this, '_fireLoadingEvent', transition, originRoute);
      },

      _fireLoadingEvent: function(transition, originRoute) {
        if (!this.router.activeTransition) {
          // Don't fire an event if we've since moved on from
          // the transition that put us in a loading state.
          return;
        }

        transition.trigger(true, 'loading', transition, originRoute);
      },

      _cancelLoadingEvent: function () {
        if (this._loadingStateTimer) {
          run.cancel(this._loadingStateTimer);
        }
        this._loadingStateTimer = null;
      }
    });

    
    function forEachRouteAbove(originRoute, transition, callback) {
      var handlerInfos = transition.state.handlerInfos;
      var originRouteFound = false;
      var handlerInfo, route;

      for (var i = handlerInfos.length - 1; i >= 0; --i) {
        handlerInfo = handlerInfos[i];
        route = handlerInfo.handler;

        if (!originRouteFound) {
          if (originRoute === route) {
            originRouteFound = true;
          }
          continue;
        }

        if (callback(route, handlerInfos[i + 1].handler) !== true) {
          return false;
        }
      }
      return true;
    }

    // These get invoked when an action bubbles above ApplicationRoute
    // and are not meant to be overridable.
    var defaultActionHandlers = {

      willResolveModel: function(transition, originRoute) {
        originRoute.router._scheduleLoadingEvent(transition, originRoute);
      },

      error: function(error, transition, originRoute) {
        // Attempt to find an appropriate error substate to enter.
        var router = originRoute.router;

        var tryTopLevel = forEachRouteAbove(originRoute, transition, function(route, childRoute) {
          var childErrorRouteName = findChildRouteName(route, childRoute, 'error');
          if (childErrorRouteName) {
            router.intermediateTransitionTo(childErrorRouteName, error);
            return;
          }
          return true;
        });

        if (tryTopLevel) {
          // Check for top-level error state to enter.
          if (routeHasBeenDefined(originRoute.router, 'application_error')) {
            router.intermediateTransitionTo('application_error', error);
            return;
          }
        }

        logError(error, 'Error while processing route: ' + transition.targetName);
      },

      loading: function(transition, originRoute) {
        // Attempt to find an appropriate loading substate to enter.
        var router = originRoute.router;

        var tryTopLevel = forEachRouteAbove(originRoute, transition, function(route, childRoute) {
          var childLoadingRouteName = findChildRouteName(route, childRoute, 'loading');

          if (childLoadingRouteName) {
            router.intermediateTransitionTo(childLoadingRouteName);
            return;
          }

          // Don't bubble above pivot route.
          if (transition.pivotHandler !== route) {
            return true;
          }
        });

        if (tryTopLevel) {
          // Check for top-level loading state to enter.
          if (routeHasBeenDefined(originRoute.router, 'application_loading')) {
            router.intermediateTransitionTo('application_loading');
            return;
          }
        }
      }
    };

    function logError(error, initialMessage) {
      var errorArgs = [];

      if (initialMessage) { errorArgs.push(initialMessage); }

      if (error) {
        if (error.message) { errorArgs.push(error.message); }
        if (error.stack)   { errorArgs.push(error.stack); }

        if (typeof error === "string") { errorArgs.push(error); }
      }

      Ember.Logger.error.apply(this, errorArgs);
    }

    function findChildRouteName(parentRoute, originatingChildRoute, name) {
      var router = parentRoute.router;
      var childName;
      var targetChildRouteName = originatingChildRoute.routeName.split('.').pop();
      var namespace = parentRoute.routeName === 'application' ? '' : parentRoute.routeName + '.';

      
      // Second, try general loading state, e.g. 'loading'
      childName = namespace + name;
      if (routeHasBeenDefined(router, childName)) {
        return childName;
      }
    }

    function routeHasBeenDefined(router, name) {
      var container = router.container;
      return router.hasRoute(name) &&
             (container.has('template:' + name) || container.has('route:' + name));
    }

    function triggerEvent(handlerInfos, ignoreFailure, args) {
      var name = args.shift();

      if (!handlerInfos) {
        if (ignoreFailure) { return; }
        throw new EmberError("Can't trigger action '" + name + "' because your app hasn't finished transitioning into its first route. To trigger an action on destination routes during a transition, you can call `.send()` on the `Transition` object passed to the `model/beforeModel/afterModel` hooks.");
      }

      var eventWasHandled = false;
      var handlerInfo, handler;

      for (var i = handlerInfos.length - 1; i >= 0; i--) {
        handlerInfo = handlerInfos[i];
        handler = handlerInfo.handler;

        if (handler._actions && handler._actions[name]) {
          if (handler._actions[name].apply(handler, args) === true) {
            eventWasHandled = true;
          } else {
            return;
          }
        }
      }

      if (defaultActionHandlers[name]) {
        defaultActionHandlers[name].apply(null, args);
        return;
      }

      if (!eventWasHandled && !ignoreFailure) {
        throw new EmberError("Nothing handled the action '" + name + "'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.");
      }
    }

    function calculatePostTransitionState(emberRouter, leafRouteName, contexts) {
      var routerjs = emberRouter.router;
      var state = routerjs.applyIntent(leafRouteName, contexts);
      var handlerInfos = state.handlerInfos;
      var params = state.params;

      for (var i = 0, len = handlerInfos.length; i < len; ++i) {
        var handlerInfo = handlerInfos[i];
        if (!handlerInfo.isResolved) {
          handlerInfo = handlerInfo.becomeResolved(null, handlerInfo.context);
        }
        params[handlerInfo.name] = handlerInfo.params;
      }
      return state;
    }

    function updatePaths(router) {
      var appController = router.container.lookup('controller:application');

      if (!appController) {
        // appController might not exist when top-level loading/error
        // substates have been entered since ApplicationRoute hasn't
        // actually been entered at that point.
        return;
      }

      var infos = router.router.currentHandlerInfos,
          path = EmberRouter._routePath(infos);

      if (!('currentPath' in appController)) {
        defineProperty(appController, 'currentPath');
      }

      set(appController, 'currentPath', path);

      if (!('currentRouteName' in appController)) {
        defineProperty(appController, 'currentRouteName');
      }

      set(appController, 'currentRouteName', infos[infos.length - 1].name);
    }

    EmberRouter.reopenClass({
      router: null,

      
      map: function(callback) {
        var router = this.router;
        if (!router) {
          router = new Router();

          
            router._triggerWillChangeContext = Ember.K;
            router._triggerWillLeave = Ember.K;
          

          router.callbacks = [];
          router.triggerEvent = triggerEvent;
          this.reopenClass({ router: router });
        }

        var dsl = EmberRouterDSL.map(function() {
          this.resource('application', { path: "/" }, function() {
            for (var i=0; i < router.callbacks.length; i++) {
              router.callbacks[i].call(this);
            }
            callback.call(this);
          });
        });

        router.callbacks.push(callback);
        router.map(dsl.generate());
        return router;
      },

      _routePath: function(handlerInfos) {
        var path = [];

        // We have to handle coalescing resource names that
        // are prefixed with their parent's names, e.g.
        // ['foo', 'foo.bar.baz'] => 'foo.bar.baz', not 'foo.foo.bar.baz'

        function intersectionMatches(a1, a2) {
          for (var i = 0, len = a1.length; i < len; ++i) {
            if (a1[i] !== a2[i]) {
              return false;
            }
          }
          return true;
        }

        var name, nameParts, oldNameParts;
        for (var i=1, l=handlerInfos.length; i<l; i++) {
          name = handlerInfos[i].name;
          nameParts = name.split(".");
          oldNameParts = slice.call(path);

          while (oldNameParts.length) {
            if (intersectionMatches(oldNameParts, nameParts)) {
              break;
            }
            oldNameParts.shift();
          }

          path.push.apply(path, nameParts.slice(oldNameParts.length));
        }

        return path.join(".");
      }
    });

    function listenForTransitionErrors(transition) {
      transition.then(null, function(error) {
        if (!error || !error.name) { return; }

        if (error.name === "UnrecognizedURLError") {
          Ember.assert("The URL '" + error.message + "' did not match any routes in your application");
        }
        return error;
      }, 'Ember: Process errors from Router');
    }

    function resemblesURL(str) {
      return typeof str === 'string' && ( str === '' || str.charAt(0) === '/');
    }

    function forEachQueryParam(router, targetRouteName, queryParams, callback) {
      
        var qpCache = router._queryParamsFor(targetRouteName),
        qps = qpCache.qps;

        for (var key in queryParams) {
          if (!queryParams.hasOwnProperty(key)) { continue; }
          var value = queryParams[key],
          qp = qpCache.map[key];

          if (qp) {
            callback(key, value, qp);
          }
        }
          }

    __exports__["default"] = EmberRouter;
  });
define("ember-runtime",
  ["ember-metal","ember-runtime/core","ember-runtime/keys","ember-runtime/compare","ember-runtime/copy","ember-runtime/system/namespace","ember-runtime/system/object","ember-runtime/system/tracked_array","ember-runtime/system/subarray","ember-runtime/system/container","ember-runtime/system/application","ember-runtime/system/array_proxy","ember-runtime/system/object_proxy","ember-runtime/system/core_object","ember-runtime/system/each_proxy","ember-runtime/system/native_array","ember-runtime/system/set","ember-runtime/system/string","ember-runtime/system/deferred","ember-runtime/system/lazy_load","ember-runtime/mixins/array","ember-runtime/mixins/comparable","ember-runtime/mixins/copyable","ember-runtime/mixins/enumerable","ember-runtime/mixins/freezable","ember-runtime/mixins/observable","ember-runtime/mixins/action_handler","ember-runtime/mixins/deferred","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/mutable_array","ember-runtime/mixins/target_action_support","ember-runtime/mixins/evented","ember-runtime/mixins/promise_proxy","ember-runtime/mixins/sortable","ember-runtime/computed/array_computed","ember-runtime/computed/reduce_computed","ember-runtime/computed/reduce_computed_macros","ember-runtime/controllers/array_controller","ember-runtime/controllers/object_controller","ember-runtime/controllers/controller","ember-runtime/mixins/controller","ember-runtime/ext/rsvp","ember-runtime/ext/string","ember-runtime/ext/function","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __dependency27__, __dependency28__, __dependency29__, __dependency30__, __dependency31__, __dependency32__, __dependency33__, __dependency34__, __dependency35__, __dependency36__, __dependency37__, __dependency38__, __dependency39__, __dependency40__, __dependency41__, __dependency42__, __dependency43__, __dependency44__, __exports__) {
    "use strict";
    

    // BEGIN IMPORTS
    var Ember = __dependency1__["default"];
    var isEqual = __dependency2__.isEqual;
    var keys = __dependency3__["default"];
    var compare = __dependency4__["default"];
    var copy = __dependency5__["default"];

    var Namespace = __dependency6__["default"];
    var EmberObject = __dependency7__["default"];
    var TrackedArray = __dependency8__["default"];
    var SubArray = __dependency9__["default"];
    var Container = __dependency10__["default"];
    var Application = __dependency11__["default"];
    var ArrayProxy = __dependency12__["default"];
    var ObjectProxy = __dependency13__["default"];
    var CoreObject = __dependency14__["default"];
    var EachArray = __dependency15__.EachArray;
    var EachProxy = __dependency15__.EachProxy;

    var NativeArray = __dependency16__["default"];
    var Set = __dependency17__["default"];
    var EmberStringUtils = __dependency18__["default"];
    var Deferred = __dependency19__["default"];
    var onLoad = __dependency20__.onLoad;
    var runLoadHooks = __dependency20__.runLoadHooks;

    var EmberArray = __dependency21__["default"];
    var Comparable = __dependency22__["default"];
    var Copyable = __dependency23__["default"];
    var Enumerable = __dependency24__["default"];
    var Freezable = __dependency25__.Freezable;
    var FROZEN_ERROR = __dependency25__.FROZEN_ERROR;

    var Observable = __dependency26__["default"];
    var ActionHandler = __dependency27__["default"];
    var DeferredMixin = __dependency28__["default"];
    var MutableEnumerable = __dependency29__["default"];
    var MutableArray = __dependency30__["default"];
    var TargetActionSupport = __dependency31__["default"];
    var Evented = __dependency32__["default"];
    var PromiseProxyMixin = __dependency33__["default"];
    var SortableMixin = __dependency34__["default"];
    var arrayComputed = __dependency35__.arrayComputed;
    var ArrayComputedProperty = __dependency35__.ArrayComputedProperty;

    var reduceComputed = __dependency36__.reduceComputed;
    var ReduceComputedProperty = __dependency36__.ReduceComputedProperty;

    var sum = __dependency37__.sum;
    var min = __dependency37__.min;
    var max = __dependency37__.max;
    var map = __dependency37__.map;
    var sort = __dependency37__.sort;
    var setDiff = __dependency37__.setDiff;
    var mapBy = __dependency37__.mapBy;
    var mapProperty = __dependency37__.mapProperty;
    var filter = __dependency37__.filter;
    var filterBy = __dependency37__.filterBy;
    var filterProperty = __dependency37__.filterProperty;
    var uniq = __dependency37__.uniq;
    var union = __dependency37__.union;
    var intersect = __dependency37__.intersect;

    var ArrayController = __dependency38__["default"];
    var ObjectController = __dependency39__["default"];
    var Controller = __dependency40__["default"];
    var ControllerMixin = __dependency41__["default"];

    var RSVP = __dependency42__["default"];
        // just for side effect of extending Ember.RSVP
      // just for side effect of extending String.prototype
    // just for side effect of extending Function.prototype
    // END IMPORTS

    // BEGIN EXPORTS
    Ember.compare = compare;
    Ember.copy = copy;
    Ember.isEqual = isEqual;
    Ember.keys = keys;

    Ember.Array = EmberArray;

    Ember.Comparable = Comparable;
    Ember.Copyable = Copyable;

    Ember.SortableMixin = SortableMixin;

    Ember.Freezable = Freezable;
    Ember.FROZEN_ERROR = FROZEN_ERROR;

    Ember.DeferredMixin = DeferredMixin;

    Ember.MutableEnumerable = MutableEnumerable;
    Ember.MutableArray = MutableArray;

    Ember.TargetActionSupport = TargetActionSupport;
    Ember.Evented = Evented;

    Ember.PromiseProxyMixin = PromiseProxyMixin;

    Ember.Observable = Observable;

    Ember.arrayComputed = arrayComputed;
    Ember.ArrayComputedProperty = ArrayComputedProperty;
    Ember.reduceComputed = reduceComputed;
    Ember.ReduceComputedProperty = ReduceComputedProperty;

    // ES6TODO: this seems a less than ideal way/place to add properties to Ember.computed
    var EmComputed = Ember.computed;

    EmComputed.sum = sum;
    EmComputed.min = min;
    EmComputed.max = max;
    EmComputed.map = map;
    EmComputed.sort = sort;
    EmComputed.setDiff = setDiff;
    EmComputed.mapBy = mapBy;
    EmComputed.mapProperty = mapProperty;
    EmComputed.filter = filter;
    EmComputed.filterBy = filterBy;
    EmComputed.filterProperty = filterProperty;
    EmComputed.uniq = uniq;
    EmComputed.union = union;
    EmComputed.intersect = intersect;

    Ember.String = EmberStringUtils;
    Ember.Object = EmberObject;
    Ember.TrackedArray = TrackedArray;
    Ember.SubArray = SubArray;
    Ember.Container = Container;
    Ember.Namespace = Namespace;
    Ember.Enumerable = Enumerable;
    Ember.ArrayProxy = ArrayProxy;
    Ember.ObjectProxy = ObjectProxy;
    Ember.ActionHandler = ActionHandler;
    Ember.CoreObject = CoreObject;
    Ember.EachArray = EachArray;
    Ember.EachProxy = EachProxy;
    Ember.NativeArray = NativeArray;
    // ES6TODO: Currently we must rely on the global from ember-metal/core to avoid circular deps
    // Ember.A = A;
    Ember.Set = Set;
    Ember.Deferred = Deferred;
    Ember.onLoad = onLoad;
    Ember.runLoadHooks = runLoadHooks;

    Ember.ArrayController = ArrayController;
    Ember.ObjectController = ObjectController;
    Ember.Controller = Controller;
    Ember.ControllerMixin = ControllerMixin;

    Ember.RSVP = RSVP;
    // END EXPORTS

    __exports__["default"] = Ember;
  });
define("ember-runtime/compare",
  ["ember-metal/core","ember-metal/utils","ember-runtime/mixins/comparable","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
     // for Ember.ORDER_DEFINITION
    var typeOf = __dependency2__.typeOf;
    var Comparable = __dependency3__["default"];

    // Used by Ember.compare
    Ember.ORDER_DEFINITION = Ember.ENV.ORDER_DEFINITION || [
      'undefined',
      'null',
      'boolean',
      'number',
      'string',
      'array',
      'object',
      'instance',
      'function',
      'class',
      'date'
    ];

    
    __exports__["default"] = function compare(v, w) {
      if (v === w) { return 0; }

      var type1 = typeOf(v);
      var type2 = typeOf(w);

      if (Comparable) {
        if (type1==='instance' && Comparable.detect(v.constructor)) {
          return v.constructor.compare(v, w);
        }

        if (type2 === 'instance' && Comparable.detect(w.constructor)) {
          return 1-w.constructor.compare(w, v);
        }
      }

      // If we haven't yet generated a reverse-mapping of Ember.ORDER_DEFINITION,
      // do so now.
      var mapping = Ember.ORDER_DEFINITION_MAPPING;
      if (!mapping) {
        var order = Ember.ORDER_DEFINITION;
        mapping = Ember.ORDER_DEFINITION_MAPPING = {};
        var idx, len;
        for (idx = 0, len = order.length; idx < len;  ++idx) {
          mapping[order[idx]] = idx;
        }

        // We no longer need Ember.ORDER_DEFINITION.
        delete Ember.ORDER_DEFINITION;
      }

      var type1Index = mapping[type1];
      var type2Index = mapping[type2];

      if (type1Index < type2Index) { return -1; }
      if (type1Index > type2Index) { return 1; }

      // types are equal - so we have to check values now
      switch (type1) {
        case 'boolean':
        case 'number':
          if (v < w) { return -1; }
          if (v > w) { return 1; }
          return 0;

        case 'string':
          var comp = v.localeCompare(w);
          if (comp < 0) { return -1; }
          if (comp > 0) { return 1; }
          return 0;

        case 'array':
          var vLen = v.length;
          var wLen = w.length;
          var l = Math.min(vLen, wLen);
          var r = 0;
          var i = 0;
          while (r === 0 && i < l) {
            r = compare(v[i],w[i]);
            i++;
          }
          if (r !== 0) { return r; }

          // all elements are equal now
          // shorter array should be ordered first
          if (vLen < wLen) { return -1; }
          if (vLen > wLen) { return 1; }
          // arrays are equal now
          return 0;

        case 'instance':
          if (Comparable && Comparable.detect(v)) {
            return v.compare(v, w);
          }
          return 0;

        case 'date':
          var vNum = v.getTime();
          var wNum = w.getTime();
          if (vNum < wNum) { return -1; }
          if (vNum > wNum) { return 1; }
          return 0;

        default:
          return 0;
      }
    }
  });
define("ember-runtime/computed/array_computed",
  ["ember-metal/core","ember-runtime/computed/reduce_computed","ember-metal/enumerable_utils","ember-metal/platform","ember-metal/observer","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var reduceComputed = __dependency2__.reduceComputed;
    var ReduceComputedProperty = __dependency2__.ReduceComputedProperty;
    var forEach = __dependency3__.forEach;
    var o_create = __dependency4__.create;
    var addObserver = __dependency5__.addObserver;
    var EmberError = __dependency6__["default"];

    var a_slice = [].slice;

    function ArrayComputedProperty() {
      var cp = this;

      ReduceComputedProperty.apply(this, arguments);

      this.func = (function(reduceFunc) {
        return function (propertyName) {
          if (!cp._hasInstanceMeta(this, propertyName)) {
            // When we recompute an array computed property, we need already
            // retrieved arrays to be updated; we can't simply empty the cache and
            // hope the array is re-retrieved.
            forEach(cp._dependentKeys, function(dependentKey) {
              addObserver(this, dependentKey, function() {
                cp.recomputeOnce.call(this, propertyName);
              });
            }, this);
          }

          return reduceFunc.apply(this, arguments);
        };
      })(this.func);

      return this;
    }

    ArrayComputedProperty.prototype = o_create(ReduceComputedProperty.prototype);
    ArrayComputedProperty.prototype.initialValue = function () {
      return Ember.A();
    };
    ArrayComputedProperty.prototype.resetValue = function (array) {
      array.clear();
      return array;
    };

    // This is a stopgap to keep the reference counts correct with lazy CPs.
    ArrayComputedProperty.prototype.didChange = function (obj, keyName) {
      return;
    };

    
    function arrayComputed (options) {
      var args;

      if (arguments.length > 1) {
        args = a_slice.call(arguments, 0, -1);
        options = a_slice.call(arguments, -1)[0];
      }

      if (typeof options !== "object") {
        throw new EmberError("Array Computed Property declared without an options hash");
      }

      var cp = new ArrayComputedProperty(options);

      if (args) {
        cp.property.apply(cp, args);
      }

      return cp;
    }

    __exports__.arrayComputed = arrayComputed;
    __exports__.ArrayComputedProperty = ArrayComputedProperty;
  });
define("ember-runtime/computed/reduce_computed",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/property_events","ember-metal/expand_properties","ember-metal/observer","ember-metal/computed","ember-metal/platform","ember-metal/enumerable_utils","ember-runtime/system/tracked_array","ember-runtime/mixins/array","ember-metal/run_loop","ember-runtime/system/set","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.assert
    var e_get = __dependency2__.get;
    var set = __dependency3__.set;
    var guidFor = __dependency4__.guidFor;
    var metaFor = __dependency4__.meta;
    var EmberError = __dependency5__["default"];
    var propertyWillChange = __dependency6__.propertyWillChange;
    var propertyDidChange = __dependency6__.propertyDidChange;
    var expandProperties = __dependency7__["default"];
    var addObserver = __dependency8__.addObserver;
    var observersFor = __dependency8__.observersFor;
    var removeObserver = __dependency8__.removeObserver;
    var addBeforeObserver = __dependency8__.addBeforeObserver;
    var removeBeforeObserver = __dependency8__.removeBeforeObserver;
    var ComputedProperty = __dependency9__.ComputedProperty;
    var cacheFor = __dependency9__.cacheFor;
    var o_create = __dependency10__.create;
    var forEach = __dependency11__.forEach;
    var TrackedArray = __dependency12__["default"];
    var EmberArray = __dependency13__["default"];
    var run = __dependency14__["default"];
    var Set = __dependency15__["default"];
    var isArray = __dependency4__.isArray;

    var cacheSet = cacheFor.set;
    var cacheGet = cacheFor.get;
    var cacheRemove = cacheFor.remove;
    var a_slice = [].slice;
    // Here we explicitly don't allow `@each.foo`; it would require some special
    // testing, but there's no particular reason why it should be disallowed.
    var eachPropertyPattern = /^(.*)\.@each\.(.*)/;
    var doubleEachPropertyPattern = /(.*\.@each){2,}/;
    var arrayBracketPattern = /\.\[\]$/;

    function get(obj, key) {
      if (key === '@this') {
        return obj;
      }

      return e_get(obj, key);
    }

    
    function DependentArraysObserver(callbacks, cp, instanceMeta, context, propertyName, sugarMeta) {
      // user specified callbacks for `addedItem` and `removedItem`
      this.callbacks = callbacks;

      // the computed property: remember these are shared across instances
      this.cp = cp;

      // the ReduceComputedPropertyInstanceMeta this DependentArraysObserver is
      // associated with
      this.instanceMeta = instanceMeta;

      // A map of array guids to dependentKeys, for the given context.  We track
      // this because we want to set up the computed property potentially before the
      // dependent array even exists, but when the array observer fires, we lack
      // enough context to know what to update: we can recover that context by
      // getting the dependentKey.
      this.dependentKeysByGuid = {};

      // a map of dependent array guids -> TrackedArray instances.  We use
      // this to lazily recompute indexes for item property observers.
      this.trackedArraysByGuid = {};

      // We suspend observers to ignore replacements from `reset` when totally
      // recomputing.  Unfortunately we cannot properly suspend the observers
      // because we only have the key; instead we make the observers no-ops
      this.suspended = false;

      // This is used to coalesce item changes from property observers within a
      // single item.
      this.changedItems = {};
      // This is used to coalesce item changes for multiple items that depend on
      // some shared state.
      this.changedItemCount = 0;
    }

    function ItemPropertyObserverContext (dependentArray, index, trackedArray) {
      Ember.assert("Internal error: trackedArray is null or undefined", trackedArray);

      this.dependentArray = dependentArray;
      this.index = index;
      this.item = dependentArray.objectAt(index);
      this.trackedArray = trackedArray;
      this.beforeObserver = null;
      this.observer = null;

      this.destroyed = false;
    }

    DependentArraysObserver.prototype = {
      setValue: function (newValue) {
        this.instanceMeta.setValue(newValue, true);
      },
      getValue: function () {
        return this.instanceMeta.getValue();
      },

      setupObservers: function (dependentArray, dependentKey) {
        this.dependentKeysByGuid[guidFor(dependentArray)] = dependentKey;

        dependentArray.addArrayObserver(this, {
          willChange: 'dependentArrayWillChange',
          didChange: 'dependentArrayDidChange'
        });

        if (this.cp._itemPropertyKeys[dependentKey]) {
          this.setupPropertyObservers(dependentKey, this.cp._itemPropertyKeys[dependentKey]);
        }
      },

      teardownObservers: function (dependentArray, dependentKey) {
        var itemPropertyKeys = this.cp._itemPropertyKeys[dependentKey] || [];

        delete this.dependentKeysByGuid[guidFor(dependentArray)];

        this.teardownPropertyObservers(dependentKey, itemPropertyKeys);

        dependentArray.removeArrayObserver(this, {
          willChange: 'dependentArrayWillChange',
          didChange: 'dependentArrayDidChange'
        });
      },

      suspendArrayObservers: function (callback, binding) {
        var oldSuspended = this.suspended;
        this.suspended = true;
        callback.call(binding);
        this.suspended = oldSuspended;
      },

      setupPropertyObservers: function (dependentKey, itemPropertyKeys) {
        var dependentArray = get(this.instanceMeta.context, dependentKey),
            length = get(dependentArray, 'length'),
            observerContexts = new Array(length);

        this.resetTransformations(dependentKey, observerContexts);

        forEach(dependentArray, function (item, index) {
          var observerContext = this.createPropertyObserverContext(dependentArray, index, this.trackedArraysByGuid[dependentKey]);
          observerContexts[index] = observerContext;

          forEach(itemPropertyKeys, function (propertyKey) {
            addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver);
            addObserver(item, propertyKey, this, observerContext.observer);
          }, this);
        }, this);
      },

      teardownPropertyObservers: function (dependentKey, itemPropertyKeys) {
        var dependentArrayObserver = this,
            trackedArray = this.trackedArraysByGuid[dependentKey],
            beforeObserver,
            observer,
            item;

        if (!trackedArray) { return; }

        trackedArray.apply(function (observerContexts, offset, operation) {
          if (operation === TrackedArray.DELETE) { return; }

          forEach(observerContexts, function (observerContext) {
            observerContext.destroyed = true;
            beforeObserver = observerContext.beforeObserver;
            observer = observerContext.observer;
            item = observerContext.item;

            forEach(itemPropertyKeys, function (propertyKey) {
              removeBeforeObserver(item, propertyKey, dependentArrayObserver, beforeObserver);
              removeObserver(item, propertyKey, dependentArrayObserver, observer);
            });
          });
        });
      },

      createPropertyObserverContext: function (dependentArray, index, trackedArray) {
        var observerContext = new ItemPropertyObserverContext(dependentArray, index, trackedArray);

        this.createPropertyObserver(observerContext);

        return observerContext;
      },

      createPropertyObserver: function (observerContext) {
        var dependentArrayObserver = this;

        observerContext.beforeObserver = function (obj, keyName) {
          return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext);
        };
        observerContext.observer = function (obj, keyName) {
          return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext);
        };
      },

      resetTransformations: function (dependentKey, observerContexts) {
        this.trackedArraysByGuid[dependentKey] = new TrackedArray(observerContexts);
      },

      trackAdd: function (dependentKey, index, newItems) {
        var trackedArray = this.trackedArraysByGuid[dependentKey];
        if (trackedArray) {
          trackedArray.addItems(index, newItems);
        }
      },

      trackRemove: function (dependentKey, index, removedCount) {
        var trackedArray = this.trackedArraysByGuid[dependentKey];

        if (trackedArray) {
          return trackedArray.removeItems(index, removedCount);
        }

        return [];
      },

      updateIndexes: function (trackedArray, array) {
        var length = get(array, 'length');
        // OPTIMIZE: we could stop updating once we hit the object whose observer
        // fired; ie partially apply the transformations
        trackedArray.apply(function (observerContexts, offset, operation, operationIndex) {
          // we don't even have observer contexts for removed items, even if we did,
          // they no longer have any index in the array
          if (operation === TrackedArray.DELETE) { return; }
          if (operationIndex === 0 && operation === TrackedArray.RETAIN && observerContexts.length === length && offset === 0) {
            // If we update many items we don't want to walk the array each time: we
            // only need to update the indexes at most once per run loop.
            return;
          }

          forEach(observerContexts, function (context, index) {
            context.index = index + offset;
          });
        });
      },

      dependentArrayWillChange: function (dependentArray, index, removedCount, addedCount) {
        if (this.suspended) { return; }

        var removedItem = this.callbacks.removedItem;
        var changeMeta;
        var guid = guidFor(dependentArray);
        var dependentKey = this.dependentKeysByGuid[guid];
        var itemPropertyKeys = this.cp._itemPropertyKeys[dependentKey] || [];
        var length = get(dependentArray, 'length');
        var normalizedIndex = normalizeIndex(index, length, 0);
        var normalizedRemoveCount = normalizeRemoveCount(normalizedIndex, length, removedCount);
        var item, itemIndex, sliceIndex, observerContexts;

        observerContexts = this.trackRemove(dependentKey, normalizedIndex, normalizedRemoveCount);

        function removeObservers(propertyKey) {
          observerContexts[sliceIndex].destroyed = true;
          removeBeforeObserver(item, propertyKey, this, observerContexts[sliceIndex].beforeObserver);
          removeObserver(item, propertyKey, this, observerContexts[sliceIndex].observer);
        }

        for (sliceIndex = normalizedRemoveCount - 1; sliceIndex >= 0; --sliceIndex) {
          itemIndex = normalizedIndex + sliceIndex;
          if (itemIndex >= length) { break; }

          item = dependentArray.objectAt(itemIndex);

          forEach(itemPropertyKeys, removeObservers, this);

          changeMeta = new ChangeMeta(dependentArray, item, itemIndex, this.instanceMeta.propertyName, this.cp, normalizedRemoveCount);
          this.setValue( removedItem.call(
            this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta));
        }
      },

      dependentArrayDidChange: function (dependentArray, index, removedCount, addedCount) {
        if (this.suspended) { return; }

        var addedItem = this.callbacks.addedItem;
        var guid = guidFor(dependentArray);
        var dependentKey = this.dependentKeysByGuid[guid];
        var observerContexts = new Array(addedCount);
        var itemPropertyKeys = this.cp._itemPropertyKeys[dependentKey];
        var length = get(dependentArray, 'length');
        var normalizedIndex = normalizeIndex(index, length, addedCount);
        var changeMeta, observerContext;

        forEach(dependentArray.slice(normalizedIndex, normalizedIndex + addedCount), function (item, sliceIndex) {
          if (itemPropertyKeys) {
            observerContext =
              observerContexts[sliceIndex] =
              this.createPropertyObserverContext(dependentArray, normalizedIndex + sliceIndex, this.trackedArraysByGuid[dependentKey]);
            forEach(itemPropertyKeys, function (propertyKey) {
              addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver);
              addObserver(item, propertyKey, this, observerContext.observer);
            }, this);
          }

          changeMeta = new ChangeMeta(dependentArray, item, normalizedIndex + sliceIndex, this.instanceMeta.propertyName, this.cp, addedCount);
          this.setValue( addedItem.call(
            this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta));
        }, this);

        this.trackAdd(dependentKey, normalizedIndex, observerContexts);
      },

      itemPropertyWillChange: function (obj, keyName, array, observerContext) {
        var guid = guidFor(obj);

        if (!this.changedItems[guid]) {
          this.changedItems[guid] = {
            array:            array,
            observerContext:  observerContext,
            obj:              obj,
            previousValues:   {}
          };
        }
        ++this.changedItemCount;

        this.changedItems[guid].previousValues[keyName] = get(obj, keyName);
      },

      itemPropertyDidChange: function(obj, keyName, array, observerContext) {
        if (--this.changedItemCount === 0) {
          this.flushChanges();
        }
      },

      flushChanges: function() {
        var changedItems = this.changedItems, key, c, changeMeta;

        for (key in changedItems) {
          c = changedItems[key];
          if (c.observerContext.destroyed) { continue; }

          this.updateIndexes(c.observerContext.trackedArray, c.observerContext.dependentArray);

          changeMeta = new ChangeMeta(c.array, c.obj, c.observerContext.index, this.instanceMeta.propertyName, this.cp, changedItems.length, c.previousValues);
          this.setValue(
            this.callbacks.removedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta));
          this.setValue(
            this.callbacks.addedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta));
        }
        this.changedItems = {};
      }
    };

    function normalizeIndex(index, length, newItemsOffset) {
      if (index < 0) {
        return Math.max(0, length + index);
      } else if (index < length) {
        return index;
      } else  {
        return Math.min(length - newItemsOffset, index);
      }
    }

    function normalizeRemoveCount(index, length, removedCount) {
      return Math.min(removedCount, length - index);
    }

    function ChangeMeta(dependentArray, item, index, propertyName, property, changedCount, previousValues){
      this.arrayChanged = dependentArray;
      this.index = index;
      this.item = item;
      this.propertyName = propertyName;
      this.property = property;
      this.changedCount = changedCount;

      if (previousValues) {
        // previous values only available for item property changes
        this.previousValues = previousValues;
      }
    }

    function addItems (dependentArray, callbacks, cp, propertyName, meta) {
      forEach(dependentArray, function (item, index) {
        meta.setValue( callbacks.addedItem.call(
          this, meta.getValue(), item, new ChangeMeta(dependentArray, item, index, propertyName, cp, dependentArray.length), meta.sugarMeta));
      }, this);
    }

    function reset(cp, propertyName) {
      var callbacks = cp._callbacks(),
          meta;

      if (cp._hasInstanceMeta(this, propertyName)) {
        meta = cp._instanceMeta(this, propertyName);
        meta.setValue(cp.resetValue(meta.getValue()));
      } else {
        meta = cp._instanceMeta(this, propertyName);
      }

      if (cp.options.initialize) {
        cp.options.initialize.call(this, meta.getValue(), { property: cp, propertyName: propertyName }, meta.sugarMeta);
      }
    }

    function partiallyRecomputeFor(obj, dependentKey) {
      if (arrayBracketPattern.test(dependentKey)) {
        return false;
      }

      var value = get(obj, dependentKey);
      return EmberArray.detect(value);
    }

    function ReduceComputedPropertyInstanceMeta(context, propertyName, initialValue) {
      this.context = context;
      this.propertyName = propertyName;
      this.cache = metaFor(context).cache;

      this.dependentArrays = {};
      this.sugarMeta = {};

      this.initialValue = initialValue;
    }

    ReduceComputedPropertyInstanceMeta.prototype = {
      getValue: function () {
        var value = cacheGet(this.cache, this.propertyName);
        if (value !== undefined) {
          return value;
        } else {
          return this.initialValue;
        }
      },

      setValue: function(newValue, triggerObservers) {
        // This lets sugars force a recomputation, handy for very simple
        // implementations of eg max.
        if (newValue === cacheGet(this.cache, this.propertyName)) {
          return;
        }

        if (triggerObservers) {
          propertyWillChange(this.context, this.propertyName);
        }

        if (newValue === undefined) {
          cacheRemove(this.cache, this.propertyName);
        } else {
          cacheSet(this.cache, this.propertyName, newValue);
        }

        if (triggerObservers) {
          propertyDidChange(this.context, this.propertyName);
        }
      }
    };

    

    __exports__.ReduceComputedProperty = ReduceComputedProperty;
    // TODO: default export
    function ReduceComputedProperty(options) {
      var cp = this;

      this.options = options;

      this._dependentKeys = null;
      // A map of dependentKey -> [itemProperty, ...] that tracks what properties of
      // items in the array we must track to update this property.
      this._itemPropertyKeys = {};
      this._previousItemPropertyKeys = {};

      this.readOnly();
      this.cacheable();

      this.recomputeOnce = function(propertyName) {
        // What we really want to do is coalesce by <cp, propertyName>.
        // We need a form of `scheduleOnce` that accepts an arbitrary token to
        // coalesce by, in addition to the target and method.
        run.once(this, recompute, propertyName);
      };
      var recompute = function(propertyName) {
        var dependentKeys = cp._dependentKeys,
            meta = cp._instanceMeta(this, propertyName),
            callbacks = cp._callbacks();

        reset.call(this, cp, propertyName);

        meta.dependentArraysObserver.suspendArrayObservers(function () {
          forEach(cp._dependentKeys, function (dependentKey) {
            Ember.assert(
              "dependent array " + dependentKey + " must be an `Ember.Array`.  " +
              "If you are not extending arrays, you will need to wrap native arrays with `Ember.A`",
              !(isArray(get(this, dependentKey)) && !EmberArray.detect(get(this, dependentKey))));

            if (!partiallyRecomputeFor(this, dependentKey)) { return; }

            var dependentArray = get(this, dependentKey),
                previousDependentArray = meta.dependentArrays[dependentKey];

            if (dependentArray === previousDependentArray) {
              // The array may be the same, but our item property keys may have
              // changed, so we set them up again.  We can't easily tell if they've
              // changed: the array may be the same object, but with different
              // contents.
              if (cp._previousItemPropertyKeys[dependentKey]) {
                delete cp._previousItemPropertyKeys[dependentKey];
                meta.dependentArraysObserver.setupPropertyObservers(dependentKey, cp._itemPropertyKeys[dependentKey]);
              }
            } else {
              meta.dependentArrays[dependentKey] = dependentArray;

              if (previousDependentArray) {
                meta.dependentArraysObserver.teardownObservers(previousDependentArray, dependentKey);
              }

              if (dependentArray) {
                meta.dependentArraysObserver.setupObservers(dependentArray, dependentKey);
              }
            }
          }, this);
        }, this);

        forEach(cp._dependentKeys, function(dependentKey) {
          if (!partiallyRecomputeFor(this, dependentKey)) { return; }

          var dependentArray = get(this, dependentKey);
          if (dependentArray) {
            addItems.call(this, dependentArray, callbacks, cp, propertyName, meta);
          }
        }, this);
      };


      this.func = function (propertyName) {
        Ember.assert("Computed reduce values require at least one dependent key", cp._dependentKeys);

        recompute.call(this, propertyName);

        return cp._instanceMeta(this, propertyName).getValue();
      };
    }

    ReduceComputedProperty.prototype = o_create(ComputedProperty.prototype);

    function defaultCallback(computedValue) {
      return computedValue;
    }

    ReduceComputedProperty.prototype._callbacks = function () {
      if (!this.callbacks) {
        var options = this.options;
        this.callbacks = {
          removedItem: options.removedItem || defaultCallback,
          addedItem: options.addedItem || defaultCallback
        };
      }
      return this.callbacks;
    };

    ReduceComputedProperty.prototype._hasInstanceMeta = function (context, propertyName) {
      return !!metaFor(context).cacheMeta[propertyName];
    };

    ReduceComputedProperty.prototype._instanceMeta = function (context, propertyName) {
      var cacheMeta = metaFor(context).cacheMeta,
          meta = cacheMeta[propertyName];

      if (!meta) {
        meta = cacheMeta[propertyName] = new ReduceComputedPropertyInstanceMeta(context, propertyName, this.initialValue());
        meta.dependentArraysObserver = new DependentArraysObserver(this._callbacks(), this, meta, context, propertyName, meta.sugarMeta);
      }

      return meta;
    };

    ReduceComputedProperty.prototype.initialValue = function () {
      if (typeof this.options.initialValue === 'function') {
        return this.options.initialValue();
      }
      else {
        return this.options.initialValue;
      }
    };

    ReduceComputedProperty.prototype.resetValue = function (value) {
      return this.initialValue();
    };

    ReduceComputedProperty.prototype.itemPropertyKey = function (dependentArrayKey, itemPropertyKey) {
      this._itemPropertyKeys[dependentArrayKey] = this._itemPropertyKeys[dependentArrayKey] || [];
      this._itemPropertyKeys[dependentArrayKey].push(itemPropertyKey);
    };

    ReduceComputedProperty.prototype.clearItemPropertyKeys = function (dependentArrayKey) {
      if (this._itemPropertyKeys[dependentArrayKey]) {
        this._previousItemPropertyKeys[dependentArrayKey] = this._itemPropertyKeys[dependentArrayKey];
        this._itemPropertyKeys[dependentArrayKey] = [];
      }
    };

    ReduceComputedProperty.prototype.property = function () {
      var cp = this,
          args = a_slice.call(arguments),
          propertyArgs = new Set(),
          match,
          dependentArrayKey,
          itemPropertyKey;

      forEach(args, function (dependentKey) {
        if (doubleEachPropertyPattern.test(dependentKey)) {
          throw new EmberError("Nested @each properties not supported: " + dependentKey);
        } else if (match = eachPropertyPattern.exec(dependentKey)) {
          dependentArrayKey = match[1];

          var itemPropertyKeyPattern = match[2],
              addItemPropertyKey = function (itemPropertyKey) {
                cp.itemPropertyKey(dependentArrayKey, itemPropertyKey);
              };

          expandProperties(itemPropertyKeyPattern, addItemPropertyKey);
          propertyArgs.add(dependentArrayKey);
        } else {
          propertyArgs.add(dependentKey);
        }
      });

      return ComputedProperty.prototype.property.apply(this, propertyArgs.toArray());

    };

    
    function reduceComputed(options) {
      var args;

      if (arguments.length > 1) {
        args = a_slice.call(arguments, 0, -1);
        options = a_slice.call(arguments, -1)[0];
      }

      if (typeof options !== "object") {
        throw new EmberError("Reduce Computed Property declared without an options hash");
      }

      if (!('initialValue' in options)) {
        throw new EmberError("Reduce Computed Property declared without an initial value");
      }

      var cp = new ReduceComputedProperty(options);

      if (args) {
        cp.property.apply(cp, args);
      }

      return cp;
    }

    __exports__.reduceComputed = reduceComputed;
  });
define("ember-runtime/computed/reduce_computed_macros",
  ["ember-metal/core","ember-metal/merge","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/enumerable_utils","ember-metal/run_loop","ember-metal/observer","ember-runtime/computed/array_computed","ember-runtime/computed/reduce_computed","ember-runtime/system/object_proxy","ember-runtime/system/subarray","ember-runtime/keys","ember-runtime/compare","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.assert
    var merge = __dependency2__["default"];
    var get = __dependency3__.get;
    var set = __dependency4__.set;
    var isArray = __dependency5__.isArray;
    var guidFor = __dependency5__.guidFor;
    var EmberError = __dependency6__["default"];
    var forEach = __dependency7__.forEach;
    var run = __dependency8__["default"];
    var addObserver = __dependency9__.addObserver;
    var arrayComputed = __dependency10__.arrayComputed;
    var reduceComputed = __dependency11__.reduceComputed;
    var ObjectProxy = __dependency12__["default"];
    var SubArray = __dependency13__["default"];
    var keys = __dependency14__["default"];
    var compare = __dependency15__["default"];

    var a_slice = [].slice;

    

    function sum(dependentKey){
      return reduceComputed(dependentKey, {
        initialValue: 0,

        addedItem: function(accumulatedValue, item, changeMeta, instanceMeta){
          return accumulatedValue + item;
        },

        removedItem: function(accumulatedValue, item, changeMeta, instanceMeta){
          return accumulatedValue - item;
        }
      });
    }

    __exports__.sum = sum;
    function max (dependentKey) {
      return reduceComputed(dependentKey, {
        initialValue: -Infinity,

        addedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
          return Math.max(accumulatedValue, item);
        },

        removedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
          if (item < accumulatedValue) {
            return accumulatedValue;
          }
        }
      });
    }

    __exports__.max = max;
    function min(dependentKey) {
      return reduceComputed(dependentKey, {
        initialValue: Infinity,

        addedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
          return Math.min(accumulatedValue, item);
        },

        removedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
          if (item > accumulatedValue) {
            return accumulatedValue;
          }
        }
      });
    }

    __exports__.min = min;
    function map(dependentKey, callback) {
      var options = {
        addedItem: function(array, item, changeMeta, instanceMeta) {
          var mapped = callback.call(this, item);
          array.insertAt(changeMeta.index, mapped);
          return array;
        },
        removedItem: function(array, item, changeMeta, instanceMeta) {
          array.removeAt(changeMeta.index, 1);
          return array;
        }
      };

      return arrayComputed(dependentKey, options);
    }

    __exports__.map = map;
    function mapBy (dependentKey, propertyKey) {
      var callback = function(item) { return get(item, propertyKey); };
      return map(dependentKey + '.@each.' + propertyKey, callback);
    }

    __exports__.mapBy = mapBy;
    var mapProperty = mapBy;
    __exports__.mapProperty = mapProperty;
    
    function filter(dependentKey, callback) {
      var options = {
        initialize: function (array, changeMeta, instanceMeta) {
          instanceMeta.filteredArrayIndexes = new SubArray();
        },

        addedItem: function(array, item, changeMeta, instanceMeta) {
          var match = !!callback.call(this, item),
              filterIndex = instanceMeta.filteredArrayIndexes.addItem(changeMeta.index, match);

          if (match) {
            array.insertAt(filterIndex, item);
          }

          return array;
        },

        removedItem: function(array, item, changeMeta, instanceMeta) {
          var filterIndex = instanceMeta.filteredArrayIndexes.removeItem(changeMeta.index);

          if (filterIndex > -1) {
            array.removeAt(filterIndex);
          }

          return array;
        }
      };

      return arrayComputed(dependentKey, options);
    }

    __exports__.filter = filter;
    function filterBy (dependentKey, propertyKey, value) {
      var callback;

      if (arguments.length === 2) {
        callback = function(item) {
          return get(item, propertyKey);
        };
      } else {
        callback = function(item) {
          return get(item, propertyKey) === value;
        };
      }

      return filter(dependentKey + '.@each.' + propertyKey, callback);
    }

    __exports__.filterBy = filterBy;
    var filterProperty = filterBy;
    __exports__.filterProperty = filterProperty;
    
    function uniq() {
      var args = a_slice.call(arguments);
      args.push({
        initialize: function(array, changeMeta, instanceMeta) {
          instanceMeta.itemCounts = {};
        },

        addedItem: function(array, item, changeMeta, instanceMeta) {
          var guid = guidFor(item);

          if (!instanceMeta.itemCounts[guid]) {
            instanceMeta.itemCounts[guid] = 1;
          } else {
            ++instanceMeta.itemCounts[guid];
          }
          array.addObject(item);
          return array;
        },
        removedItem: function(array, item, _, instanceMeta) {
          var guid = guidFor(item),
              itemCounts = instanceMeta.itemCounts;

          if (--itemCounts[guid] === 0) {
            array.removeObject(item);
          }
          return array;
        }
      });
      return arrayComputed.apply(null, args);
    }

    __exports__.uniq = uniq;
    var union = uniq;
    __exports__.union = union;
    
    function intersect() {
      var args = a_slice.call(arguments);
      args.push({
        initialize: function (array, changeMeta, instanceMeta) {
          instanceMeta.itemCounts = {};
        },

        addedItem: function(array, item, changeMeta, instanceMeta) {
          var itemGuid = guidFor(item);
          var dependentGuid = guidFor(changeMeta.arrayChanged);
          var numberOfDependentArrays = changeMeta.property._dependentKeys.length;
          var itemCounts = instanceMeta.itemCounts;

          if (!itemCounts[itemGuid]) { itemCounts[itemGuid] = {}; }
          if (itemCounts[itemGuid][dependentGuid] === undefined) { itemCounts[itemGuid][dependentGuid] = 0; }

          if (++itemCounts[itemGuid][dependentGuid] === 1 &&
              numberOfDependentArrays === keys(itemCounts[itemGuid]).length) {

            array.addObject(item);
          }
          return array;
        },
        removedItem: function(array, item, changeMeta, instanceMeta) {
          var itemGuid = guidFor(item);
          var dependentGuid = guidFor(changeMeta.arrayChanged);
          var numberOfDependentArrays = changeMeta.property._dependentKeys.length;
          var numberOfArraysItemAppearsIn;
          var itemCounts = instanceMeta.itemCounts;

          if (itemCounts[itemGuid][dependentGuid] === undefined) {
            itemCounts[itemGuid][dependentGuid] = 0;
          }

          if (--itemCounts[itemGuid][dependentGuid] === 0) {
            delete itemCounts[itemGuid][dependentGuid];
            numberOfArraysItemAppearsIn = keys(itemCounts[itemGuid]).length;

            if (numberOfArraysItemAppearsIn === 0) {
              delete itemCounts[itemGuid];
            }
            array.removeObject(item);
          }
          return array;
        }
      });
      return arrayComputed.apply(null, args);
    }

    __exports__.intersect = intersect;
    function setDiff(setAProperty, setBProperty) {
      if (arguments.length !== 2) {
        throw new EmberError("setDiff requires exactly two dependent arrays.");
      }
      return arrayComputed(setAProperty, setBProperty, {
        addedItem: function (array, item, changeMeta, instanceMeta) {
          var setA = get(this, setAProperty),
              setB = get(this, setBProperty);

          if (changeMeta.arrayChanged === setA) {
            if (!setB.contains(item)) {
              array.addObject(item);
            }
          } else {
            array.removeObject(item);
          }
          return array;
        },

        removedItem: function (array, item, changeMeta, instanceMeta) {
          var setA = get(this, setAProperty),
              setB = get(this, setBProperty);

          if (changeMeta.arrayChanged === setB) {
            if (setA.contains(item)) {
              array.addObject(item);
            }
          } else {
            array.removeObject(item);
          }
          return array;
        }
      });
    }

    __exports__.setDiff = setDiff;function binarySearch(array, item, low, high) {
      var mid, midItem, res, guidMid, guidItem;

      if (arguments.length < 4) { high = get(array, 'length'); }
      if (arguments.length < 3) { low = 0; }

      if (low === high) {
        return low;
      }

      mid = low + Math.floor((high - low) / 2);
      midItem = array.objectAt(mid);

      guidMid = _guidFor(midItem);
      guidItem = _guidFor(item);

      if (guidMid === guidItem) {
        return mid;
      }

      res = this.order(midItem, item);
      if (res === 0) {
        res = guidMid < guidItem ? -1 : 1;
      }


      if (res < 0) {
        return this.binarySearch(array, item, mid+1, high);
      } else if (res > 0) {
        return this.binarySearch(array, item, low, mid);
      }

      return mid;

      function _guidFor(item) {
        if (SearchProxy.detectInstance(item)) {
          return guidFor(get(item, 'content'));
        }
        return guidFor(item);
      }
    }


    var SearchProxy = ObjectProxy.extend();

    
    function sort(itemsKey, sortDefinition) {
      Ember.assert("Ember.computed.sort requires two arguments: an array key to sort and either a sort properties key or sort function", arguments.length === 2);

      var initFn, sortPropertiesKey;

      if (typeof sortDefinition === 'function') {
        initFn = function (array, changeMeta, instanceMeta) {
          instanceMeta.order = sortDefinition;
          instanceMeta.binarySearch = binarySearch;
        };
      } else {
        sortPropertiesKey = sortDefinition;
        initFn = function (array, changeMeta, instanceMeta) {
          function setupSortProperties() {
            var sortPropertyDefinitions = get(this, sortPropertiesKey),
                sortProperty,
                sortProperties = instanceMeta.sortProperties = [],
                sortPropertyAscending = instanceMeta.sortPropertyAscending = {},
                idx,
                asc;

            Ember.assert("Cannot sort: '" + sortPropertiesKey + "' is not an array.", isArray(sortPropertyDefinitions));

            changeMeta.property.clearItemPropertyKeys(itemsKey);

            forEach(sortPropertyDefinitions, function (sortPropertyDefinition) {
              if ((idx = sortPropertyDefinition.indexOf(':')) !== -1) {
                sortProperty = sortPropertyDefinition.substring(0, idx);
                asc = sortPropertyDefinition.substring(idx+1).toLowerCase() !== 'desc';
              } else {
                sortProperty = sortPropertyDefinition;
                asc = true;
              }

              sortProperties.push(sortProperty);
              sortPropertyAscending[sortProperty] = asc;
              changeMeta.property.itemPropertyKey(itemsKey, sortProperty);
            });

            sortPropertyDefinitions.addObserver('@each', this, updateSortPropertiesOnce);
          }

          function updateSortPropertiesOnce() {
            run.once(this, updateSortProperties, changeMeta.propertyName);
          }

          function updateSortProperties(propertyName) {
            setupSortProperties.call(this);
            changeMeta.property.recomputeOnce.call(this, propertyName);
          }

          addObserver(this, sortPropertiesKey, updateSortPropertiesOnce);

          setupSortProperties.call(this);


          instanceMeta.order = function (itemA, itemB) {
            var isProxy = itemB instanceof SearchProxy,
                sortProperty, result, asc;

            for (var i = 0; i < this.sortProperties.length; ++i) {
              sortProperty = this.sortProperties[i];
              result = compare(get(itemA, sortProperty), isProxy ? itemB[sortProperty] : get(itemB, sortProperty));

              if (result !== 0) {
                asc = this.sortPropertyAscending[sortProperty];
                return asc ? result : (-1 * result);
              }
            }

            return 0;
          };

          instanceMeta.binarySearch = binarySearch;
        };
      }

      return arrayComputed(itemsKey, {
        initialize: initFn,

        addedItem: function (array, item, changeMeta, instanceMeta) {
          var index = instanceMeta.binarySearch(array, item);
          array.insertAt(index, item);
          return array;
        },

        removedItem: function (array, item, changeMeta, instanceMeta) {
          var proxyProperties, index, searchItem;

          if (changeMeta.previousValues) {
            proxyProperties = merge({ content: item }, changeMeta.previousValues);

            searchItem = SearchProxy.create(proxyProperties);
          } else {
            searchItem = item;
          }

          index = instanceMeta.binarySearch(array, searchItem);
          array.removeAt(index);
          return array;
        }
      });
    }

    __exports__.sort = sort;
  });
define("ember-runtime/controllers/array_controller",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/enumerable_utils","ember-runtime/system/array_proxy","ember-runtime/mixins/sortable","ember-runtime/mixins/controller","ember-metal/computed","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var forEach = __dependency4__.forEach;
    var replace = __dependency4__.replace;
    var ArrayProxy = __dependency5__["default"];
    var SortableMixin = __dependency6__["default"];
    var ControllerMixin = __dependency7__["default"];
    var computed = __dependency8__.computed;
    var EmberError = __dependency9__["default"];


    

    __exports__["default"] = ArrayProxy.extend(ControllerMixin, SortableMixin, {

      
      itemController: null,

      
      lookupItemController: function(object) {
        return get(this, 'itemController');
      },

      objectAtContent: function(idx) {
        var length = get(this, 'length');
        var arrangedContent = get(this, 'arrangedContent');
        var object = arrangedContent && arrangedContent.objectAt(idx);
        var controllerClass;

        if (idx >= 0 && idx < length) {
          controllerClass = this.lookupItemController(object);
          if (controllerClass) {
            return this.controllerAt(idx, object, controllerClass);
          }
        }

        // When `controllerClass` is falsy, we have not opted in to using item
        // controllers, so return the object directly.

        // When the index is out of range, we want to return the "out of range"
        // value, whatever that might be.  Rather than make assumptions
        // (e.g. guessing `null` or `undefined`) we defer this to `arrangedContent`.
        return object;
      },

      arrangedContentDidChange: function() {
        this._super();
        this._resetSubControllers();
      },

      arrayContentDidChange: function(idx, removedCnt, addedCnt) {
        var subControllers = this._subControllers;

        if (subControllers.length) {
          var subControllersToRemove = subControllers.slice(idx, idx + removedCnt);

          forEach(subControllersToRemove, function(subController) {
            if (subController) {
              subController.destroy();
            }
          });

          replace(subControllers, idx, removedCnt, new Array(addedCnt));
        }

        // The shadow array of subcontrollers must be updated before we trigger
        // observers, otherwise observers will get the wrong subcontainer when
        // calling `objectAt`
        this._super(idx, removedCnt, addedCnt);
      },

      init: function() {
        this._super();
        this._subControllers = [];
      },

      model: computed(function () {
        return Ember.A();
      }),

      
      _isVirtual: false,

      controllerAt: function(idx, object, controllerClass) {
        var fullName, subController, parentController;

        var container = get(this, 'container');
        var subControllers = this._subControllers;

        if (subControllers.length > idx) {
          subController = subControllers[idx];

          if (subController) {
            return subController;
          }
        }

        fullName = 'controller:' + controllerClass;

        if (!container.has(fullName)) {
          throw new EmberError('Could not resolve itemController: "' + controllerClass + '"');
        }

        if (this._isVirtual) {
          parentController = get(this, 'parentController');
        } else {
          parentController = this;
        }

        subController = container.lookupFactory(fullName).create({
          target: parentController,
          parentController: parentController,
          model: object
        });

        subControllers[idx] = subController;

        return subController;
      },

      _subControllers: null,

      _resetSubControllers: function() {
        var controller;
        var subControllers = this._subControllers;

        if (subControllers.length) {
          for (var i = 0, length = subControllers.length; length > i; i++) {
            controller = subControllers[i];
            if (controller) {
              controller.destroy();
            }
          }

          subControllers.length = 0;
        }
      },

      willDestroy: function() {
        this._resetSubControllers();
        this._super();
      }
    });
  });
define("ember-runtime/controllers/controller",
  ["ember-runtime/system/object","ember-runtime/mixins/controller","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var EmberObject = __dependency1__["default"];
    var Mixin = __dependency2__["default"];

    

    
    __exports__["default"] = EmberObject.extend(Mixin);
  });
define("ember-runtime/controllers/object_controller",
  ["ember-runtime/mixins/controller","ember-runtime/system/object_proxy","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var ControllerMixin = __dependency1__["default"];
    var ObjectProxy = __dependency2__["default"];

    

    
    __exports__["default"] = ObjectProxy.extend(ControllerMixin);
  });
define("ember-runtime/copy",
  ["ember-metal/enumerable_utils","ember-metal/utils","ember-runtime/system/object","ember-runtime/mixins/copyable","ember-metal/platform","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    var indexOf = __dependency1__.indexOf;
    var typeOf = __dependency2__.typeOf;
    var EmberObject = __dependency3__["default"];
    var Copyable = __dependency4__["default"];
    var create = __dependency5__.create;

    function _copy(obj, deep, seen, copies) {
      var ret, loc, key;

      // primitive data types are immutable, just return them.
      if ('object' !== typeof obj || obj===null) return obj;

      // avoid cyclical loops
      if (deep && (loc=indexOf(seen, obj))>=0) return copies[loc];

      Ember.assert('Cannot clone an Ember.Object that does not implement Ember.Copyable', !(obj instanceof EmberObject) || (Copyable && Copyable.detect(obj)));

      // IMPORTANT: this specific test will detect a native array only. Any other
      // object will need to implement Copyable.
      if (typeOf(obj) === 'array') {
        ret = obj.slice();
        if (deep) {
          loc = ret.length;
          while(--loc>=0) ret[loc] = _copy(ret[loc], deep, seen, copies);
        }
      } else if (Copyable && Copyable.detect(obj)) {
        ret = obj.copy(deep, seen, copies);
      } else if (obj instanceof Date) {
        ret = new Date(obj.getTime());
      } else {
        ret = {};
        for(key in obj) {
          if (!obj.hasOwnProperty(key)) continue;

          // Prevents browsers that don't respect non-enumerability from
          // copying internal Ember properties
          if (key.substring(0,2) === '__') continue;

          ret[key] = deep ? _copy(obj[key], deep, seen, copies) : obj[key];
        }
      }

      if (deep) {
        seen.push(obj);
        copies.push(ret);
      }

      return ret;
    }

    
    __exports__["default"] = function copy(obj, deep) {
      // fast paths
      if ('object' !== typeof obj || obj === null) return obj; // can't copy primitives
      if (Copyable && Copyable.detect(obj)) return obj.copy(deep);
      return _copy(obj, deep, deep ? [] : null, deep ? [] : null);
    }
  });
define("ember-runtime/core",
  ["exports"],
  function(__exports__) {
    "use strict";
    

    
    var isEqual = function isEqual(a, b) {
      if (a && 'function'===typeof a.isEqual) return a.isEqual(b);
      if (a instanceof Date && b instanceof Date) {
        return a.getTime() === b.getTime();
      }
      return a === b;
    };
    __exports__.isEqual = isEqual;
  });
define("ember-runtime/ext/function",
  ["ember-metal/core","ember-metal/expand_properties","ember-metal/computed"],
  function(__dependency1__, __dependency2__, __dependency3__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.EXTEND_PROTOTYPES, Ember.assert
    var expandProperties = __dependency2__["default"];
    var computed = __dependency3__.computed;

    var a_slice = Array.prototype.slice;
    var FunctionPrototype = Function.prototype;

    if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) {

      
      FunctionPrototype.property = function() {
        var ret = computed(this);
        // ComputedProperty.prototype.property expands properties; no need for us to
        // do so here.
        return ret.property.apply(ret, arguments);
      };

      
      FunctionPrototype.observes = function() {
        var addWatchedProperty = function (obs) { watched.push(obs); };
        var watched = [];

        for (var i=0; i<arguments.length; ++i) {
          expandProperties(arguments[i], addWatchedProperty);
        }

        this.__ember_observes__ = watched;

        return this;
      };

      
      FunctionPrototype.observesImmediately = function() {
        for (var i=0, l=arguments.length; i<l; i++) {
          var arg = arguments[i];
          Ember.assert("Immediate observers must observe internal properties only, not properties on other objects.", arg.indexOf('.') === -1);
        }

        // observes handles property expansion
        return this.observes.apply(this, arguments);
      };

      
      FunctionPrototype.observesBefore = function() {
        var addWatchedProperty = function (obs) { watched.push(obs); };
        var watched = [];

        for (var i=0; i<arguments.length; ++i) {
          expandProperties(arguments[i], addWatchedProperty);
        }

        this.__ember_observesBefore__ = watched;

        return this;
      };

      
      FunctionPrototype.on = function() {
        var events = a_slice.call(arguments);
        this.__ember_listens__ = events;
        return this;
      };
    }
  });
define("ember-runtime/ext/rsvp",
  ["ember-metal/core","ember-metal/logger","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    var Logger = __dependency2__["default"];

    var RSVP = requireModule("rsvp");
    var Test, testModuleName = 'ember-testing/test';

    RSVP.onerrorDefault = function(error) {
      if (error instanceof Error) {
        if (Ember.testing) {
          // ES6TODO: remove when possible
          if (!Test && Ember.__loader.registry[testModuleName]) {
            Test = requireModule(testModuleName)['default'];
          }

          if (Test && Test.adapter) {
            Test.adapter.exception(error);
          } else {
            throw error;
          }
        } else if (Ember.onerror) {
          Ember.onerror(error);
        } else {
          Logger.error(error.stack);
          Ember.assert(error, false);
        }
      }
    };

    RSVP.on('error', RSVP.onerrorDefault);

    __exports__["default"] = RSVP;
  });
define("ember-runtime/ext/string",
  ["ember-metal/core","ember-runtime/system/string"],
  function(__dependency1__, __dependency2__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.EXTEND_PROTOTYPES, Ember.assert, Ember.FEATURES
    var fmt = __dependency2__.fmt;
    var w = __dependency2__.w;
    var loc = __dependency2__.loc;
    var camelize = __dependency2__.camelize;
    var decamelize = __dependency2__.decamelize;
    var dasherize = __dependency2__.dasherize;
    var underscore = __dependency2__.underscore;
    var capitalize = __dependency2__.capitalize;
    var classify = __dependency2__.classify;

    var StringPrototype = String.prototype;

    if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {

      
      StringPrototype.fmt = function() {
        return fmt(this, arguments);
      };

      
      StringPrototype.w = function() {
        return w(this);
      };

      
      StringPrototype.loc = function() {
        return loc(this, arguments);
      };

      
      StringPrototype.camelize = function() {
        return camelize(this);
      };

      
      StringPrototype.decamelize = function() {
        return decamelize(this);
      };

      
      StringPrototype.dasherize = function() {
        return dasherize(this);
      };

      
      StringPrototype.underscore = function() {
        return underscore(this);
      };

      
      StringPrototype.classify = function() {
        return classify(this);
      };

      
      StringPrototype.capitalize = function() {
        return capitalize(this);
      };
    }
  });
define("ember-runtime/keys",
  ["ember-metal/enumerable_utils","ember-metal/platform","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var EnumerableUtils = __dependency1__["default"];
    var create = __dependency2__.create;

    
    var keys = Object.keys;
    if (!keys || create.isSimulated) {
      var prototypeProperties = [
        'constructor',
        'hasOwnProperty',
        'isPrototypeOf',
        'propertyIsEnumerable',
        'valueOf',
        'toLocaleString',
        'toString'
      ],
      pushPropertyName = function(obj, array, key) {
        // Prevents browsers that don't respect non-enumerability from
        // copying internal Ember properties
        if (key.substring(0,2) === '__') return;
        if (key === '_super') return;
        if (EnumerableUtils.indexOf(array, key) >= 0) return;
        if (!Object.prototype.hasOwnProperty.call(obj, key)) return;

        array.push(key);
      };

      keys = function keys(obj) {
        var ret = [], key;
        for (key in obj) {
          pushPropertyName(obj, ret, key);
        }

        // IE8 doesn't enumerate property that named the same as prototype properties.
        for (var i = 0, l = prototypeProperties.length; i < l; i++) {
          key = prototypeProperties[i];

          pushPropertyName(obj, ret, key);
        }

        return ret;
      };
    }

    __exports__["default"] = keys;
  });
define("ember-runtime/mixins/action_handler",
  ["ember-metal/merge","ember-metal/mixin","ember-metal/property_get","ember-metal/utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    
    var merge = __dependency1__["default"];
    var Mixin = __dependency2__.Mixin;
    var get = __dependency3__.get;
    var typeOf = __dependency4__.typeOf;

    
    var ActionHandler = Mixin.create({
      mergedProperties: ['_actions'],

      

      
      willMergeMixin: function(props) {
        var hashName;

        if (!props._actions) {
          Ember.assert("'actions' should not be a function", typeof(props.actions) !== 'function');

          if (typeOf(props.actions) === 'object') {
            hashName = 'actions';
          } else if (typeOf(props.events) === 'object') {
            Ember.deprecate('Action handlers contained in an `events` object are deprecated in favor of putting them in an `actions` object', false);
            hashName = 'events';
          }

          if (hashName) {
            props._actions = merge(props._actions || {}, props[hashName]);
          }

          delete props[hashName];
        }
      },

      
      send: function(actionName) {
        var args = [].slice.call(arguments, 1), target;

        if (this._actions && this._actions[actionName]) {
          if (this._actions[actionName].apply(this, args) === true) {
            // handler returned true, so this action will bubble
          } else {
            return;
          }
        } else if (!Ember.FEATURES.isEnabled('ember-routing-drop-deprecated-action-style') && this.deprecatedSend && this.deprecatedSendHandles && this.deprecatedSendHandles(actionName)) {
          Ember.warn("The current default is deprecated but will prefer to handle actions directly on the controller instead of a similarly named action in the actions hash. To turn off this deprecated feature set: Ember.FEATURES['ember-routing-drop-deprecated-action-style'] = true");
          if (this.deprecatedSend.apply(this, [].slice.call(arguments)) === true) {
            // handler return true, so this action will bubble
          } else {
            return;
          }
        }

        if (target = get(this, 'target')) {
          Ember.assert("The `target` for " + this + " (" + target + ") does not have a `send` method", typeof target.send === 'function');
          target.send.apply(target, arguments);
        }
      }
    });

    __exports__["default"] = ActionHandler;
  });
define("ember-runtime/mixins/array",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/is_none","ember-runtime/mixins/enumerable","ember-metal/enumerable_utils","ember-metal/mixin","ember-metal/property_events","ember-metal/events","ember-metal/watching","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) {
    "use strict";
    

    // ..........................................................
    // HELPERS
    //
    var Ember = __dependency1__["default"];
    // ES6TODO: Ember.A

    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var computed = __dependency4__.computed;
    var cacheFor = __dependency4__.cacheFor;
    var isNone = __dependency5__.isNone;
    var none = __dependency5__.none;
    var Enumerable = __dependency6__["default"];
    var map = __dependency7__.map;
    var Mixin = __dependency8__.Mixin;
    var required = __dependency8__.required;
    var propertyWillChange = __dependency9__.propertyWillChange;
    var propertyDidChange = __dependency9__.propertyDidChange;
    var addListener = __dependency10__.addListener;
    var removeListener = __dependency10__.removeListener;
    var sendEvent = __dependency10__.sendEvent;
    var hasListeners = __dependency10__.hasListeners;
    var isWatching = __dependency11__.isWatching;

    // ..........................................................
    // ARRAY
    //
    
    __exports__["default"] = Mixin.create(Enumerable, {

      
      length: required(),

      
      objectAt: function(idx) {
        if ((idx < 0) || (idx >= get(this, 'length'))) return undefined;
        return get(this, idx);
      },

      
      objectsAt: function(indexes) {
        var self = this;
        return map(indexes, function(idx) { return self.objectAt(idx); });
      },

      // overrides Ember.Enumerable version
      nextObject: function(idx) {
        return this.objectAt(idx);
      },

      
      '[]': computed(function(key, value) {
        if (value !== undefined) this.replace(0, get(this, 'length'), value) ;
        return this ;
      }),

      firstObject: computed(function() {
        return this.objectAt(0);
      }),

      lastObject: computed(function() {
        return this.objectAt(get(this, 'length')-1);
      }),

      // optimized version from Enumerable
      contains: function(obj) {
        return this.indexOf(obj) >= 0;
      },

      // Add any extra methods to Ember.Array that are native to the built-in Array.
      
      slice: function(beginIndex, endIndex) {
        var ret = Ember.A();
        var length = get(this, 'length') ;
        if (isNone(beginIndex)) beginIndex = 0 ;
        if (isNone(endIndex) || (endIndex > length)) endIndex = length ;

        if (beginIndex < 0) beginIndex = length + beginIndex;
        if (endIndex < 0) endIndex = length + endIndex;

        while(beginIndex < endIndex) {
          ret[ret.length] = this.objectAt(beginIndex++) ;
        }
        return ret ;
      },

      
      indexOf: function(object, startAt) {
        var idx, len = get(this, 'length');

        if (startAt === undefined) startAt = 0;
        if (startAt < 0) startAt += len;

        for(idx = startAt; idx < len; idx++) {
          if (this.objectAt(idx) === object) return idx;
        }
        return -1;
      },

      
      lastIndexOf: function(object, startAt) {
        var idx, len = get(this, 'length');

        if (startAt === undefined || startAt >= len) startAt = len-1;
        if (startAt < 0) startAt += len;

        for(idx = startAt; idx >= 0; idx--) {
          if (this.objectAt(idx) === object) return idx;
        }
        return -1;
      },

      // ..........................................................
      // ARRAY OBSERVERS
      //

      
      addArrayObserver: function(target, opts) {
        var willChange = (opts && opts.willChange) || 'arrayWillChange',
            didChange  = (opts && opts.didChange) || 'arrayDidChange';

        var hasObservers = get(this, 'hasArrayObservers');
        if (!hasObservers) propertyWillChange(this, 'hasArrayObservers');
        addListener(this, '@array:before', target, willChange);
        addListener(this, '@array:change', target, didChange);
        if (!hasObservers) propertyDidChange(this, 'hasArrayObservers');
        return this;
      },

      
      removeArrayObserver: function(target, opts) {
        var willChange = (opts && opts.willChange) || 'arrayWillChange',
            didChange  = (opts && opts.didChange) || 'arrayDidChange';

        var hasObservers = get(this, 'hasArrayObservers');
        if (hasObservers) propertyWillChange(this, 'hasArrayObservers');
        removeListener(this, '@array:before', target, willChange);
        removeListener(this, '@array:change', target, didChange);
        if (hasObservers) propertyDidChange(this, 'hasArrayObservers');
        return this;
      },

      
      hasArrayObservers: computed(function() {
        return hasListeners(this, '@array:change') || hasListeners(this, '@array:before');
      }),

      
      arrayContentWillChange: function(startIdx, removeAmt, addAmt) {

        // if no args are passed assume everything changes
        if (startIdx===undefined) {
          startIdx = 0;
          removeAmt = addAmt = -1;
        } else {
          if (removeAmt === undefined) removeAmt=-1;
          if (addAmt    === undefined) addAmt=-1;
        }

        // Make sure the @each proxy is set up if anyone is observing @each
        if (isWatching(this, '@each')) { get(this, '@each'); }

        sendEvent(this, '@array:before', [this, startIdx, removeAmt, addAmt]);

        var removing, lim;
        if (startIdx>=0 && removeAmt>=0 && get(this, 'hasEnumerableObservers')) {
          removing = [];
          lim = startIdx+removeAmt;
          for(var idx=startIdx;idx<lim;idx++) removing.push(this.objectAt(idx));
        } else {
          removing = removeAmt;
        }

        this.enumerableContentWillChange(removing, addAmt);

        return this;
      },

      
      arrayContentDidChange: function(startIdx, removeAmt, addAmt) {

        // if no args are passed assume everything changes
        if (startIdx===undefined) {
          startIdx = 0;
          removeAmt = addAmt = -1;
        } else {
          if (removeAmt === undefined) removeAmt=-1;
          if (addAmt    === undefined) addAmt=-1;
        }

        var adding, lim;
        if (startIdx>=0 && addAmt>=0 && get(this, 'hasEnumerableObservers')) {
          adding = [];
          lim = startIdx+addAmt;
          for(var idx=startIdx;idx<lim;idx++) adding.push(this.objectAt(idx));
        } else {
          adding = addAmt;
        }

        this.enumerableContentDidChange(removeAmt, adding);
        sendEvent(this, '@array:change', [this, startIdx, removeAmt, addAmt]);

        var length      = get(this, 'length'),
            cachedFirst = cacheFor(this, 'firstObject'),
            cachedLast  = cacheFor(this, 'lastObject');
        if (this.objectAt(0) !== cachedFirst) {
          propertyWillChange(this, 'firstObject');
          propertyDidChange(this, 'firstObject');
        }
        if (this.objectAt(length-1) !== cachedLast) {
          propertyWillChange(this, 'lastObject');
          propertyDidChange(this, 'lastObject');
        }

        return this;
      },

      // ..........................................................
      // ENUMERATED PROPERTIES
      //

      
      '@each': computed(function() {
        if (!this.__each) {
          // ES6TODO: GRRRRR
          var EachProxy = requireModule('ember-runtime/system/each_proxy')['EachProxy'];

          this.__each = new EachProxy(this);
        }

        return this.__each;
      })
    });
  });
define("ember-runtime/mixins/comparable",
  ["ember-metal/mixin","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Mixin = __dependency1__.Mixin;
    var required = __dependency1__.required;

    

    
    __exports__["default"] = Mixin.create({

      
      compare: required(Function)
    });
  });
define("ember-runtime/mixins/controller",
  ["ember-metal/core","ember-metal/property_get","ember-runtime/system/object","ember-metal/mixin","ember-metal/computed","ember-runtime/mixins/action_handler","ember-runtime/mixins/controller_content_model_alias_deprecation","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.assert, Ember.deprecate
    var get = __dependency2__.get;
    var EmberObject = __dependency3__["default"];
    var Mixin = __dependency4__.Mixin;
    var computed = __dependency5__.computed;
    var ActionHandler = __dependency6__["default"];
    var ControllerContentModelAliasDeprecation = __dependency7__["default"];

    
    __exports__["default"] = Mixin.create(ActionHandler, ControllerContentModelAliasDeprecation, {
      
      isController: true,

      
      target: null,

      container: null,

      parentController: null,

      store: null,

      
      model: null,

      
      content: computed.alias('model'),

      deprecatedSendHandles: function(actionName) {
        return !!this[actionName];
      },

      deprecatedSend: function(actionName) {
        var args = [].slice.call(arguments, 1);
        Ember.assert('' + this + " has the action " + actionName + " but it is not a function", typeof this[actionName] === 'function');
        Ember.deprecate('Action handlers implemented directly on controllers are deprecated in favor of action handlers on an `actions` object ( action: `' + actionName + '` on ' + this + ')', false);
        this[actionName].apply(this, args);
        return;
      }
    });
  });
define("ember-runtime/mixins/controller_content_model_alias_deprecation",
  ["ember-metal/core","ember-metal/property_get","ember-metal/mixin","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.deprecate
    var get = __dependency2__.get;
    var Mixin = __dependency3__.Mixin;

    
    __exports__["default"] = Mixin.create({
      
      willMergeMixin: function(props) {
        // Calling super is only OK here since we KNOW that
        // there is another Mixin loaded first.
        this._super.apply(this, arguments);

        var modelSpecified = !!props.model;

        if (props.content && !modelSpecified) {
          props.model = props.content;
          delete props['content'];

          Ember.deprecate('Do not specify `content` on a Controller, use `model` instead.', false);
        }
      }
    });
  });
define("ember-runtime/mixins/copyable",
  ["ember-metal/property_get","ember-metal/property_set","ember-metal/mixin","ember-runtime/mixins/freezable","ember-runtime/system/string","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    


    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var required = __dependency3__.required;
    var Freezable = __dependency4__.Freezable;
    var Mixin = __dependency3__.Mixin;
    var fmt = __dependency5__.fmt;
    var EmberError = __dependency6__["default"];


    
    __exports__["default"] = Mixin.create({
      
      copy: required(Function),

      
      frozenCopy: function() {
        if (Freezable && Freezable.detect(this)) {
          return get(this, 'isFrozen') ? this : this.copy().freeze();
        } else {
          throw new EmberError(fmt("%@ does not support freezing", [this]));
        }
      }
    });
  });
define("ember-runtime/mixins/deferred",
  ["ember-metal/core","ember-metal/property_get","ember-metal/mixin","ember-metal/computed","ember-metal/run_loop","ember-runtime/ext/rsvp","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.FEATURES, Ember.Test
    var get = __dependency2__.get;
    var Mixin = __dependency3__.Mixin;
    var computed = __dependency4__.computed;
    var run = __dependency5__["default"];
    var RSVP = __dependency6__["default"];

    var asyncStart = function() {
      if (Ember.Test && Ember.Test.adapter) {
        Ember.Test.adapter.asyncStart();
      }
    };

    var asyncEnd = function() {
      if (Ember.Test && Ember.Test.adapter) {
        Ember.Test.adapter.asyncEnd();
      }
    };

    RSVP.configure('async', function(callback, promise) {
      var async = !run.currentRunLoop;

      if (Ember.testing && async) { asyncStart(); }

      run.backburner.schedule('actions', function(){
        if (Ember.testing && async) { asyncEnd(); }
        callback(promise);
      });
    });

    RSVP.Promise.prototype.fail = function(callback, label){
      Ember.deprecate('RSVP.Promise.fail has been renamed as RSVP.Promise.catch');
      return this['catch'](callback, label);
    };

    


    
    __exports__["default"] = Mixin.create({
      
      then: function(resolve, reject, label) {
        var deferred, promise, entity;

        entity = this;
        deferred = get(this, '_deferred');
        promise = deferred.promise;

        function fulfillmentHandler(fulfillment) {
          if (fulfillment === promise) {
            return resolve(entity);
          } else {
            return resolve(fulfillment);
          }
        }

        return promise.then(resolve && fulfillmentHandler, reject, label);
      },

      
      resolve: function(value) {
        var deferred, promise;

        deferred = get(this, '_deferred');
        promise = deferred.promise;

        if (value === this) {
          deferred.resolve(promise);
        } else {
          deferred.resolve(value);
        }
      },

      
      reject: function(value) {
        get(this, '_deferred').reject(value);
      },

      _deferred: computed(function() {
        Ember.deprecate('Usage of Ember.DeferredMixin or Ember.Deferred is deprecated.', this._suppressDeferredDeprecation);

        return RSVP.defer('Ember: DeferredMixin - ' + this);
      })
    });
  });
define("ember-runtime/mixins/enumerable",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/mixin","ember-metal/enumerable_utils","ember-metal/computed","ember-metal/property_events","ember-metal/events","ember-runtime/compare","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) {
    "use strict";
    

    // ..........................................................
    // HELPERS
    //

    var Ember = __dependency1__["default"];
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var apply = __dependency4__.apply;
    var Mixin = __dependency5__.Mixin;
    var required = __dependency5__.required;
    var aliasMethod = __dependency5__.aliasMethod;
    var indexOf = __dependency6__.indexOf;
    var computed = __dependency7__.computed;
    var propertyWillChange = __dependency8__.propertyWillChange;
    var propertyDidChange = __dependency8__.propertyDidChange;
    var addListener = __dependency9__.addListener;
    var removeListener = __dependency9__.removeListener;
    var sendEvent = __dependency9__.sendEvent;
    var hasListeners = __dependency9__.hasListeners;
    var compare = __dependency10__["default"];

    var a_slice = Array.prototype.slice;

    var contexts = [];

    function popCtx() {
      return contexts.length===0 ? {} : contexts.pop();
    }

    function pushCtx(ctx) {
      contexts.push(ctx);
      return null;
    }

    function iter(key, value) {
      var valueProvided = arguments.length === 2;

      function i(item) {
        var cur = get(item, key);
        return valueProvided ? value===cur : !!cur;
      }

      return i;
    }

    
    __exports__["default"] = Mixin.create({

      
      nextObject: required(Function),

      
      firstObject: computed('[]', function() {
        if (get(this, 'length')===0) return undefined ;

        // handle generic enumerables
        var context = popCtx(), ret;
        ret = this.nextObject(0, null, context);
        pushCtx(context);
        return ret;
      }),

      
      lastObject: computed('[]', function() {
        var len = get(this, 'length');
        if (len===0) return undefined ;
        var context = popCtx(), idx=0, cur, last = null;
        do {
          last = cur;
          cur = this.nextObject(idx++, last, context);
        } while (cur !== undefined);
        pushCtx(context);
        return last;
      }),

      
      contains: function(obj) {
        return this.find(function(item) { return item===obj; }) !== undefined;
      },

      
      forEach: function(callback, target) {
        if (typeof callback !== 'function') throw new TypeError() ;
        var len = get(this, 'length'), last = null, context = popCtx();

        if (target === undefined) target = null;

        for(var idx=0;idx<len;idx++) {
          var next = this.nextObject(idx, last, context) ;
          callback.call(target, next, idx, this);
          last = next ;
        }
        last = null ;
        context = pushCtx(context);
        return this ;
      },

      
      getEach: function(key) {
        return this.mapBy(key);
      },

      
      setEach: function(key, value) {
        return this.forEach(function(item) {
          set(item, key, value);
        });
      },

      
      map: function(callback, target) {
        var ret = Ember.A();
        this.forEach(function(x, idx, i) {
          ret[idx] = callback.call(target, x, idx,i);
        });
        return ret ;
      },

      
      mapBy: function(key) {
        return this.map(function(next) {
          return get(next, key);
        });
      },

      

      mapProperty: aliasMethod('mapBy'),

      
      filter: function(callback, target) {
        var ret = Ember.A();
        this.forEach(function(x, idx, i) {
          if (callback.call(target, x, idx, i)) ret.push(x);
        });
        return ret ;
      },

      
      reject: function(callback, target) {
        return this.filter(function() {
          return !(apply(target, callback, arguments));
        });
      },

      
      filterBy: function(key, value) {
        return this.filter(apply(this, iter, arguments));
      },

      
      filterProperty: aliasMethod('filterBy'),

      
      rejectBy: function(key, value) {
        var exactValue = function(item) { return get(item, key) === value; },
            hasValue = function(item) { return !!get(item, key); },
            use = (arguments.length === 2 ? exactValue : hasValue);

        return this.reject(use);
      },

      
      rejectProperty: aliasMethod('rejectBy'),

      
      find: function(callback, target) {
        var len = get(this, 'length') ;
        if (target === undefined) target = null;

        var last = null, next, found = false, ret ;
        var context = popCtx();
        for(var idx=0;idx<len && !found;idx++) {
          next = this.nextObject(idx, last, context) ;
          if (found = callback.call(target, next, idx, this)) ret = next ;
          last = next ;
        }
        next = last = null ;
        context = pushCtx(context);
        return ret ;
      },

      
      findBy: function(key, value) {
        return this.find(apply(this, iter, arguments));
      },

      
      findProperty: aliasMethod('findBy'),

      
      every: function(callback, target) {
        return !this.find(function(x, idx, i) {
          return !callback.call(target, x, idx, i);
        });
      },

      
      everyBy: aliasMethod('isEvery'),

      
      everyProperty: aliasMethod('isEvery'),

      
      isEvery: function(key, value) {
        return this.every(apply(this, iter, arguments));
      },

      
      any: function(callback, target) {
        var len     = get(this, 'length'),
            context = popCtx(),
            found   = false,
            last    = null,
            next, idx;

        if (target === undefined) { target = null; }

        for (idx = 0; idx < len && !found; idx++) {
          next  = this.nextObject(idx, last, context);
          found = callback.call(target, next, idx, this);
          last  = next;
        }

        next = last = null;
        context = pushCtx(context);
        return found;
      },

      
      some: aliasMethod('any'),

      
      isAny: function(key, value) {
        return this.any(apply(this, iter, arguments));
      },

      
      anyBy: aliasMethod('isAny'),

      
      someProperty: aliasMethod('isAny'),

      
      reduce: function(callback, initialValue, reducerProperty) {
        if (typeof callback !== "function") { throw new TypeError(); }

        var ret = initialValue;

        this.forEach(function(item, i) {
          ret = callback(ret, item, i, this, reducerProperty);
        }, this);

        return ret;
      },

      
      invoke: function(methodName) {
        var args, ret = Ember.A();
        if (arguments.length>1) args = a_slice.call(arguments, 1);

        this.forEach(function(x, idx) {
          var method = x && x[methodName];
          if ('function' === typeof method) {
            ret[idx] = args ? apply(x, method, args) : x[methodName]();
          }
        }, this);

        return ret;
      },

      
      toArray: function() {
        var ret = Ember.A();
        this.forEach(function(o, idx) { ret[idx] = o; });
        return ret;
      },

      
      compact: function() {
        return this.filter(function(value) { return value != null; });
      },

      
      without: function(value) {
        if (!this.contains(value)) return this; // nothing to do
        var ret = Ember.A();
        this.forEach(function(k) {
          if (k !== value) ret[ret.length] = k;
        }) ;
        return ret ;
      },

      
      uniq: function() {
        var ret = Ember.A();
        this.forEach(function(k) {
          if (indexOf(ret, k)<0) ret.push(k);
        });
        return ret;
      },

      
      '[]': computed(function(key, value) {
        return this;
      }),

      // ..........................................................
      // ENUMERABLE OBSERVERS
      //

      
      addEnumerableObserver: function(target, opts) {
        var willChange = (opts && opts.willChange) || 'enumerableWillChange',
            didChange  = (opts && opts.didChange) || 'enumerableDidChange';

        var hasObservers = get(this, 'hasEnumerableObservers');
        if (!hasObservers) propertyWillChange(this, 'hasEnumerableObservers');
        addListener(this, '@enumerable:before', target, willChange);
        addListener(this, '@enumerable:change', target, didChange);
        if (!hasObservers) propertyDidChange(this, 'hasEnumerableObservers');
        return this;
      },

      
      removeEnumerableObserver: function(target, opts) {
        var willChange = (opts && opts.willChange) || 'enumerableWillChange',
            didChange  = (opts && opts.didChange) || 'enumerableDidChange';

        var hasObservers = get(this, 'hasEnumerableObservers');
        if (hasObservers) propertyWillChange(this, 'hasEnumerableObservers');
        removeListener(this, '@enumerable:before', target, willChange);
        removeListener(this, '@enumerable:change', target, didChange);
        if (hasObservers) propertyDidChange(this, 'hasEnumerableObservers');
        return this;
      },

      
      hasEnumerableObservers: computed(function() {
        return hasListeners(this, '@enumerable:change') || hasListeners(this, '@enumerable:before');
      }),


      
      enumerableContentWillChange: function(removing, adding) {

        var removeCnt, addCnt, hasDelta;

        if ('number' === typeof removing) removeCnt = removing;
        else if (removing) removeCnt = get(removing, 'length');
        else removeCnt = removing = -1;

        if ('number' === typeof adding) addCnt = adding;
        else if (adding) addCnt = get(adding,'length');
        else addCnt = adding = -1;

        hasDelta = addCnt<0 || removeCnt<0 || addCnt-removeCnt!==0;

        if (removing === -1) removing = null;
        if (adding   === -1) adding   = null;

        propertyWillChange(this, '[]');
        if (hasDelta) propertyWillChange(this, 'length');
        sendEvent(this, '@enumerable:before', [this, removing, adding]);

        return this;
      },

      
      enumerableContentDidChange: function(removing, adding) {
        var removeCnt, addCnt, hasDelta;

        if ('number' === typeof removing) removeCnt = removing;
        else if (removing) removeCnt = get(removing, 'length');
        else removeCnt = removing = -1;

        if ('number' === typeof adding) addCnt = adding;
        else if (adding) addCnt = get(adding, 'length');
        else addCnt = adding = -1;

        hasDelta = addCnt<0 || removeCnt<0 || addCnt-removeCnt!==0;

        if (removing === -1) removing = null;
        if (adding   === -1) adding   = null;

        sendEvent(this, '@enumerable:change', [this, removing, adding]);
        if (hasDelta) propertyDidChange(this, 'length');
        propertyDidChange(this, '[]');

        return this ;
      },

      
      sortBy: function() {
        var sortKeys = arguments;
        return this.toArray().sort(function(a, b){
          for(var i = 0; i < sortKeys.length; i++) {
            var key = sortKeys[i],
            propA = get(a, key),
            propB = get(b, key);
            // return 1 or -1 else continue to the next sortKey
            var compareValue = compare(propA, propB);
            if (compareValue) { return compareValue; }
          }
          return 0;
        });
      }
    });
  });
define("ember-runtime/mixins/evented",
  ["ember-metal/mixin","ember-metal/events","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Mixin = __dependency1__.Mixin;
    var addListener = __dependency2__.addListener;
    var removeListener = __dependency2__.removeListener;
    var hasListeners = __dependency2__.hasListeners;
    var sendEvent = __dependency2__.sendEvent;

    

    
    __exports__["default"] = Mixin.create({

      
      on: function(name, target, method) {
        addListener(this, name, target, method);
        return this;
      },

      
      one: function(name, target, method) {
        if (!method) {
          method = target;
          target = null;
        }

        addListener(this, name, target, method, true);
        return this;
      },

      
      trigger: function(name) {
        var length = arguments.length;
        var args = new Array(length - 1);

        for (var i = 1; i < length; i++) {
          args[i - 1] = arguments[i];
        }

        sendEvent(this, name, args);
      },

      
      off: function(name, target, method) {
        removeListener(this, name, target, method);
        return this;
      },

      
      has: function(name) {
        return hasListeners(this, name);
      }
    });
  });
define("ember-runtime/mixins/freezable",
  ["ember-metal/mixin","ember-metal/property_get","ember-metal/property_set","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    

    var Mixin = __dependency1__.Mixin;
    var get = __dependency2__.get;
    var set = __dependency3__.set;

    
    var Freezable = Mixin.create({

      
      isFrozen: false,

      
      freeze: function() {
        if (get(this, 'isFrozen')) return this;
        set(this, 'isFrozen', true);
        return this;
      }

    });
    __exports__.Freezable = Freezable;
    var FROZEN_ERROR = "Frozen object cannot be modified.";
    __exports__.FROZEN_ERROR = FROZEN_ERROR;
  });
define("ember-runtime/mixins/mutable_array",
  ["ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/mixin","ember-runtime/mixins/array","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/enumerable","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    


    // require('ember-runtime/mixins/array');
    // require('ember-runtime/mixins/mutable_enumerable');

    // ..........................................................
    // CONSTANTS
    //

    var OUT_OF_RANGE_EXCEPTION = "Index out of range";
    var EMPTY = [];

    // ..........................................................
    // HELPERS
    //

    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var isArray = __dependency3__.isArray;
    var EmberError = __dependency4__["default"];
    var Mixin = __dependency5__.Mixin;
    var required = __dependency5__.required;
    var EmberArray = __dependency6__["default"];
    var MutableEnumerable = __dependency7__["default"];
    var Enumerable = __dependency8__["default"];
    
    __exports__["default"] = Mixin.create(EmberArray, MutableEnumerable, {

      
      replace: required(),

      
      clear: function () {
        var len = get(this, 'length');
        if (len === 0) return this;
        this.replace(0, len, EMPTY);
        return this;
      },

      
      insertAt: function(idx, object) {
        if (idx > get(this, 'length')) throw new EmberError(OUT_OF_RANGE_EXCEPTION);
        this.replace(idx, 0, [object]);
        return this;
      },

      
      removeAt: function(start, len) {
        if ('number' === typeof start) {

          if ((start < 0) || (start >= get(this, 'length'))) {
            throw new EmberError(OUT_OF_RANGE_EXCEPTION);
          }

          // fast case
          if (len === undefined) len = 1;
          this.replace(start, len, EMPTY);
        }

        return this;
      },

      
      pushObject: function(obj) {
        this.insertAt(get(this, 'length'), obj);
        return obj;
      },

      
      pushObjects: function(objects) {
        if (!(Enumerable.detect(objects) || isArray(objects))) {
          throw new TypeError("Must pass Ember.Enumerable to Ember.MutableArray#pushObjects");
        }
        this.replace(get(this, 'length'), 0, objects);
        return this;
      },

      
      popObject: function() {
        var len = get(this, 'length');
        if (len === 0) return null;

        var ret = this.objectAt(len-1);
        this.removeAt(len-1, 1);
        return ret;
      },

      
      shiftObject: function() {
        if (get(this, 'length') === 0) return null;
        var ret = this.objectAt(0);
        this.removeAt(0);
        return ret;
      },

      
      unshiftObject: function(obj) {
        this.insertAt(0, obj);
        return obj;
      },

      
      unshiftObjects: function(objects) {
        this.replace(0, 0, objects);
        return this;
      },

      
      reverseObjects: function() {
        var len = get(this, 'length');
        if (len === 0) return this;
        var objects = this.toArray().reverse();
        this.replace(0, len, objects);
        return this;
      },

      
      setObjects: function(objects) {
        if (objects.length === 0) return this.clear();

        var len = get(this, 'length');
        this.replace(0, len, objects);
        return this;
      },

      // ..........................................................
      // IMPLEMENT Ember.MutableEnumerable
      //

      
      removeObject: function(obj) {
        var loc = get(this, 'length') || 0;
        while(--loc >= 0) {
          var curObject = this.objectAt(loc);
          if (curObject === obj) this.removeAt(loc);
        }
        return this;
      },

      
      addObject: function(obj) {
        if (!this.contains(obj)) this.pushObject(obj);
        return this;
      }

    });
  });
define("ember-runtime/mixins/mutable_enumerable",
  ["ember-metal/enumerable_utils","ember-runtime/mixins/enumerable","ember-metal/mixin","ember-metal/property_events","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    var forEach = __dependency1__.forEach;
    var Enumerable = __dependency2__["default"];
    var Mixin = __dependency3__.Mixin;
    var required = __dependency3__.required;
    var beginPropertyChanges = __dependency4__.beginPropertyChanges;
    var endPropertyChanges = __dependency4__.endPropertyChanges;

    

    
    __exports__["default"] = Mixin.create(Enumerable, {

      
      addObject: required(Function),

      
      addObjects: function(objects) {
        beginPropertyChanges(this);
        forEach(objects, function(obj) { this.addObject(obj); }, this);
        endPropertyChanges(this);
        return this;
      },

      
      removeObject: required(Function),


      
      removeObjects: function(objects) {
        beginPropertyChanges(this);
        for (var i = objects.length - 1; i >= 0; i--) {
          this.removeObject(objects[i]);
        }
        endPropertyChanges(this);
        return this;
      }
    });
  });
define("ember-runtime/mixins/observable",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/get_properties","ember-metal/set_properties","ember-metal/mixin","ember-metal/events","ember-metal/property_events","ember-metal/observer","ember-metal/computed","ember-metal/is_none","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) {
    "use strict";
    
    var Ember = __dependency1__["default"];
    // Ember.assert

    var get = __dependency2__.get;
    var getWithDefault = __dependency2__.getWithDefault;
    var set = __dependency3__.set;
    var apply = __dependency4__.apply;
    var getProperties = __dependency5__["default"];
    var setProperties = __dependency6__["default"];
    var Mixin = __dependency7__.Mixin;
    var hasListeners = __dependency8__.hasListeners;
    var beginPropertyChanges = __dependency9__.beginPropertyChanges;
    var propertyWillChange = __dependency9__.propertyWillChange;
    var propertyDidChange = __dependency9__.propertyDidChange;
    var endPropertyChanges = __dependency9__.endPropertyChanges;
    var addObserver = __dependency10__.addObserver;
    var addBeforeObserver = __dependency10__.addBeforeObserver;
    var removeObserver = __dependency10__.removeObserver;
    var observersFor = __dependency10__.observersFor;
    var cacheFor = __dependency11__.cacheFor;
    var isNone = __dependency12__.isNone;


    var slice = Array.prototype.slice;
    
    __exports__["default"] = Mixin.create({

      
      get: function(keyName) {
        return get(this, keyName);
      },

      
      getProperties: function() {
        return apply(null, getProperties, [this].concat(slice.call(arguments)));
      },

      
      set: function(keyName, value) {
        set(this, keyName, value);
        return this;
      },


      
      setProperties: function(hash) {
        return setProperties(this, hash);
      },

      
      beginPropertyChanges: function() {
        beginPropertyChanges();
        return this;
      },

      
      endPropertyChanges: function() {
        endPropertyChanges();
        return this;
      },

      
      propertyWillChange: function(keyName) {
        propertyWillChange(this, keyName);
        return this;
      },

      
      propertyDidChange: function(keyName) {
        propertyDidChange(this, keyName);
        return this;
      },

      
      notifyPropertyChange: function(keyName) {
        this.propertyWillChange(keyName);
        this.propertyDidChange(keyName);
        return this;
      },

      addBeforeObserver: function(key, target, method) {
        addBeforeObserver(this, key, target, method);
      },

      
      addObserver: function(key, target, method) {
        addObserver(this, key, target, method);
      },

      
      removeObserver: function(key, target, method) {
        removeObserver(this, key, target, method);
      },

      
      hasObserverFor: function(key) {
        return hasListeners(this, key+':change');
      },

      
      getWithDefault: function(keyName, defaultValue) {
        return getWithDefault(this, keyName, defaultValue);
      },

      
      incrementProperty: function(keyName, increment) {
        if (isNone(increment)) { increment = 1; }
        Ember.assert("Must pass a numeric value to incrementProperty", (!isNaN(parseFloat(increment)) && isFinite(increment)));
        set(this, keyName, (parseFloat(get(this, keyName)) || 0) + increment);
        return get(this, keyName);
      },

      
      decrementProperty: function(keyName, decrement) {
        if (isNone(decrement)) { decrement = 1; }
        Ember.assert("Must pass a numeric value to decrementProperty", (!isNaN(parseFloat(decrement)) && isFinite(decrement)));
        set(this, keyName, (get(this, keyName) || 0) - decrement);
        return get(this, keyName);
      },

      
      toggleProperty: function(keyName) {
        set(this, keyName, !get(this, keyName));
        return get(this, keyName);
      },

      
      cacheFor: function(keyName) {
        return cacheFor(this, keyName);
      },

      // intended for debugging purposes
      observersForKey: function(keyName) {
        return observersFor(this, keyName);
      }
    });
  });
define("ember-runtime/mixins/promise_proxy",
  ["ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/mixin","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var set = __dependency2__.set;
    var computed = __dependency3__.computed;
    var Mixin = __dependency4__.Mixin;
    var EmberError = __dependency5__["default"];

    var not = computed.not;
    var or = computed.or;

    

    function tap(proxy, promise) {
      set(proxy, 'isFulfilled', false);
      set(proxy, 'isRejected', false);

      return promise.then(function(value) {
        set(proxy, 'isFulfilled', true);
        set(proxy, 'content', value);
        return value;
      }, function(reason) {
        set(proxy, 'isRejected', true);
        set(proxy, 'reason', reason);
        throw reason;
      }, "Ember: PromiseProxy");
    }

    
    __exports__["default"] = Mixin.create({
      
      reason:  null,

      
      isPending:  not('isSettled').readOnly(),

      
      isSettled:  or('isRejected', 'isFulfilled').readOnly(),

      
      isRejected:  false,

      
      isFulfilled: false,

      
      promise: computed(function(key, promise) {
        if (arguments.length === 2) {
          return tap(this, promise);
        } else {
          throw new EmberError("PromiseProxy's promise must be set");
        }
      }),

      
      then: promiseAlias('then'),

      
      'catch': promiseAlias('catch'),

      
      'finally': promiseAlias('finally')

    });

    function promiseAlias(name) {
      return function () {
        var promise = get(this, 'promise');
        return promise[name].apply(promise, arguments);
      };
    }
  });
define("ember-runtime/mixins/sortable",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/enumerable_utils","ember-metal/mixin","ember-runtime/mixins/mutable_enumerable","ember-runtime/compare","ember-metal/observer","ember-metal/computed","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.assert, Ember.A

    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var forEach = __dependency4__.forEach;
    var Mixin = __dependency5__.Mixin;
    var MutableEnumerable = __dependency6__["default"];
    var compare = __dependency7__["default"];
    var addObserver = __dependency8__.addObserver;
    var removeObserver = __dependency8__.removeObserver;
    var computed = __dependency9__.computed;
    var beforeObserver = __dependency5__.beforeObserver;
    var observer = __dependency5__.observer;
    //ES6TODO: should we access these directly from their package or from how thier exposed in ember-metal?

    
    __exports__["default"] = Mixin.create(MutableEnumerable, {

      
      sortProperties: null,

      
      sortAscending: true,

      
      sortFunction: compare,

      orderBy: function(item1, item2) {
        var result = 0,
            sortProperties = get(this, 'sortProperties'),
            sortAscending = get(this, 'sortAscending'),
            sortFunction = get(this, 'sortFunction');

        Ember.assert("you need to define `sortProperties`", !!sortProperties);

        forEach(sortProperties, function(propertyName) {
          if (result === 0) {
            result = sortFunction.call(this, get(item1, propertyName), get(item2, propertyName));
            if ((result !== 0) && !sortAscending) {
              result = (-1) * result;
            }
          }
        }, this);

        return result;
      },

      destroy: function() {
        var content = get(this, 'content'),
            sortProperties = get(this, 'sortProperties');

        if (content && sortProperties) {
          forEach(content, function(item) {
            forEach(sortProperties, function(sortProperty) {
              removeObserver(item, sortProperty, this, 'contentItemSortPropertyDidChange');
            }, this);
          }, this);
        }

        return this._super();
      },

      isSorted: computed.notEmpty('sortProperties'),

      

      arrangedContent: computed('content', 'sortProperties.@each', function(key, value) {
        var content = get(this, 'content'),
            isSorted = get(this, 'isSorted'),
            sortProperties = get(this, 'sortProperties'),
            self = this;

        if (content && isSorted) {
          content = content.slice();
          content.sort(function(item1, item2) {
            return self.orderBy(item1, item2);
          });
          forEach(content, function(item) {
            forEach(sortProperties, function(sortProperty) {
              addObserver(item, sortProperty, this, 'contentItemSortPropertyDidChange');
            }, this);
          }, this);
          return Ember.A(content);
        }

        return content;
      }),

      _contentWillChange: beforeObserver('content', function() {
        var content = get(this, 'content'),
            sortProperties = get(this, 'sortProperties');

        if (content && sortProperties) {
          forEach(content, function(item) {
            forEach(sortProperties, function(sortProperty) {
              removeObserver(item, sortProperty, this, 'contentItemSortPropertyDidChange');
            }, this);
          }, this);
        }

        this._super();
      }),

      sortPropertiesWillChange: beforeObserver('sortProperties', function() {
        this._lastSortAscending = undefined;
      }),

      sortPropertiesDidChange: observer('sortProperties', function() {
        this._lastSortAscending = undefined;
      }),

      sortAscendingWillChange: beforeObserver('sortAscending', function() {
        this._lastSortAscending = get(this, 'sortAscending');
      }),

      sortAscendingDidChange: observer('sortAscending', function() {
        if (this._lastSortAscending !== undefined && get(this, 'sortAscending') !== this._lastSortAscending) {
          var arrangedContent = get(this, 'arrangedContent');
          arrangedContent.reverseObjects();
        }
      }),

      contentArrayWillChange: function(array, idx, removedCount, addedCount) {
        var isSorted = get(this, 'isSorted');

        if (isSorted) {
          var arrangedContent = get(this, 'arrangedContent');
          var removedObjects = array.slice(idx, idx+removedCount);
          var sortProperties = get(this, 'sortProperties');

          forEach(removedObjects, function(item) {
            arrangedContent.removeObject(item);

            forEach(sortProperties, function(sortProperty) {
              removeObserver(item, sortProperty, this, 'contentItemSortPropertyDidChange');
            }, this);
          }, this);
        }

        return this._super(array, idx, removedCount, addedCount);
      },

      contentArrayDidChange: function(array, idx, removedCount, addedCount) {
        var isSorted = get(this, 'isSorted'),
            sortProperties = get(this, 'sortProperties');

        if (isSorted) {
          var addedObjects = array.slice(idx, idx+addedCount);

          forEach(addedObjects, function(item) {
            this.insertItemSorted(item);

            forEach(sortProperties, function(sortProperty) {
              addObserver(item, sortProperty, this, 'contentItemSortPropertyDidChange');
            }, this);
          }, this);
        }

        return this._super(array, idx, removedCount, addedCount);
      },

      insertItemSorted: function(item) {
        var arrangedContent = get(this, 'arrangedContent');
        var length = get(arrangedContent, 'length');

        var idx = this._binarySearch(item, 0, length);
        arrangedContent.insertAt(idx, item);
      },

      contentItemSortPropertyDidChange: function(item) {
        var arrangedContent = get(this, 'arrangedContent'),
            oldIndex = arrangedContent.indexOf(item),
            leftItem = arrangedContent.objectAt(oldIndex - 1),
            rightItem = arrangedContent.objectAt(oldIndex + 1),
            leftResult = leftItem && this.orderBy(item, leftItem),
            rightResult = rightItem && this.orderBy(item, rightItem);

        if (leftResult < 0 || rightResult > 0) {
          arrangedContent.removeObject(item);
          this.insertItemSorted(item);
        }
      },

      _binarySearch: function(item, low, high) {
        var mid, midItem, res, arrangedContent;

        if (low === high) {
          return low;
        }

        arrangedContent = get(this, 'arrangedContent');

        mid = low + Math.floor((high - low) / 2);
        midItem = arrangedContent.objectAt(mid);

        res = this.orderBy(midItem, item);

        if (res < 0) {
          return this._binarySearch(item, mid+1, high);
        } else if (res > 0) {
          return this._binarySearch(item, low, mid);
        }

        return mid;
      }
    });
  });
define("ember-runtime/mixins/target_action_support",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/mixin","ember-metal/computed","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    
    var Ember = __dependency1__["default"];
    // Ember.lookup, Ember.assert

    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var typeOf = __dependency4__.typeOf;
    var Mixin = __dependency5__.Mixin;
    var computed = __dependency6__.computed;

    
    var TargetActionSupport = Mixin.create({
      target: null,
      action: null,
      actionContext: null,

      targetObject: computed(function() {
        var target = get(this, 'target');

        if (typeOf(target) === "string") {
          var value = get(this, target);
          if (value === undefined) { value = get(Ember.lookup, target); }
          return value;
        } else {
          return target;
        }
      }).property('target'),

      actionContextObject: computed(function() {
        var actionContext = get(this, 'actionContext');

        if (typeOf(actionContext) === "string") {
          var value = get(this, actionContext);
          if (value === undefined) { value = get(Ember.lookup, actionContext); }
          return value;
        } else {
          return actionContext;
        }
      }).property('actionContext'),

      
      triggerAction: function(opts) {
        opts = opts || {};
        var action = opts.action || get(this, 'action'),
            target = opts.target || get(this, 'targetObject'),
            actionContext = opts.actionContext;

        function args(options, actionName) {
          var ret = [];
          if (actionName) { ret.push(actionName); }

          return ret.concat(options);
        }

        if (typeof actionContext === 'undefined') {
          actionContext = get(this, 'actionContextObject') || this;
        }

        if (target && action) {
          var ret;

          if (target.send) {
            ret = target.send.apply(target, args(actionContext, action));
          } else {
            Ember.assert("The action '" + action + "' did not exist on " + target, typeof target[action] === 'function');
            ret = target[action].apply(target, args(actionContext));
          }

          if (ret !== false) ret = true;

          return ret;
        } else {
          return false;
        }
      }
    });

    __exports__["default"] = TargetActionSupport;
  });
define("ember-runtime/system/application",
  ["ember-runtime/system/namespace","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Namespace = __dependency1__["default"];

    __exports__["default"] = Namespace.extend();
  });
define("ember-runtime/system/array_proxy",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/computed","ember-metal/mixin","ember-metal/property_events","ember-metal/error","ember-runtime/system/object","ember-runtime/mixins/mutable_array","ember-runtime/mixins/enumerable","ember-runtime/system/string","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.K, Ember.assert
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var isArray = __dependency4__.isArray;
    var apply = __dependency4__.apply;
    var computed = __dependency5__.computed;
    var beforeObserver = __dependency6__.beforeObserver;
    var observer = __dependency6__.observer;
    var beginPropertyChanges = __dependency7__.beginPropertyChanges;
    var endPropertyChanges = __dependency7__.endPropertyChanges;
    var EmberError = __dependency8__["default"];
    var EmberObject = __dependency9__["default"];
    var MutableArray = __dependency10__["default"];
    var Enumerable = __dependency11__["default"];
    var fmt = __dependency12__.fmt;

    

    var OUT_OF_RANGE_EXCEPTION = "Index out of range";
    var EMPTY = [];
    var alias = computed.alias;
    var K = Ember.K;

    
    var ArrayProxy = EmberObject.extend(MutableArray, {

      
      content: null,

      
      arrangedContent: alias('content'),

      
      objectAtContent: function(idx) {
        return get(this, 'arrangedContent').objectAt(idx);
      },

      
      replaceContent: function(idx, amt, objects) {
        get(this, 'content').replace(idx, amt, objects);
      },

      
      _contentWillChange: beforeObserver('content', function() {
        this._teardownContent();
      }),

      _teardownContent: function() {
        var content = get(this, 'content');

        if (content) {
          content.removeArrayObserver(this, {
            willChange: 'contentArrayWillChange',
            didChange: 'contentArrayDidChange'
          });
        }
      },

      contentArrayWillChange: K,
      contentArrayDidChange: K,

      
      _contentDidChange: observer('content', function() {
        var content = get(this, 'content');

        Ember.assert("Can't set ArrayProxy's content to itself", content !== this);

        this._setupContent();
      }),

      _setupContent: function() {
        var content = get(this, 'content');

        if (content) {
          Ember.assert(fmt('ArrayProxy expects an Array or ' +
            'Ember.ArrayProxy, but you passed %@', [typeof content]),
            isArray(content) || content.isDestroyed);

          content.addArrayObserver(this, {
            willChange: 'contentArrayWillChange',
            didChange: 'contentArrayDidChange'
          });
        }
      },

      _arrangedContentWillChange: beforeObserver('arrangedContent', function() {
        var arrangedContent = get(this, 'arrangedContent'),
            len = arrangedContent ? get(arrangedContent, 'length') : 0;

        this.arrangedContentArrayWillChange(this, 0, len, undefined);
        this.arrangedContentWillChange(this);

        this._teardownArrangedContent(arrangedContent);
      }),

      _arrangedContentDidChange: observer('arrangedContent', function() {
        var arrangedContent = get(this, 'arrangedContent'),
            len = arrangedContent ? get(arrangedContent, 'length') : 0;

        Ember.assert("Can't set ArrayProxy's content to itself", arrangedContent !== this);

        this._setupArrangedContent();

        this.arrangedContentDidChange(this);
        this.arrangedContentArrayDidChange(this, 0, undefined, len);
      }),

      _setupArrangedContent: function() {
        var arrangedContent = get(this, 'arrangedContent');

        if (arrangedContent) {
          Ember.assert(fmt('ArrayProxy expects an Array or ' +
            'Ember.ArrayProxy, but you passed %@', [typeof arrangedContent]),
            isArray(arrangedContent) || arrangedContent.isDestroyed);

          arrangedContent.addArrayObserver(this, {
            willChange: 'arrangedContentArrayWillChange',
            didChange: 'arrangedContentArrayDidChange'
          });
        }
      },

      _teardownArrangedContent: function() {
        var arrangedContent = get(this, 'arrangedContent');

        if (arrangedContent) {
          arrangedContent.removeArrayObserver(this, {
            willChange: 'arrangedContentArrayWillChange',
            didChange: 'arrangedContentArrayDidChange'
          });
        }
      },

      arrangedContentWillChange: K,
      arrangedContentDidChange: K,

      objectAt: function(idx) {
        return get(this, 'content') && this.objectAtContent(idx);
      },

      length: computed(function() {
        var arrangedContent = get(this, 'arrangedContent');
        return arrangedContent ? get(arrangedContent, 'length') : 0;
        // No dependencies since Enumerable notifies length of change
      }),

      _replace: function(idx, amt, objects) {
        var content = get(this, 'content');
        Ember.assert('The content property of '+ this.constructor + ' should be set before modifying it', content);
        if (content) this.replaceContent(idx, amt, objects);
        return this;
      },

      replace: function() {
        if (get(this, 'arrangedContent') === get(this, 'content')) {
          apply(this, this._replace, arguments);
        } else {
          throw new EmberError("Using replace on an arranged ArrayProxy is not allowed.");
        }
      },

      _insertAt: function(idx, object) {
        if (idx > get(this, 'content.length')) throw new EmberError(OUT_OF_RANGE_EXCEPTION);
        this._replace(idx, 0, [object]);
        return this;
      },

      insertAt: function(idx, object) {
        if (get(this, 'arrangedContent') === get(this, 'content')) {
          return this._insertAt(idx, object);
        } else {
          throw new EmberError("Using insertAt on an arranged ArrayProxy is not allowed.");
        }
      },

      removeAt: function(start, len) {
        if ('number' === typeof start) {
          var content = get(this, 'content'),
              arrangedContent = get(this, 'arrangedContent'),
              indices = [], i;

          if ((start < 0) || (start >= get(this, 'length'))) {
            throw new EmberError(OUT_OF_RANGE_EXCEPTION);
          }

          if (len === undefined) len = 1;

          // Get a list of indices in original content to remove
          for (i=start; i<start+len; i++) {
            // Use arrangedContent here so we avoid confusion with objects transformed by objectAtContent
            indices.push(content.indexOf(arrangedContent.objectAt(i)));
          }

          // Replace in reverse order since indices will change
          indices.sort(function(a,b) { return b - a; });

          beginPropertyChanges();
          for (i=0; i<indices.length; i++) {
            this._replace(indices[i], 1, EMPTY);
          }
          endPropertyChanges();
        }

        return this ;
      },

      pushObject: function(obj) {
        this._insertAt(get(this, 'content.length'), obj) ;
        return obj ;
      },

      pushObjects: function(objects) {
        if (!(Enumerable.detect(objects) || isArray(objects))) {
          throw new TypeError("Must pass Ember.Enumerable to Ember.MutableArray#pushObjects");
        }
        this._replace(get(this, 'length'), 0, objects);
        return this;
      },

      setObjects: function(objects) {
        if (objects.length === 0) return this.clear();

        var len = get(this, 'length');
        this._replace(0, len, objects);
        return this;
      },

      unshiftObject: function(obj) {
        this._insertAt(0, obj) ;
        return obj ;
      },

      unshiftObjects: function(objects) {
        this._replace(0, 0, objects);
        return this;
      },

      slice: function() {
        var arr = this.toArray();
        return arr.slice.apply(arr, arguments);
      },

      arrangedContentArrayWillChange: function(item, idx, removedCnt, addedCnt) {
        this.arrayContentWillChange(idx, removedCnt, addedCnt);
      },

      arrangedContentArrayDidChange: function(item, idx, removedCnt, addedCnt) {
        this.arrayContentDidChange(idx, removedCnt, addedCnt);
      },

      init: function() {
        this._super();
        this._setupContent();
        this._setupArrangedContent();
      },

      willDestroy: function() {
        this._teardownArrangedContent();
        this._teardownContent();
      }
    });

    __exports__["default"] = ArrayProxy;
  });
define("ember-runtime/system/container",
  ["ember-metal/property_set","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var set = __dependency1__["default"];

    var Container = requireModule('container')["default"];
    Container.set = set;

    __exports__["default"] = Container;
  });
define("ember-runtime/system/core_object",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/platform","ember-metal/watching","ember-metal/chains","ember-metal/events","ember-metal/mixin","ember-metal/enumerable_utils","ember-metal/error","ember-runtime/keys","ember-runtime/mixins/action_handler","ember-metal/properties","ember-metal/binding","ember-metal/computed","ember-metal/run_loop","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.ENV.MANDATORY_SETTER, Ember.assert, Ember.K, Ember.config

    // NOTE: this object should never be included directly. Instead use `Ember.Object`.
    // We only define this separately so that `Ember.Set` can depend on it.
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var guidFor = __dependency4__.guidFor;
    var apply = __dependency4__.apply;
    var o_create = __dependency5__.create;
    var generateGuid = __dependency4__.generateGuid;
    var GUID_KEY = __dependency4__.GUID_KEY;
    var meta = __dependency4__.meta;
    var META_KEY = __dependency4__.META_KEY;
    var makeArray = __dependency4__.makeArray;
    var rewatch = __dependency6__.rewatch;
    var finishChains = __dependency7__.finishChains;
    var sendEvent = __dependency8__.sendEvent;
    var IS_BINDING = __dependency9__.IS_BINDING;
    var Mixin = __dependency9__.Mixin;
    var required = __dependency9__.required;
    var indexOf = __dependency10__.indexOf;
    var EmberError = __dependency11__["default"];
    var platform = __dependency5__.platform;
    var keys = __dependency12__["default"];
    var ActionHandler = __dependency13__["default"];
    var defineProperty = __dependency14__.defineProperty;
    var Binding = __dependency15__.Binding;
    var ComputedProperty = __dependency16__.ComputedProperty;
    var run = __dependency17__["default"];
    var destroy = __dependency6__.destroy;

    var K = __dependency1__.K;
    var o_defineProperty = platform.defineProperty;
    var schedule = run.schedule;
    var applyMixin = Mixin._apply;
    var finishPartial = Mixin.finishPartial;
    var reopen = Mixin.prototype.reopen;
    var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
    var hasCachedComputedProperties = false;

    var undefinedDescriptor = {
      configurable: true,
      writable: true,
      enumerable: false,
      value: undefined
    };

    var nullDescriptor = {
      configurable: true,
      writable: true,
      enumerable: false,
      value: null
    };

    function makeCtor() {

      // Note: avoid accessing any properties on the object since it makes the
      // method a lot faster. This is glue code so we want it to be as fast as
      // possible.

      var wasApplied = false, initMixins, initProperties;

      var Class = function() {
        if (!wasApplied) {
          Class.proto(); // prepare prototype...
        }
        o_defineProperty(this, GUID_KEY, nullDescriptor);
        o_defineProperty(this, '__nextSuper', undefinedDescriptor);
        var m = meta(this), proto = m.proto;
        m.proto = this;
        if (initMixins) {
          // capture locally so we can clear the closed over variable
          var mixins = initMixins;
          initMixins = null;
          apply(this, this.reopen, mixins);
        }
        if (initProperties) {
          // capture locally so we can clear the closed over variable
          var props = initProperties;
          initProperties = null;

          var concatenatedProperties = this.concatenatedProperties;

          for (var i = 0, l = props.length; i < l; i++) {
            var properties = props[i];

            Ember.assert("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(properties instanceof Mixin));

            if (typeof properties !== 'object' && properties !== undefined) {
              throw new EmberError("Ember.Object.create only accepts objects.");
            }

            if (!properties) { continue; }

            var keyNames = keys(properties);

            for (var j = 0, ll = keyNames.length; j < ll; j++) {
              var keyName = keyNames[j];
              if (!properties.hasOwnProperty(keyName)) { continue; }

              var value = properties[keyName];

              if (IS_BINDING.test(keyName)) {
                var bindings = m.bindings;
                if (!bindings) {
                  bindings = m.bindings = {};
                } else if (!m.hasOwnProperty('bindings')) {
                  bindings = m.bindings = o_create(m.bindings);
                }
                bindings[keyName] = value;
              }

              var desc = m.descs[keyName];

              Ember.assert("Ember.Object.create no longer supports defining computed properties. Define computed properties using extend() or reopen() before calling create().", !(value instanceof ComputedProperty));
              Ember.assert("Ember.Object.create no longer supports defining methods that call _super.", !(typeof value === 'function' && value.toString().indexOf('._super') !== -1));
              Ember.assert("`actions` must be provided at extend time, not at create " +
                           "time, when Ember.ActionHandler is used (i.e. views, " +
                           "controllers & routes).", !((keyName === 'actions') && ActionHandler.detect(this)));

              if (concatenatedProperties && indexOf(concatenatedProperties, keyName) >= 0) {
                var baseValue = this[keyName];

                if (baseValue) {
                  if ('function' === typeof baseValue.concat) {
                    value = baseValue.concat(value);
                  } else {
                    value = makeArray(baseValue).concat(value);
                  }
                } else {
                  value = makeArray(value);
                }
              }

              if (desc) {
                desc.set(this, keyName, value);
              } else {
                if (typeof this.setUnknownProperty === 'function' && !(keyName in this)) {
                  this.setUnknownProperty(keyName, value);
                } else if (MANDATORY_SETTER) {
                  defineProperty(this, keyName, null, value); // setup mandatory setter
                } else {
                  this[keyName] = value;
                }
              }
            }
          }
        }
        finishPartial(this, m);
        var length = arguments.length;
        var args = new Array(length);
        for (var x = 0; x < length; x++) {
          args[x] = arguments[x];
        }
        apply(this, this.init, args);
        m.proto = proto;
        finishChains(this);
        sendEvent(this, "init");
      };

      Class.toString = Mixin.prototype.toString;
      Class.willReopen = function() {
        if (wasApplied) {
          Class.PrototypeMixin = Mixin.create(Class.PrototypeMixin);
        }

        wasApplied = false;
      };
      Class._initMixins = function(args) { initMixins = args; };
      Class._initProperties = function(args) { initProperties = args; };

      Class.proto = function() {
        var superclass = Class.superclass;
        if (superclass) { superclass.proto(); }

        if (!wasApplied) {
          wasApplied = true;
          Class.PrototypeMixin.applyPartial(Class.prototype);
          rewatch(Class.prototype);
        }

        return this.prototype;
      };

      return Class;

    }

    
    var CoreObject = makeCtor();
    CoreObject.toString = function() { return "Ember.CoreObject"; };

    CoreObject.PrototypeMixin = Mixin.create({
      reopen: function() {
        var length = arguments.length;
        var args = new Array(length);
        for (var i = 0; i < length; i++) {
          args[i] = arguments[i];
        }
        applyMixin(this, args, true);
        return this;
      },

      
      init: function() {},

      
      concatenatedProperties: null,

      
      isDestroyed: false,

      
      isDestroying: false,

      
      destroy: function() {
        if (this.isDestroying) { return; }
        this.isDestroying = true;

        schedule('actions', this, this.willDestroy);
        schedule('destroy', this, this._scheduledDestroy);
        return this;
      },

      
      willDestroy: K,

      
      _scheduledDestroy: function() {
        if (this.isDestroyed) { return; }
        destroy(this);
        this.isDestroyed = true;
      },

      bind: function(to, from) {
        if (!(from instanceof Binding)) { from = Binding.from(from); }
        from.to(to).connect(this);
        return from;
      },

      
      toString: function toString() {
        var hasToStringExtension = typeof this.toStringExtension === 'function',
            extension = hasToStringExtension ? ":" + this.toStringExtension() : '';
        var ret = '<'+this.constructor.toString()+':'+guidFor(this)+extension+'>';
        this.toString = makeToString(ret);
        return ret;
      }
    });

    CoreObject.PrototypeMixin.ownerConstructor = CoreObject;

    function makeToString(ret) {
      return function() { return ret; };
    }

    if (Ember.config.overridePrototypeMixin) {
      Ember.config.overridePrototypeMixin(CoreObject.PrototypeMixin);
    }

    CoreObject.__super__ = null;

    var ClassMixin = Mixin.create({

      ClassMixin: required(),

      PrototypeMixin: required(),

      isClass: true,

      isMethod: false,

      
      extend: function() {
        var Class = makeCtor(), proto;
        Class.ClassMixin = Mixin.create(this.ClassMixin);
        Class.PrototypeMixin = Mixin.create(this.PrototypeMixin);

        Class.ClassMixin.ownerConstructor = Class;
        Class.PrototypeMixin.ownerConstructor = Class;

        reopen.apply(Class.PrototypeMixin, arguments);

        Class.superclass = this;
        Class.__super__  = this.prototype;

        proto = Class.prototype = o_create(this.prototype);
        proto.constructor = Class;
        generateGuid(proto);
        meta(proto).proto = proto; // this will disable observers on prototype

        Class.ClassMixin.apply(Class);
        return Class;
      },

      
      createWithMixins: function() {
        var C = this;
        var l= arguments.length;
        if (l > 0) {
          var args = new Array(l);
          for (var i = 0; i < l; i++) {
            args[i] = arguments[i];
          }
          this._initMixins(args);
        }
        return new C();
      },

      
      create: function() {
        var C = this;
        var l = arguments.length;
        if (l > 0) {
          var args = new Array(l);
          for (var i = 0; i < l; i++) {
            args[i] = arguments[i];
          }
          this._initProperties(args);
        }
        return new C();
      },

      
      reopen: function() {
        this.willReopen();

        var l = arguments.length;
        var args = new Array(l);
        if (l > 0) {
          for (var i = 0; i < l; i++) {
            args[i] = arguments[i];
          }
        }

        apply(this.PrototypeMixin, reopen, args);
        return this;
      },

      
      reopenClass: function() {
        var l = arguments.length;
        var args = new Array(l);
        if (l > 0) {
          for (var i = 0; i < l; i++) {
            args[i] = arguments[i];
          }
        }

        apply(this.ClassMixin, reopen, args);
        applyMixin(this, arguments, false);
        return this;
      },

      detect: function(obj) {
        if ('function' !== typeof obj) { return false; }
        while(obj) {
          if (obj===this) { return true; }
          obj = obj.superclass;
        }
        return false;
      },

      detectInstance: function(obj) {
        return obj instanceof this;
      },

      
      metaForProperty: function(key) {
        var meta = this.proto()[META_KEY],
            desc = meta && meta.descs[key];

        Ember.assert("metaForProperty() could not find a computed property with key '"+key+"'.", !!desc && desc instanceof ComputedProperty);
        return desc._meta || {};
      },

      _computedProperties: Ember.computed(function() {
        hasCachedComputedProperties = true;
        var proto = this.proto();
        var descs = meta(proto).descs;
        var property;
        var properties = [];

        for (var name in descs) {
          property = descs[name];

          if (property instanceof ComputedProperty) {
            properties.push({
              name: name,
              meta: property._meta
            });
          }
        }
        return properties;
      }).readOnly(),

      
      eachComputedProperty: function(callback, binding) {
        var property, name;
        var empty = {};

        var properties = get(this, '_computedProperties');

        for (var i = 0, length = properties.length; i < length; i++) {
          property = properties[i];
          name = property.name;
          callback.call(binding || this, property.name, property.meta || empty);
        }
      }
    });

    ClassMixin.ownerConstructor = CoreObject;

    if (Ember.config.overrideClassMixin) {
      Ember.config.overrideClassMixin(ClassMixin);
    }

    CoreObject.ClassMixin = ClassMixin;

    ClassMixin.apply(CoreObject);

    CoreObject.reopen({
      didDefineProperty: function(proto, key, value) {
        if (hasCachedComputedProperties === false) { return; }
        if (value instanceof Ember.ComputedProperty) {
          var cache = Ember.meta(this.constructor).cache;

          if (cache._computedProperties !== undefined) {
            cache._computedProperties = undefined;
          }
        }

        this._super();
      }
    });


    __exports__["default"] = CoreObject;
  });
define("ember-runtime/system/deferred",
  ["ember-metal/core","ember-runtime/mixins/deferred","ember-metal/property_get","ember-runtime/system/object","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var DeferredMixin = __dependency2__["default"];
    var get = __dependency3__.get;
    var EmberObject = __dependency4__["default"];

    var Deferred = EmberObject.extend(DeferredMixin, {
      init: function() {
        Ember.deprecate('Usage of Ember.Deferred is deprecated.');
        this._super();
      }
    });

    Deferred.reopenClass({
      promise: function(callback, binding) {
        var deferred = Deferred.create();
        callback.call(binding, deferred);
        return deferred;
      }
    });

    __exports__["default"] = Deferred;
  });
define("ember-runtime/system/each_proxy",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/enumerable_utils","ember-metal/array","ember-runtime/mixins/array","ember-runtime/system/object","ember-metal/computed","ember-metal/observer","ember-metal/events","ember-metal/properties","ember-metal/property_events","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.assert

    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var guidFor = __dependency4__.guidFor;
    var forEach = __dependency5__.forEach;
    var indexOf = __dependency6__.indexOf;
    var EmberArray = __dependency7__["default"];
    // ES6TODO: WAT? Circular dep?
    var EmberObject = __dependency8__["default"];
    var computed = __dependency9__.computed;
    var addObserver = __dependency10__.addObserver;
    var addBeforeObserver = __dependency10__.addBeforeObserver;
    var removeBeforeObserver = __dependency10__.removeBeforeObserver;
    var removeObserver = __dependency10__.removeObserver;
    var typeOf = __dependency4__.typeOf;
    var watchedEvents = __dependency11__.watchedEvents;
    var defineProperty = __dependency12__.defineProperty;
    var beginPropertyChanges = __dependency13__.beginPropertyChanges;
    var propertyDidChange = __dependency13__.propertyDidChange;
    var propertyWillChange = __dependency13__.propertyWillChange;
    var endPropertyChanges = __dependency13__.endPropertyChanges;
    var changeProperties = __dependency13__.changeProperties;

    var EachArray = EmberObject.extend(EmberArray, {

      init: function(content, keyName, owner) {
        this._super();
        this._keyName = keyName;
        this._owner   = owner;
        this._content = content;
      },

      objectAt: function(idx) {
        var item = this._content.objectAt(idx);
        return item && get(item, this._keyName);
      },

      length: computed(function() {
        var content = this._content;
        return content ? get(content, 'length') : 0;
      })

    });

    var IS_OBSERVER = /^.+:(before|change)$/;

    function addObserverForContentKey(content, keyName, proxy, idx, loc) {
      var objects = proxy._objects, guid;
      if (!objects) objects = proxy._objects = {};

      while(--loc>=idx) {
        var item = content.objectAt(loc);
        if (item) {
          Ember.assert('When using @each to observe the array ' + content + ', the array must return an object', typeOf(item) === 'instance' || typeOf(item) === 'object');
          addBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
          addObserver(item, keyName, proxy, 'contentKeyDidChange');

          // keep track of the index each item was found at so we can map
          // it back when the obj changes.
          guid = guidFor(item);
          if (!objects[guid]) objects[guid] = [];
          objects[guid].push(loc);
        }
      }
    }

    function removeObserverForContentKey(content, keyName, proxy, idx, loc) {
      var objects = proxy._objects;
      if (!objects) objects = proxy._objects = {};
      var indicies, guid;

      while(--loc>=idx) {
        var item = content.objectAt(loc);
        if (item) {
          removeBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
          removeObserver(item, keyName, proxy, 'contentKeyDidChange');

          guid = guidFor(item);
          indicies = objects[guid];
          indicies[indexOf.call(indicies, loc)] = null;
        }
      }
    }

    
    var EachProxy = EmberObject.extend({

      init: function(content) {
        this._super();
        this._content = content;
        content.addArrayObserver(this);

        // in case someone is already observing some keys make sure they are
        // added
        forEach(watchedEvents(this), function(eventName) {
          this.didAddListener(eventName);
        }, this);
      },

      
      unknownProperty: function(keyName, value) {
        var ret;
        ret = new EachArray(this._content, keyName, this);
        defineProperty(this, keyName, null, ret);
        this.beginObservingContentKey(keyName);
        return ret;
      },

      // ..........................................................
      // ARRAY CHANGES
      // Invokes whenever the content array itself changes.

      arrayWillChange: function(content, idx, removedCnt, addedCnt) {
        var keys = this._keys, key, lim;

        lim = removedCnt>0 ? idx+removedCnt : -1;
        beginPropertyChanges(this);

        for(key in keys) {
          if (!keys.hasOwnProperty(key)) { continue; }

          if (lim>0) { removeObserverForContentKey(content, key, this, idx, lim); }

          propertyWillChange(this, key);
        }

        propertyWillChange(this._content, '@each');
        endPropertyChanges(this);
      },

      arrayDidChange: function(content, idx, removedCnt, addedCnt) {
        var keys = this._keys, lim;

        lim = addedCnt>0 ? idx+addedCnt : -1;
        changeProperties(function() {
          for(var key in keys) {
            if (!keys.hasOwnProperty(key)) { continue; }

            if (lim>0) { addObserverForContentKey(content, key, this, idx, lim); }

            propertyDidChange(this, key);
          }

          propertyDidChange(this._content, '@each');
        }, this);
      },

      // ..........................................................
      // LISTEN FOR NEW OBSERVERS AND OTHER EVENT LISTENERS
      // Start monitoring keys based on who is listening...

      didAddListener: function(eventName) {
        if (IS_OBSERVER.test(eventName)) {
          this.beginObservingContentKey(eventName.slice(0, -7));
        }
      },

      didRemoveListener: function(eventName) {
        if (IS_OBSERVER.test(eventName)) {
          this.stopObservingContentKey(eventName.slice(0, -7));
        }
      },

      // ..........................................................
      // CONTENT KEY OBSERVING
      // Actual watch keys on the source content.

      beginObservingContentKey: function(keyName) {
        var keys = this._keys;
        if (!keys) keys = this._keys = {};
        if (!keys[keyName]) {
          keys[keyName] = 1;
          var content = this._content,
              len = get(content, 'length');
          addObserverForContentKey(content, keyName, this, 0, len);
        } else {
          keys[keyName]++;
        }
      },

      stopObservingContentKey: function(keyName) {
        var keys = this._keys;
        if (keys && (keys[keyName]>0) && (--keys[keyName]<=0)) {
          var content = this._content,
              len     = get(content, 'length');
          removeObserverForContentKey(content, keyName, this, 0, len);
        }
      },

      contentKeyWillChange: function(obj, keyName) {
        propertyWillChange(this, keyName);
      },

      contentKeyDidChange: function(obj, keyName) {
        propertyDidChange(this, keyName);
      }
    });

    __exports__.EachArray = EachArray;
    __exports__.EachProxy = EachProxy;
  });
define("ember-runtime/system/lazy_load",
  ["ember-metal/core","ember-metal/array","ember-runtime/system/native_array","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.ENV.EMBER_LOAD_HOOKS
    var forEach = __dependency2__.forEach;
    // make sure Ember.A is setup.

    

    var loadHooks = Ember.ENV.EMBER_LOAD_HOOKS || {};
    var loaded = {};

    
    function onLoad(name, callback) {
      var object;

      loadHooks[name] = loadHooks[name] || Ember.A();
      loadHooks[name].pushObject(callback);

      if (object = loaded[name]) {
        callback(object);
      }
    }

    __exports__.onLoad = onLoad;
    function runLoadHooks(name, object) {
      loaded[name] = object;

      if (typeof window === 'object' && typeof window.dispatchEvent === 'function' && typeof CustomEvent === "function") {
        var event = new CustomEvent(name, {detail: object, name: name});
        window.dispatchEvent(event);
      }

      if (loadHooks[name]) {
        forEach.call(loadHooks[name], function(callback) {
          callback(object);
        });
      }
    }

    __exports__.runLoadHooks = runLoadHooks;
  });
define("ember-runtime/system/namespace",
  ["ember-metal/core","ember-metal/property_get","ember-metal/array","ember-metal/utils","ember-metal/mixin","ember-runtime/system/object","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
    "use strict";
    

    // Ember.lookup, Ember.BOOTED, Ember.deprecate, Ember.NAME_KEY, Ember.anyUnprocessedMixins
    var Ember = __dependency1__["default"];
    var get = __dependency2__.get;
    var indexOf = __dependency3__.indexOf;
    var GUID_KEY = __dependency4__.GUID_KEY;
    var guidFor = __dependency4__.guidFor;
    var Mixin = __dependency5__.Mixin;

    var EmberObject = __dependency6__["default"];

    
    var Namespace = EmberObject.extend({
      isNamespace: true,

      init: function() {
        Namespace.NAMESPACES.push(this);
        Namespace.PROCESSED = false;
      },

      toString: function() {
        var name = get(this, 'name');
        if (name) { return name; }

        findNamespaces();
        return this[NAME_KEY];
      },

      nameClasses: function() {
        processNamespace([this.toString()], this, {});
      },

      destroy: function() {
        var namespaces = Namespace.NAMESPACES,
            toString = this.toString();

        if (toString) {
          Ember.lookup[toString] = undefined;
          delete Namespace.NAMESPACES_BY_ID[toString];
        }
        namespaces.splice(indexOf.call(namespaces, this), 1);
        this._super();
      }
    });

    Namespace.reopenClass({
      NAMESPACES: [Ember],
      NAMESPACES_BY_ID: {},
      PROCESSED: false,
      processAll: processAllNamespaces,
      byName: function(name) {
        if (!Ember.BOOTED) {
          processAllNamespaces();
        }

        return NAMESPACES_BY_ID[name];
      }
    });

    var NAMESPACES_BY_ID = Namespace.NAMESPACES_BY_ID;

    var hasOwnProp = ({}).hasOwnProperty;

    function processNamespace(paths, root, seen) {
      var idx = paths.length;

      NAMESPACES_BY_ID[paths.join('.')] = root;

      // Loop over all of the keys in the namespace, looking for classes
      for(var key in root) {
        if (!hasOwnProp.call(root, key)) { continue; }
        var obj = root[key];

        // If we are processing the `Ember` namespace, for example, the
        // `paths` will start with `["Ember"]`. Every iteration through
        // the loop will update the **second** element of this list with
        // the key, so processing `Ember.View` will make the Array
        // `['Ember', 'View']`.
        paths[idx] = key;

        // If we have found an unprocessed class
        if (obj && obj.toString === classToString) {
          // Replace the class' `toString` with the dot-separated path
          // and set its `NAME_KEY`
          obj.toString = makeToString(paths.join('.'));
          obj[NAME_KEY] = paths.join('.');

        // Support nested namespaces
        } else if (obj && obj.isNamespace) {
          // Skip aliased namespaces
          if (seen[guidFor(obj)]) { continue; }
          seen[guidFor(obj)] = true;

          // Process the child namespace
          processNamespace(paths, obj, seen);
        }
      }

      paths.length = idx; // cut out last item
    }

    var STARTS_WITH_UPPERCASE = /^[A-Z]/;

    function tryIsNamespace(lookup, prop) {
      try {
        var obj = lookup[prop];
        return obj && obj.isNamespace && obj;
      } catch (e) {
        // continue
      }
    }

    function findNamespaces() {
      var lookup = Ember.lookup, obj, isNamespace;

      if (Namespace.PROCESSED) { return; }

      for (var prop in lookup) {
        // Only process entities that start with uppercase A-Z
        if (!STARTS_WITH_UPPERCASE.test(prop)) { continue; }

        // Unfortunately, some versions of IE don't support window.hasOwnProperty
        if (lookup.hasOwnProperty && !lookup.hasOwnProperty(prop)) { continue; }

        // At times we are not allowed to access certain properties for security reasons.
        // There are also times where even if we can access them, we are not allowed to access their properties.
        obj = tryIsNamespace(lookup, prop);
        if (obj) {
          obj[NAME_KEY] = prop;
        }
      }
    }

    var NAME_KEY = Ember.NAME_KEY = GUID_KEY + '_name';

    function superClassString(mixin) {
      var superclass = mixin.superclass;
      if (superclass) {
        if (superclass[NAME_KEY]) { return superclass[NAME_KEY]; }
        else { return superClassString(superclass); }
      } else {
        return;
      }
    }

    function classToString() {
      if (!Ember.BOOTED && !this[NAME_KEY]) {
        processAllNamespaces();
      }

      var ret;

      if (this[NAME_KEY]) {
        ret = this[NAME_KEY];
      } else if (this._toString) {
        ret = this._toString;
      } else {
        var str = superClassString(this);
        if (str) {
          ret = "(subclass of " + str + ")";
        } else {
          ret = "(unknown mixin)";
        }
        this.toString = makeToString(ret);
      }

      return ret;
    }

    function processAllNamespaces() {
      var unprocessedNamespaces = !Namespace.PROCESSED,
          unprocessedMixins = Ember.anyUnprocessedMixins;

      if (unprocessedNamespaces) {
        findNamespaces();
        Namespace.PROCESSED = true;
      }

      if (unprocessedNamespaces || unprocessedMixins) {
        var namespaces = Namespace.NAMESPACES, namespace;
        for (var i=0, l=namespaces.length; i<l; i++) {
          namespace = namespaces[i];
          processNamespace([namespace.toString()], namespace, {});
        }

        Ember.anyUnprocessedMixins = false;
      }
    }

    function makeToString(ret) {
      return function() { return ret; };
    }

    Mixin.prototype.toString = classToString; // ES6TODO: altering imported objects. SBB.

    __exports__["default"] = Namespace;
  });
define("ember-runtime/system/native_array",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/enumerable_utils","ember-metal/mixin","ember-runtime/mixins/array","ember-runtime/mixins/mutable_array","ember-runtime/mixins/observable","ember-runtime/mixins/copyable","ember-runtime/mixins/freezable","ember-runtime/copy","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.EXTEND_PROTOTYPES

    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var replace = __dependency4__._replace;
    var forEach = __dependency4__.forEach;
    var Mixin = __dependency5__.Mixin;
    var EmberArray = __dependency6__["default"];
    var MutableArray = __dependency7__["default"];
    var Observable = __dependency8__["default"];
    var Copyable = __dependency9__["default"];
    var FROZEN_ERROR = __dependency10__.FROZEN_ERROR;
    var copy = __dependency11__["default"];

    // Add Ember.Array to Array.prototype. Remove methods with native
    // implementations and supply some more optimized versions of generic methods
    // because they are so common.

    
    var NativeArray = Mixin.create(MutableArray, Observable, Copyable, {

      // because length is a built-in property we need to know to just get the
      // original property.
      get: function(key) {
        if (key==='length') return this.length;
        else if ('number' === typeof key) return this[key];
        else return this._super(key);
      },

      objectAt: function(idx) {
        return this[idx];
      },

      // primitive for array support.
      replace: function(idx, amt, objects) {

        if (this.isFrozen) throw FROZEN_ERROR;

        // if we replaced exactly the same number of items, then pass only the
        // replaced range. Otherwise, pass the full remaining array length
        // since everything has shifted
        var len = objects ? get(objects, 'length') : 0;
        this.arrayContentWillChange(idx, amt, len);

        if (len === 0) {
          this.splice(idx, amt);
        } else {
          replace(this, idx, amt, objects);
        }

        this.arrayContentDidChange(idx, amt, len);
        return this;
      },

      // If you ask for an unknown property, then try to collect the value
      // from member items.
      unknownProperty: function(key, value) {
        var ret;// = this.reducedProperty(key, value) ;
        if ((value !== undefined) && ret === undefined) {
          ret = this[key] = value;
        }
        return ret ;
      },

      // If browser did not implement indexOf natively, then override with
      // specialized version
      indexOf: function(object, startAt) {
        var idx, len = this.length;

        if (startAt === undefined) startAt = 0;
        else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt);
        if (startAt < 0) startAt += len;

        for(idx=startAt;idx<len;idx++) {
          if (this[idx] === object) return idx ;
        }
        return -1;
      },

      lastIndexOf: function(object, startAt) {
        var idx, len = this.length;

        if (startAt === undefined) startAt = len-1;
        else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt);
        if (startAt < 0) startAt += len;

        for(idx=startAt;idx>=0;idx--) {
          if (this[idx] === object) return idx ;
        }
        return -1;
      },

      copy: function(deep) {
        if (deep) {
          return this.map(function(item) { return copy(item, true); });
        }

        return this.slice();
      }
    });

    // Remove any methods implemented natively so we don't override them
    var ignore = ['length'];
    forEach(NativeArray.keys(), function(methodName) {
      if (Array.prototype[methodName]) ignore.push(methodName);
    });

    if (ignore.length>0) {
      NativeArray = NativeArray.without.apply(NativeArray, ignore);
    }

    
    var A = function(arr) {
      if (arr === undefined) { arr = []; }
      return EmberArray.detect(arr) ? arr : NativeArray.apply(arr);
    };

    
    NativeArray.activate = function() {
      NativeArray.apply(Array.prototype);

      A = function(arr) { return arr || []; };
    };

    if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Array) {
      NativeArray.activate();
    }

    Ember.A = A; // ES6TODO: Setting A onto the object returned by ember-metal/core to avoid circles
    __exports__.A = A;
    __exports__.NativeArray = NativeArray;
    __exports__["default"] = NativeArray;
  });
define("ember-runtime/system/object",
  ["ember-runtime/system/core_object","ember-runtime/mixins/observable","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    

    var CoreObject = __dependency1__["default"];
    var Observable = __dependency2__["default"];

    
    var EmberObject = CoreObject.extend(Observable);
    EmberObject.toString = function() {
      return "Ember.Object";
    };

    __exports__["default"] = EmberObject;
  });
define("ember-runtime/system/object_proxy",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/observer","ember-metal/property_events","ember-metal/computed","ember-metal/properties","ember-metal/mixin","ember-runtime/system/string","ember-runtime/system/object","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) {
    "use strict";
    
    var Ember = __dependency1__["default"];
    // Ember.assert
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var meta = __dependency4__.meta;
    var addObserver = __dependency5__.addObserver;
    var removeObserver = __dependency5__.removeObserver;
    var addBeforeObserver = __dependency5__.addBeforeObserver;
    var removeBeforeObserver = __dependency5__.removeBeforeObserver;
    var propertyWillChange = __dependency6__.propertyWillChange;
    var propertyDidChange = __dependency6__.propertyDidChange;
    var computed = __dependency7__.computed;
    var defineProperty = __dependency8__.defineProperty;
    var observer = __dependency9__.observer;
    var fmt = __dependency10__.fmt;
    var EmberObject = __dependency11__["default"];

    function contentPropertyWillChange(content, contentKey) {
      var key = contentKey.slice(8); // remove "content."
      if (key in this) { return; }  // if shadowed in proxy
      propertyWillChange(this, key);
    }

    function contentPropertyDidChange(content, contentKey) {
      var key = contentKey.slice(8); // remove "content."
      if (key in this) { return; } // if shadowed in proxy
      propertyDidChange(this, key);
    }

    
    var ObjectProxy = EmberObject.extend({
      
      content: null,
      _contentDidChange: observer('content', function() {
        Ember.assert("Can't set ObjectProxy's content to itself", get(this, 'content') !== this);
      }),

      isTruthy: computed.bool('content'),

      _debugContainerKey: null,

      willWatchProperty: function (key) {
        var contentKey = 'content.' + key;
        addBeforeObserver(this, contentKey, null, contentPropertyWillChange);
        addObserver(this, contentKey, null, contentPropertyDidChange);
      },

      didUnwatchProperty: function (key) {
        var contentKey = 'content.' + key;
        removeBeforeObserver(this, contentKey, null, contentPropertyWillChange);
        removeObserver(this, contentKey, null, contentPropertyDidChange);
      },

      unknownProperty: function (key) {
        var content = get(this, 'content');
        if (content) {
          return get(content, key);
        }
      },

      setUnknownProperty: function (key, value) {
        var m = meta(this);
        if (m.proto === this) {
          // if marked as prototype then just defineProperty
          // rather than delegate
          defineProperty(this, key, null, value);
          return value;
        }

        var content = get(this, 'content');
        Ember.assert(fmt("Cannot delegate set('%@', %@) to the 'content' property of object proxy %@: its 'content' is undefined.", [key, value, this]), content);
        return set(content, key, value);
      }

    });

    __exports__["default"] = ObjectProxy;
  });
define("ember-runtime/system/set",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/is_none","ember-runtime/system/string","ember-runtime/system/core_object","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/enumerable","ember-runtime/mixins/copyable","ember-runtime/mixins/freezable","ember-metal/error","ember-metal/property_events","ember-metal/mixin","ember-metal/computed","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) {
    "use strict";
    
    var Ember = __dependency1__["default"];
    // Ember.isNone

    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var guidFor = __dependency4__.guidFor;
    var isNone = __dependency5__.isNone;
    var fmt = __dependency6__.fmt;
    var CoreObject = __dependency7__["default"];
    var MutableEnumerable = __dependency8__["default"];
    var Enumerable = __dependency9__["default"];
    var Copyable = __dependency10__["default"];
    var Freezable = __dependency11__.Freezable;
    var FROZEN_ERROR = __dependency11__.FROZEN_ERROR;
    var EmberError = __dependency12__["default"];
    var propertyWillChange = __dependency13__.propertyWillChange;
    var propertyDidChange = __dependency13__.propertyDidChange;
    var aliasMethod = __dependency14__.aliasMethod;
    var computed = __dependency15__.computed;

    
    __exports__["default"] = CoreObject.extend(MutableEnumerable, Copyable, Freezable, {

      // ..........................................................
      // IMPLEMENT ENUMERABLE APIS
      //

      
      length: 0,

      
      clear: function() {
        if (this.isFrozen) { throw new EmberError(FROZEN_ERROR); }

        var len = get(this, 'length');
        if (len === 0) { return this; }

        var guid;

        this.enumerableContentWillChange(len, 0);
        propertyWillChange(this, 'firstObject');
        propertyWillChange(this, 'lastObject');

        for (var i=0; i < len; i++) {
          guid = guidFor(this[i]);
          delete this[guid];
          delete this[i];
        }

        set(this, 'length', 0);

        propertyDidChange(this, 'firstObject');
        propertyDidChange(this, 'lastObject');
        this.enumerableContentDidChange(len, 0);

        return this;
      },

      
      isEqual: function(obj) {
        // fail fast
        if (!Enumerable.detect(obj)) return false;

        var loc = get(this, 'length');
        if (get(obj, 'length') !== loc) return false;

        while(--loc >= 0) {
          if (!obj.contains(this[loc])) return false;
        }

        return true;
      },

      
      add: aliasMethod('addObject'),

      
      remove: aliasMethod('removeObject'),

      
      pop: function() {
        if (get(this, 'isFrozen')) throw new EmberError(FROZEN_ERROR);
        var obj = this.length > 0 ? this[this.length-1] : null;
        this.remove(obj);
        return obj;
      },

      
      push: aliasMethod('addObject'),

      
      shift: aliasMethod('pop'),

      
      unshift: aliasMethod('push'),

      
      addEach: aliasMethod('addObjects'),

      
      removeEach: aliasMethod('removeObjects'),

      // ..........................................................
      // PRIVATE ENUMERABLE SUPPORT
      //

      init: function(items) {
        this._super();
        if (items) this.addObjects(items);
      },

      // implement Ember.Enumerable
      nextObject: function(idx) {
        return this[idx];
      },

      // more optimized version
      firstObject: computed(function() {
        return this.length > 0 ? this[0] : undefined;
      }),

      // more optimized version
      lastObject: computed(function() {
        return this.length > 0 ? this[this.length-1] : undefined;
      }),

      // implements Ember.MutableEnumerable
      addObject: function(obj) {
        if (get(this, 'isFrozen')) throw new EmberError(FROZEN_ERROR);
        if (isNone(obj)) return this; // nothing to do

        var guid = guidFor(obj),
            idx  = this[guid],
            len  = get(this, 'length'),
            added ;

        if (idx>=0 && idx<len && (this[idx] === obj)) return this; // added

        added = [obj];

        this.enumerableContentWillChange(null, added);
        propertyWillChange(this, 'lastObject');

        len = get(this, 'length');
        this[guid] = len;
        this[len] = obj;
        set(this, 'length', len+1);

        propertyDidChange(this, 'lastObject');
        this.enumerableContentDidChange(null, added);

        return this;
      },

      // implements Ember.MutableEnumerable
      removeObject: function(obj) {
        if (get(this, 'isFrozen')) throw new EmberError(FROZEN_ERROR);
        if (isNone(obj)) return this; // nothing to do

        var guid = guidFor(obj),
            idx  = this[guid],
            len = get(this, 'length'),
            isFirst = idx === 0,
            isLast = idx === len-1,
            last, removed;


        if (idx>=0 && idx<len && (this[idx] === obj)) {
          removed = [obj];

          this.enumerableContentWillChange(removed, null);
          if (isFirst) { propertyWillChange(this, 'firstObject'); }
          if (isLast)  { propertyWillChange(this, 'lastObject'); }

          // swap items - basically move the item to the end so it can be removed
          if (idx < len-1) {
            last = this[len-1];
            this[idx] = last;
            this[guidFor(last)] = idx;
          }

          delete this[guid];
          delete this[len-1];
          set(this, 'length', len-1);

          if (isFirst) { propertyDidChange(this, 'firstObject'); }
          if (isLast)  { propertyDidChange(this, 'lastObject'); }
          this.enumerableContentDidChange(removed, null);
        }

        return this;
      },

      // optimized version
      contains: function(obj) {
        return this[guidFor(obj)]>=0;
      },

      copy: function() {
        var C = this.constructor, ret = new C(), loc = get(this, 'length');
        set(ret, 'length', loc);
        while(--loc>=0) {
          ret[loc] = this[loc];
          ret[guidFor(this[loc])] = loc;
        }
        return ret;
      },

      toString: function() {
        var len = this.length, idx, array = [];
        for(idx = 0; idx < len; idx++) {
          array[idx] = this[idx];
        }
        return fmt("Ember.Set<%@>", [array.join(',')]);
      }
    });
  });
define("ember-runtime/system/string",
  ["ember-metal/core","ember-metal/utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    
    var Ember = __dependency1__["default"];
    // Ember.STRINGS, Ember.FEATURES
    var isArray = __dependency2__.isArray;
    var emberInspect = __dependency2__.inspect;

    var STRING_DASHERIZE_REGEXP = (/[ _]/g);
    var STRING_DASHERIZE_CACHE = {};
    var STRING_DECAMELIZE_REGEXP = (/([a-z\d])([A-Z])/g);
    var STRING_CAMELIZE_REGEXP = (/(\-|_|\.|\s)+(.)?/g);
    var STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g);
    var STRING_UNDERSCORE_REGEXP_2 = (/\-|\s+/g);

    function fmt(str, formats) {
      if (!isArray(formats) || arguments.length > 2) {
        formats = Array.prototype.slice.call(arguments, 1);
      }

      // first, replace any ORDERED replacements.
      var idx  = 0; // the current index for non-numerical replacements
      return str.replace(/%@([0-9]+)?/g, function(s, argIndex) {
        argIndex = (argIndex) ? parseInt(argIndex, 10) - 1 : idx++;
        s = formats[argIndex];
        return (s === null) ? '(null)' : (s === undefined) ? '' : emberInspect(s);
      });
    }

    function loc(str, formats) {
      if (!isArray(formats) || arguments.length > 2) {
        formats = Array.prototype.slice.call(arguments, 1);
      }

      str = Ember.STRINGS[str] || str;
      return fmt(str, formats);
    }

    function w(str) {
      return str.split(/\s+/);
    }

    function decamelize(str) {
      return str.replace(STRING_DECAMELIZE_REGEXP, '$1_$2').toLowerCase();
    }

    function dasherize(str) {
      var cache = STRING_DASHERIZE_CACHE,
          hit   = cache.hasOwnProperty(str),
          ret;

      if (hit) {
        return cache[str];
      } else {
        ret = decamelize(str).replace(STRING_DASHERIZE_REGEXP,'-');
        cache[str] = ret;
      }

      return ret;
    }

    function camelize(str) {
      return str.replace(STRING_CAMELIZE_REGEXP, function(match, separator, chr) {
        return chr ? chr.toUpperCase() : '';
      }).replace(/^([A-Z])/, function(match, separator, chr) {
        return match.toLowerCase();
      });
    }

    function classify(str) {
      var parts = str.split("."),
          out = [];

      for (var i=0, l=parts.length; i<l; i++) {
        var camelized = camelize(parts[i]);
        out.push(camelized.charAt(0).toUpperCase() + camelized.substr(1));
      }

      return out.join(".");
    }

    function underscore(str) {
      return str.replace(STRING_UNDERSCORE_REGEXP_1, '$1_$2').
        replace(STRING_UNDERSCORE_REGEXP_2, '_').toLowerCase();
    }

    function capitalize(str) {
      return str.charAt(0).toUpperCase() + str.substr(1);
    }

    
    Ember.STRINGS = {};

    
    __exports__["default"] = {
      
      fmt: fmt,

      
      loc: loc,

      
      w: w,

      
      decamelize: decamelize,

      
      dasherize: dasherize,

      
      camelize: camelize,

      
      classify: classify,

      
      underscore: underscore,

      
      capitalize: capitalize
    };

    __exports__.fmt = fmt;
    __exports__.loc = loc;
    __exports__.w = w;
    __exports__.decamelize = decamelize;
    __exports__.dasherize = dasherize;
    __exports__.camelize = camelize;
    __exports__.classify = classify;
    __exports__.underscore = underscore;
    __exports__.capitalize = capitalize;
  });
define("ember-runtime/system/subarray",
  ["ember-metal/property_get","ember-metal/error","ember-metal/enumerable_utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var EmberError = __dependency2__["default"];
    var EnumerableUtils = __dependency3__["default"];

    var RETAIN = 'r';
    var FILTER = 'f';

    function Operation(type, count) {
      this.type = type;
      this.count = count;
    }

    __exports__["default"] = SubArray;

    
    function SubArray (length) {
      if (arguments.length < 1) { length = 0; }

      if (length > 0) {
        this._operations = [new Operation(RETAIN, length)];
      } else {
        this._operations = [];
      }
    }


    SubArray.prototype = {
      
      addItem: function(index, match) {
        var returnValue = -1,
            itemType = match ? RETAIN : FILTER,
            self = this;

        this._findOperation(index, function(operation, operationIndex, rangeStart, rangeEnd, seenInSubArray) {
          var newOperation, splitOperation;

          if (itemType === operation.type) {
            ++operation.count;
          } else if (index === rangeStart) {
            // insert to the left of `operation`
            self._operations.splice(operationIndex, 0, new Operation(itemType, 1));
          } else {
            newOperation = new Operation(itemType, 1);
            splitOperation = new Operation(operation.type, rangeEnd - index + 1);
            operation.count = index - rangeStart;

            self._operations.splice(operationIndex + 1, 0, newOperation, splitOperation);
          }

          if (match) {
            if (operation.type === RETAIN) {
              returnValue = seenInSubArray + (index - rangeStart);
            } else {
              returnValue = seenInSubArray;
            }
          }

          self._composeAt(operationIndex);
        }, function(seenInSubArray) {
          self._operations.push(new Operation(itemType, 1));

          if (match) {
            returnValue = seenInSubArray;
          }

          self._composeAt(self._operations.length-1);
        });

        return returnValue;
      },

      
      removeItem: function(index) {
        var returnValue = -1,
            self = this;

        this._findOperation(index, function (operation, operationIndex, rangeStart, rangeEnd, seenInSubArray) {
          if (operation.type === RETAIN) {
            returnValue = seenInSubArray + (index - rangeStart);
          }

          if (operation.count > 1) {
            --operation.count;
          } else {
            self._operations.splice(operationIndex, 1);
            self._composeAt(operationIndex);
          }
        }, function() {
          throw new EmberError("Can't remove an item that has never been added.");
        });

        return returnValue;
      },


      _findOperation: function (index, foundCallback, notFoundCallback) {
        var operationIndex,
            len,
            operation,
            rangeStart,
            rangeEnd,
            seenInSubArray = 0;

        // OPTIMIZE: change to balanced tree
        // find leftmost operation to the right of `index`
        for (operationIndex = rangeStart = 0, len = this._operations.length; operationIndex < len; rangeStart = rangeEnd + 1, ++operationIndex) {
          operation = this._operations[operationIndex];
          rangeEnd = rangeStart + operation.count - 1;

          if (index >= rangeStart && index <= rangeEnd) {
            foundCallback(operation, operationIndex, rangeStart, rangeEnd, seenInSubArray);
            return;
          } else if (operation.type === RETAIN) {
            seenInSubArray += operation.count;
          }
        }

        notFoundCallback(seenInSubArray);
      },

      _composeAt: function(index) {
        var op = this._operations[index],
            otherOp;

        if (!op) {
          // Composing out of bounds is a no-op, as when removing the last operation
          // in the list.
          return;
        }

        if (index > 0) {
          otherOp = this._operations[index-1];
          if (otherOp.type === op.type) {
            op.count += otherOp.count;
            this._operations.splice(index-1, 1);
            --index;
          }
        }

        if (index < this._operations.length-1) {
          otherOp = this._operations[index+1];
          if (otherOp.type === op.type) {
            op.count += otherOp.count;
            this._operations.splice(index+1, 1);
          }
        }
      },

      toString: function () {
        var str = "";
        EnumerableUtils.forEach(this._operations, function (operation) {
          str += " " + operation.type + ":" + operation.count;
        });
        return str.substring(1);
      }
    };
  });
define("ember-runtime/system/tracked_array",
  ["ember-metal/property_get","ember-metal/enumerable_utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var get = __dependency1__.get;
    var forEach = __dependency2__.forEach;

    var RETAIN = 'r';
    var INSERT = 'i';
    var DELETE = 'd';

    __exports__["default"] = TrackedArray;

    
    function TrackedArray(items) {
      if (arguments.length < 1) { items = []; }

      var length = get(items, 'length');

      if (length) {
        this._operations = [new ArrayOperation(RETAIN, length, items)];
      } else {
        this._operations = [];
      }
    }

    TrackedArray.RETAIN = RETAIN;
    TrackedArray.INSERT = INSERT;
    TrackedArray.DELETE = DELETE;

    TrackedArray.prototype = {

      
      addItems: function (index, newItems) {
        var count = get(newItems, 'length');
        if (count < 1) { return; }

        var match = this._findArrayOperation(index),
            arrayOperation = match.operation,
            arrayOperationIndex = match.index,
            arrayOperationRangeStart = match.rangeStart,
            composeIndex,
            splitIndex,
            splitItems,
            splitArrayOperation,
            newArrayOperation;

        newArrayOperation = new ArrayOperation(INSERT, count, newItems);

        if (arrayOperation) {
          if (!match.split) {
            // insert left of arrayOperation
            this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
            composeIndex = arrayOperationIndex;
          } else {
            this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
            composeIndex = arrayOperationIndex + 1;
          }
        } else {
          // insert at end
          this._operations.push(newArrayOperation);
          composeIndex = arrayOperationIndex;
        }

        this._composeInsert(composeIndex);
      },

      
      removeItems: function (index, count) {
        if (count < 1) { return; }

        var match = this._findArrayOperation(index),
            arrayOperation = match.operation,
            arrayOperationIndex = match.index,
            arrayOperationRangeStart = match.rangeStart,
            newArrayOperation,
            composeIndex;

        newArrayOperation = new ArrayOperation(DELETE, count);
        if (!match.split) {
          // insert left of arrayOperation
          this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
          composeIndex = arrayOperationIndex;
        } else {
          this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
          composeIndex = arrayOperationIndex + 1;
        }

        return this._composeDelete(composeIndex);
      },

      
      apply: function (callback) {
        var items = [],
            offset = 0;

        forEach(this._operations, function (arrayOperation, operationIndex) {
          callback(arrayOperation.items, offset, arrayOperation.type, operationIndex);

          if (arrayOperation.type !== DELETE) {
            offset += arrayOperation.count;
            items = items.concat(arrayOperation.items);
          }
        });

        this._operations = [new ArrayOperation(RETAIN, items.length, items)];
      },

      
      _findArrayOperation: function (index) {
        var arrayOperationIndex,
            len,
            split = false,
            arrayOperation,
            arrayOperationRangeStart,
            arrayOperationRangeEnd;

        // OPTIMIZE: we could search these faster if we kept a balanced tree.
        // find leftmost arrayOperation to the right of `index`
        for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._operations.length; arrayOperationIndex < len; ++arrayOperationIndex) {
          arrayOperation = this._operations[arrayOperationIndex];

          if (arrayOperation.type === DELETE) { continue; }

          arrayOperationRangeEnd = arrayOperationRangeStart + arrayOperation.count - 1;

          if (index === arrayOperationRangeStart) {
            break;
          } else if (index > arrayOperationRangeStart && index <= arrayOperationRangeEnd) {
            split = true;
            break;
          } else {
            arrayOperationRangeStart = arrayOperationRangeEnd + 1;
          }
        }

        return new ArrayOperationMatch(arrayOperation, arrayOperationIndex, split, arrayOperationRangeStart);
      },

      _split: function (arrayOperationIndex, splitIndex, newArrayOperation) {
        var arrayOperation = this._operations[arrayOperationIndex];
        var splitItems = arrayOperation.items.slice(splitIndex);
        var splitArrayOperation = new ArrayOperation(arrayOperation.type, splitItems.length, splitItems);

        // truncate LHS
        arrayOperation.count = splitIndex;
        arrayOperation.items = arrayOperation.items.slice(0, splitIndex);

        this._operations.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation);
      },

      // see SubArray for a better implementation.
      _composeInsert: function (index) {
        var newArrayOperation = this._operations[index],
            leftArrayOperation = this._operations[index-1], // may be undefined
            rightArrayOperation = this._operations[index+1], // may be undefined
            leftOp = leftArrayOperation && leftArrayOperation.type,
            rightOp = rightArrayOperation && rightArrayOperation.type;

        if (leftOp === INSERT) {
            // merge left
            leftArrayOperation.count += newArrayOperation.count;
            leftArrayOperation.items = leftArrayOperation.items.concat(newArrayOperation.items);

          if (rightOp === INSERT) {
            // also merge right (we have split an insert with an insert)
            leftArrayOperation.count += rightArrayOperation.count;
            leftArrayOperation.items = leftArrayOperation.items.concat(rightArrayOperation.items);
            this._operations.splice(index, 2);
          } else {
            // only merge left
            this._operations.splice(index, 1);
          }
        } else if (rightOp === INSERT) {
          // merge right
          newArrayOperation.count += rightArrayOperation.count;
          newArrayOperation.items = newArrayOperation.items.concat(rightArrayOperation.items);
          this._operations.splice(index + 1, 1);
        }
      },

      _composeDelete: function (index) {
        var arrayOperation = this._operations[index],
            deletesToGo = arrayOperation.count,
            leftArrayOperation = this._operations[index-1], // may be undefined
            leftOp = leftArrayOperation && leftArrayOperation.type,
            nextArrayOperation,
            nextOp,
            nextCount,
            removeNewAndNextOp = false,
            removedItems = [];

        if (leftOp === DELETE) {
          arrayOperation = leftArrayOperation;
          index -= 1;
        }

        for (var i = index + 1; deletesToGo > 0; ++i) {
          nextArrayOperation = this._operations[i];
          nextOp = nextArrayOperation.type;
          nextCount = nextArrayOperation.count;

          if (nextOp === DELETE) {
            arrayOperation.count += nextCount;
            continue;
          }

          if (nextCount > deletesToGo) {
            // d:2 {r,i}:5  we reduce the retain or insert, but it stays
            removedItems = removedItems.concat(nextArrayOperation.items.splice(0, deletesToGo));
            nextArrayOperation.count -= deletesToGo;

            // In the case where we truncate the last arrayOperation, we don't need to
            // remove it; also the deletesToGo reduction is not the entirety of
            // nextCount
            i -= 1;
            nextCount = deletesToGo;

            deletesToGo = 0;
          } else {
            if (nextCount === deletesToGo) {
              // Handle edge case of d:2 i:2 in which case both operations go away
              // during composition.
              removeNewAndNextOp = true;
            }
            removedItems = removedItems.concat(nextArrayOperation.items);
            deletesToGo -= nextCount;
          }

          if (nextOp === INSERT) {
            // d:2 i:3 will result in delete going away
            arrayOperation.count -= nextCount;
          }
        }

        if (arrayOperation.count > 0) {
          // compose our new delete with possibly several operations to the right of
          // disparate types
          this._operations.splice(index+1, i-1-index);
        } else {
          // The delete operation can go away; it has merely reduced some other
          // operation, as in d:3 i:4; it may also have eliminated that operation,
          // as in d:3 i:3.
          this._operations.splice(index, removeNewAndNextOp ? 2 : 1);
        }

        return removedItems;
      },

      toString: function () {
        var str = "";
        forEach(this._operations, function (operation) {
          str += " " + operation.type + ":" + operation.count;
        });
        return str.substring(1);
      }
    };

    
    function ArrayOperation (operation, count, items) {
      this.type = operation; // RETAIN | INSERT | DELETE
      this.count = count;
      this.items = items;
    }

    
    function ArrayOperationMatch(operation, index, split, rangeStart) {
      this.operation = operation;
      this.index = index;
      this.split = split;
      this.rangeStart = rangeStart;
    }
  });
define("ember-testing",
  ["ember-metal/core","ember-testing/initializers","ember-testing/support","ember-testing/setup_for_testing","ember-testing/test","ember-testing/adapters/adapter","ember-testing/adapters/qunit","ember-testing/helpers"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__) {
    "use strict";
    var Ember = __dependency1__["default"];

    // to setup initializer
         // to handle various edge cases

    var setupForTesting = __dependency4__["default"];
    var Test = __dependency5__["default"];
    var Adapter = __dependency6__["default"];
    var QUnitAdapter = __dependency7__["default"];
         // adds helpers to helpers object in Test

    

    Ember.Test = Test;
    Ember.Test.Adapter = Adapter;
    Ember.Test.QUnitAdapter = QUnitAdapter;
    Ember.setupForTesting = setupForTesting;
  });
define("ember-testing/adapters/adapter",
  ["ember-metal/core","ember-metal/utils","ember-runtime/system/object","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.K
    var inspect = __dependency2__.inspect;
    var EmberObject = __dependency3__["default"];

    

    
    var Adapter = EmberObject.extend({
      
      asyncStart: Ember.K,

      
      asyncEnd: Ember.K,

      
      exception: function(error) {
        throw error;
      }
    });

    __exports__["default"] = Adapter;
  });
define("ember-testing/adapters/qunit",
  ["ember-testing/adapters/adapter","ember-metal/utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Adapter = __dependency1__["default"];
    var inspect = __dependency2__.inspect;

    
    __exports__["default"] = Adapter.extend({
      asyncStart: function() {
        QUnit.stop();
      },
      asyncEnd: function() {
        QUnit.start();
      },
      exception: function(error) {
        ok(false, inspect(error));
      }
    });
  });
define("ember-testing/helpers",
  ["ember-metal/property_get","ember-metal/error","ember-metal/run_loop","ember-views/system/jquery","ember-testing/test"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
    "use strict";
    var get = __dependency1__.get;
    var EmberError = __dependency2__["default"];
    var run = __dependency3__["default"];
    var jQuery = __dependency4__["default"];
    var Test = __dependency5__["default"];

    

    var helper = Test.registerHelper;
    var asyncHelper = Test.registerAsyncHelper;
    var countAsync = 0;

    function currentRouteName(app){
      var appController = app.__container__.lookup('controller:application');

      return get(appController, 'currentRouteName');
    }

    function currentPath(app){
      var appController = app.__container__.lookup('controller:application');

      return get(appController, 'currentPath');
    }

    function currentURL(app){
      var router = app.__container__.lookup('router:main');

      return get(router, 'location').getURL();
    }

    function visit(app, url) {
      var router = app.__container__.lookup('router:main');
      router.location.setURL(url);

      if (app._readinessDeferrals > 0) {
        router['initialURL'] = url;
        run(app, 'advanceReadiness');
        delete router['initialURL'];
      } else {
        run(app, app.handleURL, url);
      }

      return app.testHelpers.wait();
    }

    function click(app, selector, context) {
      var $el = app.testHelpers.findWithAssert(selector, context);
      run($el, 'mousedown');

      if ($el.is(':input')) {
        var type = $el.prop('type');
        if (type !== 'checkbox' && type !== 'radio' && type !== 'hidden') {
          run($el, function(){
            // Firefox does not trigger the `focusin` event if the window
            // does not have focus. If the document doesn't have focus just
            // use trigger('focusin') instead.
            if (!document.hasFocus || document.hasFocus()) {
              this.focus();
            } else {
              this.trigger('focusin');
            }
          });
        }
      }

      run($el, 'mouseup');
      run($el, 'click');

      return app.testHelpers.wait();
    }

    function triggerEvent(app, selector, context, type, options){
      if (arguments.length === 3) {
        // context and options are optional, so this is
        // app, selector, type
        type = context;
        context = null;
        options = {};
      }

      if (arguments.length === 4) {
        // context and options are optional, so this is
        if (typeof type === "object") {  // either
          // app, selector, type, options
          options = type;
          type = context;
          context = null;
        } else { // or
          // app, selector, context, type
          options = {};
        }
      }

      var $el = app.testHelpers.findWithAssert(selector, context);

      var event = jQuery.Event(type, options);

      run($el, 'trigger', event);

      return app.testHelpers.wait();
    }

    function keyEvent(app, selector, context, type, keyCode) {
      if (typeof keyCode === 'undefined') {
        keyCode = type;
        type = context;
        context = null;
      }

      return app.testHelpers.triggerEvent(selector, context, type, { keyCode: keyCode, which: keyCode });
    }

    function fillIn(app, selector, context, text) {
      var $el;
      if (typeof text === 'undefined') {
        text = context;
        context = null;
      }
      $el = app.testHelpers.findWithAssert(selector, context);
      run(function() {
        $el.val(text).change();
      });
      return app.testHelpers.wait();
    }

    function findWithAssert(app, selector, context) {
      var $el = app.testHelpers.find(selector, context);
      if ($el.length === 0) {
        throw new EmberError("Element " + selector + " not found.");
      }
      return $el;
    }

    function find(app, selector, context) {
      var $el;
      context = context || get(app, 'rootElement');
      $el = app.$(selector, context);

      return $el;
    }

    function andThen(app, callback) {
      return app.testHelpers.wait(callback(app));
    }

    function wait(app, value) {
      return Test.promise(function(resolve) {
        // If this is the first async promise, kick off the async test
        if (++countAsync === 1) {
          Test.adapter.asyncStart();
        }

        // Every 10ms, poll for the async thing to have finished
        var watcher = setInterval(function() {
          // 1. If the router is loading, keep polling
          var routerIsLoading = !!app.__container__.lookup('router:main').router.activeTransition;
          if (routerIsLoading) { return; }

          // 2. If there are pending Ajax requests, keep polling
          if (Test.pendingAjaxRequests) { return; }

          // 3. If there are scheduled timers or we are inside of a run loop, keep polling
          if (run.hasScheduledTimers() || run.currentRunLoop) { return; }
          if (Test.waiters && Test.waiters.any(function(waiter) {
            var context = waiter[0];
            var callback = waiter[1];
            return !callback.call(context);
          })) { return; }
          // Stop polling
          clearInterval(watcher);

          // If this is the last async promise, end the async test
          if (--countAsync === 0) {
            Test.adapter.asyncEnd();
          }

          // Synchronously resolve the promise
          run(null, resolve, value);
        }, 10);
      });

    }


    
    asyncHelper('visit', visit);

    
    asyncHelper('click', click);

    
    asyncHelper('keyEvent', keyEvent);

    
    asyncHelper('fillIn', fillIn);

    
    helper('find', find);

    
    helper('findWithAssert', findWithAssert);

    
    asyncHelper('wait', wait);
    asyncHelper('andThen', andThen);


    
    helper('currentRouteName', currentRouteName);

    
    helper('currentPath', currentPath);

    
    helper('currentURL', currentURL);

    
    asyncHelper('triggerEvent', triggerEvent);
  });
define("ember-testing/initializers",
  ["ember-runtime/system/lazy_load"],
  function(__dependency1__) {
    "use strict";
    var onLoad = __dependency1__.onLoad;

    var name = 'deferReadiness in `testing` mode';

    onLoad('Ember.Application', function(Application) {
      if (!Application.initializers[name]) {
        Application.initializer({
          name: name,

          initialize: function(container, application){
            if (application.testing) {
              application.deferReadiness();
            }
          }
        });
      }
    });
  });
define("ember-testing/setup_for_testing",
  ["ember-metal/core","ember-testing/adapters/qunit","ember-views/system/jquery","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // import Test from "ember-testing/test";  // ES6TODO: fix when cycles are supported
    var QUnitAdapter = __dependency2__["default"];
    var jQuery = __dependency3__["default"];

    var Test, requests;

    function incrementAjaxPendingRequests(_, xhr){
      requests.push(xhr);
      Test.pendingAjaxRequests = requests.length;
    }

    function decrementAjaxPendingRequests(_, xhr){
      for (var i=0;i<requests.length;i++) {
        if (xhr === requests[i]) {
          requests.splice(i, 1);
        }
      }
      Test.pendingAjaxRequests = requests.length;
    }

    
    __exports__["default"] = function setupForTesting() {
      if (!Test) { Test = requireModule('ember-testing/test')['default']; }

      Ember.testing = true;

      // if adapter is not manually set default to QUnit
      if (!Test.adapter) {
        Test.adapter = QUnitAdapter.create();
      }

      requests = [];
      Test.pendingAjaxRequests = requests.length;

      jQuery(document).off('ajaxSend', incrementAjaxPendingRequests);
      jQuery(document).off('ajaxComplete', decrementAjaxPendingRequests);
      jQuery(document).on('ajaxSend', incrementAjaxPendingRequests);
      jQuery(document).on('ajaxComplete', decrementAjaxPendingRequests);
    }
  });
define("ember-testing/support",
  ["ember-metal/core","ember-views/system/jquery"],
  function(__dependency1__, __dependency2__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var jQuery = __dependency2__["default"];

    

    var $ = jQuery;

    
    function testCheckboxClick(handler) {
      $('<input type="checkbox">')
        .css({ position: 'absolute', left: '-1000px', top: '-1000px' })
        .appendTo('body')
        .on('click', handler)
        .trigger('click')
        .remove();
    }

    $(function() {
      
      testCheckboxClick(function() {
        if (!this.checked && !$.event.special.click) {
          $.event.special.click = {
            // For checkbox, fire native event so checked state will be right
            trigger: function() {
              if ($.nodeName( this, "input" ) && this.type === "checkbox" && this.click) {
                this.click();
                return false;
              }
            }
          };
        }
      });

      // Try again to verify that the patch took effect or blow up.
      testCheckboxClick(function() {
        Ember.warn("clicked checkboxes should be checked! the jQuery patch didn't work", this.checked);
      });
    });
  });
define("ember-testing/test",
  ["ember-metal/core","ember-metal/run_loop","ember-metal/platform","ember-runtime/compare","ember-runtime/ext/rsvp","ember-testing/setup_for_testing","ember-application/system/application","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    var emberRun = __dependency2__["default"];
    var create = __dependency3__.create;
    var compare = __dependency4__["default"];
    var RSVP = __dependency5__["default"];
    var setupForTesting = __dependency6__["default"];
    var EmberApplication = __dependency7__["default"];

    
    var slice = [].slice;
    var helpers = {};
    var injectHelpersCallbacks = [];

    
    var Test = {
      
      _helpers: helpers,

      
      registerHelper: function(name, helperMethod) {
        helpers[name] = {
          method: helperMethod,
          meta: { wait: false }
        };
      },

      
      registerAsyncHelper: function(name, helperMethod) {
        helpers[name] = {
          method: helperMethod,
          meta: { wait: true }
        };
      },

      
      unregisterHelper: function(name) {
        delete helpers[name];
        delete Test.Promise.prototype[name];
      },

      
      onInjectHelpers: function(callback) {
        injectHelpersCallbacks.push(callback);
      },

      
      promise: function(resolver) {
        return new Test.Promise(resolver);
      },

      
      adapter: null,

      
      resolve: function(val) {
        return Test.promise(function(resolve) {
          return resolve(val);
        });
      },

      
      registerWaiter: function(context, callback) {
        if (arguments.length === 1) {
          callback = context;
          context = null;
        }
        if (!this.waiters) {
          this.waiters = Ember.A();
        }
        this.waiters.push([context, callback]);
      },
      
      unregisterWaiter: function(context, callback) {
        var pair;
        if (!this.waiters) { return; }
        if (arguments.length === 1) {
          callback = context;
          context = null;
        }
        pair = [context, callback];
        this.waiters = Ember.A(this.waiters.filter(function(elt) {
          return compare(elt, pair)!==0;
        }));
      }
    };

    function helper(app, name) {
      var fn = helpers[name].method,
          meta = helpers[name].meta;

      return function() {
        var args = slice.call(arguments),
            lastPromise = Test.lastPromise;

        args.unshift(app);

        // some helpers are not async and
        // need to return a value immediately.
        // example: `find`
        if (!meta.wait) {
          return fn.apply(app, args);
        }

        if (!lastPromise) {
          // It's the first async helper in current context
          lastPromise = fn.apply(app, args);
        } else {
          // wait for last helper's promise to resolve
          // and then execute
          run(function() {
            lastPromise = Test.resolve(lastPromise).then(function() {
              return fn.apply(app, args);
            });
          });
        }

        return lastPromise;
      };
    }

    function run(fn) {
      if (!emberRun.currentRunLoop) {
        emberRun(fn);
      } else {
        fn();
      }
    }

    EmberApplication.reopen({
      
      testHelpers: {},

      
      originalMethods: {},


      
      testing: false,

      
      setupForTesting: function() {
        setupForTesting();

        this.testing = true;

        this.Router.reopen({
          location: 'none'
        });
      },

      
      helperContainer: window,

      
      injectTestHelpers: function(helperContainer) {
        if (helperContainer) { this.helperContainer = helperContainer; }

        this.testHelpers = {};
        for (var name in helpers) {
          this.originalMethods[name] = this.helperContainer[name];
          this.testHelpers[name] = this.helperContainer[name] = helper(this, name);
          protoWrap(Test.Promise.prototype, name, helper(this, name), helpers[name].meta.wait);
        }

        for(var i = 0, l = injectHelpersCallbacks.length; i < l; i++) {
          injectHelpersCallbacks[i](this);
        }
      },

      
      removeTestHelpers: function() {
        for (var name in helpers) {
          this.helperContainer[name] = this.originalMethods[name];
          delete this.testHelpers[name];
          delete this.originalMethods[name];
        }
      }
    });

    // This method is no longer needed
    // But still here for backwards compatibility
    // of helper chaining
    function protoWrap(proto, name, callback, isAsync) {
      proto[name] = function() {
        var args = arguments;
        if (isAsync) {
          return callback.apply(this, args);
        } else {
          return this.then(function() {
            return callback.apply(this, args);
          });
        }
      };
    }

    Test.Promise = function() {
      RSVP.Promise.apply(this, arguments);
      Test.lastPromise = this;
    };

    Test.Promise.prototype = create(RSVP.Promise.prototype);
    Test.Promise.prototype.constructor = Test.Promise;

    // Patch `then` to isolate async methods
    // specifically `Ember.Test.lastPromise`
    var originalThen = RSVP.Promise.prototype.then;
    Test.Promise.prototype.then = function(onSuccess, onFailure) {
      return originalThen.call(this, function(val) {
        return isolate(onSuccess, val);
      }, onFailure);
    };

    // This method isolates nested async methods
    // so that they don't conflict with other last promises.
    //
    // 1. Set `Ember.Test.lastPromise` to null
    // 2. Invoke method
    // 3. Return the last promise created during method
    // 4. Restore `Ember.Test.lastPromise` to original value
    function isolate(fn, val) {
      var value, lastPromise;

      // Reset lastPromise for nested helpers
      Test.lastPromise = null;

      value = fn(val);

      lastPromise = Test.lastPromise;

      // If the method returned a promise
      // return that promise. If not,
      // return the last async helper's promise
      if ((value && (value instanceof Test.Promise)) || !lastPromise) {
        return value;
      } else {
        run(function() {
          lastPromise = Test.resolve(lastPromise).then(function() {
            return value;
          });
        });
        return lastPromise;
      }
    }

    __exports__["default"] = Test;
  });
define("ember-views",
  ["ember-runtime","ember-views/system/jquery","ember-views/system/utils","ember-views/system/render_buffer","ember-views/system/ext","ember-views/views/states","ember-views/views/core_view","ember-views/views/view","ember-views/views/view_collection","ember-views/views/container_view","ember-views/views/collection_view","ember-views/views/component","ember-views/system/event_dispatcher","ember-views/mixins/view_target_action_support","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __exports__) {
    "use strict";
    

    // BEGIN IMPORTS
    var Ember = __dependency1__["default"];
    var jQuery = __dependency2__["default"];
    var setInnerHTML = __dependency3__.setInnerHTML;
    var isSimpleClick = __dependency3__.isSimpleClick;
    var RenderBuffer = __dependency4__["default"];
     // for the side effect of extending Ember.run.queues
    var cloneStates = __dependency6__.cloneStates;
    var states = __dependency6__.states;

    var CoreView = __dependency7__["default"];
    var View = __dependency8__["default"];
    var ViewCollection = __dependency9__["default"];
    var ContainerView = __dependency10__["default"];
    var CollectionView = __dependency11__["default"];
    var Component = __dependency12__["default"];

    var EventDispatcher = __dependency13__["default"];
    var ViewTargetActionSupport = __dependency14__["default"];
    // END IMPORTS

    

    // BEGIN EXPORTS
    Ember.$ = jQuery;

    Ember.ViewTargetActionSupport = ViewTargetActionSupport;
    Ember.RenderBuffer = RenderBuffer;

    var ViewUtils = Ember.ViewUtils = {};
    ViewUtils.setInnerHTML = setInnerHTML;
    ViewUtils.isSimpleClick = isSimpleClick;

    Ember.CoreView = CoreView;
    Ember.View = View;
    Ember.View.states = states;
    Ember.View.cloneStates = cloneStates;

    Ember._ViewCollection = ViewCollection;
    Ember.ContainerView = ContainerView;
    Ember.CollectionView = CollectionView;
    Ember.Component = Component;
    Ember.EventDispatcher = EventDispatcher;
    // END EXPORTS

    __exports__["default"] = Ember;
  });
define("ember-views/mixins/component_template_deprecation",
  ["ember-metal/core","ember-metal/property_get","ember-metal/mixin","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.deprecate
    var get = __dependency2__.get;
    var Mixin = __dependency3__.Mixin;

    
    __exports__["default"] = Mixin.create({
      
      willMergeMixin: function(props) {
        // must call _super here to ensure that the ActionHandler
        // mixin is setup properly (moves actions -> _actions)
        //
        // Calling super is only OK here since we KNOW that
        // there is another Mixin loaded first.
        this._super.apply(this, arguments);

        var deprecatedProperty, replacementProperty,
            layoutSpecified = (props.layoutName || props.layout || get(this, 'layoutName'));

        if (props.templateName && !layoutSpecified) {
          deprecatedProperty = 'templateName';
          replacementProperty = 'layoutName';

          props.layoutName = props.templateName;
          delete props['templateName'];
        }

        if (props.template && !layoutSpecified) {
          deprecatedProperty = 'template';
          replacementProperty = 'layout';

          props.layout = props.template;
          delete props['template'];
        }

        if (deprecatedProperty) {
          Ember.deprecate('Do not specify ' + deprecatedProperty + ' on a Component, use ' + replacementProperty + ' instead.', false);
        }
      }
    });
  });
define("ember-views/mixins/view_target_action_support",
  ["ember-metal/mixin","ember-runtime/mixins/target_action_support","ember-metal/computed","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Mixin = __dependency1__.Mixin;
    var TargetActionSupport = __dependency2__["default"];

    // ES6TODO: computed should have its own export path so you can do import {defaultTo} from computed
    var computed = __dependency3__.computed;
    var alias = computed.alias;

    
    __exports__["default"] = Mixin.create(TargetActionSupport, {
      
      target: alias('controller'),
      
      actionContext: alias('context')
    });
  });
define("ember-views/system/event_dispatcher",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/is_none","ember-metal/run_loop","ember-metal/utils","ember-runtime/system/string","ember-runtime/system/object","ember-views/system/jquery","ember-views/views/view","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) {
    "use strict";
    
    var Ember = __dependency1__["default"];
    // Ember.assert

    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var isNone = __dependency4__.isNone;
    var run = __dependency5__["default"];
    var typeOf = __dependency6__.typeOf;
    var fmt = __dependency7__.fmt;
    var EmberObject = __dependency8__["default"];
    var jQuery = __dependency9__["default"];
    var View = __dependency10__["default"];

    var ActionHelper;

    //ES6TODO:
    // find a better way to do Ember.View.views without global state

    
    __exports__["default"] = EmberObject.extend({

      
      events: {
        touchstart  : 'touchStart',
        touchmove   : 'touchMove',
        touchend    : 'touchEnd',
        touchcancel : 'touchCancel',
        keydown     : 'keyDown',
        keyup       : 'keyUp',
        keypress    : 'keyPress',
        mousedown   : 'mouseDown',
        mouseup     : 'mouseUp',
        contextmenu : 'contextMenu',
        click       : 'click',
        dblclick    : 'doubleClick',
        mousemove   : 'mouseMove',
        focusin     : 'focusIn',
        focusout    : 'focusOut',
        mouseenter  : 'mouseEnter',
        mouseleave  : 'mouseLeave',
        submit      : 'submit',
        input       : 'input',
        change      : 'change',
        dragstart   : 'dragStart',
        drag        : 'drag',
        dragenter   : 'dragEnter',
        dragleave   : 'dragLeave',
        dragover    : 'dragOver',
        drop        : 'drop',
        dragend     : 'dragEnd'
      },

      
      rootElement: 'body',

      
      canDispatchToEventManager: true,

      
      setup: function(addedEvents, rootElement) {
        var event, events = get(this, 'events');

        jQuery.extend(events, addedEvents || {});

        if (!isNone(rootElement)) {
          set(this, 'rootElement', rootElement);
        }

        rootElement = jQuery(get(this, 'rootElement'));

        Ember.assert(fmt('You cannot use the same root element (%@) multiple times in an Ember.Application', [rootElement.selector || rootElement[0].tagName]), !rootElement.is('.ember-application'));
        Ember.assert('You cannot make a new Ember.Application using a root element that is a descendent of an existing Ember.Application', !rootElement.closest('.ember-application').length);
        Ember.assert('You cannot make a new Ember.Application using a root element that is an ancestor of an existing Ember.Application', !rootElement.find('.ember-application').length);

        rootElement.addClass('ember-application');

        Ember.assert('Unable to add "ember-application" class to rootElement. Make sure you set rootElement to the body or an element in the body.', rootElement.is('.ember-application'));

        for (event in events) {
          if (events.hasOwnProperty(event)) {
            this.setupHandler(rootElement, event, events[event]);
          }
        }
      },

      
      setupHandler: function(rootElement, event, eventName) {
        var self = this;

        rootElement.on(event + '.ember', '.ember-view', function(evt, triggeringManager) {
          var view = View.views[this.id],
              result = true;

          var manager = self.canDispatchToEventManager ? self._findNearestEventManager(view, eventName) : null;

          if (manager && manager !== triggeringManager) {
            result = self._dispatchEvent(manager, evt, eventName, view);
          } else if (view) {
            result = self._bubbleEvent(view, evt, eventName);
          }

          return result;
        });

        rootElement.on(event + '.ember', '[data-ember-action]', function(evt) {
          //ES6TODO: Needed for ActionHelper (generally not available in ember-views test suite)
          if (!ActionHelper) { ActionHelper = requireModule("ember-routing-handlebars/helpers/action")["ActionHelper"]; }

          var actionId = jQuery(evt.currentTarget).attr('data-ember-action'),
              action   = ActionHelper.registeredActions[actionId];

          // We have to check for action here since in some cases, jQuery will trigger
          // an event on `removeChild` (i.e. focusout) after we've already torn down the
          // action handlers for the view.
          if (action && action.eventName === eventName) {
            return action.handler(evt);
          }
        });
      },

      _findNearestEventManager: function(view, eventName) {
        var manager = null;

        while (view) {
          manager = get(view, 'eventManager');
          if (manager && manager[eventName]) { break; }

          view = get(view, 'parentView');
        }

        return manager;
      },

      _dispatchEvent: function(object, evt, eventName, view) {
        var result = true;

        var handler = object[eventName];
        if (typeOf(handler) === 'function') {
          result = run(object, handler, evt, view);
          // Do not preventDefault in eventManagers.
          evt.stopPropagation();
        }
        else {
          result = this._bubbleEvent(view, evt, eventName);
        }

        return result;
      },

      _bubbleEvent: function(view, evt, eventName) {
        return run(view, view.handleEvent, eventName, evt);
      },

      destroy: function() {
        var rootElement = get(this, 'rootElement');
        jQuery(rootElement).off('.ember', '**').removeClass('ember-application');
        return this._super();
      },

      toString: function() {
        return '(EventDisptacher)';
      }
    });
  });
define("ember-views/system/ext",
  ["ember-metal/run_loop"],
  function(__dependency1__) {
    "use strict";
    

    var run = __dependency1__["default"];

    // Add a new named queue for rendering views that happens
    // after bindings have synced, and a queue for scheduling actions
    // that that should occur after view rendering.
    var queues = run.queues;
    run._addQueue('render', 'actions');
    run._addQueue('afterRender', 'render');
  });
define("ember-views/system/jquery",
  ["ember-metal/core","ember-runtime/system/string","ember-metal/enumerable_utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.assert
    var w = __dependency2__.w;

    // ES6TODO: the functions on EnumerableUtils need their own exports
    var forEach = __dependency3__.forEach;

    

    var jQuery = (Ember.imports && Ember.imports.jQuery) || (this && this.jQuery);
    if (!jQuery && typeof require === 'function') {
      jQuery = require('jquery');
    }

    Ember.assert("Ember Views require jQuery between 1.7 and 2.1", jQuery && (jQuery().jquery.match(/^((1\.(7|8|9|10|11))|(2\.(0|1)))(\.\d+)?(pre|rc\d?)?/) || Ember.ENV.FORCE_JQUERY));

    
    if (jQuery) {
      // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents
      var dragEvents = w('dragstart drag dragenter dragleave dragover drop dragend');

      // Copies the `dataTransfer` property from a browser event object onto the
      // jQuery event object for the specified events
      forEach(dragEvents, function(eventName) {
        jQuery.event.fixHooks[eventName] = { props: ['dataTransfer'] };
      });
    }

    __exports__["default"] = jQuery;
  });
define("ember-views/system/render_buffer",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-views/system/utils","ember-views/system/jquery","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // jQuery

    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var setInnerHTML = __dependency4__.setInnerHTML;
    var jQuery = __dependency5__["default"];

    function ClassSet() {
      this.seen = {};
      this.list = [];
    }

    ClassSet.prototype = {
      add: function(string) {
        if (string in this.seen) { return; }
        this.seen[string] = true;

        this.list.push(string);
      },

      toDOM: function() {
        return this.list.join(" ");
      }
    };

    var BAD_TAG_NAME_TEST_REGEXP = /[^a-zA-Z0-9\-]/;
    var BAD_TAG_NAME_REPLACE_REGEXP = /[^a-zA-Z0-9\-]/g;

    function stripTagName(tagName) {
      if (!tagName) {
        return tagName;
      }

      if (!BAD_TAG_NAME_TEST_REGEXP.test(tagName)) {
        return tagName;
      }

      return tagName.replace(BAD_TAG_NAME_REPLACE_REGEXP, '');
    }

    var BAD_CHARS_REGEXP = /&(?!\w+;)|[<>"'`]/g;
    var POSSIBLE_CHARS_REGEXP = /[&<>"'`]/;

    function escapeAttribute(value) {
      // Stolen shamelessly from Handlebars

      var escape = {
        "<": "&lt;",
        ">": "&gt;",
        '"': "&quot;",
        "'": "&#x27;",
        "`": "&#x60;"
      };

      var escapeChar = function(chr) {
        return escape[chr] || "&amp;";
      };

      var string = value.toString();

      if(!POSSIBLE_CHARS_REGEXP.test(string)) { return string; }
      return string.replace(BAD_CHARS_REGEXP, escapeChar);
    }

    // IE 6/7 have bugs around setting names on inputs during creation.
    // From http://msdn.microsoft.com/en-us/library/ie/ms536389(v=vs.85).aspx:
    // "To include the NAME attribute at run time on objects created with the createElement method, use the eTag."
    var canSetNameOnInputs = (function() {
      var div = document.createElement('div'),
          el = document.createElement('input');

      el.setAttribute('name', 'foo');
      div.appendChild(el);

      return !!div.innerHTML.match('foo');
    })();

    
    __exports__["default"] = function RenderBuffer(tagName) {
      return new _RenderBuffer(tagName); // jshint ignore:line
    }

    function _RenderBuffer(tagName) {
      this.tagNames = [tagName || null];
      this.buffer = "";
    }

    _RenderBuffer.prototype = {

      // The root view's element
      _element: null,

      _hasElement: true,

      
      elementClasses: null,

      
      classes: null,

      
      elementId: null,

      
      elementAttributes: null,

      
      elementProperties: null,

      
      elementTag: null,

      
      elementStyle: null,

      
      push: function(string) {
        this.buffer += string;
        return this;
      },

      
      addClass: function(className) {
        // lazily create elementClasses
        this.elementClasses = (this.elementClasses || new ClassSet());
        this.elementClasses.add(className);
        this.classes = this.elementClasses.list;

        return this;
      },

      setClasses: function(classNames) {
        this.elementClasses = null;
        var len = classNames.length, i;
        for (i = 0; i < len; i++) {
          this.addClass(classNames[i]);
        }
      },

      
      id: function(id) {
        this.elementId = id;
        return this;
      },

      // duck type attribute functionality like jQuery so a render buffer
      // can be used like a jQuery object in attribute binding scenarios.

      
      attr: function(name, value) {
        var attributes = this.elementAttributes = (this.elementAttributes || {});

        if (arguments.length === 1) {
          return attributes[name];
        } else {
          attributes[name] = value;
        }

        return this;
      },

      
      removeAttr: function(name) {
        var attributes = this.elementAttributes;
        if (attributes) { delete attributes[name]; }

        return this;
      },

      
      prop: function(name, value) {
        var properties = this.elementProperties = (this.elementProperties || {});

        if (arguments.length === 1) {
          return properties[name];
        } else {
          properties[name] = value;
        }

        return this;
      },

      
      removeProp: function(name) {
        var properties = this.elementProperties;
        if (properties) { delete properties[name]; }

        return this;
      },

      
      style: function(name, value) {
        this.elementStyle = (this.elementStyle || {});

        this.elementStyle[name] = value;
        return this;
      },

      begin: function(tagName) {
        this.tagNames.push(tagName || null);
        return this;
      },

      pushOpeningTag: function() {
        var tagName = this.currentTagName();
        if (!tagName) { return; }

        if (this._hasElement && !this._element && this.buffer.length === 0) {
          this._element = this.generateElement();
          return;
        }

        var buffer = this.buffer,
            id = this.elementId,
            classes = this.classes,
            attrs = this.elementAttributes,
            props = this.elementProperties,
            style = this.elementStyle,
            attr, prop;

        buffer += '<' + stripTagName(tagName);

        if (id) {
          buffer += ' id="' + escapeAttribute(id) + '"';
          this.elementId = null;
        }
        if (classes) {
          buffer += ' class="' + escapeAttribute(classes.join(' ')) + '"';
          this.classes = null;
          this.elementClasses = null;
        }

        if (style) {
          buffer += ' style="';

          for (prop in style) {
            if (style.hasOwnProperty(prop)) {
              buffer += prop + ':' + escapeAttribute(style[prop]) + ';';
            }
          }

          buffer += '"';

          this.elementStyle = null;
        }

        if (attrs) {
          for (attr in attrs) {
            if (attrs.hasOwnProperty(attr)) {
              buffer += ' ' + attr + '="' + escapeAttribute(attrs[attr]) + '"';
            }
          }

          this.elementAttributes = null;
        }

        if (props) {
          for (prop in props) {
            if (props.hasOwnProperty(prop)) {
              var value = props[prop];
              if (value || typeof(value) === 'number') {
                if (value === true) {
                  buffer += ' ' + prop + '="' + prop + '"';
                } else {
                  buffer += ' ' + prop + '="' + escapeAttribute(props[prop]) + '"';
                }
              }
            }
          }

          this.elementProperties = null;
        }

        buffer += '>';
        this.buffer = buffer;
      },

      pushClosingTag: function() {
        var tagName = this.tagNames.pop();
        if (tagName) { this.buffer += '</' + stripTagName(tagName) + '>'; }
      },

      currentTagName: function() {
        return this.tagNames[this.tagNames.length-1];
      },

      generateElement: function() {
        var tagName = this.tagNames.pop(), // pop since we don't need to close
            id = this.elementId,
            classes = this.classes,
            attrs = this.elementAttributes,
            props = this.elementProperties,
            style = this.elementStyle,
            styleBuffer = '', attr, prop, tagString;

        if (attrs && attrs.name && !canSetNameOnInputs) {
          // IE allows passing a tag to createElement. See note on `canSetNameOnInputs` above as well.
          tagString = '<'+stripTagName(tagName)+' name="'+escapeAttribute(attrs.name)+'">';
        } else {
          tagString = tagName;
        }

        var element = document.createElement(tagString),
            $element = jQuery(element);

        if (id) {
          $element.attr('id', id);
          this.elementId = null;
        }
        if (classes) {
          $element.attr('class', classes.join(' '));
          this.classes = null;
          this.elementClasses = null;
        }

        if (style) {
          for (prop in style) {
            if (style.hasOwnProperty(prop)) {
              styleBuffer += (prop + ':' + style[prop] + ';');
            }
          }

          $element.attr('style', styleBuffer);

          this.elementStyle = null;
        }

        if (attrs) {
          for (attr in attrs) {
            if (attrs.hasOwnProperty(attr)) {
              $element.attr(attr, attrs[attr]);
            }
          }

          this.elementAttributes = null;
        }

        if (props) {
          for (prop in props) {
            if (props.hasOwnProperty(prop)) {
              $element.prop(prop, props[prop]);
            }
          }

          this.elementProperties = null;
        }

        return element;
      },

      
      element: function() {
        var html = this.innerString();

        if (html) {
          this._element = setInnerHTML(this._element, html);
        }

        return this._element;
      },

      
      string: function() {
        if (this._hasElement && this._element) {
          // Firefox versions < 11 do not have support for element.outerHTML.
          var thisElement = this.element(), outerHTML = thisElement.outerHTML;
          if (typeof outerHTML === 'undefined') {
            return jQuery('<div/>').append(thisElement).html();
          }
          return outerHTML;
        } else {
          return this.innerString();
        }
      },

      innerString: function() {
        return this.buffer;
      }
    };
  });
define("ember-views/system/utils",
  ["ember-metal/core","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    

    var Ember = __dependency1__["default"];
    // Ember.assert

    

    

    // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
    // is a "zero-scope" element. This problem can be worked around by making
    // the first node an invisible text node. We, like Modernizr, use &shy;

    var needsShy = typeof document !== 'undefined' && (function() {
      var testEl = document.createElement('div');
      testEl.innerHTML = "<div></div>";
      testEl.firstChild.innerHTML = "<script></script>";
      return testEl.firstChild.innerHTML === '';
    })();

    // IE 8 (and likely earlier) likes to move whitespace preceeding
    // a script tag to appear after it. This means that we can
    // accidentally remove whitespace when updating a morph.
    var movesWhitespace = typeof document !== 'undefined' && (function() {
      var testEl = document.createElement('div');
      testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
      return testEl.childNodes[0].nodeValue === 'Test:' &&
              testEl.childNodes[2].nodeValue === ' Value';
    })();

    // Use this to find children by ID instead of using jQuery
    var findChildById = function(element, id) {
      if (element.getAttribute('id') === id) { return element; }

      var len = element.childNodes.length, idx, node, found;
      for (idx=0; idx<len; idx++) {
        node = element.childNodes[idx];
        found = node.nodeType === 1 && findChildById(node, id);
        if (found) { return found; }
      }
    };

    var setInnerHTMLWithoutFix = function(element, html) {
      if (needsShy) {
        html = '&shy;' + html;
      }

      var matches = [];
      if (movesWhitespace) {
        // Right now we only check for script tags with ids with the
        // goal of targeting morphs.
        html = html.replace(/(\s+)(<script id='([^']+)')/g, function(match, spaces, tag, id) {
          matches.push([id, spaces]);
          return tag;
        });
      }

      element.innerHTML = html;

      // If we have to do any whitespace adjustments do them now
      if (matches.length > 0) {
        var len = matches.length, idx;
        for (idx=0; idx<len; idx++) {
          var script = findChildById(element, matches[idx][0]),
              node = document.createTextNode(matches[idx][1]);
          script.parentNode.insertBefore(node, script);
        }
      }

      if (needsShy) {
        var shyElement = element.firstChild;
        while (shyElement.nodeType === 1 && !shyElement.nodeName) {
          shyElement = shyElement.firstChild;
        }
        if (shyElement.nodeType === 3 && shyElement.nodeValue.charAt(0) === "\u00AD") {
          shyElement.nodeValue = shyElement.nodeValue.slice(1);
        }
      }
    };

    


    var innerHTMLTags = {};
    var canSetInnerHTML = function(tagName) {
      if (innerHTMLTags[tagName] !== undefined) {
        return innerHTMLTags[tagName];
      }

      var canSet = true;

      // IE 8 and earlier don't allow us to do innerHTML on select
      if (tagName.toLowerCase() === 'select') {
        var el = document.createElement('select');
        setInnerHTMLWithoutFix(el, '<option value="test">Test</option>');
        canSet = el.options.length === 1;
      }

      innerHTMLTags[tagName] = canSet;

      return canSet;
    };

    function setInnerHTML(element, html) {
      var tagName = element.tagName;

      if (canSetInnerHTML(tagName)) {
        setInnerHTMLWithoutFix(element, html);
      } else {
        // Firefox versions < 11 do not have support for element.outerHTML.
        var outerHTML = element.outerHTML || new XMLSerializer().serializeToString(element);
        Ember.assert("Can't set innerHTML on "+element.tagName+" in this browser", outerHTML);

        var startTag = outerHTML.match(new RegExp("<"+tagName+"([^>]*)>", 'i'))[0],
            endTag = '</'+tagName+'>';

        var wrapper = document.createElement('div');
        setInnerHTMLWithoutFix(wrapper, startTag + html + endTag);
        element = wrapper.firstChild;
        while (element.tagName !== tagName) {
          element = element.nextSibling;
        }
      }

      return element;
    }

    __exports__.setInnerHTML = setInnerHTML;function isSimpleClick(event) {
      var modifier = event.shiftKey || event.metaKey || event.altKey || event.ctrlKey,
          secondaryClick = event.which > 1; // IE9 may return undefined

      return !modifier && !secondaryClick;
    }

    __exports__.isSimpleClick = isSimpleClick;
  });
define("ember-views/views/collection_view",
  ["ember-metal/core","ember-metal/platform","ember-metal/binding","ember-metal/merge","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/string","ember-views/views/container_view","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","ember-runtime/mixins/array","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) {
    "use strict";

    

    var Ember = __dependency1__["default"];
    // Ember.assert
    var create = __dependency2__.create;
    var isGlobalPath = __dependency3__.isGlobalPath;
    var merge = __dependency4__["default"];
    var get = __dependency5__.get;
    var set = __dependency6__.set;
    var fmt = __dependency7__.fmt;
    var ContainerView = __dependency8__["default"];
    var CoreView = __dependency9__["default"];
    var View = __dependency10__["default"];
    var observer = __dependency11__.observer;
    var beforeObserver = __dependency11__.beforeObserver;
    var EmberArray = __dependency12__["default"];

    
    var CollectionView = ContainerView.extend({

      
      content: null,

      
      emptyViewClass: View,

      
      emptyView: null,

      
      itemViewClass: View,

      
      init: function() {
        var ret = this._super();
        this._contentDidChange();
        return ret;
      },

      
      _contentWillChange: beforeObserver('content', function() {
        var content = this.get('content');

        if (content) { content.removeArrayObserver(this); }
        var len = content ? get(content, 'length') : 0;
        this.arrayWillChange(content, 0, len);
      }),

      
      _contentDidChange: observer('content', function() {
        var content = get(this, 'content');

        if (content) {
          this._assertArrayLike(content);
          content.addArrayObserver(this);
        }

        var len = content ? get(content, 'length') : 0;
        this.arrayDidChange(content, 0, null, len);
      }),

      
      _assertArrayLike: function(content) {
        Ember.assert(fmt("an Ember.CollectionView's content must implement Ember.Array. You passed %@", [content]), EmberArray.detect(content));
      },

      
      destroy: function() {
        if (!this._super()) { return; }

        var content = get(this, 'content');
        if (content) { content.removeArrayObserver(this); }

        if (this._createdEmptyView) {
          this._createdEmptyView.destroy();
        }

        return this;
      },

      
      arrayWillChange: function(content, start, removedCount) {
        // If the contents were empty before and this template collection has an
        // empty view remove it now.
        var emptyView = get(this, 'emptyView');
        if (emptyView && emptyView instanceof View) {
          emptyView.removeFromParent();
        }

        // Loop through child views that correspond with the removed items.
        // Note that we loop from the end of the array to the beginning because
        // we are mutating it as we go.
        var childViews = this._childViews, childView, idx, len;

        len = this._childViews.length;

        var removingAll = removedCount === len;

        if (removingAll) {
          this.currentState.empty(this);
          this.invokeRecursively(function(view) {
            view.removedFromDOM = true;
          }, false);
        }

        for (idx = start + removedCount - 1; idx >= start; idx--) {
          childView = childViews[idx];
          childView.destroy();
        }
      },

      
      arrayDidChange: function(content, start, removed, added) {
        var addedViews = [], view, item, idx, len, itemViewClass,
          emptyView;

        len = content ? get(content, 'length') : 0;

        if (len) {
          itemViewClass = get(this, 'itemViewClass');

          if ('string' === typeof itemViewClass && isGlobalPath(itemViewClass)) {
            itemViewClass = get(itemViewClass) || itemViewClass;
          }

          Ember.assert(fmt("itemViewClass must be a subclass of Ember.View, not %@",
                           [itemViewClass]),
                           'string' === typeof itemViewClass || View.detect(itemViewClass));

          for (idx = start; idx < start+added; idx++) {
            item = content.objectAt(idx);

            view = this.createChildView(itemViewClass, {
              content: item,
              contentIndex: idx
            });

            addedViews.push(view);
          }
        } else {
          emptyView = get(this, 'emptyView');

          if (!emptyView) { return; }

          if ('string' === typeof emptyView && isGlobalPath(emptyView)) {
            emptyView = get(emptyView) || emptyView;
          }

          emptyView = this.createChildView(emptyView);
          addedViews.push(emptyView);
          set(this, 'emptyView', emptyView);

          if (CoreView.detect(emptyView)) {
            this._createdEmptyView = emptyView;
          }
        }

        this.replace(start, 0, addedViews);
      },

      
      createChildView: function(view, attrs) {
        view = this._super(view, attrs);

        var itemTagName = get(view, 'tagName');

        if (itemTagName === null || itemTagName === undefined) {
          itemTagName = CollectionView.CONTAINER_MAP[get(this, 'tagName')];
          set(view, 'tagName', itemTagName);
        }

        return view;
      }
    });

    
    CollectionView.CONTAINER_MAP = {
      ul: 'li',
      ol: 'li',
      table: 'tr',
      thead: 'tr',
      tbody: 'tr',
      tfoot: 'tr',
      tr: 'td',
      select: 'option'
    };

    __exports__["default"] = CollectionView;
  });
define("ember-views/views/component",
  ["ember-metal/core","ember-views/mixins/component_template_deprecation","ember-runtime/mixins/target_action_support","ember-views/views/view","ember-metal/property_get","ember-metal/property_set","ember-metal/is_none","ember-metal/computed","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.assert, Ember.Handlebars

    var ComponentTemplateDeprecation = __dependency2__["default"];
    var TargetActionSupport = __dependency3__["default"];
    var View = __dependency4__["default"];

    var get = __dependency5__.get;
    var set = __dependency6__.set;
    var isNone = __dependency7__.isNone;

    var computed = __dependency8__.computed;

    var a_slice = Array.prototype.slice;

    

    
    var Component = View.extend(TargetActionSupport, ComponentTemplateDeprecation, {
      instrumentName: 'component',
      instrumentDisplay: computed(function() {
        if (this._debugContainerKey) {
          return '{{' + this._debugContainerKey.split(':')[1] + '}}';
        }
      }),

      init: function() {
        this._super();
        set(this, 'origContext', get(this, 'context'));
        set(this, 'context', this);
        set(this, 'controller', this);
      },

      defaultLayout: function(context, options){
        Ember.Handlebars.helpers['yield'].call(context, options);
      },

      
      template: computed(function(key, value) {
        if (value !== undefined) { return value; }

        var templateName = get(this, 'templateName'),
            template = this.templateForName(templateName, 'template');

        Ember.assert("You specified the templateName " + templateName + " for " + this + ", but it did not exist.", !templateName || template);

        return template || get(this, 'defaultTemplate');
      }).property('templateName'),

      
      templateName: null,

      // during render, isolate keywords
      cloneKeywords: function() {
        return {
          view: this,
          controller: this
        };
      },

      _yield: function(context, options) {
        var view = options.data.view,
            parentView = this._parentView,
            template = get(this, 'template');

        if (template) {
          Ember.assert("A Component must have a parent view in order to yield.", parentView);

          view.appendChild(View, {
            isVirtual: true,
            tagName: '',
            _contextView: parentView,
            template: template,
            context: options.data.insideGroup ? get(this, 'origContext') : get(parentView, 'context'),
            controller: get(parentView, 'controller'),
            templateData: { keywords: parentView.cloneKeywords(), insideGroup: options.data.insideGroup }
          });
        }
      },

      
      targetObject: computed(function(key) {
        var parentView = get(this, '_parentView');
        return parentView ? get(parentView, 'controller') : null;
      }).property('_parentView'),

      
      sendAction: function(action) {
        var actionName,
            contexts = a_slice.call(arguments, 1);

        // Send the default action
        if (action === undefined) {
          actionName = get(this, 'action');
          Ember.assert("The default action was triggered on the component " + this.toString() +
                       ", but the action name (" + actionName + ") was not a string.",
                       isNone(actionName) || typeof actionName === 'string');
        } else {
          actionName = get(this, action);
          Ember.assert("The " + action + " action was triggered on the component " +
                       this.toString() + ", but the action name (" + actionName +
                       ") was not a string.",
                       isNone(actionName) || typeof actionName === 'string');
        }

        // If no action name for that action could be found, just abort.
        if (actionName === undefined) { return; }

        this.triggerAction({
          action: actionName,
          actionContext: contexts
        });
      }
    });

    __exports__["default"] = Component;
  });
define("ember-views/views/container_view",
  ["ember-metal/core","ember-metal/merge","ember-runtime/mixins/mutable_array","ember-metal/property_get","ember-metal/property_set","ember-views/views/view","ember-views/views/view_collection","ember-views/views/states","ember-metal/error","ember-metal/enumerable_utils","ember-metal/computed","ember-metal/run_loop","ember-metal/properties","ember-views/system/render_buffer","ember-metal/mixin","ember-runtime/system/native_array","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.assert, Ember.K

    var merge = __dependency2__["default"];
    var MutableArray = __dependency3__["default"];
    var get = __dependency4__.get;
    var set = __dependency5__.set;

    var View = __dependency6__["default"];
    var ViewCollection = __dependency7__["default"];

    var cloneStates = __dependency8__.cloneStates;
    var EmberViewStates = __dependency8__.states;

    var EmberError = __dependency9__["default"];

    var forEach = __dependency10__.forEach;

    var computed = __dependency11__.computed;
    var run = __dependency12__["default"];
    var defineProperty = __dependency13__.defineProperty;
    var renderBuffer = __dependency14__["default"];
    var observer = __dependency15__.observer;
    var beforeObserver = __dependency15__.beforeObserver;
    var emberA = __dependency16__.A;

    

    var states = cloneStates(EmberViewStates);

    
    var ContainerView = View.extend(MutableArray, {
      _states: states,

      willWatchProperty: function(prop){
        Ember.deprecate(
          "ContainerViews should not be observed as arrays. This behavior will change in future implementations of ContainerView.",
          !prop.match(/\[]/) && prop.indexOf('@') !== 0
        );
      },

      init: function() {
        this._super();

        var childViews = get(this, 'childViews');

        // redefine view's childViews property that was obliterated
        defineProperty(this, 'childViews', View.childViewsProperty);

        var _childViews = this._childViews;

        forEach(childViews, function(viewName, idx) {
          var view;

          if ('string' === typeof viewName) {
            view = get(this, viewName);
            view = this.createChildView(view);
            set(this, viewName, view);
          } else {
            view = this.createChildView(viewName);
          }

          _childViews[idx] = view;
        }, this);

        var currentView = get(this, 'currentView');
        if (currentView) {
          if (!_childViews.length) { _childViews = this._childViews = this._childViews.slice(); }
          _childViews.push(this.createChildView(currentView));
        }
      },

      replace: function(idx, removedCount, addedViews) {
        var addedCount = addedViews ? get(addedViews, 'length') : 0;
        var self = this;
        Ember.assert("You can't add a child to a container - the child is already a child of another view", emberA(addedViews).every(function(item) { return !get(item, '_parentView') || get(item, '_parentView') === self; }));

        this.arrayContentWillChange(idx, removedCount, addedCount);
        this.childViewsWillChange(this._childViews, idx, removedCount);

        if (addedCount === 0) {
          this._childViews.splice(idx, removedCount) ;
        } else {
          var args = [idx, removedCount].concat(addedViews);
          if (addedViews.length && !this._childViews.length) { this._childViews = this._childViews.slice(); }
          this._childViews.splice.apply(this._childViews, args);
        }

        this.arrayContentDidChange(idx, removedCount, addedCount);
        this.childViewsDidChange(this._childViews, idx, removedCount, addedCount);

        return this;
      },

      objectAt: function(idx) {
        return this._childViews[idx];
      },

      length: computed(function () {
        return this._childViews.length;
      })["volatile"](),

      
      render: function(buffer) {
        this.forEachChildView(function(view) {
          view.renderToBuffer(buffer);
        });
      },

      instrumentName: 'container',

      
      childViewsWillChange: function(views, start, removed) {
        this.propertyWillChange('childViews');

        if (removed > 0) {
          var changedViews = views.slice(start, start+removed);
          // transition to preRender before clearing parentView
          this.currentState.childViewsWillChange(this, views, start, removed);
          this.initializeViews(changedViews, null, null);
        }
      },

      removeChild: function(child) {
        this.removeObject(child);
        return this;
      },

      
      childViewsDidChange: function(views, start, removed, added) {
        if (added > 0) {
          var changedViews = views.slice(start, start+added);
          this.initializeViews(changedViews, this, get(this, 'templateData'));
          this.currentState.childViewsDidChange(this, views, start, added);
        }
        this.propertyDidChange('childViews');
      },

      initializeViews: function(views, parentView, templateData) {
        forEach(views, function(view) {
          set(view, '_parentView', parentView);

          if (!view.container && parentView) {
            set(view, 'container', parentView.container);
          }

          if (!get(view, 'templateData')) {
            set(view, 'templateData', templateData);
          }
        });
      },

      currentView: null,

      _currentViewWillChange: beforeObserver('currentView', function() {
        var currentView = get(this, 'currentView');
        if (currentView) {
          currentView.destroy();
        }
      }),

      _currentViewDidChange: observer('currentView', function() {
        var currentView = get(this, 'currentView');
        if (currentView) {
          Ember.assert("You tried to set a current view that already has a parent. Make sure you don't have multiple outlets in the same view.", !get(currentView, '_parentView'));
          this.pushObject(currentView);
        }
      }),

      _ensureChildrenAreInDOM: function () {
        this.currentState.ensureChildrenAreInDOM(this);
      }
    });

    merge(states._default, {
      childViewsWillChange: Ember.K,
      childViewsDidChange: Ember.K,
      ensureChildrenAreInDOM: Ember.K
    });

    merge(states.inBuffer, {
      childViewsDidChange: function(parentView, views, start, added) {
        throw new EmberError('You cannot modify child views while in the inBuffer state');
      }
    });

    merge(states.hasElement, {
      childViewsWillChange: function(view, views, start, removed) {
        for (var i=start; i<start+removed; i++) {
          views[i].remove();
        }
      },

      childViewsDidChange: function(view, views, start, added) {
        run.scheduleOnce('render', view, '_ensureChildrenAreInDOM');
      },

      ensureChildrenAreInDOM: function(view) {
        var childViews = view._childViews, i, len, childView, previous, buffer, viewCollection = new ViewCollection();

        for (i = 0, len = childViews.length; i < len; i++) {
          childView = childViews[i];

          if (!buffer) { buffer = renderBuffer(); buffer._hasElement = false; }

          if (childView.renderToBufferIfNeeded(buffer)) {
            viewCollection.push(childView);
          } else if (viewCollection.length) {
            insertViewCollection(view, viewCollection, previous, buffer);
            buffer = null;
            previous = childView;
            viewCollection.clear();
          } else {
            previous = childView;
          }
        }

        if (viewCollection.length) {
          insertViewCollection(view, viewCollection, previous, buffer);
        }
      }
    });

    function insertViewCollection(view, viewCollection, previous, buffer) {
      viewCollection.triggerRecursively('willInsertElement');

      if (previous) {
        previous.domManager.after(previous, buffer.string());
      } else {
        view.domManager.prepend(view, buffer.string());
      }

      viewCollection.forEach(function(v) {
        v._transitionTo('inDOM');
        v.propertyDidChange('element');
        v.triggerRecursively('didInsertElement');
      });
    }


    __exports__["default"] = ContainerView;
  });
define("ember-views/views/core_view",
  ["ember-views/views/states","ember-runtime/system/object","ember-runtime/mixins/evented","ember-runtime/mixins/action_handler","ember-metal/properties","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/utils","ember-metal/instrumentation","ember-views/system/render_buffer","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) {
    "use strict";
    var cloneStates = __dependency1__.cloneStates;
    var states = __dependency1__.states;
    var EmberObject = __dependency2__["default"];
    var Evented = __dependency3__["default"];
    var ActionHandler = __dependency4__["default"];

    var defineProperty = __dependency5__.defineProperty;
    var deprecateProperty = __dependency5__.deprecateProperty;
    var get = __dependency6__.get;
    var set = __dependency7__.set;
    var computed = __dependency8__.computed;

    var typeOf = __dependency9__.typeOf;

    var instrument = __dependency10__.instrument;


    var renderBuffer = __dependency11__["default"];

    
    var CoreView = EmberObject.extend(Evented, ActionHandler, {
      isView: true,

      _states: cloneStates(states),

      init: function() {
        this._super();
        this._transitionTo('preRender');
        this._isVisible = get(this, 'isVisible');

        deprecateProperty(this, 'states', '_states');
        deprecateProperty(this, 'state', '_state');
      },

      
      parentView: computed('_parentView', function() {
        var parent = this._parentView;

        if (parent && parent.isVirtual) {
          return get(parent, 'parentView');
        } else {
          return parent;
        }
      }),

      _state: null,

      _parentView: null,

      // return the current view, not including virtual views
      concreteView: computed('parentView', function() {
        if (!this.isVirtual) { return this; }
        else { return get(this, 'parentView.concreteView'); }
      }),

      instrumentName: 'core_view',

      instrumentDetails: function(hash) {
        hash.object = this.toString();
        hash.containerKey = this._debugContainerKey;
        hash.view = this;
      },

      
      renderToBuffer: function(buffer) {
        var name = 'render.' + this.instrumentName,
            details = {};

        this.instrumentDetails(details);

        return instrument(name, details, function instrumentRenderToBuffer() {
          return this._renderToBuffer(buffer);
        }, this);
      },

      _renderToBuffer: function(_buffer) {
        // If this is the top-most view, start a new buffer. Otherwise,
        // create a new buffer relative to the original using the
        // provided buffer operation (for example, `insertAfter` will
        // insert a new buffer after the "parent buffer").
        var tagName = this.tagName;

        if (tagName === null || tagName === undefined) {
          tagName = 'div';
        }

        var buffer = this.buffer = _buffer && _buffer.begin(tagName) || renderBuffer(tagName);
        this._transitionTo('inBuffer', false);

        this.beforeRender(buffer);
        this.render(buffer);
        this.afterRender(buffer);

        return buffer;
      },

      
      trigger: function() {
        this._super.apply(this, arguments);
        var name = arguments[0];
        var method = this[name];
        if (method) {
          var length = arguments.length;
          var args = new Array(length - 1);
          for (var i = 1; i < length; i++) {
            args[i - 1] = arguments[i];
          }
          return method.apply(this, args);
        }
      },

      deprecatedSendHandles: function(actionName) {
        return !!this[actionName];
      },

      deprecatedSend: function(actionName) {
        var args = [].slice.call(arguments, 1);
        Ember.assert('' + this + " has the action " + actionName + " but it is not a function", typeof this[actionName] === 'function');
        Ember.deprecate('Action handlers implemented directly on views are deprecated in favor of action handlers on an `actions` object ( action: `' + actionName + '` on ' + this + ')', false);
        this[actionName].apply(this, args);
        return;
      },

      has: function(name) {
        return typeOf(this[name]) === 'function' || this._super(name);
      },

      destroy: function() {
        var parent = this._parentView;

        if (!this._super()) { return; }

        // destroy the element -- this will avoid each child view destroying
        // the element over and over again...
        if (!this.removedFromDOM) { this.destroyElement(); }

        // remove from parent if found. Don't call removeFromParent,
        // as removeFromParent will try to remove the element from
        // the DOM again.
        if (parent) { parent.removeChild(this); }

        this._transitionTo('destroying', false);

        return this;
      },

      clearRenderedChildren: Ember.K,
      triggerRecursively: Ember.K,
      invokeRecursively: Ember.K,
      _transitionTo: Ember.K,
      destroyElement: Ember.K
    });

    __exports__["default"] = CoreView;
  });
define("ember-views/views/states",
  ["ember-metal/platform","ember-metal/merge","ember-views/views/states/default","ember-views/views/states/pre_render","ember-views/views/states/in_buffer","ember-views/views/states/has_element","ember-views/views/states/in_dom","ember-views/views/states/destroying","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var create = __dependency1__.create;
    var merge = __dependency2__["default"];
    var _default = __dependency3__["default"];
    var preRender = __dependency4__["default"];
    var inBuffer = __dependency5__["default"];
    var hasElement = __dependency6__["default"];
    var inDOM = __dependency7__["default"];
    var destroying = __dependency8__["default"];

    function cloneStates(from) {
      var into = {};

      into._default = {};
      into.preRender = create(into._default);
      into.destroying = create(into._default);
      into.inBuffer = create(into._default);
      into.hasElement = create(into._default);
      into.inDOM = create(into.hasElement);

      for (var stateName in from) {
        if (!from.hasOwnProperty(stateName)) { continue; }
        merge(into[stateName], from[stateName]);
      }

      return into;
    }

    __exports__.cloneStates = cloneStates;var states = {
      _default: _default,
      preRender: preRender,
      inDOM: inDOM,
      inBuffer: inBuffer,
      hasElement: hasElement,
      destroying: destroying
    };
    __exports__.states = states;
  });
define("ember-views/views/states/default",
  ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/run_loop","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.K
    var get = __dependency2__.get;
    var set = __dependency3__.set;
    var run = __dependency4__["default"];
    var EmberError = __dependency5__["default"];

    
    __exports__["default"] = {
      // appendChild is only legal while rendering the buffer.
      appendChild: function() {
        throw new EmberError("You can't use appendChild outside of the rendering process");
      },

      $: function() {
        return undefined;
      },

      getElement: function() {
        return null;
      },

      // Handle events from `Ember.EventDispatcher`
      handleEvent: function() {
        return true; // continue event propagation
      },

      destroyElement: function(view) {
        set(view, 'element', null);
        if (view._scheduledInsert) {
          run.cancel(view._scheduledInsert);
          view._scheduledInsert = null;
        }
        return view;
      },

      renderToBufferIfNeeded: function () {
        return false;
      },

      rerender: Ember.K,
      invokeObserver: Ember.K
    };
  });
define("ember-views/views/states/destroying",
  ["ember-metal/merge","ember-metal/platform","ember-runtime/system/string","ember-views/views/states/default","ember-metal/error","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    var merge = __dependency1__["default"];
    var create = __dependency2__.create;
    var fmt = __dependency3__.fmt;
    var _default = __dependency4__["default"];
    var EmberError = __dependency5__["default"];
    

    var destroyingError = "You can't call %@ on a view being destroyed";

    var destroying = create(_default);

    merge(destroying, {
      appendChild: function() {
        throw new EmberError(fmt(destroyingError, ['appendChild']));
      },
      rerender: function() {
        throw new EmberError(fmt(destroyingError, ['rerender']));
      },
      destroyElement: function() {
        throw new EmberError(fmt(destroyingError, ['destroyElement']));
      },
      empty: function() {
        throw new EmberError(fmt(destroyingError, ['empty']));
      },

      setElement: function() {
        throw new EmberError(fmt(destroyingError, ["set('element', ...)"]));
      },

      renderToBufferIfNeeded: function() {
        return false;
      },

      // Since element insertion is scheduled, don't do anything if
      // the view has been destroyed between scheduling and execution
      insertElement: Ember.K
    });

    __exports__["default"] = destroying;
  });
define("ember-views/views/states/has_element",
  ["ember-views/views/states/default","ember-metal/run_loop","ember-metal/merge","ember-metal/platform","ember-views/system/jquery","ember-metal/error","ember-metal/property_get","ember-metal/property_set","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var _default = __dependency1__["default"];
    var run = __dependency2__["default"];
    var merge = __dependency3__["default"];
    var create = __dependency4__.create;
    var jQuery = __dependency5__["default"];
    var EmberError = __dependency6__["default"];

    

    var get = __dependency7__.get;
    var set = __dependency8__.set;

    var hasElement = create(_default);

    merge(hasElement, {
      $: function(view, sel) {
        var elem = get(view, 'element');
        return sel ? jQuery(sel, elem) : jQuery(elem);
      },

      getElement: function(view) {
        var parent = get(view, 'parentView');
        if (parent) { parent = get(parent, 'element'); }
        if (parent) { return view.findElementInParentElement(parent); }
        return jQuery("#" + get(view, 'elementId'))[0];
      },

      setElement: function(view, value) {
        if (value === null) {
          view._transitionTo('preRender');
        } else {
          throw new EmberError("You cannot set an element to a non-null value when the element is already in the DOM.");
        }

        return value;
      },

      // once the view has been inserted into the DOM, rerendering is
      // deferred to allow bindings to synchronize.
      rerender: function(view) {
        view.triggerRecursively('willClearRender');

        view.clearRenderedChildren();

        view.domManager.replace(view);
        return view;
      },

      // once the view is already in the DOM, destroying it removes it
      // from the DOM, nukes its element, and puts it back into the
      // preRender state if inDOM.

      destroyElement: function(view) {
        view._notifyWillDestroyElement();
        view.domManager.remove(view);
        set(view, 'element', null);
        if (view._scheduledInsert) {
          run.cancel(view._scheduledInsert);
          view._scheduledInsert = null;
        }
        return view;
      },

      empty: function(view) {
        var _childViews = view._childViews, len, idx;
        if (_childViews) {
          len = _childViews.length;
          for (idx = 0; idx < len; idx++) {
            _childViews[idx]._notifyWillDestroyElement();
          }
        }
        view.domManager.empty(view);
      },

      // Handle events from `Ember.EventDispatcher`
      handleEvent: function(view, eventName, evt) {
        if (view.has(eventName)) {
          // Handler should be able to re-dispatch events, so we don't
          // preventDefault or stopPropagation.
          return view.trigger(eventName, evt);
        } else {
          return true; // continue event propagation
        }
      },

      invokeObserver: function(target, observer) {
        observer.call(target);
      }
    });

    __exports__["default"] = hasElement;
  });
define("ember-views/views/states/in_buffer",
  ["ember-views/views/states/default","ember-metal/error","ember-metal/core","ember-metal/platform","ember-metal/merge","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    var _default = __dependency1__["default"];
    var EmberError = __dependency2__["default"];

    var Ember = __dependency3__["default"];
    // Ember.assert
    var create = __dependency4__.create;
    var merge = __dependency5__["default"];

    

    var inBuffer = create(_default);

    merge(inBuffer, {
      $: function(view, sel) {
        // if we don't have an element yet, someone calling this.$() is
        // trying to update an element that isn't in the DOM. Instead,
        // rerender the view to allow the render method to reflect the
        // changes.
        view.rerender();
        return Ember.$();
      },

      // when a view is rendered in a buffer, rerendering it simply
      // replaces the existing buffer with a new one
      rerender: function(view) {
        throw new EmberError("Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.");
      },

      // when a view is rendered in a buffer, appending a child
      // view will render that view and append the resulting
      // buffer into its buffer.
      appendChild: function(view, childView, options) {
        var buffer = view.buffer, _childViews = view._childViews;

        childView = view.createChildView(childView, options);
        if (!_childViews.length) { _childViews = view._childViews = _childViews.slice(); }
        _childViews.push(childView);

        childView.renderToBuffer(buffer);

        view.propertyDidChange('childViews');

        return childView;
      },

      // when a view is rendered in a buffer, destroying the
      // element will simply destroy the buffer and put the
      // state back into the preRender state.
      destroyElement: function(view) {
        view.clearBuffer();
        var viewCollection = view._notifyWillDestroyElement();
        viewCollection.transitionTo('preRender', false);

        return view;
      },

      empty: function() {
        Ember.assert("Emptying a view in the inBuffer state is not allowed and " +
                     "should not happen under normal circumstances. Most likely " +
                     "there is a bug in your application. This may be due to " +
                     "excessive property change notifications.");
      },

      renderToBufferIfNeeded: function (view, buffer) {
        return false;
      },

      // It should be impossible for a rendered view to be scheduled for
      // insertion.
      insertElement: function() {
        throw new EmberError("You can't insert an element that has already been rendered");
      },

      setElement: function(view, value) {
        if (value === null) {
          view._transitionTo('preRender');
        } else {
          view.clearBuffer();
          view._transitionTo('hasElement');
        }

        return value;
      },

      invokeObserver: function(target, observer) {
        observer.call(target);
      }
    });

    __exports__["default"] = inBuffer;
  });
define("ember-views/views/states/in_dom",
  ["ember-metal/core","ember-metal/platform","ember-metal/merge","ember-metal/error","ember-views/views/states/has_element","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
    "use strict";
    var Ember = __dependency1__["default"];
    // Ember.assert
    var create = __dependency2__.create;
    var merge = __dependency3__["default"];
    var EmberError = __dependency4__["default"];

    var hasElement = __dependency5__["default"];
    

    var inDOM = create(hasElement);

    var View;

    merge(inDOM, {
      enter: function(view) {
        if (!View) { View = requireModule('ember-views/views/view')["default"]; } // ES6TODO: this sucks. Have to avoid cycles...

        // Register the view for event handling. This hash is used by
        // Ember.EventDispatcher to dispatch incoming events.
        if (!view.isVirtual) {
          Ember.assert("Attempted to register a view with an id already in use: "+view.elementId, !View.views[view.elementId]);
          View.views[view.elementId] = view;
        }

        view.addBeforeObserver('elementId', function() {
          throw new EmberError("Changing a view's elementId after creation is not allowed");
        });
      },

      exit: function(view) {
        if (!View) { View = requireModule('ember-views/views/view')["default"]; } // ES6TODO: this sucks. Have to avoid cycles...

        if (!this.isVirtual) delete View.views[view.elementId];
      },

      insertElement: function(view, fn) {
        throw new EmberError("You can't insert an element into the DOM that has already been inserted");
      }
    });

    __exports__["default"] = inDOM;
  });
define("ember-views/views/states/pre_render",
  ["ember-views/views/states/default","ember-metal/platform","ember-metal/merge","ember-views/system/jquery","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    

    var _default = __dependency1__["default"];
    var create = __dependency2__.create;
    var merge = __dependency3__["default"];
    var jQuery = __dependency4__["default"];

    
    var preRender = create(_default);

    merge(preRender, {
      // a view leaves the preRender state once its element has been
      // created (createElement).
      insertElement: function(view, fn) {
        view.createElement();
        var viewCollection = view.viewHierarchyCollection();

        viewCollection.trigger('willInsertElement');

        fn.call(view);

        // We transition to `inDOM` if the element exists in the DOM
        var element = view.get('element');
        if (jQuery.contains(document.body, element)) {
          viewCollection.transitionTo('inDOM', false);
          viewCollection.trigger('didInsertElement');
        }
      },

      renderToBufferIfNeeded: function(view, buffer) {
        view.renderToBuffer(buffer);
        return true;
      },

      empty: Ember.K,

      setElement: function(view, value) {
        if (value !== null) {
          view._transitionTo('hasElement');
        }
        return value;
      }
    });

    __exports__["default"] = preRender;
  });
define("ember-views/views/view",
  ["ember-metal/core","ember-runtime/mixins/evented","ember-runtime/system/object","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-metal/set_properties","ember-metal/run_loop","ember-metal/observer","ember-metal/properties","ember-metal/utils","ember-metal/computed","ember-metal/mixin","ember-metal/is_none","ember-runtime/system/native_array","ember-runtime/system/string","ember-metal/enumerable_utils","ember-runtime/copy","ember-metal/binding","ember-metal/property_events","ember-views/system/jquery","ember-views/system/ext","ember-views/views/core_view","ember-views/views/view_collection","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __exports__) {
    "use strict";
    // Ember.assert, Ember.deprecate, Ember.warn, Ember.TEMPLATES,
    // Ember.K, jQuery, Ember.lookup,
    // Ember.ContainerView circular dependency
    // Ember.ENV
    var Ember = __dependency1__["default"];

    var Evented = __dependency2__["default"];
    var EmberObject = __dependency3__["default"];
    var EmberError = __dependency4__["default"];
    var get = __dependency5__.get;
    var set = __dependency6__.set;
    var setProperties = __dependency7__["default"];
    var run = __dependency8__["default"];
    var addObserver = __dependency9__.addObserver;
    var removeObserver = __dependency9__.removeObserver;

    var defineProperty = __dependency10__.defineProperty;
    var deprecateProperty = __dependency10__.deprecateProperty;
    var guidFor = __dependency11__.guidFor;
    var meta = __dependency11__.meta;
    var computed = __dependency12__.computed;
    var observer = __dependency13__.observer;

    var typeOf = __dependency11__.typeOf;
    var isArray = __dependency11__.isArray;
    var isNone = __dependency14__.isNone;
    var Mixin = __dependency13__.Mixin;
    var emberA = __dependency15__.A;

    var dasherize = __dependency16__.dasherize;

    // ES6TODO: functions on EnumerableUtils should get their own export
    var forEach = __dependency17__.forEach;
    var addObject = __dependency17__.addObject;
    var removeObject = __dependency17__.removeObject;

    var beforeObserver = __dependency13__.beforeObserver;
    var copy = __dependency18__["default"];
    var isGlobalPath = __dependency19__.isGlobalPath;

    var propertyWillChange = __dependency20__.propertyWillChange;
    var propertyDidChange = __dependency20__.propertyDidChange;

    var jQuery = __dependency21__["default"];
     // for the side effect of extending Ember.run.queues

    var CoreView = __dependency23__["default"];
    var ViewCollection = __dependency24__["default"];

    

    var ContainerView;

    function nullViewsBuffer(view) {
      view.buffer = null;

    }

    function clearCachedElement(view) {
      meta(view).cache.element = undefined;
    }

    var childViewsProperty = computed(function() {
      var childViews = this._childViews, ret = emberA(), view = this;

      forEach(childViews, function(view) {
        var currentChildViews;
        if (view.isVirtual) {
          if (currentChildViews = get(view, 'childViews')) {
            ret.pushObjects(currentChildViews);
          }
        } else {
          ret.push(view);
        }
      });

      ret.replace = function (idx, removedCount, addedViews) {
        if (!ContainerView) { ContainerView = requireModule('ember-views/views/container_view')['default']; } // ES6TODO: stupid circular dep

        if (view instanceof ContainerView) {
          Ember.deprecate("Manipulating an Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray.");
          return view.replace(idx, removedCount, addedViews);
        }
        throw new EmberError("childViews is immutable");
      };

      return ret;
    });

    Ember.warn("The VIEW_PRESERVES_CONTEXT flag has been removed and the functionality can no longer be disabled.", Ember.ENV.VIEW_PRESERVES_CONTEXT !== false);

    
    Ember.TEMPLATES = {};

    var EMPTY_ARRAY = [];

    
    var View = CoreView.extend({

      concatenatedProperties: ['classNames', 'classNameBindings', 'attributeBindings'],

      
      isView: true,

      // ..........................................................
      // TEMPLATE SUPPORT
      //

      
      templateName: null,

      
      layoutName: null,

      
      instrumentDisplay: computed(function() {
        if (this.helperName) {
          return '{{' + this.helperName + '}}';
        }
      }),

      
      template: computed('templateName', function(key, value) {
        if (value !== undefined) { return value; }

        var templateName = get(this, 'templateName'),
            template = this.templateForName(templateName, 'template');

        Ember.assert("You specified the templateName " + templateName + " for " + this + ", but it did not exist.", !templateName || template);

        return template || get(this, 'defaultTemplate');
      }),

      
      controller: computed('_parentView', function(key) {
        var parentView = get(this, '_parentView');
        return parentView ? get(parentView, 'controller') : null;
      }),

      
      layout: computed(function(key) {
        var layoutName = get(this, 'layoutName'),
            layout = this.templateForName(layoutName, 'layout');

        Ember.assert("You specified the layoutName " + layoutName + " for " + this + ", but it did not exist.", !layoutName || layout);

        return layout || get(this, 'defaultLayout');
      }).property('layoutName'),

      _yield: function(context, options) {
        var template = get(this, 'template');
        if (template) { template(context, options); }
      },

      templateForName: function(name, type) {
        if (!name) { return; }
        Ember.assert("templateNames are not allowed to contain periods: "+name, name.indexOf('.') === -1);

        if (!this.container) {
          throw new EmberError('Container was not found when looking up a views template. ' +
                     'This is most likely due to manually instantiating an Ember.View. ' +
                     'See: http://git.io/EKPpnA');
        }

        return this.container.lookup('template:' + name);
      },

      
      context: computed(function(key, value) {
        if (arguments.length === 2) {
          set(this, '_context', value);
          return value;
        } else {
          return get(this, '_context');
        }
      })["volatile"](),

      
      _context: computed(function(key) {
        var parentView, controller;

        if (controller = get(this, 'controller')) {
          return controller;
        }

        parentView = this._parentView;
        if (parentView) {
          return get(parentView, '_context');
        }

        return null;
      }),

      
      _contextDidChange: observer('context', function() {
        this.rerender();
      }),

      
      isVisible: true,

      
      childViews: childViewsProperty,

      _childViews: EMPTY_ARRAY,

      // When it's a virtual view, we need to notify the parent that their
      // childViews will change.
      _childViewsWillChange: beforeObserver('childViews', function() {
        if (this.isVirtual) {
          var parentView = get(this, 'parentView');
          if (parentView) { propertyWillChange(parentView, 'childViews'); }
        }
      }),

      // When it's a virtual view, we need to notify the parent that their
      // childViews did change.
      _childViewsDidChange: observer('childViews', function() {
        if (this.isVirtual) {
          var parentView = get(this, 'parentView');
          if (parentView) { propertyDidChange(parentView, 'childViews'); }
        }
      }),

      
      nearestInstanceOf: function(klass) {
        Ember.deprecate("nearestInstanceOf is deprecated and will be removed from future releases. Use nearestOfType.");
        var view = get(this, 'parentView');

        while (view) {
          if (view instanceof klass) { return view; }
          view = get(view, 'parentView');
        }
      },

      
      nearestOfType: function(klass) {
        var view = get(this, 'parentView'),
            isOfType = klass instanceof Mixin ?
                       function(view) { return klass.detect(view); } :
                       function(view) { return klass.detect(view.constructor); };

        while (view) {
          if (isOfType(view)) { return view; }
          view = get(view, 'parentView');
        }
      },

      
      nearestWithProperty: function(property) {
        var view = get(this, 'parentView');

        while (view) {
          if (property in view) { return view; }
          view = get(view, 'parentView');
        }
      },

      
      nearestChildOf: function(klass) {
        var view = get(this, 'parentView');

        while (view) {
          if (get(view, 'parentView') instanceof klass) { return view; }
          view = get(view, 'parentView');
        }
      },

      
      _parentViewDidChange: observer('_parentView', function() {
        if (this.isDestroying) { return; }

        this.trigger('parentViewDidChange');

        if (get(this, 'parentView.controller') && !get(this, 'controller')) {
          this.notifyPropertyChange('controller');
        }
      }),

      _controllerDidChange: observer('controller', function() {
        if (this.isDestroying) { return; }

        this.rerender();

        this.forEachChildView(function(view) {
          view.propertyDidChange('controller');
        });
      }),

      cloneKeywords: function() {
        var templateData = get(this, 'templateData');

        var keywords = templateData ? copy(templateData.keywords) : {};
        set(keywords, 'view', this.isVirtual ? keywords.view : this);
        set(keywords, '_view', this);
        set(keywords, 'controller', get(this, 'controller'));

        return keywords;
      },

      
      render: function(buffer) {
        // If this view has a layout, it is the responsibility of the
        // the layout to render the view's template. Otherwise, render the template
        // directly.
        var template = get(this, 'layout') || get(this, 'template');

        if (template) {
          var context = get(this, 'context');
          var keywords = this.cloneKeywords();
          var output;

          var data = {
            view: this,
            buffer: buffer,
            isRenderData: true,
            keywords: keywords,
            insideGroup: get(this, 'templateData.insideGroup')
          };

          // Invoke the template with the provided template context, which
          // is the view's controller by default. A hash of data is also passed that provides
          // the template with access to the view and render buffer.

          Ember.assert('template must be a function. Did you mean to call Ember.Handlebars.compile("...") or specify templateName instead?', typeof template === 'function');
          // The template should write directly to the render buffer instead
          // of returning a string.
          output = template(context, { data: data });

          // If the template returned a string instead of writing to the buffer,
          // push the string onto the buffer.
          if (output !== undefined) { buffer.push(output); }
        }
      },

      
      rerender: function() {
        return this.currentState.rerender(this);
      },

      clearRenderedChildren: function() {
        var lengthBefore = this.lengthBeforeRender,
            lengthAfter  = this.lengthAfterRender;

        // If there were child views created during the last call to render(),
        // remove them under the assumption that they will be re-created when
        // we re-render.

        // VIEW-TODO: Unit test this path.
        var childViews = this._childViews;
        for (var i=lengthAfter-1; i>=lengthBefore; i--) {
          if (childViews[i]) { childViews[i].destroy(); }
        }
      },

      
      _applyClassNameBindings: function(classBindings) {
        var classNames = this.classNames,
        elem, newClass, dasherizedClass;

        // Loop through all of the configured bindings. These will be either
        // property names ('isUrgent') or property paths relative to the view
        // ('content.isUrgent')
        forEach(classBindings, function(binding) {

          Ember.assert("classNameBindings must not have spaces in them. Multiple class name bindings can be provided as elements of an array, e.g. ['foo', ':bar']", binding.indexOf(' ') === -1);

          // Variable in which the old class value is saved. The observer function
          // closes over this variable, so it knows which string to remove when
          // the property changes.
          var oldClass;
          // Extract just the property name from bindings like 'foo:bar'
          var parsedPath = View._parsePropertyPath(binding);

          // Set up an observer on the context. If the property changes, toggle the
          // class name.
          var observer = function() {
            // Get the current value of the property
            newClass = this._classStringForProperty(binding);
            elem = this.$();

            // If we had previously added a class to the element, remove it.
            if (oldClass) {
              elem.removeClass(oldClass);
              // Also remove from classNames so that if the view gets rerendered,
              // the class doesn't get added back to the DOM.
              classNames.removeObject(oldClass);
            }

            // If necessary, add a new class. Make sure we keep track of it so
            // it can be removed in the future.
            if (newClass) {
              elem.addClass(newClass);
              oldClass = newClass;
            } else {
              oldClass = null;
            }
          };

          // Get the class name for the property at its current value
          dasherizedClass = this._classStringForProperty(binding);

          if (dasherizedClass) {
            // Ensure that it gets into the classNames array
            // so it is displayed when we render.
            addObject(classNames, dasherizedClass);

            // Save a reference to the class name so we can remove it
            // if the observer fires. Remember that this variable has
            // been closed over by the observer.
            oldClass = dasherizedClass;
          }

          this.registerObserver(this, parsedPath.path, observer);
          // Remove className so when the view is rerendered,
          // the className is added based on binding reevaluation
          this.one('willClearRender', function() {
            if (oldClass) {
              classNames.removeObject(oldClass);
              oldClass = null;
            }
          });

        }, this);
      },

      _unspecifiedAttributeBindings: null,

      
      _applyAttributeBindings: function(buffer, attributeBindings) {
        var attributeValue,
            unspecifiedAttributeBindings = this._unspecifiedAttributeBindings = this._unspecifiedAttributeBindings || {};

        forEach(attributeBindings, function(binding) {
          var split = binding.split(':'),
              property = split[0],
              attributeName = split[1] || property;

          if (property in this) {
            this._setupAttributeBindingObservation(property, attributeName);

            // Determine the current value and add it to the render buffer
            // if necessary.
            attributeValue = get(this, property);
            View.applyAttributeBindings(buffer, attributeName, attributeValue);
          } else {
            unspecifiedAttributeBindings[property] = attributeName;
          }
        }, this);

        // Lazily setup setUnknownProperty after attributeBindings are initially applied
        this.setUnknownProperty = this._setUnknownProperty;
      },

      _setupAttributeBindingObservation: function(property, attributeName) {
        var attributeValue, elem;

        // Create an observer to add/remove/change the attribute if the
        // JavaScript property changes.
        var observer = function() {
          elem = this.$();

          attributeValue = get(this, property);

          View.applyAttributeBindings(elem, attributeName, attributeValue);
        };

        this.registerObserver(this, property, observer);
      },

      
      setUnknownProperty: null, // Gets defined after initialization by _applyAttributeBindings

      _setUnknownProperty: function(key, value) {
        var attributeName = this._unspecifiedAttributeBindings && this._unspecifiedAttributeBindings[key];
        if (attributeName) {
          this._setupAttributeBindingObservation(key, attributeName);
        }

        defineProperty(this, key);
        return set(this, key, value);
      },

      
      _classStringForProperty: function(property) {
        var parsedPath = View._parsePropertyPath(property);
        var path = parsedPath.path;

        var val = get(this, path);
        if (val === undefined && isGlobalPath(path)) {
          val = get(Ember.lookup, path);
        }

        return View._classStringForValue(path, val, parsedPath.className, parsedPath.falsyClassName);
      },

      // ..........................................................
      // ELEMENT SUPPORT
      //

      
      element: computed('_parentView', function(key, value) {
        if (value !== undefined) {
          return this.currentState.setElement(this, value);
        } else {
          return this.currentState.getElement(this);
        }
      }),

      
      $: function(sel) {
        return this.currentState.$(this, sel);
      },

      mutateChildViews: function(callback) {
        var childViews = this._childViews,
            idx = childViews.length,
            view;

        while(--idx >= 0) {
          view = childViews[idx];
          callback(this, view, idx);
        }

        return this;
      },

      forEachChildView: function(callback) {
        var childViews = this._childViews;

        if (!childViews) { return this; }

        var len = childViews.length,
            view, idx;

        for (idx = 0; idx < len; idx++) {
          view = childViews[idx];
          callback(view);
        }

        return this;
      },

      
      appendTo: function(target) {
        // Schedule the DOM element to be created and appended to the given
        // element after bindings have synchronized.
        this._insertElementLater(function() {
          Ember.assert("You tried to append to (" + target + ") but that isn't in the DOM", jQuery(target).length > 0);
          Ember.assert("You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead.", !jQuery(target).is('.ember-view') && !jQuery(target).parents().is('.ember-view'));
          this.$().appendTo(target);
        });

        return this;
      },

      
      replaceIn: function(target) {
        Ember.assert("You tried to replace in (" + target + ") but that isn't in the DOM", jQuery(target).length > 0);
        Ember.assert("You cannot replace an existing Ember.View. Consider using Ember.ContainerView instead.", !jQuery(target).is('.ember-view') && !jQuery(target).parents().is('.ember-view'));

        this._insertElementLater(function() {
          jQuery(target).empty();
          this.$().appendTo(target);
        });

        return this;
      },

      
      _insertElementLater: function(fn) {
        this._scheduledInsert = run.scheduleOnce('render', this, '_insertElement', fn);
      },

      _insertElement: function (fn) {
        this._scheduledInsert = null;
        this.currentState.insertElement(this, fn);
      },

      
      append: function() {
        return this.appendTo(document.body);
      },

      
      remove: function() {
        // What we should really do here is wait until the end of the run loop
        // to determine if the element has been re-appended to a different
        // element.
        // In the interim, we will just re-render if that happens. It is more
        // important than elements get garbage collected.
        if (!this.removedFromDOM) { this.destroyElement(); }
        this.invokeRecursively(function(view) {
          if (view.clearRenderedChildren) { view.clearRenderedChildren(); }
        });
      },

      elementId: null,

      
      findElementInParentElement: function(parentElem) {
        var id = "#" + this.elementId;
        return jQuery(id)[0] || jQuery(id, parentElem)[0];
      },

      
      createElement: function() {
        if (get(this, 'element')) { return this; }

        var buffer = this.renderToBuffer();
        set(this, 'element', buffer.element());

        return this;
      },

      
      willInsertElement: Ember.K,

      
      didInsertElement: Ember.K,

      
      willClearRender: Ember.K,

      
      invokeRecursively: function(fn, includeSelf) {
        var childViews = (includeSelf === false) ? this._childViews : [this];
        var currentViews, view, currentChildViews;

        while (childViews.length) {
          currentViews = childViews.slice();
          childViews = [];

          for (var i=0, l=currentViews.length; i<l; i++) {
            view = currentViews[i];
            currentChildViews = view._childViews ? view._childViews.slice(0) : null;
            fn(view);
            if (currentChildViews) {
              childViews.push.apply(childViews, currentChildViews);
            }
          }
        }
      },

      triggerRecursively: function(eventName) {
        var childViews = [this], currentViews, view, currentChildViews;

        while (childViews.length) {
          currentViews = childViews.slice();
          childViews = [];

          for (var i=0, l=currentViews.length; i<l; i++) {
            view = currentViews[i];
            currentChildViews = view._childViews ? view._childViews.slice(0) : null;
            if (view.trigger) { view.trigger(eventName); }
            if (currentChildViews) {
              childViews.push.apply(childViews, currentChildViews);
            }

          }
        }
      },

      viewHierarchyCollection: function() {
        var currentView, viewCollection = new ViewCollection([this]);

        for (var i = 0; i < viewCollection.length; i++) {
          currentView = viewCollection.objectAt(i);
          if (currentView._childViews) {
            viewCollection.push.apply(viewCollection, currentView._childViews);
          }
        }

        return viewCollection;
      },

      
      destroyElement: function() {
        return this.currentState.destroyElement(this);
      },

      
      willDestroyElement: Ember.K,

      
      _notifyWillDestroyElement: function() {
        var viewCollection = this.viewHierarchyCollection();
        viewCollection.trigger('willClearRender');
        viewCollection.trigger('willDestroyElement');
        return viewCollection;
      },

      
      _elementDidChange: observer('element', function() {
        this.forEachChildView(clearCachedElement);
      }),

      
      parentViewDidChange: Ember.K,

      instrumentName: 'view',

      instrumentDetails: function(hash) {
        hash.template = get(this, 'templateName');
        this._super(hash);
      },

      _renderToBuffer: function(buffer) {
        this.lengthBeforeRender = this._childViews.length;
        buffer = this._super(buffer);
        this.lengthAfterRender = this._childViews.length;

        return buffer;
      },

      renderToBufferIfNeeded: function (buffer) {
        return this.currentState.renderToBufferIfNeeded(this, buffer);
      },

      beforeRender: function(buffer) {
        this.applyAttributesToBuffer(buffer);
        buffer.pushOpeningTag();
      },

      afterRender: function(buffer) {
        buffer.pushClosingTag();
      },

      applyAttributesToBuffer: function(buffer) {
        // Creates observers for all registered class name and attribute bindings,
        // then adds them to the element.
        var classNameBindings = get(this, 'classNameBindings');
        if (classNameBindings.length) {
          this._applyClassNameBindings(classNameBindings);
        }

        // Pass the render buffer so the method can apply attributes directly.
        // This isn't needed for class name bindings because they use the
        // existing classNames infrastructure.
        var attributeBindings = get(this, 'attributeBindings');
        if (attributeBindings.length) {
          this._applyAttributeBindings(buffer, attributeBindings);
        }

        buffer.setClasses(this.classNames);
        buffer.id(this.elementId);

        var role = get(this, 'ariaRole');
        if (role) {
          buffer.attr('role', role);
        }

        if (get(this, 'isVisible') === false) {
          buffer.style('display', 'none');
        }
      },

      // ..........................................................
      // STANDARD RENDER PROPERTIES
      //

      

      // We leave this null by default so we can tell the difference between
      // the default case and a user-specified tag.
      tagName: null,

      
      ariaRole: null,

      
      classNames: ['ember-view'],

      
      classNameBindings: EMPTY_ARRAY,

      
      attributeBindings: EMPTY_ARRAY,

      // .......................................................
      // CORE DISPLAY METHODS
      //

      
      init: function() {
        this.elementId = this.elementId || guidFor(this);

        this._super();

        // setup child views. be sure to clone the child views array first
        this._childViews = this._childViews.slice();

        Ember.assert("Only arrays are allowed for 'classNameBindings'", typeOf(this.classNameBindings) === 'array');
        this.classNameBindings = emberA(this.classNameBindings.slice());

        Ember.assert("Only arrays are allowed for 'classNames'", typeOf(this.classNames) === 'array');
        this.classNames = emberA(this.classNames.slice());
      },

      appendChild: function(view, options) {
        return this.currentState.appendChild(this, view, options);
      },

      
      removeChild: function(view) {
        // If we're destroying, the entire subtree will be
        // freed, and the DOM will be handled separately,
        // so no need to mess with childViews.
        if (this.isDestroying) { return; }

        // update parent node
        set(view, '_parentView', null);

        // remove view from childViews array.
        var childViews = this._childViews;

        removeObject(childViews, view);

        this.propertyDidChange('childViews'); // HUH?! what happened to will change?

        return this;
      },

      
      removeAllChildren: function() {
        return this.mutateChildViews(function(parentView, view) {
          parentView.removeChild(view);
        });
      },

      destroyAllChildren: function() {
        return this.mutateChildViews(function(parentView, view) {
          view.destroy();
        });
      },

      
      removeFromParent: function() {
        var parent = this._parentView;

        // Remove DOM element from parent
        this.remove();

        if (parent) { parent.removeChild(this); }
        return this;
      },

      
      destroy: function() {
        var childViews = this._childViews,
            // get parentView before calling super because it'll be destroyed
            nonVirtualParentView = get(this, 'parentView'),
            viewName = this.viewName,
            childLen, i;

        if (!this._super()) { return; }

        childLen = childViews.length;
        for (i=childLen-1; i>=0; i--) {
          childViews[i].removedFromDOM = true;
        }

        // remove from non-virtual parent view if viewName was specified
        if (viewName && nonVirtualParentView) {
          nonVirtualParentView.set(viewName, null);
        }

        childLen = childViews.length;
        for (i=childLen-1; i>=0; i--) {
          childViews[i].destroy();
        }

        return this;
      },

      
      createChildView: function(view, attrs) {
        if (!view) {
          throw new TypeError("createChildViews first argument must exist");
        }

        if (view.isView && view._parentView === this && view.container === this.container) {
          return view;
        }

        attrs = attrs || {};
        attrs._parentView = this;

        if (CoreView.detect(view)) {
          attrs.templateData = attrs.templateData || get(this, 'templateData');

          attrs.container = this.container;
          view = view.create(attrs);

          // don't set the property on a virtual view, as they are invisible to
          // consumers of the view API
          if (view.viewName) {
            set(get(this, 'concreteView'), view.viewName, view);
          }
        } else if ('string' === typeof view) {
          var fullName = 'view:' + view;
          var ViewKlass = this.container.lookupFactory(fullName);

          Ember.assert("Could not find view: '" + fullName + "'", !!ViewKlass);

          attrs.templateData = get(this, 'templateData');
          view = ViewKlass.create(attrs);
        } else {
          Ember.assert('You must pass instance or subclass of View', view.isView);
          attrs.container = this.container;

          if (!get(view, 'templateData')) {
            attrs.templateData = get(this, 'templateData');
          }

          setProperties(view, attrs);

        }

        return view;
      },

      becameVisible: Ember.K,
      becameHidden: Ember.K,

      
      _isVisibleDidChange: observer('isVisible', function() {
        if (this._isVisible === get(this, 'isVisible')) { return ; }
        run.scheduleOnce('render', this, this._toggleVisibility);
      }),

      _toggleVisibility: function() {
        var $el = this.$();
        if (!$el) { return; }

        var isVisible = get(this, 'isVisible');

        if (this._isVisible === isVisible) { return ; }

        $el.toggle(isVisible);

        this._isVisible = isVisible;

        if (this._isAncestorHidden()) { return; }

        if (isVisible) {
          this._notifyBecameVisible();
        } else {
          this._notifyBecameHidden();
        }
      },

      _notifyBecameVisible: function() {
        this.trigger('becameVisible');

        this.forEachChildView(function(view) {
          var isVisible = get(view, 'isVisible');

          if (isVisible || isVisible === null) {
            view._notifyBecameVisible();
          }
        });
      },

      _notifyBecameHidden: function() {
        this.trigger('becameHidden');
        this.forEachChildView(function(view) {
          var isVisible = get(view, 'isVisible');

          if (isVisible || isVisible === null) {
            view._notifyBecameHidden();
          }
        });
      },

      _isAncestorHidden: function() {
        var parent = get(this, 'parentView');

        while (parent) {
          if (get(parent, 'isVisible') === false) { return true; }

          parent = get(parent, 'parentView');
        }

        return false;
      },

      clearBuffer: function() {
        this.invokeRecursively(nullViewsBuffer);
      },
      transitionTo: function(state, children) {
        Ember.deprecate("Ember.View#transitionTo has been deprecated, it is for internal use only");
        this._transitionTo(state, children);
      },
      _transitionTo: function(state, children) {
        var priorState = this.currentState;
        var currentState = this.currentState = this._states[state];

        this._state = state;

        if (priorState && priorState.exit) { priorState.exit(this); }
        if (currentState.enter) { currentState.enter(this); }
        if (state === 'inDOM') { meta(this).cache.element = undefined; }

        if (children !== false) {
          this.forEachChildView(function(view) {
            view._transitionTo(state);
          });
        }
      },

      // .......................................................
      // EVENT HANDLING
      //

      
      handleEvent: function(eventName, evt) {
        return this.currentState.handleEvent(this, eventName, evt);
      },

      registerObserver: function(root, path, target, observer) {
        if (!observer && 'function' === typeof target) {
          observer = target;
          target = null;
        }

        if (!root || typeof root !== 'object') {
          return;
        }

        var view = this,
            stateCheckedObserver = function() {
              view.currentState.invokeObserver(this, observer);
            },
            scheduledObserver = function() {
              run.scheduleOnce('render', this, stateCheckedObserver);
            };

        addObserver(root, path, target, scheduledObserver);

        this.one('willClearRender', function() {
          removeObserver(root, path, target, scheduledObserver);
        });
      }

    });

    

      // in the destroyed state, everything is illegal

      // before rendering has begun, all legal manipulations are noops.

      // inside the buffer, legal manipulations are done on the buffer

      // once the view has been inserted into the DOM, legal manipulations
      // are done on the DOM element.

    function notifyMutationListeners() {
      run.once(View, 'notifyMutationListeners');
    }

    var DOMManager = {
      prepend: function(view, html) {
        view.$().prepend(html);
        notifyMutationListeners();
      },

      after: function(view, html) {
        view.$().after(html);
        notifyMutationListeners();
      },

      html: function(view, html) {
        view.$().html(html);
        notifyMutationListeners();
      },

      replace: function(view) {
        var element = get(view, 'element');

        set(view, 'element', null);

        view._insertElementLater(function() {
          jQuery(element).replaceWith(get(view, 'element'));
          notifyMutationListeners();
        });
      },

      remove: function(view) {
        view.$().remove();
        notifyMutationListeners();
      },

      empty: function(view) {
        view.$().empty();
        notifyMutationListeners();
      }
    };

    View.reopen({
      domManager: DOMManager
    });

    View.reopenClass({

      
      _parsePropertyPath: function(path) {
        var split = path.split(':'),
            propertyPath = split[0],
            classNames = "",
            className,
            falsyClassName;

        // check if the property is defined as prop:class or prop:trueClass:falseClass
        if (split.length > 1) {
          className = split[1];
          if (split.length === 3) { falsyClassName = split[2]; }

          classNames = ':' + className;
          if (falsyClassName) { classNames += ":" + falsyClassName; }
        }

        return {
          path: propertyPath,
          classNames: classNames,
          className: (className === '') ? undefined : className,
          falsyClassName: falsyClassName
        };
      },

      
      _classStringForValue: function(path, val, className, falsyClassName) {
        if(isArray(val)) {
          val = get(val, 'length') !== 0;
        }

        // When using the colon syntax, evaluate the truthiness or falsiness
        // of the value to determine which className to return
        if (className || falsyClassName) {
          if (className && !!val) {
            return className;

          } else if (falsyClassName && !val) {
            return falsyClassName;

          } else {
            return null;
          }

        // If value is a Boolean and true, return the dasherized property
        // name.
        } else if (val === true) {
          // Normalize property path to be suitable for use
          // as a class name. For exaple, content.foo.barBaz
          // becomes bar-baz.
          var parts = path.split('.');
          return dasherize(parts[parts.length-1]);

        // If the value is not false, undefined, or null, return the current
        // value of the property.
        } else if (val !== false && val != null) {
          return val;

        // Nothing to display. Return null so that the old class is removed
        // but no new class is added.
        } else {
          return null;
        }
      }
    });

    var mutation = EmberObject.extend(Evented).create();

    View.addMutationListener = function(callback) {
      mutation.on('change', callback);
    };

    View.removeMutationListener = function(callback) {
      mutation.off('change', callback);
    };

    View.notifyMutationListeners = function() {
      mutation.trigger('change');
    };

    
    View.views = {};

    // If someone overrides the child views computed property when
    // defining their class, we want to be able to process the user's
    // supplied childViews and then restore the original computed property
    // at view initialization time. This happens in Ember.ContainerView's init
    // method.
    View.childViewsProperty = childViewsProperty;

    View.applyAttributeBindings = function(elem, name, value) {
      var type = typeOf(value);

      // if this changes, also change the logic in ember-handlebars/lib/helpers/binding.js
      if (name !== 'value' && (type === 'string' || (type === 'number' && !isNaN(value)))) {
        if (value !== elem.attr(name)) {
          elem.attr(name, value);
        }
      } else if (name === 'value' || type === 'boolean') {
        if (isNone(value) || value === false) {
          // `null`, `undefined` or `false` should remove attribute
          elem.removeAttr(name);
          // In IE8 `prop` couldn't remove attribute when name is `required`.
          if (name === 'required') {
            elem.removeProp(name);
          } else {
            elem.prop(name, '');
          }
        } else if (value !== elem.prop(name)) {
          // value should always be properties
          elem.prop(name, value);
        }
      } else if (!value) {
        elem.removeAttr(name);
      }
    };

    __exports__["default"] = View;
  });
define("ember-views/views/view_collection",
  ["ember-metal/enumerable_utils","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var forEach = __dependency1__.forEach;

    function ViewCollection(initialViews) {
      var views = this.views = initialViews || [];
      this.length = views.length;
    }

    ViewCollection.prototype = {
      length: 0,

      trigger: function(eventName) {
        var views = this.views, view;
        for (var i = 0, l = views.length; i < l; i++) {
          view = views[i];
          if (view.trigger) { view.trigger(eventName); }
        }
      },

      triggerRecursively: function(eventName) {
        var views = this.views;
        for (var i = 0, l = views.length; i < l; i++) {
          views[i].triggerRecursively(eventName);
        }
      },

      invokeRecursively: function(fn) {
        var views = this.views, view;

        for (var i = 0, l = views.length; i < l; i++) {
          view = views[i];
          fn(view);
        }
      },

      transitionTo: function(state, children) {
        var views = this.views;
        for (var i = 0, l = views.length; i < l; i++) {
          views[i]._transitionTo(state, children);
        }
      },

      push: function() {
        this.length += arguments.length;
        var views = this.views;
        return views.push.apply(views, arguments);
      },

      objectAt: function(idx) {
        return this.views[idx];
      },

      forEach: function(callback) {
        var views = this.views;
        return forEach(views, callback);
      },

      clear: function() {
        this.length = 0;
        this.views.length = 0;
      }
    };

    __exports__["default"] = ViewCollection;
  });
define("ember",
  ["ember-metal","ember-runtime","ember-handlebars","ember-views","ember-routing","ember-routing-handlebars","ember-application","ember-extension-support"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__) {
    "use strict";
    // require the main entry points for each of these packages
    // this is so that the global exports occur properly

    // do this to ensure that Ember.Test is defined properly on the global
    // if it is present.
    if (Ember.__loader.registry['ember-testing']) {
      requireModule('ember-testing');
    }

    

    function throwWithMessage(msg) {
      return function() {
        throw new Ember.Error(msg);
      };
    }

    function generateRemovedClass(className) {
      var msg = " has been moved into a plugin: https://github.com/emberjs/ember-states";

      return {
        extend: throwWithMessage(className + msg),
        create: throwWithMessage(className + msg)
      };
    }

    Ember.StateManager = generateRemovedClass("Ember.StateManager");

    

    Ember.State = generateRemovedClass("Ember.State");

    
  });
define("metamorph",
  [],
  function() {
    "use strict";
    // ==========================================================================
    // Project:   metamorph
    // Copyright: ©2014 Tilde, Inc. All rights reserved.
    // ==========================================================================

    var K = function() {},
        guid = 0,
        disableRange = (function(){
          if ('undefined' !== typeof MetamorphENV) {
            return MetamorphENV.DISABLE_RANGE_API;
          } else if ('undefined' !== ENV) {
            return ENV.DISABLE_RANGE_API;
          } else {
            return false;
          }
        })(),

        // Feature-detect the W3C range API, the extended check is for IE9 which only partially supports ranges
        supportsRange = (!disableRange) && typeof document !== 'undefined' && ('createRange' in document) && (typeof Range !== 'undefined') && Range.prototype.createContextualFragment,

        // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
        // is a "zero-scope" element. This problem can be worked around by making
        // the first node an invisible text node. We, like Modernizr, use &shy;
        needsShy = typeof document !== 'undefined' && (function() {
          var testEl = document.createElement('div');
          testEl.innerHTML = "<div></div>";
          testEl.firstChild.innerHTML = "<script></script>";
          return testEl.firstChild.innerHTML === '';
        })(),


        // IE 8 (and likely earlier) likes to move whitespace preceeding
        // a script tag to appear after it. This means that we can
        // accidentally remove whitespace when updating a morph.
        movesWhitespace = document && (function() {
          var testEl = document.createElement('div');
          testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
          return testEl.childNodes[0].nodeValue === 'Test:' &&
                  testEl.childNodes[2].nodeValue === ' Value';
        })();

    // Constructor that supports either Metamorph('foo') or new
    // Metamorph('foo');
    //
    // Takes a string of HTML as the argument.

    var Metamorph = function(html) {
      var self;

      if (this instanceof Metamorph) {
        self = this;
      } else {
        self = new K();
      }

      self.innerHTML = html;
      var myGuid = 'metamorph-'+(guid++);
      self.start = myGuid + '-start';
      self.end = myGuid + '-end';

      return self;
    };

    K.prototype = Metamorph.prototype;

    var rangeFor, htmlFunc, removeFunc, outerHTMLFunc, appendToFunc, afterFunc, prependFunc, startTagFunc, endTagFunc;

    outerHTMLFunc = function() {
      return this.startTag() + this.innerHTML + this.endTag();
    };

    startTagFunc = function() {
      
      return "<script id='" + this.start + "' type='text/x-placeholder'>\x3C/script>";
    };

    endTagFunc = function() {
      
      return "<script id='" + this.end + "' type='text/x-placeholder'>\x3C/script>";
    };

    // If we have the W3C range API, this process is relatively straight forward.
    if (supportsRange) {

      // Get a range for the current morph. Optionally include the starting and
      // ending placeholders.
      rangeFor = function(morph, outerToo) {
        var range = document.createRange();
        var before = document.getElementById(morph.start);
        var after = document.getElementById(morph.end);

        if (outerToo) {
          range.setStartBefore(before);
          range.setEndAfter(after);
        } else {
          range.setStartAfter(before);
          range.setEndBefore(after);
        }

        return range;
      };

      htmlFunc = function(html, outerToo) {
        // get a range for the current metamorph object
        var range = rangeFor(this, outerToo);

        // delete the contents of the range, which will be the
        // nodes between the starting and ending placeholder.
        range.deleteContents();

        // create a new document fragment for the HTML
        var fragment = range.createContextualFragment(html);

        // insert the fragment into the range
        range.insertNode(fragment);
      };

      
      removeFunc = function() {
        // get a range for the current metamorph object including
        // the starting and ending placeholders.
        var range = rangeFor(this, true);

        // delete the entire range.
        range.deleteContents();
      };

      appendToFunc = function(node) {
        var range = document.createRange();
        range.setStart(node);
        range.collapse(false);
        var frag = range.createContextualFragment(this.outerHTML());
        node.appendChild(frag);
      };

      afterFunc = function(html) {
        var range = document.createRange();
        var after = document.getElementById(this.end);

        range.setStartAfter(after);
        range.setEndAfter(after);

        var fragment = range.createContextualFragment(html);
        range.insertNode(fragment);
      };

      prependFunc = function(html) {
        var range = document.createRange();
        var start = document.getElementById(this.start);

        range.setStartAfter(start);
        range.setEndAfter(start);

        var fragment = range.createContextualFragment(html);
        range.insertNode(fragment);
      };

    } else {
      
      Metamorph._wrapMap = {
        select: [ 1, "<select multiple='multiple'>", "</select>" ],
        fieldset: [ 1, "<fieldset>", "</fieldset>" ],
        table: [ 1, "<table>", "</table>" ],
        tbody: [ 2, "<table><tbody>", "</tbody></table>" ],
        tr: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
        colgroup: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
        map: [ 1, "<map>", "</map>" ],
        _default: [ 0, "", "" ]
      };

      var findChildById = function(element, id) {
        if (element.getAttribute('id') === id) { return element; }

        var len = element.childNodes.length, idx, node, found;
        for (idx=0; idx<len; idx++) {
          node = element.childNodes[idx];
          found = node.nodeType === 1 && findChildById(node, id);
          if (found) { return found; }
        }
      };

      var setInnerHTML = function(element, html) {
        var matches = [];
        if (movesWhitespace) {
          // Right now we only check for script tags with ids with the
          // goal of targeting morphs.
          html = html.replace(/(\s+)(<script id='([^']+)')/g, function(match, spaces, tag, id) {
            matches.push([id, spaces]);
            return tag;
          });
        }

        element.innerHTML = html;

        // If we have to do any whitespace adjustments do them now
        if (matches.length > 0) {
          var len = matches.length, idx;
          for (idx=0; idx<len; idx++) {
            var script = findChildById(element, matches[idx][0]),
                node = document.createTextNode(matches[idx][1]);
            script.parentNode.insertBefore(node, script);
          }
        }
      };

      
      var firstNodeFor = function(parentNode, html) {
        var wrapMap = Metamorph._wrapMap;
        var arr = wrapMap[parentNode.tagName.toLowerCase()] || wrapMap._default;
        var depth = arr[0], start = arr[1], end = arr[2];

        if (needsShy) { html = '&shy;'+html; }

        var element = document.createElement('div');

        setInnerHTML(element, start + html + end);

        for (var i=0; i<=depth; i++) {
          element = element.firstChild;
        }

        // Look for &shy; to remove it.
        if (needsShy) {
          var shyElement = element;

          // Sometimes we get nameless elements with the shy inside
          while (shyElement.nodeType === 1 && !shyElement.nodeName) {
            shyElement = shyElement.firstChild;
          }

          // At this point it's the actual unicode character.
          if (shyElement.nodeType === 3 && shyElement.nodeValue.charAt(0) === "\u00AD") {
            shyElement.nodeValue = shyElement.nodeValue.slice(1);
          }
        }

        return element;
      };

      
      var realNode = function(start) {
        while (start.parentNode.tagName === "") {
          start = start.parentNode;
        }

        return start;
      };

      
      var fixParentage = function(start, end) {
        if (start.parentNode !== end.parentNode) {
          end.parentNode.insertBefore(start, end.parentNode.firstChild);
        }
      };

      htmlFunc = function(html, outerToo) {
        // get the real starting node. see realNode for details.
        var start = realNode(document.getElementById(this.start));
        var end = document.getElementById(this.end);
        var parentNode = end.parentNode;
        var node, nextSibling, last;

        // make sure that the start and end nodes share the same
        // parent. If not, fix it.
        fixParentage(start, end);

        // remove all of the nodes after the starting placeholder and
        // before the ending placeholder.
        node = start.nextSibling;
        while (node) {
          nextSibling = node.nextSibling;
          last = node === end;

          // if this is the last node, and we want to remove it as well,
          // set the `end` node to the next sibling. This is because
          // for the rest of the function, we insert the new nodes
          // before the end (note that insertBefore(node, null) is
          // the same as appendChild(node)).
          //
          // if we do not want to remove it, just break.
          if (last) {
            if (outerToo) { end = node.nextSibling; } else { break; }
          }

          node.parentNode.removeChild(node);

          // if this is the last node and we didn't break before
          // (because we wanted to remove the outer nodes), break
          // now.
          if (last) { break; }

          node = nextSibling;
        }

        // get the first node for the HTML string, even in cases like
        // tables and lists where a simple innerHTML on a div would
        // swallow some of the content.
        node = firstNodeFor(start.parentNode, html);

        if (outerToo) {
          start.parentNode.removeChild(start);
        }

        // copy the nodes for the HTML between the starting and ending
        // placeholder.
        while (node) {
          nextSibling = node.nextSibling;
          parentNode.insertBefore(node, end);
          node = nextSibling;
        }
      };

      // remove the nodes in the DOM representing this metamorph.
      //
      // this includes the starting and ending placeholders.
      removeFunc = function() {
        var start = realNode(document.getElementById(this.start));
        var end = document.getElementById(this.end);

        this.html('');
        start.parentNode.removeChild(start);
        end.parentNode.removeChild(end);
      };

      appendToFunc = function(parentNode) {
        var node = firstNodeFor(parentNode, this.outerHTML());
        var nextSibling;

        while (node) {
          nextSibling = node.nextSibling;
          parentNode.appendChild(node);
          node = nextSibling;
        }
      };

      afterFunc = function(html) {
        // get the real starting node. see realNode for details.
        var end = document.getElementById(this.end);
        var insertBefore = end.nextSibling;
        var parentNode = end.parentNode;
        var nextSibling;
        var node;

        // get the first node for the HTML string, even in cases like
        // tables and lists where a simple innerHTML on a div would
        // swallow some of the content.
        node = firstNodeFor(parentNode, html);

        // copy the nodes for the HTML between the starting and ending
        // placeholder.
        while (node) {
          nextSibling = node.nextSibling;
          parentNode.insertBefore(node, insertBefore);
          node = nextSibling;
        }
      };

      prependFunc = function(html) {
        var start = document.getElementById(this.start);
        var parentNode = start.parentNode;
        var nextSibling;
        var node;

        node = firstNodeFor(parentNode, html);
        var insertBefore = start.nextSibling;

        while (node) {
          nextSibling = node.nextSibling;
          parentNode.insertBefore(node, insertBefore);
          node = nextSibling;
        }
      };
    }

    Metamorph.prototype.html = function(html) {
      this.checkRemoved();
      if (html === undefined) { return this.innerHTML; }

      htmlFunc.call(this, html);

      this.innerHTML = html;
    };

    Metamorph.prototype.replaceWith = function(html) {
      this.checkRemoved();
      htmlFunc.call(this, html, true);
    };

    Metamorph.prototype.remove = removeFunc;
    Metamorph.prototype.outerHTML = outerHTMLFunc;
    Metamorph.prototype.appendTo = appendToFunc;
    Metamorph.prototype.after = afterFunc;
    Metamorph.prototype.prepend = prependFunc;
    Metamorph.prototype.startTag = startTagFunc;
    Metamorph.prototype.endTag = endTagFunc;

    Metamorph.prototype.isRemoved = function() {
      var before = document.getElementById(this.start);
      var after = document.getElementById(this.end);

      return !before || !after;
    };

    Metamorph.prototype.checkRemoved = function() {
      if (this.isRemoved()) {
        throw new Error("Cannot perform operations on a Metamorph that is not in the DOM.");
      }
    };

    return Metamorph;
  });

define("route-recognizer",
  ["route-recognizer/dsl","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var map = __dependency1__["default"];

    var specials = [
      '/', '.', '*', '+', '?', '|',
      '(', ')', '[', ']', '{', '}', '\\'
    ];

    var escapeRegex = new RegExp('(\\' + specials.join('|\\') + ')', 'g');

    function isArray(test) {
      return Object.prototype.toString.call(test) === "[object Array]";
    }

    // A Segment represents a segment in the original route description.
    // Each Segment type provides an `eachChar` and `regex` method.
    //
    // The `eachChar` method invokes the callback with one or more character
    // specifications. A character specification consumes one or more input
    // characters.
    //
    // The `regex` method returns a regex fragment for the segment. If the
    // segment is a dynamic of star segment, the regex fragment also includes
    // a capture.
    //
    // A character specification contains:
    //
    // * `validChars`: a String with a list of all valid characters, or
    // * `invalidChars`: a String with a list of all invalid characters
    // * `repeat`: true if the character specification can repeat

    function StaticSegment(string) { this.string = string; }
    StaticSegment.prototype = {
      eachChar: function(callback) {
        var string = this.string, ch;

        for (var i=0, l=string.length; i<l; i++) {
          ch = string.charAt(i);
          callback({ validChars: ch });
        }
      },

      regex: function() {
        return this.string.replace(escapeRegex, '\\$1');
      },

      generate: function() {
        return this.string;
      }
    };

    function DynamicSegment(name) { this.name = name; }
    DynamicSegment.prototype = {
      eachChar: function(callback) {
        callback({ invalidChars: "/", repeat: true });
      },

      regex: function() {
        return "([^/]+)";
      },

      generate: function(params) {
        return params[this.name];
      }
    };

    function StarSegment(name) { this.name = name; }
    StarSegment.prototype = {
      eachChar: function(callback) {
        callback({ invalidChars: "", repeat: true });
      },

      regex: function() {
        return "(.+)";
      },

      generate: function(params) {
        return params[this.name];
      }
    };

    function EpsilonSegment() {}
    EpsilonSegment.prototype = {
      eachChar: function() {},
      regex: function() { return ""; },
      generate: function() { return ""; }
    };

    function parse(route, names, types) {
      // normalize route as not starting with a "/". Recognition will
      // also normalize.
      if (route.charAt(0) === "/") { route = route.substr(1); }

      var segments = route.split("/"), results = [];

      for (var i=0, l=segments.length; i<l; i++) {
        var segment = segments[i], match;

        if (match = segment.match(/^:([^\/]+)$/)) {
          results.push(new DynamicSegment(match[1]));
          names.push(match[1]);
          types.dynamics++;
        } else if (match = segment.match(/^\*([^\/]+)$/)) {
          results.push(new StarSegment(match[1]));
          names.push(match[1]);
          types.stars++;
        } else if(segment === "") {
          results.push(new EpsilonSegment());
        } else {
          results.push(new StaticSegment(segment));
          types.statics++;
        }
      }

      return results;
    }

    // A State has a character specification and (`charSpec`) and a list of possible
    // subsequent states (`nextStates`).
    //
    // If a State is an accepting state, it will also have several additional
    // properties:
    //
    // * `regex`: A regular expression that is used to extract parameters from paths
    //   that reached this accepting state.
    // * `handlers`: Information on how to convert the list of captures into calls
    //   to registered handlers with the specified parameters
    // * `types`: How many static, dynamic or star segments in this route. Used to
    //   decide which route to use if multiple registered routes match a path.
    //
    // Currently, State is implemented naively by looping over `nextStates` and
    // comparing a character specification against a character. A more efficient
    // implementation would use a hash of keys pointing at one or more next states.

    function State(charSpec) {
      this.charSpec = charSpec;
      this.nextStates = [];
    }

    State.prototype = {
      get: function(charSpec) {
        var nextStates = this.nextStates;

        for (var i=0, l=nextStates.length; i<l; i++) {
          var child = nextStates[i];

          var isEqual = child.charSpec.validChars === charSpec.validChars;
          isEqual = isEqual && child.charSpec.invalidChars === charSpec.invalidChars;

          if (isEqual) { return child; }
        }
      },

      put: function(charSpec) {
        var state;

        // If the character specification already exists in a child of the current
        // state, just return that state.
        if (state = this.get(charSpec)) { return state; }

        // Make a new state for the character spec
        state = new State(charSpec);

        // Insert the new state as a child of the current state
        this.nextStates.push(state);

        // If this character specification repeats, insert the new state as a child
        // of itself. Note that this will not trigger an infinite loop because each
        // transition during recognition consumes a character.
        if (charSpec.repeat) {
          state.nextStates.push(state);
        }

        // Return the new state
        return state;
      },

      // Find a list of child states matching the next character
      match: function(ch) {
        // DEBUG "Processing `" + ch + "`:"
        var nextStates = this.nextStates,
            child, charSpec, chars;

        // DEBUG "  " + debugState(this)
        var returned = [];

        for (var i=0, l=nextStates.length; i<l; i++) {
          child = nextStates[i];

          charSpec = child.charSpec;

          if (typeof (chars = charSpec.validChars) !== 'undefined') {
            if (chars.indexOf(ch) !== -1) { returned.push(child); }
          } else if (typeof (chars = charSpec.invalidChars) !== 'undefined') {
            if (chars.indexOf(ch) === -1) { returned.push(child); }
          }
        }

        return returned;
      }

      
    };

    

    // This is a somewhat naive strategy, but should work in a lot of cases
    // A better strategy would properly resolve /posts/:id/new and /posts/edit/:id.
    //
    // This strategy generally prefers more static and less dynamic matching.
    // Specifically, it
    //
    //  * prefers fewer stars to more, then
    //  * prefers using stars for less of the match to more, then
    //  * prefers fewer dynamic segments to more, then
    //  * prefers more static segments to more
    function sortSolutions(states) {
      return states.sort(function(a, b) {
        if (a.types.stars !== b.types.stars) { return a.types.stars - b.types.stars; }

        if (a.types.stars) {
          if (a.types.statics !== b.types.statics) { return b.types.statics - a.types.statics; }
          if (a.types.dynamics !== b.types.dynamics) { return b.types.dynamics - a.types.dynamics; }
        }

        if (a.types.dynamics !== b.types.dynamics) { return a.types.dynamics - b.types.dynamics; }
        if (a.types.statics !== b.types.statics) { return b.types.statics - a.types.statics; }

        return 0;
      });
    }

    function recognizeChar(states, ch) {
      var nextStates = [];

      for (var i=0, l=states.length; i<l; i++) {
        var state = states[i];

        nextStates = nextStates.concat(state.match(ch));
      }

      return nextStates;
    }

    var oCreate = Object.create || function(proto) {
      function F() {}
      F.prototype = proto;
      return new F();
    };

    function RecognizeResults(queryParams) {
      this.queryParams = queryParams || {};
    }
    RecognizeResults.prototype = oCreate({
      splice: Array.prototype.splice,
      slice:  Array.prototype.slice,
      push:   Array.prototype.push,
      length: 0,
      queryParams: null
    });

    function findHandler(state, path, queryParams) {
      var handlers = state.handlers, regex = state.regex;
      var captures = path.match(regex), currentCapture = 1;
      var result = new RecognizeResults(queryParams);

      for (var i=0, l=handlers.length; i<l; i++) {
        var handler = handlers[i], names = handler.names, params = {};

        for (var j=0, m=names.length; j<m; j++) {
          params[names[j]] = captures[currentCapture++];
        }

        result.push({ handler: handler.handler, params: params, isDynamic: !!names.length });
      }

      return result;
    }

    function addSegment(currentState, segment) {
      segment.eachChar(function(ch) {
        var state;

        currentState = currentState.put(ch);
      });

      return currentState;
    }

    // The main interface

    var RouteRecognizer = function() {
      this.rootState = new State();
      this.names = {};
    };


    RouteRecognizer.prototype = {
      add: function(routes, options) {
        var currentState = this.rootState, regex = "^",
            types = { statics: 0, dynamics: 0, stars: 0 },
            handlers = [], allSegments = [], name;

        var isEmpty = true;

        for (var i=0, l=routes.length; i<l; i++) {
          var route = routes[i], names = [];

          var segments = parse(route.path, names, types);

          allSegments = allSegments.concat(segments);

          for (var j=0, m=segments.length; j<m; j++) {
            var segment = segments[j];

            if (segment instanceof EpsilonSegment) { continue; }

            isEmpty = false;

            // Add a "/" for the new segment
            currentState = currentState.put({ validChars: "/" });
            regex += "/";

            // Add a representation of the segment to the NFA and regex
            currentState = addSegment(currentState, segment);
            regex += segment.regex();
          }

          var handler = { handler: route.handler, names: names };
          handlers.push(handler);
        }

        if (isEmpty) {
          currentState = currentState.put({ validChars: "/" });
          regex += "/";
        }

        currentState.handlers = handlers;
        currentState.regex = new RegExp(regex + "$");
        currentState.types = types;

        if (name = options && options.as) {
          this.names[name] = {
            segments: allSegments,
            handlers: handlers
          };
        }
      },

      handlersFor: function(name) {
        var route = this.names[name], result = [];
        if (!route) { throw new Error("There is no route named " + name); }

        for (var i=0, l=route.handlers.length; i<l; i++) {
          result.push(route.handlers[i]);
        }

        return result;
      },

      hasRoute: function(name) {
        return !!this.names[name];
      },

      generate: function(name, params) {
        var route = this.names[name], output = "";
        if (!route) { throw new Error("There is no route named " + name); }

        var segments = route.segments;

        for (var i=0, l=segments.length; i<l; i++) {
          var segment = segments[i];

          if (segment instanceof EpsilonSegment) { continue; }

          output += "/";
          output += segment.generate(params);
        }

        if (output.charAt(0) !== '/') { output = '/' + output; }

        if (params && params.queryParams) {
          output += this.generateQueryString(params.queryParams, route.handlers);
        }

        return output;
      },

      generateQueryString: function(params, handlers) {
        var pairs = [];
        var keys = [];
        for(var key in params) {
          if (params.hasOwnProperty(key)) {
            keys.push(key);
          }
        }
        keys.sort();
        for (var i = 0, len = keys.length; i < len; i++) {
          key = keys[i];
          var value = params[key];
          if (value == null) {
            continue;
          }
          var pair = encodeURIComponent(key);
          if (isArray(value)) {
            for (var j = 0, l = value.length; j < l; j++) {
              var arrayPair = key + '[]' + '=' + encodeURIComponent(value[j]);
              pairs.push(arrayPair);
            }
          } else {
            pair += "=" + encodeURIComponent(value);
            pairs.push(pair);
          }
        }

        if (pairs.length === 0) { return ''; }

        return "?" + pairs.join("&");
      },

      parseQueryString: function(queryString) {
        var pairs = queryString.split("&"), queryParams = {};
        for(var i=0; i < pairs.length; i++) {
          var pair      = pairs[i].split('='),
              key       = decodeURIComponent(pair[0]),
              keyLength = key.length,
              isArray = false,
              value;
          if (pair.length === 1) {
            value = 'true';
          } else {
            //Handle arrays
            if (keyLength > 2 && key.slice(keyLength -2) === '[]') {
              isArray = true;
              key = key.slice(0, keyLength - 2);
              if(!queryParams[key]) {
                queryParams[key] = [];
              }
            }
            value = pair[1] ? decodeURIComponent(pair[1]) : '';
          }
          if (isArray) {
            queryParams[key].push(value);
          } else {
            queryParams[key] = value;
          }
        }
        return queryParams;
      },

      recognize: function(path) {
        var states = [ this.rootState ],
            pathLen, i, l, queryStart, queryParams = {},
            isSlashDropped = false;

        queryStart = path.indexOf('?');
        if (queryStart !== -1) {
          var queryString = path.substr(queryStart + 1, path.length);
          path = path.substr(0, queryStart);
          queryParams = this.parseQueryString(queryString);
        }

        path = decodeURI(path);

        // DEBUG GROUP path

        if (path.charAt(0) !== "/") { path = "/" + path; }

        pathLen = path.length;
        if (pathLen > 1 && path.charAt(pathLen - 1) === "/") {
          path = path.substr(0, pathLen - 1);
          isSlashDropped = true;
        }

        for (i=0, l=path.length; i<l; i++) {
          states = recognizeChar(states, path.charAt(i));
          if (!states.length) { break; }
        }

        // END DEBUG GROUP

        var solutions = [];
        for (i=0, l=states.length; i<l; i++) {
          if (states[i].handlers) { solutions.push(states[i]); }
        }

        states = sortSolutions(solutions);

        var state = solutions[0];

        if (state && state.handlers) {
          // if a trailing slash was dropped and a star segment is the last segment
          // specified, put the trailing slash back
          if (isSlashDropped && state.regex.source.slice(-5) === "(.+)$") {
            path = path + "/";
          }
          return findHandler(state, path, queryParams);
        }
      }
    };

    RouteRecognizer.prototype.map = map;

    __exports__["default"] = RouteRecognizer;
  });
define("route-recognizer/dsl",
  ["exports"],
  function(__exports__) {
    "use strict";
    function Target(path, matcher, delegate) {
      this.path = path;
      this.matcher = matcher;
      this.delegate = delegate;
    }

    Target.prototype = {
      to: function(target, callback) {
        var delegate = this.delegate;

        if (delegate && delegate.willAddRoute) {
          target = delegate.willAddRoute(this.matcher.target, target);
        }

        this.matcher.add(this.path, target);

        if (callback) {
          if (callback.length === 0) { throw new Error("You must have an argument in the function passed to `to`"); }
          this.matcher.addChild(this.path, target, callback, this.delegate);
        }
        return this;
      }
    };

    function Matcher(target) {
      this.routes = {};
      this.children = {};
      this.target = target;
    }

    Matcher.prototype = {
      add: function(path, handler) {
        this.routes[path] = handler;
      },

      addChild: function(path, target, callback, delegate) {
        var matcher = new Matcher(target);
        this.children[path] = matcher;

        var match = generateMatch(path, matcher, delegate);

        if (delegate && delegate.contextEntered) {
          delegate.contextEntered(target, match);
        }

        callback(match);
      }
    };

    function generateMatch(startingPath, matcher, delegate) {
      return function(path, nestedCallback) {
        var fullPath = startingPath + path;

        if (nestedCallback) {
          nestedCallback(generateMatch(fullPath, matcher, delegate));
        } else {
          return new Target(startingPath + path, matcher, delegate);
        }
      };
    }

    function addRoute(routeArray, path, handler) {
      var len = 0;
      for (var i=0, l=routeArray.length; i<l; i++) {
        len += routeArray[i].path.length;
      }

      path = path.substr(len);
      var route = { path: path, handler: handler };
      routeArray.push(route);
    }

    function eachRoute(baseRoute, matcher, callback, binding) {
      var routes = matcher.routes;

      for (var path in routes) {
        if (routes.hasOwnProperty(path)) {
          var routeArray = baseRoute.slice();
          addRoute(routeArray, path, routes[path]);

          if (matcher.children[path]) {
            eachRoute(routeArray, matcher.children[path], callback, binding);
          } else {
            callback.call(binding, routeArray);
          }
        }
      }
    }

    __exports__["default"] = function(callback, addRouteCallback) {
      var matcher = new Matcher();

      callback(generateMatch("", matcher, this.delegate));

      eachRoute([], matcher, function(route) {
        if (addRouteCallback) { addRouteCallback(this, route); }
        else { this.add(route); }
      }, this);
    }
  });

define("router/handler-info",
  ["./utils","rsvp/promise","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var bind = __dependency1__.bind;
    var merge = __dependency1__.merge;
    var serialize = __dependency1__.serialize;
    var promiseLabel = __dependency1__.promiseLabel;
    var applyHook = __dependency1__.applyHook;
    var Promise = __dependency2__["default"];

    function HandlerInfo(_props) {
      var props = _props || {};
      merge(this, props);
      this.initialize(props);
    }

    HandlerInfo.prototype = {
      name: null,
      handler: null,
      params: null,
      context: null,

      // Injected by the handler info factory.
      factory: null,

      initialize: function() {},

      log: function(payload, message) {
        if (payload.log) {
          payload.log(this.name + ': ' + message);
        }
      },

      promiseLabel: function(label) {
        return promiseLabel("'" + this.name + "' " + label);
      },

      getUnresolved: function() {
        return this;
      },

      serialize: function() {
        return this.params || {};
      },

      resolve: function(shouldContinue, payload) {
        var checkForAbort  = bind(this, this.checkForAbort,      shouldContinue),
            beforeModel    = bind(this, this.runBeforeModelHook, payload),
            model          = bind(this, this.getModel,           payload),
            afterModel     = bind(this, this.runAfterModelHook,  payload),
            becomeResolved = bind(this, this.becomeResolved,     payload);

        return Promise.resolve(undefined, this.promiseLabel("Start handler"))
               .then(checkForAbort, null, this.promiseLabel("Check for abort"))
               .then(beforeModel, null, this.promiseLabel("Before model"))
               .then(checkForAbort, null, this.promiseLabel("Check if aborted during 'beforeModel' hook"))
               .then(model, null, this.promiseLabel("Model"))
               .then(checkForAbort, null, this.promiseLabel("Check if aborted in 'model' hook"))
               .then(afterModel, null, this.promiseLabel("After model"))
               .then(checkForAbort, null, this.promiseLabel("Check if aborted in 'afterModel' hook"))
               .then(becomeResolved, null, this.promiseLabel("Become resolved"));
      },

      runBeforeModelHook: function(payload) {
        if (payload.trigger) {
          payload.trigger(true, 'willResolveModel', payload, this.handler);
        }
        return this.runSharedModelHook(payload, 'beforeModel', []);
      },

      runAfterModelHook: function(payload, resolvedModel) {
        // Stash the resolved model on the payload.
        // This makes it possible for users to swap out
        // the resolved model in afterModel.
        var name = this.name;
        this.stashResolvedModel(payload, resolvedModel);

        return this.runSharedModelHook(payload, 'afterModel', [resolvedModel])
                   .then(function() {
                     // Ignore the fulfilled value returned from afterModel.
                     // Return the value stashed in resolvedModels, which
                     // might have been swapped out in afterModel.
                     return payload.resolvedModels[name];
                   }, null, this.promiseLabel("Ignore fulfillment value and return model value"));
      },

      runSharedModelHook: function(payload, hookName, args) {
        this.log(payload, "calling " + hookName + " hook");

        if (this.queryParams) {
          args.push(this.queryParams);
        }
        args.push(payload);

        var result = applyHook(this.handler, hookName, args);

        if (result && result.isTransition) {
          result = null;
        }

        return Promise.resolve(result, this.promiseLabel("Resolve value returned from one of the model hooks"));
      },

      // overridden by subclasses
      getModel: null,

      checkForAbort: function(shouldContinue, promiseValue) {
        return Promise.resolve(shouldContinue(), this.promiseLabel("Check for abort")).then(function() {
          // We don't care about shouldContinue's resolve value;
          // pass along the original value passed to this fn.
          return promiseValue;
        }, null, this.promiseLabel("Ignore fulfillment value and continue"));
      },

      stashResolvedModel: function(payload, resolvedModel) {
        payload.resolvedModels = payload.resolvedModels || {};
        payload.resolvedModels[this.name] = resolvedModel;
      },

      becomeResolved: function(payload, resolvedContext) {
        var params = this.serialize(resolvedContext);

        if (payload) {
          this.stashResolvedModel(payload, resolvedContext);
          payload.params = payload.params || {};
          payload.params[this.name] = params;
        }

        return this.factory('resolved', {
          context: resolvedContext,
          name: this.name,
          handler: this.handler,
          params: params
        });
      },

      shouldSupercede: function(other) {
        // Prefer this newer handlerInfo over `other` if:
        // 1) The other one doesn't exist
        // 2) The names don't match
        // 3) This handler has a context that doesn't match
        //    the other one (or the other one doesn't have one).
        // 4) This handler has parameters that don't match the other.
        if (!other) { return true; }

        var contextsMatch = (other.context === this.context);
        return other.name !== this.name ||
               (this.hasOwnProperty('context') && !contextsMatch) ||
               (this.hasOwnProperty('params') && !paramsMatch(this.params, other.params));
      }
    };

    function paramsMatch(a, b) {
      if ((!a) ^ (!b)) {
        // Only one is null.
        return false;
      }

      if (!a) {
        // Both must be null.
        return true;
      }

      // Note: this assumes that both params have the same
      // number of keys, but since we're comparing the
      // same handlers, they should.
      for (var k in a) {
        if (a.hasOwnProperty(k) && a[k] !== b[k]) {
          return false;
        }
      }
      return true;
    }

    __exports__["default"] = HandlerInfo;
  });
define("router/handler-info/factory",
  ["router/handler-info/resolved-handler-info","router/handler-info/unresolved-handler-info-by-object","router/handler-info/unresolved-handler-info-by-param","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var ResolvedHandlerInfo = __dependency1__["default"];
    var UnresolvedHandlerInfoByObject = __dependency2__["default"];
    var UnresolvedHandlerInfoByParam = __dependency3__["default"];

    handlerInfoFactory.klasses = {
      resolved: ResolvedHandlerInfo,
      param: UnresolvedHandlerInfoByParam,
      object: UnresolvedHandlerInfoByObject
    };

    function handlerInfoFactory(name, props) {
      var Ctor = handlerInfoFactory.klasses[name],
          handlerInfo = new Ctor(props || {});
      handlerInfo.factory = handlerInfoFactory;
      return handlerInfo;
    }

    __exports__["default"] = handlerInfoFactory;
  });
define("router/handler-info/resolved-handler-info",
  ["../handler-info","router/utils","rsvp/promise","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var HandlerInfo = __dependency1__["default"];
    var subclass = __dependency2__.subclass;
    var promiseLabel = __dependency2__.promiseLabel;
    var Promise = __dependency3__["default"];

    var ResolvedHandlerInfo = subclass(HandlerInfo, {
      resolve: function(shouldContinue, payload) {
        // A ResolvedHandlerInfo just resolved with itself.
        if (payload && payload.resolvedModels) {
          payload.resolvedModels[this.name] = this.context;
        }
        return Promise.resolve(this, this.promiseLabel("Resolve"));
      },

      getUnresolved: function() {
        return this.factory('param', {
          name: this.name,
          handler: this.handler,
          params: this.params
        });
      },

      isResolved: true
    });

    __exports__["default"] = ResolvedHandlerInfo;
  });
define("router/handler-info/unresolved-handler-info-by-object",
  ["../handler-info","router/utils","rsvp/promise","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var HandlerInfo = __dependency1__["default"];
    var merge = __dependency2__.merge;
    var subclass = __dependency2__.subclass;
    var promiseLabel = __dependency2__.promiseLabel;
    var isParam = __dependency2__.isParam;
    var Promise = __dependency3__["default"];

    var UnresolvedHandlerInfoByObject = subclass(HandlerInfo, {
      getModel: function(payload) {
        this.log(payload, this.name + ": resolving provided model");
        return Promise.resolve(this.context);
      },

      initialize: function(props) {
        this.names = props.names || [];
        this.context = props.context;
      },

      
      serialize: function(_model) {
        var model = _model || this.context,
            names = this.names,
            handler = this.handler;

        var object = {};
        if (isParam(model)) {
          object[names[0]] = model;
          return object;
        }

        // Use custom serialize if it exists.
        if (handler.serialize) {
          return handler.serialize(model, names);
        }

        if (names.length !== 1) { return; }

        var name = names[0];

        if (/_id$/.test(name)) {
          object[name] = model.id;
        } else {
          object[name] = model;
        }
        return object;
      }
    });

    __exports__["default"] = UnresolvedHandlerInfoByObject;
  });
define("router/handler-info/unresolved-handler-info-by-param",
  ["../handler-info","router/utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var HandlerInfo = __dependency1__["default"];
    var resolveHook = __dependency2__.resolveHook;
    var merge = __dependency2__.merge;
    var subclass = __dependency2__.subclass;
    var promiseLabel = __dependency2__.promiseLabel;

    // Generated by URL transitions and non-dynamic route segments in named Transitions.
    var UnresolvedHandlerInfoByParam = subclass (HandlerInfo, {
      initialize: function(props) {
        this.params = props.params || {};
      },

      getModel: function(payload) {
        var fullParams = this.params;
        if (payload && payload.queryParams) {
          fullParams = {};
          merge(fullParams, this.params);
          fullParams.queryParams = payload.queryParams;
        }

        var handler = this.handler;
        var hookName = resolveHook(handler, 'deserialize') ||
                       resolveHook(handler, 'model');

        return this.runSharedModelHook(payload, hookName, [fullParams]);
      }
    });

    __exports__["default"] = UnresolvedHandlerInfoByParam;
  });
define("router/router",
  ["route-recognizer","rsvp/promise","./utils","./transition-state","./transition","./transition-intent/named-transition-intent","./transition-intent/url-transition-intent","./handler-info","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var RouteRecognizer = __dependency1__["default"];
    var Promise = __dependency2__["default"];
    var trigger = __dependency3__.trigger;
    var log = __dependency3__.log;
    var slice = __dependency3__.slice;
    var forEach = __dependency3__.forEach;
    var merge = __dependency3__.merge;
    var serialize = __dependency3__.serialize;
    var extractQueryParams = __dependency3__.extractQueryParams;
    var getChangelist = __dependency3__.getChangelist;
    var promiseLabel = __dependency3__.promiseLabel;
    var callHook = __dependency3__.callHook;
    var TransitionState = __dependency4__["default"];
    var logAbort = __dependency5__.logAbort;
    var Transition = __dependency5__.Transition;
    var TransitionAborted = __dependency5__.TransitionAborted;
    var NamedTransitionIntent = __dependency6__["default"];
    var URLTransitionIntent = __dependency7__["default"];
    var ResolvedHandlerInfo = __dependency8__.ResolvedHandlerInfo;

    var pop = Array.prototype.pop;

    function Router() {
      this.recognizer = new RouteRecognizer();
      this.reset();
    }

    Router.prototype = {

      
      map: function(callback) {
        this.recognizer.delegate = this.delegate;

        this.recognizer.map(callback, function(recognizer, routes) {
          for (var i = routes.length - 1, proceed = true; i >= 0 && proceed; --i) {
            var route = routes[i];
            recognizer.add(routes, { as: route.handler });
            proceed = route.path === '/' || route.path === '' || route.handler.slice(-6) === '.index';
          }
        });
      },

      hasRoute: function(route) {
        return this.recognizer.hasRoute(route);
      },

      queryParamsTransition: function(changelist, wasTransitioning, oldState, newState) {
        var router = this;

        fireQueryParamDidChange(this, newState, changelist);

        if (!wasTransitioning && this.activeTransition) {
          // One of the handlers in queryParamsDidChange
          // caused a transition. Just return that transition.
          return this.activeTransition;
        } else {
          // Running queryParamsDidChange didn't change anything.
          // Just update query params and be on our way.

          // We have to return a noop transition that will
          // perform a URL update at the end. This gives
          // the user the ability to set the url update
          // method (default is replaceState).
          var newTransition = new Transition(this);
          newTransition.queryParamsOnly = true;

          oldState.queryParams = finalizeQueryParamChange(this, newState.handlerInfos, newState.queryParams, newTransition);

          newTransition.promise = newTransition.promise.then(function(result) {
            updateURL(newTransition, oldState, true);
            if (router.didTransition) {
              router.didTransition(router.currentHandlerInfos);
            }
            return result;
          }, null, promiseLabel("Transition complete"));
          return newTransition;
        }
      },

      // NOTE: this doesn't really belong here, but here
      // it shall remain until our ES6 transpiler can
      // handle cyclical deps.
      transitionByIntent: function(intent, isIntermediate) {

        var wasTransitioning = !!this.activeTransition;
        var oldState = wasTransitioning ? this.activeTransition.state : this.state;
        var newTransition;
        var router = this;

        try {
          var newState = intent.applyToState(oldState, this.recognizer, this.getHandler, isIntermediate);
          var queryParamChangelist = getChangelist(oldState.queryParams, newState.queryParams);

          if (handlerInfosEqual(newState.handlerInfos, oldState.handlerInfos)) {

            // This is a no-op transition. See if query params changed.
            if (queryParamChangelist) {
              newTransition = this.queryParamsTransition(queryParamChangelist, wasTransitioning, oldState, newState);
              if (newTransition) {
                return newTransition;
              }
            }

            // No-op. No need to create a new transition.
            return new Transition(this);
          }

          if (isIntermediate) {
            setupContexts(this, newState);
            return;
          }

          // Create a new transition to the destination route.
          newTransition = new Transition(this, intent, newState);

          // Abort and usurp any previously active transition.
          if (this.activeTransition) {
            this.activeTransition.abort();
          }
          this.activeTransition = newTransition;

          // Transition promises by default resolve with resolved state.
          // For our purposes, swap out the promise to resolve
          // after the transition has been finalized.
          newTransition.promise = newTransition.promise.then(function(result) {
            return finalizeTransition(newTransition, result.state);
          }, null, promiseLabel("Settle transition promise when transition is finalized"));

          if (!wasTransitioning) {
            notifyExistingHandlers(this, newState, newTransition);
          }

          fireQueryParamDidChange(this, newState, queryParamChangelist);

          return newTransition;
        } catch(e) {
          return new Transition(this, intent, null, e);
        }
      },

      
      reset: function() {
        if (this.state) {
          forEach(this.state.handlerInfos.slice().reverse(), function(handlerInfo) {
            var handler = handlerInfo.handler;
            callHook(handler, 'exit');
          });
        }

        this.state = new TransitionState();
        this.currentHandlerInfos = null;
      },

      activeTransition: null,

      
      handleURL: function(url) {
        // Perform a URL-based transition, but don't change
        // the URL afterward, since it already happened.
        var args = slice.call(arguments);
        if (url.charAt(0) !== '/') { args[0] = '/' + url; }

        return doTransition(this, args).method(null);
      },

      
      updateURL: function() {
        throw new Error("updateURL is not implemented");
      },

      
      replaceURL: function(url) {
        this.updateURL(url);
      },

      
      transitionTo: function(name) {
        return doTransition(this, arguments);
      },

      intermediateTransitionTo: function(name) {
        return doTransition(this, arguments, true);
      },

      refresh: function(pivotHandler) {
        var state = this.activeTransition ? this.activeTransition.state : this.state;
        var handlerInfos = state.handlerInfos;
        var params = {};
        for (var i = 0, len = handlerInfos.length; i < len; ++i) {
          var handlerInfo = handlerInfos[i];
          params[handlerInfo.name] = handlerInfo.params || {};
        }

        log(this, "Starting a refresh transition");
        var intent = new NamedTransitionIntent({
          name: handlerInfos[handlerInfos.length - 1].name,
          pivotHandler: pivotHandler || handlerInfos[0].handler,
          contexts: [], // TODO collect contexts...?
          queryParams: this._changedQueryParams || state.queryParams || {}
        });

        return this.transitionByIntent(intent, false);
      },

      
      replaceWith: function(name) {
        return doTransition(this, arguments).method('replace');
      },

      
      generate: function(handlerName) {

        var partitionedArgs = extractQueryParams(slice.call(arguments, 1)),
          suppliedParams = partitionedArgs[0],
          queryParams = partitionedArgs[1];

        // Construct a TransitionIntent with the provided params
        // and apply it to the present state of the router.
        var intent = new NamedTransitionIntent({ name: handlerName, contexts: suppliedParams });
        var state = intent.applyToState(this.state, this.recognizer, this.getHandler);
        var params = {};

        for (var i = 0, len = state.handlerInfos.length; i < len; ++i) {
          var handlerInfo = state.handlerInfos[i];
          var handlerParams = handlerInfo.serialize();
          merge(params, handlerParams);
        }
        params.queryParams = queryParams;

        return this.recognizer.generate(handlerName, params);
      },

      applyIntent: function(handlerName, contexts) {
        var intent = new NamedTransitionIntent({
          name: handlerName,
          contexts: contexts
        });

        var state = this.activeTransition && this.activeTransition.state || this.state;
        return intent.applyToState(state, this.recognizer, this.getHandler);
      },

      isActiveIntent: function(handlerName, contexts, queryParams) {
        var targetHandlerInfos = this.state.handlerInfos,
            found = false, names, object, handlerInfo, handlerObj, i, len;

        if (!targetHandlerInfos.length) { return false; }

        var targetHandler = targetHandlerInfos[targetHandlerInfos.length - 1].name;
        var recogHandlers = this.recognizer.handlersFor(targetHandler);

        var index = 0;
        for (len = recogHandlers.length; index < len; ++index) {
          handlerInfo = targetHandlerInfos[index];
          if (handlerInfo.name === handlerName) { break; }
        }

        if (index === recogHandlers.length) {
          // The provided route name isn't even in the route hierarchy.
          return false;
        }

        var state = new TransitionState();
        state.handlerInfos = targetHandlerInfos.slice(0, index + 1);
        recogHandlers = recogHandlers.slice(0, index + 1);

        var intent = new NamedTransitionIntent({
          name: targetHandler,
          contexts: contexts
        });

        var newState = intent.applyToHandlers(state, recogHandlers, this.getHandler, targetHandler, true, true);

        var handlersEqual = handlerInfosEqual(newState.handlerInfos, state.handlerInfos);
        if (!queryParams || !handlersEqual) {
          return handlersEqual;
        }

        // Get a hash of QPs that will still be active on new route
        var activeQPsOnNewHandler = {};
        merge(activeQPsOnNewHandler, queryParams);

        var activeQueryParams  = this.state.queryParams;
        for (var key in activeQueryParams) {
          if (activeQueryParams.hasOwnProperty(key) &&
              activeQPsOnNewHandler.hasOwnProperty(key)) {
            activeQPsOnNewHandler[key] = activeQueryParams[key];
          }
        }

        return handlersEqual && !getChangelist(activeQPsOnNewHandler, queryParams);
      },

      isActive: function(handlerName) {
        var partitionedArgs = extractQueryParams(slice.call(arguments, 1));
        return this.isActiveIntent(handlerName, partitionedArgs[0], partitionedArgs[1]);
      },

      trigger: function(name) {
        var args = slice.call(arguments);
        trigger(this, this.currentHandlerInfos, false, args);
      },

      
      log: null,

      _willChangeContextEvent: 'willChangeContext',
      _triggerWillChangeContext: function(handlerInfos, newTransition) {
        trigger(this, handlerInfos, true, [this._willChangeContextEvent, newTransition]);
      },

      _triggerWillLeave: function(handlerInfos, newTransition, leavingChecker) {
        trigger(this, handlerInfos, true, ['willLeave', newTransition, leavingChecker]);
      }
    };

    
    function fireQueryParamDidChange(router, newState, queryParamChangelist) {
      // If queryParams changed trigger event
      if (queryParamChangelist) {

        // This is a little hacky but we need some way of storing
        // changed query params given that no activeTransition
        // is guaranteed to have occurred.
        router._changedQueryParams = queryParamChangelist.all;
        trigger(router, newState.handlerInfos, true, ['queryParamsDidChange', queryParamChangelist.changed, queryParamChangelist.all, queryParamChangelist.removed]);
        router._changedQueryParams = null;
      }
    }

    
    function setupContexts(router, newState, transition) {
      var partition = partitionHandlers(router.state, newState);

      forEach(partition.exited, function(handlerInfo) {
        var handler = handlerInfo.handler;
        delete handler.context;

        callHook(handler, 'reset', true, transition);
        callHook(handler, 'exit', transition);
      });

      var oldState = router.oldState = router.state;
      router.state = newState;
      var currentHandlerInfos = router.currentHandlerInfos = partition.unchanged.slice();

      try {
        forEach(partition.reset, function(handlerInfo) {
          var handler = handlerInfo.handler;
          callHook(handler, 'reset', false, transition);
        });

        forEach(partition.updatedContext, function(handlerInfo) {
          return handlerEnteredOrUpdated(currentHandlerInfos, handlerInfo, false, transition);
        });

        forEach(partition.entered, function(handlerInfo) {
          return handlerEnteredOrUpdated(currentHandlerInfos, handlerInfo, true, transition);
        });
      } catch(e) {
        router.state = oldState;
        router.currentHandlerInfos = oldState.handlerInfos;
        throw e;
      }

      router.state.queryParams = finalizeQueryParamChange(router, currentHandlerInfos, newState.queryParams, transition);
    }


    
    function handlerEnteredOrUpdated(currentHandlerInfos, handlerInfo, enter, transition) {

      var handler = handlerInfo.handler,
          context = handlerInfo.context;

      callHook(handler, 'enter', transition);
      if (transition && transition.isAborted) {
        throw new TransitionAborted();
      }

      handler.context = context;
      callHook(handler, 'contextDidChange');

      callHook(handler, 'setup', context, transition);
      if (transition && transition.isAborted) {
        throw new TransitionAborted();
      }

      currentHandlerInfos.push(handlerInfo);

      return true;
    }


    
    function partitionHandlers(oldState, newState) {
      var oldHandlers = oldState.handlerInfos;
      var newHandlers = newState.handlerInfos;

      var handlers = {
            updatedContext: [],
            exited: [],
            entered: [],
            unchanged: []
          };

      var handlerChanged, contextChanged = false, i, l;

      for (i=0, l=newHandlers.length; i<l; i++) {
        var oldHandler = oldHandlers[i], newHandler = newHandlers[i];

        if (!oldHandler || oldHandler.handler !== newHandler.handler) {
          handlerChanged = true;
        }

        if (handlerChanged) {
          handlers.entered.push(newHandler);
          if (oldHandler) { handlers.exited.unshift(oldHandler); }
        } else if (contextChanged || oldHandler.context !== newHandler.context) {
          contextChanged = true;
          handlers.updatedContext.push(newHandler);
        } else {
          handlers.unchanged.push(oldHandler);
        }
      }

      for (i=newHandlers.length, l=oldHandlers.length; i<l; i++) {
        handlers.exited.unshift(oldHandlers[i]);
      }

      handlers.reset = handlers.updatedContext.slice();
      handlers.reset.reverse();

      return handlers;
    }

    function updateURL(transition, state, inputUrl) {
      var urlMethod = transition.urlMethod;

      if (!urlMethod) {
        return;
      }

      var router = transition.router,
          handlerInfos = state.handlerInfos,
          handlerName = handlerInfos[handlerInfos.length - 1].name,
          params = {};

      for (var i = handlerInfos.length - 1; i >= 0; --i) {
        var handlerInfo = handlerInfos[i];
        merge(params, handlerInfo.params);
        if (handlerInfo.handler.inaccessibleByURL) {
          urlMethod = null;
        }
      }

      if (urlMethod) {
        params.queryParams = transition._visibleQueryParams || state.queryParams;
        var url = router.recognizer.generate(handlerName, params);

        if (urlMethod === 'replace') {
          router.replaceURL(url);
        } else {
          router.updateURL(url);
        }
      }
    }

    
    function finalizeTransition(transition, newState) {

      try {
        log(transition.router, transition.sequence, "Resolved all models on destination route; finalizing transition.");

        var router = transition.router,
            handlerInfos = newState.handlerInfos,
            seq = transition.sequence;

        // Run all the necessary enter/setup/exit hooks
        setupContexts(router, newState, transition);

        // Check if a redirect occurred in enter/setup
        if (transition.isAborted) {
          // TODO: cleaner way? distinguish b/w targetHandlerInfos?
          router.state.handlerInfos = router.currentHandlerInfos;
          return Promise.reject(logAbort(transition));
        }

        updateURL(transition, newState, transition.intent.url);

        transition.isActive = false;
        router.activeTransition = null;

        trigger(router, router.currentHandlerInfos, true, ['didTransition']);

        if (router.didTransition) {
          router.didTransition(router.currentHandlerInfos);
        }

        log(router, transition.sequence, "TRANSITION COMPLETE.");

        // Resolve with the final handler.
        return handlerInfos[handlerInfos.length - 1].handler;
      } catch(e) {
        if (!((e instanceof TransitionAborted))) {
          //var erroneousHandler = handlerInfos.pop();
          var infos = transition.state.handlerInfos;
          transition.trigger(true, 'error', e, transition, infos[infos.length-1].handler);
          transition.abort();
        }

        throw e;
      }
    }

    
    function doTransition(router, args, isIntermediate) {
      // Normalize blank transitions to root URL transitions.
      var name = args[0] || '/';

      var lastArg = args[args.length-1];
      var queryParams = {};
      if (lastArg && lastArg.hasOwnProperty('queryParams')) {
        queryParams = pop.call(args).queryParams;
      }

      var intent;
      if (args.length === 0) {

        log(router, "Updating query params");

        // A query param update is really just a transition
        // into the route you're already on.
        var handlerInfos = router.state.handlerInfos;
        intent = new NamedTransitionIntent({
          name: handlerInfos[handlerInfos.length - 1].name,
          contexts: [],
          queryParams: queryParams
        });

      } else if (name.charAt(0) === '/') {

        log(router, "Attempting URL transition to " + name);
        intent = new URLTransitionIntent({ url: name });

      } else {

        log(router, "Attempting transition to " + name);
        intent = new NamedTransitionIntent({
          name: args[0],
          contexts: slice.call(args, 1),
          queryParams: queryParams
        });
      }

      return router.transitionByIntent(intent, isIntermediate);
    }

    function handlerInfosEqual(handlerInfos, otherHandlerInfos) {
      if (handlerInfos.length !== otherHandlerInfos.length) {
        return false;
      }

      for (var i = 0, len = handlerInfos.length; i < len; ++i) {
        if (handlerInfos[i] !== otherHandlerInfos[i]) {
          return false;
        }
      }
      return true;
    }

    function finalizeQueryParamChange(router, resolvedHandlers, newQueryParams, transition) {
      // We fire a finalizeQueryParamChange event which
      // gives the new route hierarchy a chance to tell
      // us which query params it's consuming and what
      // their final values are. If a query param is
      // no longer consumed in the final route hierarchy,
      // its serialized segment will be removed
      // from the URL.

      for (var k in newQueryParams) {
        if (newQueryParams.hasOwnProperty(k) &&
            newQueryParams[k] === null) {
          delete newQueryParams[k];
        }
      }

      var finalQueryParamsArray = [];
      trigger(router, resolvedHandlers, true, ['finalizeQueryParamChange', newQueryParams, finalQueryParamsArray, transition]);

      if (transition) {
        transition._visibleQueryParams = {};
      }

      var finalQueryParams = {};
      for (var i = 0, len = finalQueryParamsArray.length; i < len; ++i) {
        var qp = finalQueryParamsArray[i];
        finalQueryParams[qp.key] = qp.value;
        if (transition && qp.visible !== false) {
          transition._visibleQueryParams[qp.key] = qp.value;
        }
      }
      return finalQueryParams;
    }

    function notifyExistingHandlers(router, newState, newTransition) {
      var oldHandlers = router.state.handlerInfos,
          changing = [],
          leavingIndex = null,
          leaving, leavingChecker, i, oldHandlerLen, oldHandler, newHandler;

      oldHandlerLen = oldHandlers.length;
      for (i = 0; i < oldHandlerLen; i++) {
        oldHandler = oldHandlers[i];
        newHandler = newState.handlerInfos[i];

        if (!newHandler || oldHandler.name !== newHandler.name) {
          leavingIndex = i;
          break;
        }

        if (!newHandler.isResolved) {
          changing.push(oldHandler);
        }
      }

      if (leavingIndex !== null) {
        leaving = oldHandlers.slice(leavingIndex, oldHandlerLen);
        leavingChecker = function(name) {
          for (var h = 0, len = leaving.length; h < len; h++) {
            if (leaving[h].name === name) {
              return true;
            }
          }
          return false;
        };

        router._triggerWillLeave(leaving, newTransition, leavingChecker);
      }

      if (changing.length > 0) {
        router._triggerWillChangeContext(changing, newTransition);
      }

      trigger(router, oldHandlers, true, ['willTransition', newTransition]);
    }

    __exports__["default"] = Router;
  });
define("router/transition-intent",
  ["./utils","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var merge = __dependency1__.merge;

    function TransitionIntent(props) {
      this.initialize(props);

      // TODO: wat
      this.data = this.data || {};
    }

    TransitionIntent.prototype = {
      initialize: null,
      applyToState: null
    };

    __exports__["default"] = TransitionIntent;
  });
define("router/transition-intent/named-transition-intent",
  ["../transition-intent","../transition-state","../handler-info/factory","../utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    var TransitionIntent = __dependency1__["default"];
    var TransitionState = __dependency2__["default"];
    var handlerInfoFactory = __dependency3__["default"];
    var isParam = __dependency4__.isParam;
    var extractQueryParams = __dependency4__.extractQueryParams;
    var merge = __dependency4__.merge;
    var subclass = __dependency4__.subclass;

    __exports__["default"] = subclass(TransitionIntent, {
      name: null,
      pivotHandler: null,
      contexts: null,
      queryParams: null,

      initialize: function(props) {
        this.name = props.name;
        this.pivotHandler = props.pivotHandler;
        this.contexts = props.contexts || [];
        this.queryParams = props.queryParams;
      },

      applyToState: function(oldState, recognizer, getHandler, isIntermediate) {

        var partitionedArgs     = extractQueryParams([this.name].concat(this.contexts)),
          pureArgs              = partitionedArgs[0],
          queryParams           = partitionedArgs[1],
          handlers              = recognizer.handlersFor(pureArgs[0]);

        var targetRouteName = handlers[handlers.length-1].handler;

        return this.applyToHandlers(oldState, handlers, getHandler, targetRouteName, isIntermediate);
      },

      applyToHandlers: function(oldState, handlers, getHandler, targetRouteName, isIntermediate, checkingIfActive) {

        var i, len;
        var newState = new TransitionState();
        var objects = this.contexts.slice(0);

        var invalidateIndex = handlers.length;

        // Pivot handlers are provided for refresh transitions
        if (this.pivotHandler) {
          for (i = 0, len = handlers.length; i < len; ++i) {
            if (getHandler(handlers[i].handler) === this.pivotHandler) {
              invalidateIndex = i;
              break;
            }
          }
        }

        var pivotHandlerFound = !this.pivotHandler;

        for (i = handlers.length - 1; i >= 0; --i) {
          var result = handlers[i];
          var name = result.handler;
          var handler = getHandler(name);

          var oldHandlerInfo = oldState.handlerInfos[i];
          var newHandlerInfo = null;

          if (result.names.length > 0) {
            if (i >= invalidateIndex) {
              newHandlerInfo = this.createParamHandlerInfo(name, handler, result.names, objects, oldHandlerInfo);
            } else {
              newHandlerInfo = this.getHandlerInfoForDynamicSegment(name, handler, result.names, objects, oldHandlerInfo, targetRouteName, i);
            }
          } else {
            // This route has no dynamic segment.
            // Therefore treat as a param-based handlerInfo
            // with empty params. This will cause the `model`
            // hook to be called with empty params, which is desirable.
            newHandlerInfo = this.createParamHandlerInfo(name, handler, result.names, objects, oldHandlerInfo);
          }

          if (checkingIfActive) {
            // If we're performing an isActive check, we want to
            // serialize URL params with the provided context, but
            // ignore mismatches between old and new context.
            newHandlerInfo = newHandlerInfo.becomeResolved(null, newHandlerInfo.context);
            var oldContext = oldHandlerInfo && oldHandlerInfo.context;
            if (result.names.length > 0 && newHandlerInfo.context === oldContext) {
              // If contexts match in isActive test, assume params also match.
              // This allows for flexibility in not requiring that every last
              // handler provide a `serialize` method
              newHandlerInfo.params = oldHandlerInfo && oldHandlerInfo.params;
            }
            newHandlerInfo.context = oldContext;
          }

          var handlerToUse = oldHandlerInfo;
          if (i >= invalidateIndex || newHandlerInfo.shouldSupercede(oldHandlerInfo)) {
            invalidateIndex = Math.min(i, invalidateIndex);
            handlerToUse = newHandlerInfo;
          }

          if (isIntermediate && !checkingIfActive) {
            handlerToUse = handlerToUse.becomeResolved(null, handlerToUse.context);
          }

          newState.handlerInfos.unshift(handlerToUse);
        }

        if (objects.length > 0) {
          throw new Error("More context objects were passed than there are dynamic segments for the route: " + targetRouteName);
        }

        if (!isIntermediate) {
          this.invalidateChildren(newState.handlerInfos, invalidateIndex);
        }

        merge(newState.queryParams, this.queryParams || {});

        return newState;
      },

      invalidateChildren: function(handlerInfos, invalidateIndex) {
        for (var i = invalidateIndex, l = handlerInfos.length; i < l; ++i) {
          var handlerInfo = handlerInfos[i];
          handlerInfos[i] = handlerInfos[i].getUnresolved();
        }
      },

      getHandlerInfoForDynamicSegment: function(name, handler, names, objects, oldHandlerInfo, targetRouteName, i) {

        var numNames = names.length;
        var objectToUse;
        if (objects.length > 0) {

          // Use the objects provided for this transition.
          objectToUse = objects[objects.length - 1];
          if (isParam(objectToUse)) {
            return this.createParamHandlerInfo(name, handler, names, objects, oldHandlerInfo);
          } else {
            objects.pop();
          }
        } else if (oldHandlerInfo && oldHandlerInfo.name === name) {
          // Reuse the matching oldHandlerInfo
          return oldHandlerInfo;
        } else {
          if (this.preTransitionState) {
            var preTransitionHandlerInfo = this.preTransitionState.handlerInfos[i];
            objectToUse = preTransitionHandlerInfo && preTransitionHandlerInfo.context;
          } else {
            // Ideally we should throw this error to provide maximal
            // information to the user that not enough context objects
            // were provided, but this proves too cumbersome in Ember
            // in cases where inner template helpers are evaluated
            // before parent helpers un-render, in which cases this
            // error somewhat prematurely fires.
            //throw new Error("Not enough context objects were provided to complete a transition to " + targetRouteName + ". Specifically, the " + name + " route needs an object that can be serialized into its dynamic URL segments [" + names.join(', ') + "]");
            return oldHandlerInfo;
          }
        }

        return handlerInfoFactory('object', {
          name: name,
          handler: handler,
          context: objectToUse,
          names: names
        });
      },

      createParamHandlerInfo: function(name, handler, names, objects, oldHandlerInfo) {
        var params = {};

        // Soak up all the provided string/numbers
        var numNames = names.length;
        while (numNames--) {

          // Only use old params if the names match with the new handler
          var oldParams = (oldHandlerInfo && name === oldHandlerInfo.name && oldHandlerInfo.params) || {};

          var peek = objects[objects.length - 1];
          var paramName = names[numNames];
          if (isParam(peek)) {
            params[paramName] = "" + objects.pop();
          } else {
            // If we're here, this means only some of the params
            // were string/number params, so try and use a param
            // value from a previous handler.
            if (oldParams.hasOwnProperty(paramName)) {
              params[paramName] = oldParams[paramName];
            } else {
              throw new Error("You didn't provide enough string/numeric parameters to satisfy all of the dynamic segments for route " + name);
            }
          }
        }

        return handlerInfoFactory('param', {
          name: name,
          handler: handler,
          params: params
        });
      }
    });
  });
define("router/transition-intent/url-transition-intent",
  ["../transition-intent","../transition-state","../handler-info/factory","../utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    var TransitionIntent = __dependency1__["default"];
    var TransitionState = __dependency2__["default"];
    var handlerInfoFactory = __dependency3__["default"];
    var oCreate = __dependency4__.oCreate;
    var merge = __dependency4__.merge;
    var subclass = __dependency4__.subclass;

    __exports__["default"] = subclass(TransitionIntent, {
      url: null,

      initialize: function(props) {
        this.url = props.url;
      },

      applyToState: function(oldState, recognizer, getHandler) {
        var newState = new TransitionState();

        var results = recognizer.recognize(this.url),
            queryParams = {},
            i, len;

        if (!results) {
          throw new UnrecognizedURLError(this.url);
        }

        var statesDiffer = false;

        for (i = 0, len = results.length; i < len; ++i) {
          var result = results[i];
          var name = result.handler;
          var handler = getHandler(name);

          if (handler.inaccessibleByURL) {
            throw new UnrecognizedURLError(this.url);
          }

          var newHandlerInfo = handlerInfoFactory('param', {
            name: name,
            handler: handler,
            params: result.params
          });

          var oldHandlerInfo = oldState.handlerInfos[i];
          if (statesDiffer || newHandlerInfo.shouldSupercede(oldHandlerInfo)) {
            statesDiffer = true;
            newState.handlerInfos[i] = newHandlerInfo;
          } else {
            newState.handlerInfos[i] = oldHandlerInfo;
          }
        }

        merge(newState.queryParams, results.queryParams);

        return newState;
      }
    });

    
    function UnrecognizedURLError(message) {
      this.message = (message || "UnrecognizedURLError");
      this.name = "UnrecognizedURLError";
    }
  });
define("router/transition-state",
  ["./handler-info","./utils","rsvp/promise","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var ResolvedHandlerInfo = __dependency1__.ResolvedHandlerInfo;
    var forEach = __dependency2__.forEach;
    var promiseLabel = __dependency2__.promiseLabel;
    var callHook = __dependency2__.callHook;
    var Promise = __dependency3__["default"];

    function TransitionState(other) {
      this.handlerInfos = [];
      this.queryParams = {};
      this.params = {};
    }

    TransitionState.prototype = {
      handlerInfos: null,
      queryParams: null,
      params: null,

      promiseLabel: function(label) {
        var targetName = '';
        forEach(this.handlerInfos, function(handlerInfo) {
          if (targetName !== '') {
            targetName += '.';
          }
          targetName += handlerInfo.name;
        });
        return promiseLabel("'" + targetName + "': " + label);
      },

      resolve: function(shouldContinue, payload) {
        var self = this;
        // First, calculate params for this state. This is useful
        // information to provide to the various route hooks.
        var params = this.params;
        forEach(this.handlerInfos, function(handlerInfo) {
          params[handlerInfo.name] = handlerInfo.params || {};
        });

        payload = payload || {};
        payload.resolveIndex = 0;

        var currentState = this;
        var wasAborted = false;

        // The prelude RSVP.resolve() asyncs us into the promise land.
        return Promise.resolve(null, this.promiseLabel("Start transition"))
        .then(resolveOneHandlerInfo, null, this.promiseLabel('Resolve handler'))['catch'](handleError, this.promiseLabel('Handle error'));

        function innerShouldContinue() {
          return Promise.resolve(shouldContinue(), currentState.promiseLabel("Check if should continue"))['catch'](function(reason) {
            // We distinguish between errors that occurred
            // during resolution (e.g. beforeModel/model/afterModel),
            // and aborts due to a rejecting promise from shouldContinue().
            wasAborted = true;
            return Promise.reject(reason);
          }, currentState.promiseLabel("Handle abort"));
        }

        function handleError(error) {
          // This is the only possible
          // reject value of TransitionState#resolve
          var handlerInfos = currentState.handlerInfos;
          var errorHandlerIndex = payload.resolveIndex >= handlerInfos.length ?
                                  handlerInfos.length - 1 : payload.resolveIndex;
          return Promise.reject({
            error: error,
            handlerWithError: currentState.handlerInfos[errorHandlerIndex].handler,
            wasAborted: wasAborted,
            state: currentState
          });
        }

        function proceed(resolvedHandlerInfo) {
          var wasAlreadyResolved = currentState.handlerInfos[payload.resolveIndex].isResolved;

          // Swap the previously unresolved handlerInfo with
          // the resolved handlerInfo
          currentState.handlerInfos[payload.resolveIndex++] = resolvedHandlerInfo;

          if (!wasAlreadyResolved) {
            // Call the redirect hook. The reason we call it here
            // vs. afterModel is so that redirects into child
            // routes don't re-run the model hooks for this
            // already-resolved route.
            var handler = resolvedHandlerInfo.handler;
            callHook(handler, 'redirect', resolvedHandlerInfo.context, payload);
          }

          // Proceed after ensuring that the redirect hook
          // didn't abort this transition by transitioning elsewhere.
          return innerShouldContinue().then(resolveOneHandlerInfo, null, currentState.promiseLabel('Resolve handler'));
        }

        function resolveOneHandlerInfo() {
          if (payload.resolveIndex === currentState.handlerInfos.length) {
            // This is is the only possible
            // fulfill value of TransitionState#resolve
            return {
              error: null,
              state: currentState
            };
          }

          var handlerInfo = currentState.handlerInfos[payload.resolveIndex];

          return handlerInfo.resolve(innerShouldContinue, payload)
                            .then(proceed, null, currentState.promiseLabel('Proceed'));
        }
      }
    };

    __exports__["default"] = TransitionState;
  });
define("router/transition",
  ["rsvp/promise","./handler-info","./utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];
    var ResolvedHandlerInfo = __dependency2__.ResolvedHandlerInfo;
    var trigger = __dependency3__.trigger;
    var slice = __dependency3__.slice;
    var log = __dependency3__.log;
    var promiseLabel = __dependency3__.promiseLabel;

    
    function Transition(router, intent, state, error) {
      var transition = this;
      this.state = state || router.state;
      this.intent = intent;
      this.router = router;
      this.data = this.intent && this.intent.data || {};
      this.resolvedModels = {};
      this.queryParams = {};

      if (error) {
        this.promise = Promise.reject(error);
        return;
      }

      if (state) {
        this.params = state.params;
        this.queryParams = state.queryParams;
        this.handlerInfos = state.handlerInfos;

        var len = state.handlerInfos.length;
        if (len) {
          this.targetName = state.handlerInfos[len-1].name;
        }

        for (var i = 0; i < len; ++i) {
          var handlerInfo = state.handlerInfos[i];

          // TODO: this all seems hacky
          if (!handlerInfo.isResolved) { break; }
          this.pivotHandler = handlerInfo.handler;
        }

        this.sequence = Transition.currentSequence++;
        this.promise = state.resolve(checkForAbort, this)['catch'](function(result) {
          if (result.wasAborted || transition.isAborted) {
            return Promise.reject(logAbort(transition));
          } else {
            transition.trigger('error', result.error, transition, result.handlerWithError);
            transition.abort();
            return Promise.reject(result.error);
          }
        }, promiseLabel('Handle Abort'));
      } else {
        this.promise = Promise.resolve(this.state);
        this.params = {};
      }

      function checkForAbort() {
        if (transition.isAborted) {
          return Promise.reject(undefined, promiseLabel("Transition aborted - reject"));
        }
      }
    }

    Transition.currentSequence = 0;

    Transition.prototype = {
      targetName: null,
      urlMethod: 'update',
      intent: null,
      params: null,
      pivotHandler: null,
      resolveIndex: 0,
      handlerInfos: null,
      resolvedModels: null,
      isActive: true,
      state: null,
      queryParamsOnly: false,

      isTransition: true,

      isExiting: function(handler) {
        var handlerInfos = this.handlerInfos;
        for (var i = 0, len = handlerInfos.length; i < len; ++i) {
          var handlerInfo = handlerInfos[i];
          if (handlerInfo.name === handler || handlerInfo.handler === handler) {
            return false;
          }
        }
        return true;
      },

      
      promise: null,

      
      data: null,

      
      then: function(onFulfilled, onRejected, label) {
        return this.promise.then(onFulfilled, onRejected, label);
      },

      
      "catch": function(onRejection, label) {
        return this.promise["catch"](onRejection, label);
      },

      
      "finally": function(callback, label) {
        return this.promise["finally"](callback, label);
      },

      
      abort: function() {
        if (this.isAborted) { return this; }
        log(this.router, this.sequence, this.targetName + ": transition was aborted");
        this.intent.preTransitionState = this.router.state;
        this.isAborted = true;
        this.isActive = false;
        this.router.activeTransition = null;
        return this;
      },

      
      retry: function() {
        // TODO: add tests for merged state retry()s
        this.abort();
        return this.router.transitionByIntent(this.intent, false);
      },

      
      method: function(method) {
        this.urlMethod = method;
        return this;
      },

      
      trigger: function (ignoreFailure) {
        var args = slice.call(arguments);
        if (typeof ignoreFailure === 'boolean') {
          args.shift();
        } else {
          // Throw errors on unhandled trigger events by default
          ignoreFailure = false;
        }
        trigger(this.router, this.state.handlerInfos.slice(0, this.resolveIndex + 1), ignoreFailure, args);
      },

      
      followRedirects: function() {
        var router = this.router;
        return this.promise['catch'](function(reason) {
          if (router.activeTransition) {
            return router.activeTransition.followRedirects();
          }
          return Promise.reject(reason);
        });
      },

      toString: function() {
        return "Transition (sequence " + this.sequence + ")";
      },

      
      log: function(message) {
        log(this.router, this.sequence, message);
      }
    };

    // Alias 'trigger' as 'send'
    Transition.prototype.send = Transition.prototype.trigger;

    
    function logAbort(transition) {
      log(transition.router, transition.sequence, "detected abort.");
      return new TransitionAborted();
    }

    function TransitionAborted(message) {
      this.message = (message || "TransitionAborted");
      this.name = "TransitionAborted";
    }

    __exports__.Transition = Transition;
    __exports__.logAbort = logAbort;
    __exports__.TransitionAborted = TransitionAborted;
  });
define("router/utils",
  ["exports"],
  function(__exports__) {
    "use strict";
    var slice = Array.prototype.slice;

    var _isArray;
    if (!Array.isArray) {
      _isArray = function (x) {
        return Object.prototype.toString.call(x) === "[object Array]";
      };
    } else {
      _isArray = Array.isArray;
    }

    var isArray = _isArray;
    __exports__.isArray = isArray;
    function merge(hash, other) {
      for (var prop in other) {
        if (other.hasOwnProperty(prop)) { hash[prop] = other[prop]; }
      }
    }

    var oCreate = Object.create || function(proto) {
      function F() {}
      F.prototype = proto;
      return new F();
    };
    __exports__.oCreate = oCreate;
    
    function extractQueryParams(array) {
      var len = (array && array.length), head, queryParams;

      if(len && len > 0 && array[len - 1] && array[len - 1].hasOwnProperty('queryParams')) {
        queryParams = array[len - 1].queryParams;
        head = slice.call(array, 0, len - 1);
        return [head, queryParams];
      } else {
        return [array, null];
      }
    }

    __exports__.extractQueryParams = extractQueryParams;
    function coerceQueryParamsToString(queryParams) {
      for (var key in queryParams) {
        if (typeof queryParams[key] === 'number') {
          queryParams[key] = '' + queryParams[key];
        } else if (isArray(queryParams[key])) {
          for (var i = 0, l = queryParams[key].length; i < l; i++) {
            queryParams[key][i] = '' + queryParams[key][i];
          }
        }
      }
    }
    
    function log(router, sequence, msg) {
      if (!router.log) { return; }

      if (arguments.length === 3) {
        router.log("Transition #" + sequence + ": " + msg);
      } else {
        msg = sequence;
        router.log(msg);
      }
    }

    __exports__.log = log;function bind(context, fn) {
      var boundArgs = arguments;
      return function(value) {
        var args = slice.call(boundArgs, 2);
        args.push(value);
        return fn.apply(context, args);
      };
    }

    __exports__.bind = bind;function isParam(object) {
      return (typeof object === "string" || object instanceof String || typeof object === "number" || object instanceof Number);
    }


    function forEach(array, callback) {
      for (var i=0, l=array.length; i<l && false !== callback(array[i]); i++) { }
    }

    __exports__.forEach = forEach;function trigger(router, handlerInfos, ignoreFailure, args) {
      if (router.triggerEvent) {
        router.triggerEvent(handlerInfos, ignoreFailure, args);
        return;
      }

      var name = args.shift();

      if (!handlerInfos) {
        if (ignoreFailure) { return; }
        throw new Error("Could not trigger event '" + name + "'. There are no active handlers");
      }

      var eventWasHandled = false;

      for (var i=handlerInfos.length-1; i>=0; i--) {
        var handlerInfo = handlerInfos[i],
            handler = handlerInfo.handler;

        if (handler.events && handler.events[name]) {
          if (handler.events[name].apply(handler, args) === true) {
            eventWasHandled = true;
          } else {
            return;
          }
        }
      }

      if (!eventWasHandled && !ignoreFailure) {
        throw new Error("Nothing handled the event '" + name + "'.");
      }
    }

    __exports__.trigger = trigger;function getChangelist(oldObject, newObject) {
      var key;
      var results = {
        all: {},
        changed: {},
        removed: {}
      };

      merge(results.all, newObject);

      var didChange = false;
      coerceQueryParamsToString(oldObject);
      coerceQueryParamsToString(newObject);

      // Calculate removals
      for (key in oldObject) {
        if (oldObject.hasOwnProperty(key)) {
          if (!newObject.hasOwnProperty(key)) {
            didChange = true;
            results.removed[key] = oldObject[key];
          }
        }
      }

      // Calculate changes
      for (key in newObject) {
        if (newObject.hasOwnProperty(key)) {
          if (isArray(oldObject[key]) && isArray(newObject[key])) {
            if (oldObject[key].length !== newObject[key].length) {
              results.changed[key] = newObject[key];
              didChange = true;
            } else {
              for (var i = 0, l = oldObject[key].length; i < l; i++) {
                if (oldObject[key][i] !== newObject[key][i]) {
                  results.changed[key] = newObject[key];
                  didChange = true;
                }
              }
            }
          }
          else {
            if (oldObject[key] !== newObject[key]) {
              results.changed[key] = newObject[key];
              didChange = true;
            }
          }
        }
      }

      return didChange && results;
    }

    __exports__.getChangelist = getChangelist;function promiseLabel(label) {
      return 'Router: ' + label;
    }

    __exports__.promiseLabel = promiseLabel;function subclass(parentConstructor, proto) {
      function C(props) {
        parentConstructor.call(this, props || {});
      }
      C.prototype = oCreate(parentConstructor.prototype);
      merge(C.prototype, proto);
      return C;
    }

    __exports__.subclass = subclass;function resolveHook(obj, hookName) {
      if (!obj) { return; }
      var underscored = "_" + hookName;
      return obj[underscored] && underscored ||
             obj[hookName] && hookName;
    }

    function callHook(obj, hookName) {
      var args = slice.call(arguments, 2);
      return applyHook(obj, hookName, args);
    }

    function applyHook(obj, _hookName, args) {
      var hookName = resolveHook(obj, _hookName);
      if (hookName) {
        return obj[hookName].apply(obj, args);
      }
    }

    __exports__.merge = merge;
    __exports__.slice = slice;
    __exports__.isParam = isParam;
    __exports__.coerceQueryParamsToString = coerceQueryParamsToString;
    __exports__.callHook = callHook;
    __exports__.resolveHook = resolveHook;
    __exports__.applyHook = applyHook;
  });
define("router",
  ["./router/router","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Router = __dependency1__["default"];

    __exports__["default"] = Router;
  });

define("rsvp",
  ["./rsvp/promise","./rsvp/events","./rsvp/node","./rsvp/all","./rsvp/all-settled","./rsvp/race","./rsvp/hash","./rsvp/hash-settled","./rsvp/rethrow","./rsvp/defer","./rsvp/config","./rsvp/map","./rsvp/resolve","./rsvp/reject","./rsvp/filter","./rsvp/asap","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];
    var EventTarget = __dependency2__["default"];
    var denodeify = __dependency3__["default"];
    var all = __dependency4__["default"];
    var allSettled = __dependency5__["default"];
    var race = __dependency6__["default"];
    var hash = __dependency7__["default"];
    var hashSettled = __dependency8__["default"];
    var rethrow = __dependency9__["default"];
    var defer = __dependency10__["default"];
    var config = __dependency11__.config;
    var configure = __dependency11__.configure;
    var map = __dependency12__["default"];
    var resolve = __dependency13__["default"];
    var reject = __dependency14__["default"];
    var filter = __dependency15__["default"];
    var asap = __dependency16__["default"];

    config.async = asap; // default async is asap;
    var cast = resolve;
    function async(callback, arg) {
      config.async(callback, arg);
    }

    function on() {
      config.on.apply(config, arguments);
    }

    function off() {
      config.off.apply(config, arguments);
    }

    // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`
    if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'] === 'object') {
      var callbacks = window['__PROMISE_INSTRUMENTATION__'];
      configure('instrument', true);
      for (var eventName in callbacks) {
        if (callbacks.hasOwnProperty(eventName)) {
          on(eventName, callbacks[eventName]);
        }
      }
    }

    __exports__.cast = cast;
    __exports__.Promise = Promise;
    __exports__.EventTarget = EventTarget;
    __exports__.all = all;
    __exports__.allSettled = allSettled;
    __exports__.race = race;
    __exports__.hash = hash;
    __exports__.hashSettled = hashSettled;
    __exports__.rethrow = rethrow;
    __exports__.defer = defer;
    __exports__.denodeify = denodeify;
    __exports__.configure = configure;
    __exports__.on = on;
    __exports__.off = off;
    __exports__.resolve = resolve;
    __exports__.reject = reject;
    __exports__.async = async;
    __exports__.map = map;
    __exports__.filter = filter;
  });
define("rsvp.umd",
  ["./rsvp"],
  function(__dependency1__) {
    "use strict";
    var Promise = __dependency1__.Promise;
    var allSettled = __dependency1__.allSettled;
    var hash = __dependency1__.hash;
    var hashSettled = __dependency1__.hashSettled;
    var denodeify = __dependency1__.denodeify;
    var on = __dependency1__.on;
    var off = __dependency1__.off;
    var map = __dependency1__.map;
    var filter = __dependency1__.filter;
    var resolve = __dependency1__.resolve;
    var reject = __dependency1__.reject;
    var rethrow = __dependency1__.rethrow;
    var all = __dependency1__.all;
    var defer = __dependency1__.defer;
    var EventTarget = __dependency1__.EventTarget;
    var configure = __dependency1__.configure;
    var race = __dependency1__.race;
    var async = __dependency1__.async;

    var RSVP = {
      'race': race,
      'Promise': Promise,
      'allSettled': allSettled,
      'hash': hash,
      'hashSettled': hashSettled,
      'denodeify': denodeify,
      'on': on,
      'off': off,
      'map': map,
      'filter': filter,
      'resolve': resolve,
      'reject': reject,
      'all': all,
      'rethrow': rethrow,
      'defer': defer,
      'EventTarget': EventTarget,
      'configure': configure,
      'async': async
    };

    
    if (typeof define === 'function' && define.amd) {
      define(function() { return RSVP; });
    } else if (typeof module !== 'undefined' && module.exports) {
      module.exports = RSVP;
    } else if (typeof this !== 'undefined') {
      this['RSVP'] = RSVP;
    }
  });
define("rsvp/-internal",
  ["./utils","./instrument","./config","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var objectOrFunction = __dependency1__.objectOrFunction;
    var isFunction = __dependency1__.isFunction;

    var instrument = __dependency2__["default"];

    var config = __dependency3__.config;

    function noop() {}

    var PENDING   = void 0;
    var FULFILLED = 1;
    var REJECTED  = 2;

    var GET_THEN_ERROR = new ErrorObject();

    function getThen(promise) {
      try {
        return promise.then;
      } catch(error) {
        GET_THEN_ERROR.error = error;
        return GET_THEN_ERROR;
      }
    }

    function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
      try {
        then.call(value, fulfillmentHandler, rejectionHandler);
      } catch(e) {
        return e;
      }
    }

    function handleForeignThenable(promise, thenable, then) {
      config.async(function(promise) {
        var sealed = false;
        var error = tryThen(then, thenable, function(value) {
          if (sealed) { return; }
          sealed = true;
          if (thenable !== value) {
            resolve(promise, value);
          } else {
            fulfill(promise, value);
          }
        }, function(reason) {
          if (sealed) { return; }
          sealed = true;

          reject(promise, reason);
        }, 'Settle: ' + (promise._label || ' unknown promise'));

        if (!sealed && error) {
          sealed = true;
          reject(promise, error);
        }
      }, promise);
    }

    function handleOwnThenable(promise, thenable) {
      if (thenable._state === FULFILLED) {
        fulfill(promise, thenable._result);
      } else if (promise._state === REJECTED) {
        reject(promise, thenable._result);
      } else {
        subscribe(thenable, undefined, function(value) {
          if (thenable !== value) {
            resolve(promise, value);
          } else {
            fulfill(promise, value);
          }
        }, function(reason) {
          reject(promise, reason);
        });
      }
    }

    function handleMaybeThenable(promise, maybeThenable) {
      if (maybeThenable.constructor === promise.constructor) {
        handleOwnThenable(promise, maybeThenable);
      } else {
        var then = getThen(maybeThenable);

        if (then === GET_THEN_ERROR) {
          reject(promise, GET_THEN_ERROR.error);
        } else if (then === undefined) {
          fulfill(promise, maybeThenable);
        } else if (isFunction(then)) {
          handleForeignThenable(promise, maybeThenable, then);
        } else {
          fulfill(promise, maybeThenable);
        }
      }
    }

    function resolve(promise, value) {
      if (promise === value) {
        fulfill(promise, value);
      } else if (objectOrFunction(value)) {
        handleMaybeThenable(promise, value);
      } else {
        fulfill(promise, value);
      }
    }

    function publishRejection(promise) {
      if (promise._onerror) {
        promise._onerror(promise._result);
      }

      publish(promise);
    }

    function fulfill(promise, value) {
      if (promise._state !== PENDING) { return; }

      promise._result = value;
      promise._state = FULFILLED;

      if (promise._subscribers.length === 0) {
        if (config.instrument) {
          instrument('fulfilled', promise);
        }
      } else {
        config.async(publish, promise);
      }
    }

    function reject(promise, reason) {
      if (promise._state !== PENDING) { return; }
      promise._state = REJECTED;
      promise._result = reason;

      config.async(publishRejection, promise);
    }

    function subscribe(parent, child, onFulfillment, onRejection) {
      var subscribers = parent._subscribers;
      var length = subscribers.length;

      parent._onerror = null;

      subscribers[length] = child;
      subscribers[length + FULFILLED] = onFulfillment;
      subscribers[length + REJECTED]  = onRejection;

      if (length === 0 && parent._state) {
        config.async(publish, parent);
      }
    }

    function publish(promise) {
      var subscribers = promise._subscribers;
      var settled = promise._state;

      if (config.instrument) {
        instrument(settled === FULFILLED ? 'fulfilled' : 'rejected', promise);
      }

      if (subscribers.length === 0) { return; }

      var child, callback, detail = promise._result;

      for (var i = 0; i < subscribers.length; i += 3) {
        child = subscribers[i];
        callback = subscribers[i + settled];

        if (child) {
          invokeCallback(settled, child, callback, detail);
        } else {
          callback(detail);
        }
      }

      promise._subscribers.length = 0;
    }

    function ErrorObject() {
      this.error = null;
    }

    var TRY_CATCH_ERROR = new ErrorObject();

    function tryCatch(callback, detail) {
      try {
        return callback(detail);
      } catch(e) {
        TRY_CATCH_ERROR.error = e;
        return TRY_CATCH_ERROR;
      }
    }

    function invokeCallback(settled, promise, callback, detail) {
      var hasCallback = isFunction(callback),
          value, error, succeeded, failed;

      if (hasCallback) {
        value = tryCatch(callback, detail);

        if (value === TRY_CATCH_ERROR) {
          failed = true;
          error = value.error;
          value = null;
        } else {
          succeeded = true;
        }

        if (promise === value) {
          reject(promise, new TypeError('A promises callback cannot return that same promise.'));
          return;
        }

      } else {
        value = detail;
        succeeded = true;
      }

      if (promise._state !== PENDING) {
        // noop
      } else if (hasCallback && succeeded) {
        resolve(promise, value);
      } else if (failed) {
        reject(promise, error);
      } else if (settled === FULFILLED) {
        fulfill(promise, value);
      } else if (settled === REJECTED) {
        reject(promise, value);
      }
    }

    function initializePromise(promise, resolver) {
      try {
        resolver(function resolvePromise(value){
          resolve(promise, value);
        }, function rejectPromise(reason) {
          reject(promise, reason);
        });
      } catch(e) {
        reject(promise, e);
      }
    }

    __exports__.noop = noop;
    __exports__.resolve = resolve;
    __exports__.reject = reject;
    __exports__.fulfill = fulfill;
    __exports__.subscribe = subscribe;
    __exports__.publish = publish;
    __exports__.publishRejection = publishRejection;
    __exports__.initializePromise = initializePromise;
    __exports__.invokeCallback = invokeCallback;
    __exports__.FULFILLED = FULFILLED;
    __exports__.REJECTED = REJECTED;
    __exports__.PENDING = PENDING;
  });
define("rsvp/all-settled",
  ["./enumerator","./promise","./utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Enumerator = __dependency1__["default"];
    var makeSettledResult = __dependency1__.makeSettledResult;
    var Promise = __dependency2__["default"];
    var o_create = __dependency3__.o_create;

    function AllSettled(Constructor, entries, label) {
      this._superConstructor(Constructor, entries, false , label);
    }

    AllSettled.prototype = o_create(Enumerator.prototype);
    AllSettled.prototype._superConstructor = Enumerator;
    AllSettled.prototype._makeResult = makeSettledResult;
    AllSettled.prototype._validationError = function() {
      return new Error('allSettled must be called with an array');
    };

    

    __exports__["default"] = function allSettled(entries, label) {
      return new AllSettled(Promise, entries, label).promise;
    }
  });
define("rsvp/all",
  ["./promise","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];

    
    __exports__["default"] = function all(array, label) {
      return Promise.all(array, label);
    }
  });
define("rsvp/asap",
  ["exports"],
  function(__exports__) {
    "use strict";
    var len = 0;

    __exports__["default"] = function asap(callback, arg) {
      queue[len] = callback;
      queue[len + 1] = arg;
      len += 2;
      if (len === 2) {
        // If len is 1, that means that we need to schedule an async flush.
        // If additional callbacks are queued before the queue is flushed, they
        // will be processed by this flush that we are scheduling.
        scheduleFlush();
      }
    }

    var browserGlobal = (typeof window !== 'undefined') ? window : {};
    var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;

    // test for web worker but not in IE10
    var isWorker = typeof Uint8ClampedArray !== 'undefined' &&
      typeof importScripts !== 'undefined' &&
      typeof MessageChannel !== 'undefined';

    // node
    function useNextTick() {
      return function() {
        process.nextTick(flush);
      };
    }

    function useMutationObserver() {
      var iterations = 0;
      var observer = new BrowserMutationObserver(flush);
      var node = document.createTextNode('');
      observer.observe(node, { characterData: true });

      return function() {
        node.data = (iterations = ++iterations % 2);
      };
    }

    // web worker
    function useMessageChannel() {
      var channel = new MessageChannel();
      channel.port1.onmessage = flush;
      return function () {
        channel.port2.postMessage(0);
      };
    }

    function useSetTimeout() {
      return function() {
        setTimeout(flush, 1);
      };
    }

    var queue = new Array(1000);
    function flush() {
      for (var i = 0; i < len; i+=2) {
        var callback = queue[i];
        var arg = queue[i+1];

        callback(arg);

        queue[i] = undefined;
        queue[i+1] = undefined;
      }

      len = 0;
    }

    var scheduleFlush;

    // Decide what async method to use to triggering processing of queued callbacks:
    if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
      scheduleFlush = useNextTick();
    } else if (BrowserMutationObserver) {
      scheduleFlush = useMutationObserver();
    } else if (isWorker) {
      scheduleFlush = useMessageChannel();
    } else {
      scheduleFlush = useSetTimeout();
    }
  });
define("rsvp/config",
  ["./events","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var EventTarget = __dependency1__["default"];

    var config = {
      instrument: false
    };

    EventTarget.mixin(config);

    function configure(name, value) {
      if (name === 'onerror') {
        // handle for legacy users that expect the actual
        // error to be passed to their function added via
        // `RSVP.configure('onerror', someFunctionHere);`
        config.on('error', value);
        return;
      }

      if (arguments.length === 2) {
        config[name] = value;
      } else {
        return config[name];
      }
    }

    __exports__.config = config;
    __exports__.configure = configure;
  });
define("rsvp/defer",
  ["./promise","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];

    

    __exports__["default"] = function defer(label) {
      var deferred = { };

      deferred.promise = new Promise(function(resolve, reject) {
        deferred.resolve = resolve;
        deferred.reject = reject;
      }, label);

      return deferred;
    }
  });
define("rsvp/enumerator",
  ["./utils","./-internal","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var isArray = __dependency1__.isArray;
    var isMaybeThenable = __dependency1__.isMaybeThenable;

    var noop = __dependency2__.noop;
    var reject = __dependency2__.reject;
    var fulfill = __dependency2__.fulfill;
    var subscribe = __dependency2__.subscribe;
    var FULFILLED = __dependency2__.FULFILLED;
    var REJECTED = __dependency2__.REJECTED;
    var PENDING = __dependency2__.PENDING;

    function makeSettledResult(state, position, value) {
      if (state === FULFILLED) {
        return {
          state: 'fulfilled',
          value: value
        };
      } else {
        return {
          state: 'rejected',
          reason: value
        };
      }
    }

    __exports__.makeSettledResult = makeSettledResult;function Enumerator(Constructor, input, abortOnReject, label) {
      this._instanceConstructor = Constructor;
      this.promise = new Constructor(noop, label);
      this._abortOnReject = abortOnReject;

      if (this._validateInput(input)) {
        this._input     = input;
        this.length     = input.length;
        this._remaining = input.length;

        this._init();

        if (this.length === 0) {
          fulfill(this.promise, this._result);
        } else {
          this.length = this.length || 0;
          this._enumerate();
          if (this._remaining === 0) {
            fulfill(this.promise, this._result);
          }
        }
      } else {
        reject(this.promise, this._validationError());
      }
    }

    Enumerator.prototype._validateInput = function(input) {
      return isArray(input);
    };

    Enumerator.prototype._validationError = function() {
      return new Error('Array Methods must be provided an Array');
    };

    Enumerator.prototype._init = function() {
      this._result = new Array(this.length);
    };

    __exports__["default"] = Enumerator;

    Enumerator.prototype._enumerate = function() {
      var length  = this.length;
      var promise = this.promise;
      var input   = this._input;

      for (var i = 0; promise._state === PENDING && i < length; i++) {
        this._eachEntry(input[i], i);
      }
    };

    Enumerator.prototype._eachEntry = function(entry, i) {
      var c = this._instanceConstructor;
      if (isMaybeThenable(entry)) {
        if (entry.constructor === c && entry._state !== PENDING) {
          entry._onerror = null;
          this._settledAt(entry._state, i, entry._result);
        } else {
          this._willSettleAt(c.resolve(entry), i);
        }
      } else {
        this._remaining--;
        this._result[i] = this._makeResult(FULFILLED, i, entry);
      }
    };

    Enumerator.prototype._settledAt = function(state, i, value) {
      var promise = this.promise;

      if (promise._state === PENDING) {
        this._remaining--;

        if (this._abortOnReject && state === REJECTED) {
          reject(promise, value);
        } else {
          this._result[i] = this._makeResult(state, i, value);
        }
      }

      if (this._remaining === 0) {
        fulfill(promise, this._result);
      }
    };

    Enumerator.prototype._makeResult = function(state, i, value) {
      return value;
    };

    Enumerator.prototype._willSettleAt = function(promise, i) {
      var enumerator = this;

      subscribe(promise, undefined, function(value) {
        enumerator._settledAt(FULFILLED, i, value);
      }, function(reason) {
        enumerator._settledAt(REJECTED, i, reason);
      });
    };
  });
define("rsvp/events",
  ["exports"],
  function(__exports__) {
    "use strict";
    function indexOf(callbacks, callback) {
      for (var i=0, l=callbacks.length; i<l; i++) {
        if (callbacks[i] === callback) { return i; }
      }

      return -1;
    }

    function callbacksFor(object) {
      var callbacks = object._promiseCallbacks;

      if (!callbacks) {
        callbacks = object._promiseCallbacks = {};
      }

      return callbacks;
    }

    
    __exports__["default"] = {

      
      mixin: function(object) {
        object.on = this.on;
        object.off = this.off;
        object.trigger = this.trigger;
        object._promiseCallbacks = undefined;
        return object;
      },

      
      on: function(eventName, callback) {
        var allCallbacks = callbacksFor(this), callbacks;

        callbacks = allCallbacks[eventName];

        if (!callbacks) {
          callbacks = allCallbacks[eventName] = [];
        }

        if (indexOf(callbacks, callback) === -1) {
          callbacks.push(callback);
        }
      },

      
      off: function(eventName, callback) {
        var allCallbacks = callbacksFor(this), callbacks, index;

        if (!callback) {
          allCallbacks[eventName] = [];
          return;
        }

        callbacks = allCallbacks[eventName];

        index = indexOf(callbacks, callback);

        if (index !== -1) { callbacks.splice(index, 1); }
      },

      
      trigger: function(eventName, options) {
        var allCallbacks = callbacksFor(this), callbacks, callback;

        if (callbacks = allCallbacks[eventName]) {
          // Don't cache the callbacks.length since it may grow
          for (var i=0; i<callbacks.length; i++) {
            callback = callbacks[i];

            callback(options);
          }
        }
      }
    };
  });
define("rsvp/filter",
  ["./promise","./utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];
    var isFunction = __dependency2__.isFunction;

    
    __exports__["default"] = function filter(promises, filterFn, label) {
      return Promise.all(promises, label).then(function(values) {
        if (!isFunction(filterFn)) {
          throw new TypeError("You must pass a function as filter's second argument.");
        }

        var length = values.length;
        var filtered = new Array(length);

        for (var i = 0; i < length; i++) {
          filtered[i] = filterFn(values[i]);
        }

        return Promise.all(filtered, label).then(function(filtered) {
          var results = new Array(length);
          var newLength = 0;

          for (var i = 0; i < length; i++) {
            if (filtered[i]) {
              results[newLength] = values[i];
              newLength++;
            }
          }

          results.length = newLength;

          return results;
        });
      });
    }
  });
define("rsvp/hash-settled",
  ["./promise","./enumerator","./promise-hash","./utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];
    var makeSettledResult = __dependency2__.makeSettledResult;
    var PromiseHash = __dependency3__["default"];
    var Enumerator = __dependency2__["default"];
    var o_create = __dependency4__.o_create;

    function HashSettled(Constructor, object, label) {
      this._superConstructor(Constructor, object, false, label);
    }

    HashSettled.prototype = o_create(PromiseHash.prototype);
    HashSettled.prototype._superConstructor = Enumerator;
    HashSettled.prototype._makeResult = makeSettledResult;

    HashSettled.prototype._validationError = function() {
      return new Error('hashSettled must be called with an object');
    };

    
    __exports__["default"] = function hashSettled(object, label) {
      return new HashSettled(Promise, object, label).promise;
    }
  });
define("rsvp/hash",
  ["./promise","./promise-hash","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];
    var PromiseHash = __dependency2__["default"];

    
    __exports__["default"] = function hash(object, label) {
      return new PromiseHash(Promise, object, label).promise;
    }
  });
define("rsvp/instrument",
  ["./config","./utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var config = __dependency1__.config;
    var now = __dependency2__.now;

    var queue = [];

    __exports__["default"] = function instrument(eventName, promise, child) {
      if (1 === queue.push({
          name: eventName,
          payload: {
            guid: promise._guidKey + promise._id,
            eventName: eventName,
            detail: promise._result,
            childGuid: child && promise._guidKey + child._id,
            label: promise._label,
            timeStamp: now(),
            stack: new Error(promise._label).stack
          }})) {

            setTimeout(function() {
              var entry;
              for (var i = 0; i < queue.length; i++) {
                entry = queue[i];
                config.trigger(entry.name, entry.payload);
              }
              queue.length = 0;
            }, 50);
          }
      }
  });
define("rsvp/map",
  ["./promise","./utils","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];
    var isFunction = __dependency2__.isFunction;

    
    __exports__["default"] = function map(promises, mapFn, label) {
      return Promise.all(promises, label).then(function(values) {
        if (!isFunction(mapFn)) {
          throw new TypeError("You must pass a function as map's second argument.");
        }

        var length = values.length;
        var results = new Array(length);

        for (var i = 0; i < length; i++) {
          results[i] = mapFn(values[i]);
        }

        return Promise.all(results, label);
      });
    }
  });
define("rsvp/node",
  ["./promise","./-internal","./utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];
    var noop = __dependency2__.noop;
    var resolve = __dependency2__.resolve;
    var reject = __dependency2__.reject;
    var isArray = __dependency3__.isArray;

    function Result() {
      this.value = undefined;
    }

    var ERROR = new Result();
    var GET_THEN_ERROR = new Result();

    function getThen(obj) {
      try {
       return obj.then;
      } catch(error) {
        ERROR.value= error;
        return ERROR;
      }
    }


    function tryApply(f, s, a) {
      try {
        f.apply(s, a);
      } catch(error) {
        ERROR.value = error;
        return ERROR;
      }
    }

    function makeObject(_, argumentNames) {
      var obj = {};
      var name;
      var i;
      var length = _.length;
      var args = new Array(length);

      for (var x = 0; x < length; x++) {
        args[x] = _[x];
      }

      for (i = 0; i < argumentNames.length; i++) {
        name = argumentNames[i];
        obj[name] = args[i + 1];
      }

      return obj;
    }

    function arrayResult(_) {
      var length = _.length;
      var args = new Array(length - 1);

      for (var i = 1; i < length; i++) {
        args[i - 1] = _[i];
      }

      return args;
    }

    function wrapThenable(then, promise) {
      return {
        then: function(onFulFillment, onRejection) {
          return then.call(promise, onFulFillment, onRejection);
        }
      };
    }

    
    __exports__["default"] = function denodeify(nodeFunc, options) {
      var fn = function() {
        var self = this;
        var l = arguments.length;
        var args = new Array(l + 1);
        var arg;
        var promiseInput = false;

        for (var i = 0; i < l; ++i) {
          arg = arguments[i];

          if (!promiseInput) {
            // TODO: clean this up
            promiseInput = needsPromiseInput(arg);
            if (promiseInput === GET_THEN_ERROR) {
              var p = new Promise(noop);
              reject(p, GET_THEN_ERROR.value);
              return p;
            } else if (promiseInput && promiseInput !== true) {
              arg = wrapThenable(promiseInput, arg);
            }
          }
          args[i] = arg;
        }

        var promise = new Promise(noop);

        args[l] = function(err, val) {
          if (err)
            reject(promise, err);
          else if (options === undefined)
            resolve(promise, val);
          else if (options === true)
            resolve(promise, arrayResult(arguments));
          else if (isArray(options))
            resolve(promise, makeObject(arguments, options));
          else
            resolve(promise, val);
        };

        if (promiseInput) {
          return handlePromiseInput(promise, args, nodeFunc, self);
        } else {
          return handleValueInput(promise, args, nodeFunc, self);
        }
      };

      fn.__proto__ = nodeFunc;

      return fn;
    }

    function handleValueInput(promise, args, nodeFunc, self) {
      var result = tryApply(nodeFunc, self, args);
      if (result === ERROR) {
        reject(promise, result.value);
      }
      return promise;
    }

    function handlePromiseInput(promise, args, nodeFunc, self){
      return Promise.all(args).then(function(args){
        var result = tryApply(nodeFunc, self, args);
        if (result === ERROR) {
          reject(promise, result.value);
        }
        return promise;
      });
    }

    function needsPromiseInput(arg) {
      if (arg && typeof arg === 'object') {
        if (arg.constructor === Promise) {
          return true;
        } else {
          return getThen(arg);
        }
      } else {
        return false;
      }
    }
  });
define("rsvp/promise-hash",
  ["./enumerator","./-internal","./utils","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
    "use strict";
    var Enumerator = __dependency1__["default"];
    var PENDING = __dependency2__.PENDING;
    var o_create = __dependency3__.o_create;

    function PromiseHash(Constructor, object, label) {
      this._superConstructor(Constructor, object, true, label);
    }

    __exports__["default"] = PromiseHash;

    PromiseHash.prototype = o_create(Enumerator.prototype);
    PromiseHash.prototype._superConstructor = Enumerator;
    PromiseHash.prototype._init = function() {
      this._result = {};
    };

    PromiseHash.prototype._validateInput = function(input) {
      return input && typeof input === 'object';
    };

    PromiseHash.prototype._validationError = function() {
      return new Error('Promise.hash must be called with an object');
    };

    PromiseHash.prototype._enumerate = function() {
      var promise = this.promise;
      var input   = this._input;
      var results = [];

      for (var key in input) {
        if (promise._state === PENDING && input.hasOwnProperty(key)) {
          results.push({
            position: key,
            entry: input[key]
          });
        }
      }

      var length = results.length;
      this._remaining = length;
      var result;

      for (var i = 0; promise._state === PENDING && i < length; i++) {
        result = results[i];
        this._eachEntry(result.entry, result.position);
      }
    };
  });
define("rsvp/promise",
  ["./config","./instrument","./utils","./-internal","./promise/all","./promise/race","./promise/resolve","./promise/reject","exports"],
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
    "use strict";
    var config = __dependency1__.config;
    var instrument = __dependency2__["default"];

    var isFunction = __dependency3__.isFunction;
    var now = __dependency3__.now;

    var noop = __dependency4__.noop;
    var subscribe = __dependency4__.subscribe;
    var initializePromise = __dependency4__.initializePromise;
    var invokeCallback = __dependency4__.invokeCallback;
    var FULFILLED = __dependency4__.FULFILLED;
    var REJECTED = __dependency4__.REJECTED;

    var all = __dependency5__["default"];
    var race = __dependency6__["default"];
    var Resolve = __dependency7__["default"];
    var Reject = __dependency8__["default"];

    var guidKey = 'rsvp_' + now() + '-';
    var counter = 0;

    function needsResolver() {
      throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
    }

    function needsNew() {
      throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
    }
    __exports__["default"] = Promise;
    
    function Promise(resolver, label) {
      this._id = counter++;
      this._label = label;
      this._state = undefined;
      this._result = undefined;
      this._subscribers = [];

      if (config.instrument) {
        instrument('created', this);
      }

      if (noop !== resolver) {
        if (!isFunction(resolver)) {
          needsResolver();
        }

        if (!(this instanceof Promise)) {
          needsNew();
        }

        initializePromise(this, resolver);
      }
    }

    Promise.cast = Resolve; // deprecated
    Promise.all = all;
    Promise.race = race;
    Promise.resolve = Resolve;
    Promise.reject = Reject;

    Promise.prototype = {
      constructor: Promise,

      _guidKey: guidKey,

      _onerror: function (reason) {
        config.trigger('error', reason);
      },

    
      then: function(onFulfillment, onRejection, label) {
        var parent = this;
        var state = parent._state;

        if (state === FULFILLED && !onFulfillment || state === REJECTED && !onRejection) {
          if (config.instrument) {
            instrument('chained', this, this);
          }
          return this;
        }

        parent._onerror = null;

        var child = new this.constructor(noop, label);
        var result = parent._result;

        if (config.instrument) {
          instrument('chained', parent, child);
        }

        if (state) {
          var callback = arguments[state - 1];
          config.async(function(){
            invokeCallback(state, child, callback, result);
          });
        } else {
          subscribe(parent, child, onFulfillment, onRejection);
        }

        return child;
      },

    
      'catch': function(onRejection, label) {
        return this.then(null, onRejection, label);
      },

    
      'finally': function(callback, label) {
        var constructor = this.constructor;

        return this.then(function(value) {
          return constructor.resolve(callback()).then(function(){
            return value;
          });
        }, function(reason) {
          return constructor.resolve(callback()).then(function(){
            throw reason;
          });
        }, label);
      }
    };
  });
define("rsvp/promise/all",
  ["../enumerator","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Enumerator = __dependency1__["default"];

    
    __exports__["default"] = function all(entries, label) {
      return new Enumerator(this, entries, true , label).promise;
    }
  });
define("rsvp/promise/race",
  ["../utils","../-internal","exports"],
  function(__dependency1__, __dependency2__, __exports__) {
    "use strict";
    var isArray = __dependency1__.isArray;

    var noop = __dependency2__.noop;
    var resolve = __dependency2__.resolve;
    var reject = __dependency2__.reject;
    var subscribe = __dependency2__.subscribe;
    var PENDING = __dependency2__.PENDING;

    
    __exports__["default"] = function race(entries, label) {
      
      var Constructor = this;

      var promise = new Constructor(noop, label);

      if (!isArray(entries)) {
        reject(promise, new TypeError('You must pass an array to race.'));
        return promise;
      }

      var length = entries.length;

      function onFulfillment(value) {
        resolve(promise, value);
      }

      function onRejection(reason) {
        reject(promise, reason);
      }

      for (var i = 0; promise._state === PENDING && i < length; i++) {
        subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
      }

      return promise;
    }
  });
define("rsvp/promise/reject",
  ["../-internal","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var noop = __dependency1__.noop;
    var _reject = __dependency1__.reject;

    
    __exports__["default"] = function reject(reason, label) {
      
      var Constructor = this;
      var promise = new Constructor(noop, label);
      _reject(promise, reason);
      return promise;
    }
  });
define("rsvp/promise/resolve",
  ["../-internal","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var noop = __dependency1__.noop;
    var _resolve = __dependency1__.resolve;

    
    __exports__["default"] = function resolve(object, label) {
      
      var Constructor = this;

      if (object && typeof object === 'object' && object.constructor === Constructor) {
        return object;
      }

      var promise = new Constructor(noop, label);
      _resolve(promise, object);
      return promise;
    }
  });
define("rsvp/race",
  ["./promise","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];

    
    __exports__["default"] = function race(array, label) {
      return Promise.race(array, label);
    }
  });
define("rsvp/reject",
  ["./promise","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];

    
    __exports__["default"] = function reject(reason, label) {
      return Promise.reject(reason, label);
    }
  });
define("rsvp/resolve",
  ["./promise","exports"],
  function(__dependency1__, __exports__) {
    "use strict";
    var Promise = __dependency1__["default"];

    
    __exports__["default"] = function resolve(value, label) {
      return Promise.resolve(value, label);
    }
  });
define("rsvp/rethrow",
  ["exports"],
  function(__exports__) {
    "use strict";
    
    __exports__["default"] = function rethrow(reason) {
      setTimeout(function() {
        throw reason;
      });
      throw reason;
    }
  });
define("rsvp/utils",
  ["exports"],
  function(__exports__) {
    "use strict";
    function objectOrFunction(x) {
      return typeof x === 'function' || (typeof x === 'object' && x !== null);
    }

    __exports__.objectOrFunction = objectOrFunction;function isFunction(x) {
      return typeof x === 'function';
    }

    __exports__.isFunction = isFunction;function isMaybeThenable(x) {
      return typeof x === 'object' && x !== null;
    }

    __exports__.isMaybeThenable = isMaybeThenable;var _isArray;
    if (!Array.isArray) {
      _isArray = function (x) {
        return Object.prototype.toString.call(x) === '[object Array]';
      };
    } else {
      _isArray = Array.isArray;
    }

    var isArray = _isArray;
    __exports__.isArray = isArray;
    // Date.now is not available in browsers < IE9
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
    var now = Date.now || function() { return new Date().getTime(); };
    __exports__.now = now;
    function F() { }

    var o_create = (Object.create || function (o) {
      if (arguments.length > 1) {
        throw new Error('Second argument not supported');
      }
      if (typeof o !== 'object') {
        throw new TypeError('Argument must be an object');
      }
      F.prototype = o;
      return new F();
    });
    __exports__.o_create = o_create;
  });
requireModule("ember");

})();;

// Source: yithwebclient/static/vendor/sjcl/sjcl.js
"use strict";function q(a){throw a;}var t=void 0,u=!1;var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};
"undefined"!==typeof module&&module.exports&&(module.exports=sjcl);
sjcl.cipher.aes=function(a){this.k[0][0][0]||this.D();var b,c,d,e,f=this.k[0][4],g=this.k[1];b=a.length;var h=1;4!==b&&(6!==b&&8!==b)&&q(new sjcl.exception.invalid("invalid aes key size"));this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^g[3][f[c&
255]]};
sjcl.cipher.aes.prototype={encrypt:function(a){return y(this,a,0)},decrypt:function(a){return y(this,a,1)},k:[[[],[],[],[],[]],[[],[],[],[],[]]],D:function(){var a=this.k[0],b=this.k[1],c=a[4],d=b[4],e,f,g,h=[],l=[],k,n,m,p;for(e=0;0x100>e;e++)l[(h[e]=e<<1^283*(e>>7))^e]=e;for(f=g=0;!c[f];f^=k||1,g=l[g]||1){m=g^g<<1^g<<2^g<<3^g<<4;m=m>>8^m&255^99;c[f]=m;d[m]=f;n=h[e=h[k=h[f]]];p=0x1010101*n^0x10001*e^0x101*k^0x1010100*f;n=0x101*h[m]^0x1010100*m;for(e=0;4>e;e++)a[e][f]=n=n<<24^n>>>8,b[e][m]=p=p<<24^p>>>8}for(e=
0;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}};
function y(a,b,c){4!==b.length&&q(new sjcl.exception.invalid("invalid aes block size"));var d=a.b[c],e=b[0]^d[0],f=b[c?3:1]^d[1],g=b[2]^d[2];b=b[c?1:3]^d[3];var h,l,k,n=d.length/4-2,m,p=4,s=[0,0,0,0];h=a.k[c];a=h[0];var r=h[1],v=h[2],w=h[3],x=h[4];for(m=0;m<n;m++)h=a[e>>>24]^r[f>>16&255]^v[g>>8&255]^w[b&255]^d[p],l=a[f>>>24]^r[g>>16&255]^v[b>>8&255]^w[e&255]^d[p+1],k=a[g>>>24]^r[b>>16&255]^v[e>>8&255]^w[f&255]^d[p+2],b=a[b>>>24]^r[e>>16&255]^v[f>>8&255]^w[g&255]^d[p+3],p+=4,e=h,f=l,g=k;for(m=0;4>
m;m++)s[c?3&-m:m]=x[e>>>24]<<24^x[f>>16&255]<<16^x[g>>8&255]<<8^x[b&255]^d[p++],h=e,e=f,f=g,g=b,b=h;return s}
sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.P(a.slice(b/32),32-(b&31)).slice(1);return c===t?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<<c)-1},concat:function(a,b){if(0===a.length||0===b.length)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return 32===d?a.concat(b):sjcl.bitArray.P(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;return 0===
b?0:32*(b-1)+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(32*a.length<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b&=31;0<c&&b&&(a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+0x10000000000*a},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return u;var c=0,d;for(d=0;d<a.length;d++)c|=a[d]^b[d];return 0===
c},P:function(a,b,c,d){var e;e=0;for(d===t&&(d=[]);32<=b;b-=32)d.push(c),c=0;if(0===b)return d.concat(a);for(e=0;e<a.length;e++)d.push(c|a[e]>>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,32<b+a?c:d.pop(),1));return d},l:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}};
sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++)0===(d&3)&&(e=a[d/4]),b+=String.fromCharCode(e>>>24),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++)d=d<<8|a.charCodeAt(c),3===(c&3)&&(b.push(d),d=0);c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a+="00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,4*d)}};
sjcl.codec.base64={J:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b,c){var d="",e=0,f=sjcl.codec.base64.J,g=0,h=sjcl.bitArray.bitLength(a);c&&(f=f.substr(0,62)+"-_");for(c=0;6*d.length<h;)d+=f.charAt((g^a[c]>>>e)>>>26),6>e?(g=a[c]<<6-e,e+=26,c++):(g<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,f=sjcl.codec.base64.J,g=0,h;b&&(f=f.substr(0,62)+"-_");for(d=0;d<a.length;d++)h=f.indexOf(a.charAt(d)),
0>h&&q(new sjcl.exception.invalid("this isn't base64!")),26<e?(e-=26,c.push(g^h>>>e),g=h<<32-e):(e+=6,g^=h<<32-e);e&56&&c.push(sjcl.bitArray.partial(e&56,g,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.b[0]||this.D();a?(this.r=a.r.slice(0),this.o=a.o.slice(0),this.h=a.h):this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.r=this.N.slice(0);this.o=[];this.h=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.o=sjcl.bitArray.concat(this.o,a);b=this.h;a=this.h=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)z(this,c.splice(0,16));return this},finalize:function(){var a,b=this.o,c=this.r,b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.h/
4294967296));for(b.push(this.h|0);b.length;)z(this,b.splice(0,16));this.reset();return c},N:[],b:[],D:function(){function a(a){return 0x100000000*(a-Math.floor(a))|0}var b=0,c=2,d;a:for(;64>b;c++){for(d=2;d*d<=c;d++)if(0===c%d)continue a;8>b&&(this.N[b]=a(Math.pow(c,0.5)));this.b[b]=a(Math.pow(c,1/3));b++}}};
function z(a,b){var c,d,e,f=b.slice(0),g=a.r,h=a.b,l=g[0],k=g[1],n=g[2],m=g[3],p=g[4],s=g[5],r=g[6],v=g[7];for(c=0;64>c;c++)16>c?d=f[c]:(d=f[c+1&15],e=f[c+14&15],d=f[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+f[c&15]+f[c+9&15]|0),d=d+v+(p>>>6^p>>>11^p>>>25^p<<26^p<<21^p<<7)+(r^p&(s^r))+h[c],v=r,r=s,s=p,p=m+d|0,m=n,n=k,k=l,l=d+(k&n^m&(k^n))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;g[0]=g[0]+l|0;g[1]=g[1]+k|0;g[2]=g[2]+n|0;g[3]=g[3]+m|0;g[4]=g[4]+p|0;g[5]=g[5]+s|0;g[6]=
g[6]+r|0;g[7]=g[7]+v|0}
sjcl.mode.ccm={name:"ccm",encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,l=h.bitLength(c)/8,k=h.bitLength(g)/8;e=e||64;d=d||[];7>l&&q(new sjcl.exception.invalid("ccm: iv must be at least 7 bytes"));for(f=2;4>f&&k>>>8*f;f++);f<15-l&&(f=15-l);c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.L(a,b,c,d,e,f);g=sjcl.mode.ccm.p(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),l=f.clamp(b,h-e),k=f.bitSlice(b,
h-e),h=(h-e)/8;7>g&&q(new sjcl.exception.invalid("ccm: iv must be at least 7 bytes"));for(b=2;4>b&&h>>>8*b;b++);b<15-g&&(b=15-g);c=f.clamp(c,8*(15-b));l=sjcl.mode.ccm.p(a,l,c,k,e,b);a=sjcl.mode.ccm.L(a,l.data,c,d,e,b);f.equal(l.tag,a)||q(new sjcl.exception.corrupt("ccm: tag doesn't match"));return l.data},L:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,l=h.l;e/=8;(e%2||4>e||16<e)&&q(new sjcl.exception.invalid("ccm: invalid tag length"));(0xffffffff<d.length||0xffffffff<b.length)&&q(new sjcl.exception.bug("ccm: can't deal with 4GiB or more data"));
f=[h.partial(8,(d.length?64:0)|e-2<<2|f-1)];f=h.concat(f,c);f[3]|=h.bitLength(b)/8;f=a.encrypt(f);if(d.length){c=h.bitLength(d)/8;65279>=c?g=[h.partial(16,c)]:0xffffffff>=c&&(g=h.concat([h.partial(16,65534)],[c]));g=h.concat(g,d);for(d=0;d<g.length;d+=4)f=a.encrypt(l(f,g.slice(d,d+4).concat([0,0,0])))}for(d=0;d<b.length;d+=4)f=a.encrypt(l(f,b.slice(d,d+4).concat([0,0,0])));return h.clamp(f,8*e)},p:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.l;var l=b.length,k=h.bitLength(b);c=h.concat([h.partial(8,
f-1)],c).concat([0,0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!l)return{tag:d,data:[]};for(g=0;g<l;g+=4)c[3]++,e=a.encrypt(c),b[g]^=e[0],b[g+1]^=e[1],b[g+2]^=e[2],b[g+3]^=e[3];return{tag:d,data:h.clamp(b,k)}}};
sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){128!==sjcl.bitArray.bitLength(c)&&q(new sjcl.exception.invalid("ocb iv must be 128 bits"));var g,h=sjcl.mode.ocb2.H,l=sjcl.bitArray,k=l.l,n=[0,0,0,0];c=h(a.encrypt(c));var m,p=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4)m=b.slice(g,g+4),n=k(n,m),p=p.concat(k(c,a.encrypt(k(c,m)))),c=h(c);m=b.slice(g);b=l.bitLength(m);g=a.encrypt(k(c,[0,0,0,b]));m=l.clamp(k(m.concat([0,0,0]),g),b);n=k(n,k(m.concat([0,0,0]),g));n=a.encrypt(k(n,k(c,h(c))));d.length&&
(n=k(n,f?d:sjcl.mode.ocb2.pmac(a,d)));return p.concat(l.concat(m,l.clamp(n,e)))},decrypt:function(a,b,c,d,e,f){128!==sjcl.bitArray.bitLength(c)&&q(new sjcl.exception.invalid("ocb iv must be 128 bits"));e=e||64;var g=sjcl.mode.ocb2.H,h=sjcl.bitArray,l=h.l,k=[0,0,0,0],n=g(a.encrypt(c)),m,p,s=sjcl.bitArray.bitLength(b)-e,r=[];d=d||[];for(c=0;c+4<s/32;c+=4)m=l(n,a.decrypt(l(n,b.slice(c,c+4)))),k=l(k,m),r=r.concat(m),n=g(n);p=s-32*c;m=a.encrypt(l(n,[0,0,0,p]));m=l(m,h.clamp(b.slice(c),p).concat([0,0,0]));
k=l(k,m);k=a.encrypt(l(k,l(n,g(n))));d.length&&(k=l(k,f?d:sjcl.mode.ocb2.pmac(a,d)));h.equal(h.clamp(k,e),h.bitSlice(b,s))||q(new sjcl.exception.corrupt("ocb: tag doesn't match"));return r.concat(h.clamp(m,p))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.H,e=sjcl.bitArray,f=e.l,g=[0,0,0,0],h=a.encrypt([0,0,0,0]),h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4)h=d(h),g=f(g,a.encrypt(f(h,b.slice(c,c+4))));c=b.slice(c);128>e.bitLength(c)&&(h=f(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));g=f(g,c);return a.encrypt(f(d(f(h,
d(h))),g))},H:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}};
sjcl.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var f=b.slice(0);b=sjcl.bitArray;d=d||[];a=sjcl.mode.gcm.p(!0,a,f,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var f=b.slice(0),g=sjcl.bitArray,h=g.bitLength(f);e=e||128;d=d||[];e<=h?(b=g.bitSlice(f,h-e),f=g.bitSlice(f,0,h-e)):(b=f,f=[]);a=sjcl.mode.gcm.p(u,a,f,d,c,e);g.equal(a.tag,b)||q(new sjcl.exception.corrupt("gcm: tag doesn't match"));return a.data},Z:function(a,b){var c,d,e,f,g,h=sjcl.bitArray.l;e=[0,0,0,0];f=b.slice(0);
for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,f));g=0!==(f[3]&1);for(d=3;0<d;d--)f[d]=f[d]>>>1|(f[d-1]&1)<<31;f[0]>>>=1;g&&(f[0]^=-0x1f000000)}return e},g:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;d<e;d+=4)b[0]^=0xffffffff&c[d],b[1]^=0xffffffff&c[d+1],b[2]^=0xffffffff&c[d+2],b[3]^=0xffffffff&c[d+3],b=sjcl.mode.gcm.Z(b,a);return b},p:function(a,b,c,d,e,f){var g,h,l,k,n,m,p,s,r=sjcl.bitArray;m=c.length;p=r.bitLength(c);s=r.bitLength(d);h=r.bitLength(e);g=b.encrypt([0,
0,0,0]);96===h?(e=e.slice(0),e=r.concat(e,[1])):(e=sjcl.mode.gcm.g(g,[0,0,0,0],e),e=sjcl.mode.gcm.g(g,e,[0,0,Math.floor(h/0x100000000),h&0xffffffff]));h=sjcl.mode.gcm.g(g,[0,0,0,0],d);n=e.slice(0);d=h.slice(0);a||(d=sjcl.mode.gcm.g(g,h,c));for(k=0;k<m;k+=4)n[3]++,l=b.encrypt(n),c[k]^=l[0],c[k+1]^=l[1],c[k+2]^=l[2],c[k+3]^=l[3];c=r.clamp(c,p);a&&(d=sjcl.mode.gcm.g(g,h,c));a=[Math.floor(s/0x100000000),s&0xffffffff,Math.floor(p/0x100000000),p&0xffffffff];d=sjcl.mode.gcm.g(g,d,a);l=b.encrypt(e);d[0]^=l[0];
d[1]^=l[1];d[2]^=l[2];d[3]^=l[3];return{tag:r.bitSlice(d,0,f),data:c}}};sjcl.misc.hmac=function(a,b){this.M=b=b||sjcl.hash.sha256;var c=[[],[]],d,e=b.prototype.blockSize/32;this.n=[new b,new b];a.length>e&&(a=b.hash(a));for(d=0;d<e;d++)c[0][d]=a[d]^909522486,c[1][d]=a[d]^1549556828;this.n[0].update(c[0]);this.n[1].update(c[1]);this.G=new b(this.n[0])};
sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a){this.Q&&q(new sjcl.exception.invalid("encrypt on already updated hmac called!"));this.update(a);return this.digest(a)};sjcl.misc.hmac.prototype.reset=function(){this.G=new this.M(this.n[0]);this.Q=u};sjcl.misc.hmac.prototype.update=function(a){this.Q=!0;this.G.update(a)};sjcl.misc.hmac.prototype.digest=function(){var a=this.G.finalize(),a=(new this.M(this.n[1])).update(a).finalize();this.reset();return a};
sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;(0>d||0>c)&&q(sjcl.exception.invalid("invalid params to pbkdf2"));"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,l,k=[],n=sjcl.bitArray;for(l=1;32*k.length<(d||1);l++){e=f=a.encrypt(n.concat(b,[l]));for(g=1;g<c;g++){f=a.encrypt(f);for(h=0;h<f.length;h++)e[h]^=f[h]}k=k.concat(e)}d&&(k=n.clamp(k,d));return k};
sjcl.prng=function(a){this.c=[new sjcl.hash.sha256];this.i=[0];this.F=0;this.s={};this.C=0;this.K={};this.O=this.d=this.j=this.W=0;this.b=[0,0,0,0,0,0,0,0];this.f=[0,0,0,0];this.A=t;this.B=a;this.q=u;this.w={progress:{},seeded:{}};this.m=this.V=0;this.t=1;this.u=2;this.S=0x10000;this.I=[0,48,64,96,128,192,0x100,384,512,768,1024];this.T=3E4;this.R=80};
sjcl.prng.prototype={randomWords:function(a,b){var c=[],d;d=this.isReady(b);var e;d===this.m&&q(new sjcl.exception.notReady("generator isn't seeded"));if(d&this.u){d=!(d&this.t);e=[];var f=0,g;this.O=e[0]=(new Date).valueOf()+this.T;for(g=0;16>g;g++)e.push(0x100000000*Math.random()|0);for(g=0;g<this.c.length&&!(e=e.concat(this.c[g].finalize()),f+=this.i[g],this.i[g]=0,!d&&this.F&1<<g);g++);this.F>=1<<this.c.length&&(this.c.push(new sjcl.hash.sha256),this.i.push(0));this.d-=f;f>this.j&&(this.j=f);this.F++;
this.b=sjcl.hash.sha256.hash(this.b.concat(e));this.A=new sjcl.cipher.aes(this.b);for(d=0;4>d&&!(this.f[d]=this.f[d]+1|0,this.f[d]);d++);}for(d=0;d<a;d+=4)0===(d+1)%this.S&&A(this),e=B(this),c.push(e[0],e[1],e[2],e[3]);A(this);return c.slice(0,a)},setDefaultParanoia:function(a,b){0===a&&"Setting paranoia=0 will ruin your security; use it only for testing"!==b&&q("Setting paranoia=0 will ruin your security; use it only for testing");this.B=a},addEntropy:function(a,b,c){c=c||"user";var d,e,f=(new Date).valueOf(),
g=this.s[c],h=this.isReady(),l=0;d=this.K[c];d===t&&(d=this.K[c]=this.W++);g===t&&(g=this.s[c]=0);this.s[c]=(this.s[c]+1)%this.c.length;switch(typeof a){case "number":b===t&&(b=1);this.c[g].update([d,this.C++,1,b,f,1,a|0]);break;case "object":c=Object.prototype.toString.call(a);if("[object Uint32Array]"===c){e=[];for(c=0;c<a.length;c++)e.push(a[c]);a=e}else{"[object Array]"!==c&&(l=1);for(c=0;c<a.length&&!l;c++)"number"!==typeof a[c]&&(l=1)}if(!l){if(b===t)for(c=b=0;c<a.length;c++)for(e=a[c];0<e;)b++,
e>>>=1;this.c[g].update([d,this.C++,2,b,f,a.length].concat(a))}break;case "string":b===t&&(b=a.length);this.c[g].update([d,this.C++,3,b,f,a.length]);this.c[g].update(a);break;default:l=1}l&&q(new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string"));this.i[g]+=b;this.d+=b;h===this.m&&(this.isReady()!==this.m&&C("seeded",Math.max(this.j,this.d)),C("progress",this.getProgress()))},isReady:function(a){a=this.I[a!==t?a:this.B];return this.j&&this.j>=a?this.i[0]>this.R&&
(new Date).valueOf()>this.O?this.u|this.t:this.t:this.d>=a?this.u|this.m:this.m},getProgress:function(a){a=this.I[a?a:this.B];return this.j>=a?1:this.d>a?1:this.d/a},startCollectors:function(){this.q||(this.a={loadTimeCollector:D(this,this.aa),mouseCollector:D(this,this.ba),keyboardCollector:D(this,this.$),accelerometerCollector:D(this,this.U)},window.addEventListener?(window.addEventListener("load",this.a.loadTimeCollector,u),window.addEventListener("mousemove",this.a.mouseCollector,u),window.addEventListener("keypress",
this.a.keyboardCollector,u),window.addEventListener("devicemotion",this.a.accelerometerCollector,u)):document.attachEvent?(document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector)):q(new sjcl.exception.bug("can't attach event")),this.q=!0)},stopCollectors:function(){this.q&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,u),window.removeEventListener("mousemove",
this.a.mouseCollector,u),window.removeEventListener("keypress",this.a.keyboardCollector,u),window.removeEventListener("devicemotion",this.a.accelerometerCollector,u)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove",this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.q=u)},addEventListener:function(a,b){this.w[a][this.V++]=b},removeEventListener:function(a,b){var c,d,e=this.w[a],f=[];for(d in e)e.hasOwnProperty(d)&&
e[d]===b&&f.push(d);for(c=0;c<f.length;c++)d=f[c],delete e[d]},$:function(){E(1)},ba:function(a){sjcl.random.addEntropy([a.x||a.clientX||a.offsetX||0,a.y||a.clientY||a.offsetY||0],2,"mouse");E(0)},aa:function(){E(2)},U:function(a){a=a.accelerationIncludingGravity.x||a.accelerationIncludingGravity.y||a.accelerationIncludingGravity.z;var b="";window.orientation&&(b=window.orientation);sjcl.random.addEntropy([a,b],3,"accelerometer");E(0)}};
function C(a,b){var c,d=sjcl.random.w[a],e=[];for(c in d)d.hasOwnProperty(c)&&e.push(d[c]);for(c=0;c<e.length;c++)e[c](b)}function E(a){window&&window.performance&&"function"===typeof window.performance.now?sjcl.random.addEntropy(window.performance.now(),a,"loadtime"):sjcl.random.addEntropy((new Date).valueOf(),a,"loadtime")}function A(a){a.b=B(a).concat(B(a));a.A=new sjcl.cipher.aes(a.b)}function B(a){for(var b=0;4>b&&!(a.f[b]=a.f[b]+1|0,a.f[b]);b++);return a.A.encrypt(a.f)}
function D(a,b){return function(){b.apply(a,arguments)}}sjcl.random=new sjcl.prng(6);
a:try{var F,G,H;if("undefined"!==typeof module&&module.exports)G=require("crypto"),F=G.randomBytes(128),sjcl.random.addEntropy(F,1024,"crypto['randomBytes']");else if(window&&Uint32Array){H=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(H);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(H);else break a;sjcl.random.addEntropy(H,1024,"crypto['getRandomValues']")}}catch(I){console.log("There was an error collecting entropy from the browser:"),
console.log(I)}
sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},Y:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.e({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.e(f,c);c=f.adata;"string"===typeof f.salt&&(f.salt=sjcl.codec.base64.toBits(f.salt));"string"===typeof f.iv&&(f.iv=sjcl.codec.base64.toBits(f.iv));(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||"string"===typeof a&&100>=f.iter||64!==f.ts&&96!==f.ts&&128!==f.ts||128!==f.ks&&192!==f.ks&&0x100!==f.ks||2>f.iv.length||4<
f.iv.length)&&q(new sjcl.exception.invalid("json encrypt: invalid parameters"));"string"===typeof a?(g=sjcl.misc.cachedPbkdf2(a,f),a=g.key.slice(0,f.ks/32),f.salt=g.salt):sjcl.ecc&&a instanceof sjcl.ecc.elGamal.publicKey&&(g=a.kem(),f.kemtag=g.tag,a=g.key.slice(0,f.ks/32));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));"string"===typeof c&&(c=sjcl.codec.utf8String.toBits(c));g=new sjcl.cipher[f.cipher](a);e.e(d,f);d.key=a;f.ct=sjcl.mode[f.mode].encrypt(g,b,f.iv,c,f.ts);return f},encrypt:function(a,
b,c,d){var e=sjcl.json,f=e.Y.apply(e,arguments);return e.encode(f)},X:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.e(e.e(e.e({},e.defaults),b),c,!0);var f;c=b.adata;"string"===typeof b.salt&&(b.salt=sjcl.codec.base64.toBits(b.salt));"string"===typeof b.iv&&(b.iv=sjcl.codec.base64.toBits(b.iv));(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||"string"===typeof a&&100>=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&0x100!==b.ks||!b.iv||2>b.iv.length||4<b.iv.length)&&q(new sjcl.exception.invalid("json decrypt: invalid parameters"));
"string"===typeof a?(f=sjcl.misc.cachedPbkdf2(a,b),a=f.key.slice(0,b.ks/32),b.salt=f.salt):sjcl.ecc&&a instanceof sjcl.ecc.elGamal.secretKey&&(a=a.unkem(sjcl.codec.base64.toBits(b.kemtag)).slice(0,b.ks/32));"string"===typeof c&&(c=sjcl.codec.utf8String.toBits(c));f=new sjcl.cipher[b.cipher](a);c=sjcl.mode[b.mode].decrypt(f,b.ct,b.iv,c,b.ts);e.e(d,b);d.key=a;return sjcl.codec.utf8String.fromBits(c)},decrypt:function(a,b,c,d){var e=sjcl.json;return e.X(a,e.decode(b),c,d)},encode:function(a){var b,c=
"{",d="";for(b in a)if(a.hasOwnProperty(b))switch(b.match(/^[a-z0-9]+$/i)||q(new sjcl.exception.invalid("json encode: invalid property name")),c+=d+'"'+b+'":',d=",",typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],0)+'"';break;default:q(new sjcl.exception.bug("json encode: unsupported type"))}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");a.match(/^\{.*\}$/)||q(new sjcl.exception.invalid("json decode: this isn't json!"));
a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++)(d=a[c].match(/^(?:(["']?)([a-z][a-z0-9]*)\1):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i))||q(new sjcl.exception.invalid("json decode: this isn't json!")),b[d[2]]=d[3]?parseInt(d[3],10):d[2].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(d[4]):unescape(d[4]);return b},e:function(a,b,c){a===t&&(a={});if(b===t)return a;for(var d in b)b.hasOwnProperty(d)&&(c&&(a[d]!==t&&a[d]!==b[d])&&q(new sjcl.exception.invalid("required parameter overridden")),
a[d]=b[d]);return a},ea:function(a,b){var c={},d;for(d in a)a.hasOwnProperty(d)&&a[d]!==b[d]&&(c[d]=a[d]);return c},da:function(a,b){var c={},d;for(d=0;d<b.length;d++)a[b[d]]!==t&&(c[b[d]]=a[b[d]]);return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.ca={};
sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.ca,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===t?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};