JS Template Engines Performance (v90)

Revision 90 of this benchmark created on


Preparation HTML

<script>;(function(root){

  /** @namespace **/
  var Ash = window.Ash = {},

  /** @namspace **/
  template = Ash.template = {};

  /** @public template/compile **/
  template.compile = function( templateHTML ) {
    return new Template( templateHTML ).render;
  };

  /** @public tempate/partial **/
  template.partial = function( name, partialHTML ) {
    new Template( partialHTML ).cache( name );
  };

  /** @public template/render **/
  template.render = function( templateHTML, data ) {
    return new Template( templateHTML ).render( data );
  };

  var vars, z, config, undef;

  function Template( string, options ) {
    this.init( options );
    this.render = this.cache( string ) || this.parse( string );
  }

  Template.prototype = {

    config: {
      // components of tokenization
      start:      '{{',   // delimiter
      end:        '}}',   // delimiter
      partial:    '@',    // control
      literal:    '=',    // control
      iterate:    '#',    // control
      exists:     '?',    // control
      invert:     '!',    // control
      close:      '/',    // control
      // traversing context stack
      parent:     '../',  // up one level
      same:       './',   // current context only
      self:       '.'     // implicit iterator
    },

    // recognize a token (default settings)
    tokenize: /(\{\{(@|=|#|\?|!|\/)?(.*?)\}\})/,

    // compile the tokenizer regular expression
    init: function( options ) {
      if ( !options ) {
        return; // do nothing
      }
      // accept optional configuration settings
      var key, keys = Object.keys( options );
      while ( ( key = keys.shift() ) !== undef ) {
        this.config[ key ] = options[ key ];
      }
      // recompile tokenizer expression
      var regexp = '';
      // delimiter...
      regexp += escapeRegExp( this.config.start );
      // control...
      regexp += '(' + [
        escapeRegExp( this.config.partial ),
        escapeRegExp( this.config.literal ),
        escapeRegExp( this.config.iterate ),
        escapeRegExp( this.config.exists ),
        escapeRegExp( this.config.invert ),
        escapeRegExp( this.config.close )
      ].join('|') + ')?';
      // property...
      regexp += '(.*?)';
      // delimiter...
      regexp += escapeRegExp( this.config.end );
      // set the result...
      this.tokenize = new RegExp( '(' + regexp + ')' );
    },

    escapeHTML: /[&<>'"]/g,

    entityChar: function( c ) {
      return '&#' + c.charCodeAt( 0 ) + ';';
    },

    _cache: {},
    // get/set the template render function in cache
    cache: function( key, func ) {
      if ( key ) {
        // passed or existing render function
        func = func || this.render;
        // set: new key + render function
        if ( !this._cache[ key ] && func ) {
          this._cache[ key ] = func;
        }
        // get:
        return this._cache[ key ];
      }
    },

    // turn template string into a function
    parse: function( string ) {
      // reset outer scope vars
      z = 0;
      vars = {};
      config = this.config;
      // revealing module pattern
      var outer = 'var ' +
          'entity = this.entityChar,' +
          'html = this.escapeHTML,' +
          'cache = this._cache;',
        open = 'return function(' + SCOPE() + '){',
        compiled = this.compile( string.split( this.tokenize ) ),
        declared = DECLARE('output = ""'),
        close = 'return output; }',
        // the render function body string
        body = outer + open + declared + compiled + close;
      // optimize output statements with concatentation...
      body = body.replace( /;\s*output \+=/g, '+' )
        .replace( /"\s*\+\s*"/g, '' );
      /* jshint evil:true */
      return this.cache( string, ( new Function( body ) ).call( this ) );
    },

    // convert array of tokens into function body string
    compile: function( tokens, indent ) {
      z += indent ? 1 : 0;
      var token, control, property, output = '';
      while ( ( token = tokens.shift() ) !== undef ) {
        // non-token content...
        if ( !this.tokenize.test( token ) ) {
          output += this.string( token );
          continue; // next token
        }
        // tokenized content...
        control = tokens.shift();
        property = tokens.shift();
        if ( control === config.close ) {
          break; // exit recursion
        }
        if ( control === config.partial ) {
          output += this.partial( property );
          continue; // next token
        }
        // assign or output a value
        output += this.resolve( control, property );
        if ( !control || control === config.literal ) {
          continue; // next token
        }
        // recursive control structures
        if ( control === config.iterate ) {
          output += this.iterate( tokens );
        }
        if ( control === config.exists ) {
          output += this.exists( tokens );
        }
        if ( control === config.invert ) {
          output += this.invert( tokens );
        }
      }
      z -= indent ? 1 : 0;
      return output;
    },

    // }} {{ - negative space
    string: function( str ) {
      return OUTPUT( JSON.stringify( str ) );
    },

    // {{prop}} - property value
    resolve: function( control, property ) {
      // {{.}} - dot context
      if ( property === config.self ) {
        // when in control
        return control && control !== config.literal ?
          // set the value to the context
          VAR( VALUE(), SCOPE() ) + ';' :
          // or just output the context
          // IF( NOTNULL( SCOPE() ),
            OUTPUT( control === config.literal ? SCOPE() : ESCAPE( SCOPE() ) );
          // );
      }
      // resolve the value in the context stack
      /*
      var stack = [], v = z + 1;
      while ( 0 < v-- ) {
        stack.push(
          IF( RESOLVE( property, SCOPE( v ), VALUE() ),
            control && control !== config.literal ? '' :
              OUTPUT( control === config.literal ? VALUE() : ESCAPE( VALUE() ) )
          )
        );
      }
      return VAR( VALUE() ) + stack.join(' else ');
      */
      var stack = [], v = z + 1;
      while ( 0 < v-- ) {
        stack.push(
          RESOLVE( property, SCOPE( v ), VALUE() )
        );
      }
      // return IF( stack.join(':') + ':0',
      //   control === config.literal ? OUTPUT( VALUE() ) :
      //   !control ? OUTPUT( ESCAPE( VALUE() ) ) : ''
      // );
      return OUTPUT( '((' + stack.join(':') + ':0)?' + (
        control === config.literal ? VALUE() :
        !control ? ESCAPE( VALUE() ) : '""'
      ) + ':"")' );
    },

    // {{@name}} - partial control
    partial: function( property ) {
      var partial = 'cache[' + JSON.stringify( property ) + ']';
      return IF( partial, OUTPUT( partial + '(' + SCOPE() + ')' ) );
    },

    // {{#prop}} - iteration control
    iterate: function( tokens ) {
      return IF( VALUE(), FOR( VALUE(), this.compile( tokens, true ) ) );
    },

    // {{?prop}} - exists control
    exists: function( tokens ) {
      return IF( VAR( SCOPE( z + 1 ), VALUE() ), this.compile( tokens, true ) );
    },

    // {{!prop}} - invert control
    invert: function( tokens ) {
      return IF( NOT( VALUE() ), this.compile( tokens ) );
    }

  };

  // build an output expression
  function OUTPUT( expr ) {
    return 'output += ' + expr + ';';
  }

  // build an "if" statement
  function IF( cond, expr ) {
    return 'if (' + cond + '){' + expr + '}';
  }

  // build a comparison expression
  function NOTNULL( expr ) {
    return '(' + expr + ') != null';
  }

  // build an negation expression
  function NOT( expr ) {
    return '!(' + expr + ')';
  }

  // build a variable assignment, and register a declared variable
  function VAR( expr, value ) {
    vars[ expr ] = true;
    return value === undef ? '' : expr + '=' + value;
  }

  // build an expression that declares all registered variable
  function DECLARE() {
    var arr = Array.prototype.concat.apply( Object.keys( vars ), arguments );
    return 'var ' + arr.join(',') + ';';
  }

  // build the scope context expr
  function SCOPE( n ) {
    return 's' + ( n === undef ? z : n );
  }

  // build the scope value expr
  function VALUE( n ) {
    return 'v' + ( n === undef ? z : n );
  }

  // build a ternary html escaping expression
  function ESCAPE( expr ) {
    return '(' +
      'html.test(' + expr + ')?' + expr + '.replace(html,entity):' + expr +
      ')';
  }

  // build a for loop expression
  function FOR( val, expr ) {
    var i = 'i' + z,
      len = 'l' + z,
      ctx = SCOPE( z + 1 );
    return 'for (' + VAR( i, '0' ) + ',' + VAR( len, val + '.length' ) + ';' +
        i + '<' + len + ';' + i + '++){' +
        IF ( NOTNULL( VAR( ctx, val + '[' + i + ']' ) ), expr ) +
      '}';
  }

  // build a context scope property namespace conditional expression
  function RESOLVE( property, ctx, val ) {
    // return ctx + '&&' + property.split('.').map(function( x, i, self ) {
    //   ctx += '[' + JSON.stringify( x ) + ']';
    //   // assignment only on the last expression
    //   return i < self.length - 1 ? ctx : NOTNULL( VAR( val , ctx ) );
    // }).join('&&');
    return '(' + property.split('.').map(function( x, i, self ) {
      ctx += '[' + JSON.stringify( x ) + ']';
      // assignment only on the last expression
      return i < self.length - 1 ? ctx : NOTNULL( VAR( val, ctx ) );
    }).join('&&') + ')?1';
  }

  // Escape Regular Expression Characters - http://stackoverflow.com/a/6969486
  function escapeRegExp( str ) {
    return str.replace( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&' );
  }

})(window);</script>

<script>!function(a,b){"function"==typeof define&&define.amd?define([],b):a.AshArt=b()}(this,function(){var a,b,c={},d={};return a=function(a,b,d){c[a]={deps:b,callback:d}},b=function(a){var e,f,g,h,i,j=[];if(d[a])return d[a];if(!(e=c[a]))throw new Error("Cannot find module "+a);for(f=0,g=e.deps.length;g>f;++f)j.push(b(e.deps[f]));return h=e.callback.apply(this,j),d[a]=i||h},a("classes/dom/addclass",[],function(){return function(a){return a=a.split(/\s+/),this.each(function(){var b;this.classList?a.forEach(function(a){this.classList.add(a)}.bind(this)):(b=this.className.split(/\s+/).concat(a),this.className=b.join(" ").trim())})}}),a("util/each",[],function(){return function(a,b){var c,d,e,f,g=this,h=b||g,i="number"==typeof g.length;if(i)Array.prototype.forEach.call(g,a,b);else for(c=Object.keys(g),f=0,e=c.length;e>f&&(d=c[f],a.call(h,g[d],d,g)!==!1);++f);return g}}),a("type/type",["util/each"],function(a){function b(a){switch(c=typeof a){case"boolean":case"string":case"number":case"undefined":case"function":return c;default:return null===a?"null":d[e.call(a)]||"object"}}var c,d={},e=d.toString;return a.call({array:Array,"boolean":Boolean,date:Date,error:Error,"function":Function,"null":null,number:Number,object:Object,regexp:RegExp,string:String,undefined:null},function(a,c){null!==a&&(d[e.call(new a)]=c),b[c]=function(a){return b(a)===c}}),b}),a("util/extend",[],function(){return function(){var a,b,c,d,e,f=arguments,g=f.length,h=this,i=0;for(i=0,g=f.length;g>i;i++)if(d=f[i])for(b=Object.keys(d),e=0,a=b.length;a>e;e+=1)c=b[e],null!=d[c]&&(h[c]=d[c]);return h}}),a("core/cache",["type/type","util/extend"],function(a,b){var c=Object.create(null);return{get:function(d,e){if(0===arguments.length)return b.call({},c);if(!a.string(d))throw new TypeError("namespace must be a string");if(1===arguments.length)return b.call({},c[d]||{});if(!a.string(e))throw new TypeError("guid must be a string");return c[d]&&c[d][e]},set:function(b,d,e){var f;if(!a.string(b))throw new TypeError("namespace must be a string");if(!a.string(d))throw new TypeError("guid must be a string");if(!a.object(e))throw new TypeError("instance must be an object");return f=c[b]||(c[b]={}),f[d]=e},unset:function(b,d){if(!a.string(b))throw new TypeError("namespace must be a string");if(1===arguments.length)return void delete c[b];if(!a.string(d))throw new TypeError("guid must be a string");c[b]&&delete c[b][d]},clear:function(){c=Object.create(null)}}}),a("core/def",[],function(){return function(a,b){if("string"!=typeof a)throw new TypeError("def `name` must be of type string.");for(var c=arguments.length>1,d=a.split("."),e=d.pop(),f=d.length,g=this,h=0,i=d[h];f>h;h+=1){if(i=d[h],!c&&!g[i])return;g=g[i]=g[i]||{}}return c&&(g[e]=b),g[e]}}),a("core/module",["core/def","type/type"],function(a,b){return function(c,d){if("module"===c)throw new Error("`module` is a reserved namespace.");if(!c)throw new Error("Module name required.");if(!b.string(c))throw new TypeError("Module name must be of type string.");return b.function(d)&&(d=d(this)),a.call(this,c,d)}}),a("util/guid",[],function(){var a={};return function(b){return b=b||"",a[b]=a[b]||0,b+"#"+ ++a[b]}}),a("core/register",["core/cache","util/guid"],function(a,b){return function(){var c=this.constructor.name;return this.guid=this.guid||b(c),a.set(c,this.guid,this),this}}),a("core/unregister",["core/cache","util/guid"],function(a){return function(){var b=this.constructor.name;return this.guid&&a.unset(b,this.guid),this}}),a("core/subclass",["type/type","util/extend"],function(a,b){var c=/^[A-Z]/;return function d(e){var f,g,h=a.function(this)?this.prototype:{},i=Array.prototype.slice.call(arguments,1);if(!a.string(e))throw new TypeError("Invalid name");if(!c.test(e))throw new Error("Invalid class name");if(f=this.name?this.name+"_"+e:e,this[e])throw new Error("Name already in use");return this[e]=g=new Function("x","return function "+f+"() {var instance, obj = this instanceof "+f+" ? this :( {} ).constructor.create( "+f+".prototype );instance = obj.construct.apply( obj, arguments ) || obj;if ( instance === this && typeof this.register === 'function' ) {this.register();}return instance;};")(),g.prototype=Object.create(h),b.apply(g.prototype,i),g.prototype.constructor=g,g.prototype._super=h,g.name=f,g.subclass=d,g}}),a("core/undef",["core/def"],function(a){return function(b){return a.call(this,b,null)}}),a("event/var/expando",[],function(){return"Ash"+Date.now()}),a("event/var/cache",["event/var/expando","util/guid"],function(a,b){return function c(d,e){return d[a]||(d[a]=b()),e===!0?void delete c[d[a]]:c[d[a]]?c[d[a]]:c[d[a]]={events:{},data:{}}}}),a("event/var/typecache",[],function(){return{}}),a("event/emit",["event/var/cache","event/var/typecache"],function(a,b){function c(a,b){var c;try{c=new window.Event(b,{bubbles:!0,cancelable:!0})}catch(d){c=document.createEvent("Event"),c.initEvent(b,!0,!0)}a.dispatchEvent(c)}function d(a,b,d,f){var g;a.addEventListener?c(a,b):(g=d[b])&&e(g,f)}function e(a,b){for(var c,d=0,e=a.length;e>d;++d)c=a[d],b.length?c.callback.apply(c.ctx,b):c.callback.call(c.ctx)}var f=Array.prototype.slice,g=[];return function(c){var e,h,i,j,k;if(!c)return this;if(i=a(this),e=arguments.length<2?g:f.call(arguments,1),-1===c.indexOf(" "))return d(this,c,i.events,e),this;for(h=b[c]||(b[c]=c.split(" ")),k=0,j=h.length;j>k;++k)d(this,h[k],i.events,e);return this}}),a("event/off",["event/var/cache","event/var/typecache"],function(a,b){function c(a,c){return a?b[a]||(b[a]=a.split(" ")):Object.keys(c.events)}function d(a,b,c,d){return!(b&&a.callback!==b||c&&a.context!==c||d&&a.selector!==d)}function e(b,e,f,g){var h,i,j,k,l=a(this),m=c(b,l),n=0,o=m.length;for("string"!=typeof e&&(g=f,f=e,e=null),l=a(this),m=c(b,l);o>n;++n)if(i=l.events[m[n]]||[],h=[],h.handler=i.handler,i.length){for(j=0,k=i.length;k>j;++j)d(i[j],f,g,e)||h.push(i[j]);!h.length&&h.handler?(this.removeEventListener(m[n],h.handler),delete l.events[m[n]]):l.events[m[n]]=h}}function f(a,b,c){this._listeners&&this._listeners[a._listenerId]&&(this._listeners[a._listenerId].off(b,c,this),b||c||delete this._listeners[a._listenerId])}function g(){var a,b;if(e.call(this),a=this._listeners)for(b in a)this.off(a[b])}return function(a,b,c){return a||b||c?a&&"string"!=typeof a?f.apply(this,arguments):e.apply(this,arguments):g.call(this),this}}),a("classes/dom/var/matches",[],function(){return function(a,b){var c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector||function(a){var b,c,d,e,f,g=a[0],h=a.substr(1);if("#"===g)return this.id===h;if("."===g){for(b=this.className.split(" "),c=!1,d=0,e=b.length;e>d;d+=1)if(f=b[d],f===h){c=!0;break}return c}return this.tagName===a.toUpperCase()};return c.call(a,b)}}),a("event/on",["classes/dom/var/matches","event/var/cache","event/var/typecache","util/guid"],function(a,b,c,d){function e(a,b){b.events[a].handler=f,this.addEventListener(a,b.events[a].handler,!1)}function f(c){for(var d,e=b(c.currentTarget).events[c.type],f=e.length,g=0;f>g;++g)d=e[g].selector,(!d||a(c.target,d))&&e[g].callback.call(e[g].context||c.target,c)}function g(a,b,c,d,f,g){var h=g.events[b]||(g.events[b]=[]);h.push({callback:d,ctx:f||a,context:f,selector:c}),a.addEventListener&&!h.handler&&e.call(a,b,g)}function h(a,d,e,f){var h,i,j,k;if("string"!=typeof d&&(f=e,e=d,d=null),i=b(this),-1===a.indexOf(" "))return void g(this,a,d,e,f,i);for(h=c[a]||(c[a]=a.split(" ")),k=0,j=h.length;j>k;++k)g(this,h[k],d,e,f,i)}function i(a,b,c){var e,f;e=this._listeners||(this._listeners={}),f=a._listenerId||(a._listenerId=d()),e[f]=a,a.on(b,c,this)}return function(a,b){return"string"==typeof a?2===arguments.length?h.call(this,a,b):h.apply(this,arguments):i.apply(this,arguments),this}}),a("core/ash",["core/cache","core/def","core/module","core/register","core/unregister","core/subclass","core/undef","event/emit","event/off","event/on","util/extend"],function(a,b,c,d,e,f,g,h,i,j,k){var l=f.call({},"Ash",{construct:function(a){this.extend(a)},def:b,module:c,undef:g,register:d,unregister:e,off:i,on:j,emit:h,extend:k});return k.call(l,{def:b,undef:g,module:c,cache:a})}),a("util/arrayish",["type/type"],function(a){var b=!a.object(document.body.children),c=/NodeList|HTMLCollection/,d=Object.prototype.toString;return function(e){var f=a(e);return"array"===f||"object"===f&&a.number(e.length)&&e!==window||b&&c.test(d.call(e))}}),a("classes/dom/core",["core/ash","core/subclass","util/arrayish","util/each","type/type"],function(a,b,c,d,e){function f(a){var b=document.createElement("div");return b.innerHTML=a,Array.prototype.slice.call(b.children)}function g(a,b){var c,d=/^(?:#[\w-]+)$/;return!b&&d.test(a)?(c=document.getElementById(a.substr(1)))?[c]:[]:[].slice.call((b||document).querySelectorAll(a))}var h=/^<[\w\W]+>$/;return a.subclass("Dom",{construct:function(a,b){var d=[];return a?a instanceof this.constructor?a:(e.string(a)&&h.test(a)?d=f(a):e.string(a)?(this.selector=a,d=g(a,b)):d=c(a)?a:[a],void Array.prototype.push.apply(this,d)):this},splice:Array.prototype.splice,length:0,each:function(a){return d.call(this,function(b,c){return a.call(b,c,b)})},find:function(a){var b=[];return this.each(function(){b=b.concat(g(a,this))}),new this.constructor(b)},register:!1,unregister:!1})}),a("classes/dom/append",["classes/dom/core"],function(a){return function(b){return b=a(b),this.each(function(a,c){b.each(function(){c.appendChild(this)})}),this}}),a("classes/dom/appendto",["classes/dom/core"],function(a){return function(b){return a(b).each(function(a,b){this.each(function(){b.appendChild(this)})}.bind(this)),this}}),a("classes/dom/data",["event/var/cache","util/extend"],function(a,b){return function(c,d){return c?1===arguments.length&&"string"==typeof c?this.length?a(this[0]).data[c]:void 0:1!==arguments.length||"object"==typeof c&&null!==c?this.each(function(){var e=a(this).data;"string"==typeof c?e[c]=d:b.call(e,c)}):void 0:this.length?a(this[0]).data:void 0}}),a("classes/dom/emit",["event/emit"],function(a){return function(){var b=[].slice.apply(arguments);return this.each(function(){a.apply(this,b)})}}),a("classes/dom/empty",[],function(){return function(){return this.each(function(){for(;this.firstChild;)this.removeChild(this.firstChild)})}}),a("classes/dom/var/ishidden",[],function(){return function(a){return"none"===window.getComputedStyle(a).display}}),a("classes/dom/hide",["classes/dom/var/ishidden"],function(a){return function(){return this.each(function(){var b=a(this),c=this.style.display;(c&&"none"!==c||!b)&&(this.style.display="none")})}}),a("classes/dom/html",["type/type"],function(a){return function(b){return a.string(b)?this.each(function(){this.innerHTML=b}):this[0]?this[0].innerHTML:""}}),a("classes/dom/is",["classes/dom/var/matches"],function(a){return function(b){var c=!1;return this.each(function(){return!(c=c||a(this,b))}),c}}),a("classes/dom/off",["event/off"],function(a){return function(){var b=[].slice.apply(arguments);return this.each(function(){a.apply(this,b)})}}),a("classes/dom/on",["event/on"],function(a){return function(){var b=[].slice.apply(arguments);return this.each(function(){a.apply(this,b)})}}),a("classes/dom/prepend",["classes/dom/core"],function(a){return function(b){return b=a(b),this.each(function(a,c){b.each(function(){c.insertBefore(this,c.firstChild)})}),this}}),a("classes/dom/prependto",["classes/dom/core"],function(a){return function(b){return a(b).each(function(a,b){this.each(function(){b.insertBefore(this,b.firstChild)})}.bind(this)),this}}),a("classes/dom/remove",["event/var/cache"],function(a){return function(){return this.each(function(){this.parentNode&&(this.parentNode.removeChild(this),a(this,!0))})}}),a("classes/dom/removeclass",["classes/dom/core"],function(){return function(a){return a=a.split(/\s+/),this.each(function(){var b,c,d,e,f,g,h,i=[];if(this.classList)a.forEach(function(a){this.classList.remove(a)}.bind(this));else{for(b=this.className.split(/\s+/),c=0,d=b.length;d>c;c+=1){for(e=b[c],f=!1,g=0,h=a.length;h>g;g+=1)if(e===a[g]){f=!0;break}f||i.push(e)}this.className=i.join(" ").trim()}})}}),a("classes/dom/removedata",["classes/dom/core","event/var/cache"],function(a,b){return function(a){return!a&&this.length&&this.each(function(){b(this).data={}}),1===arguments.length&&"string"==typeof a&&this.length&&this.each(function(){delete b(this).data[a]}),this}}),a("classes/dom/show",["classes/dom/appendto","classes/dom/core","classes/dom/var/ishidden","classes/dom/remove"],function(a,b,c,d){function e(c,e){var f,g=b(e.createElement(c));return a.call(g,e.body),f=window.getComputedStyle(g[0]).display,d.call(g),f}function f(c){var f,h,i=g[c];return i||(i=e(c,document),"none"!==i&&i||(f=b('<iframe frameborder="0" width="0" height="0"/>'),a.call(f,document.body),h=f[0].contentDocument,h.write(),h.close(),i=e(c,h),d.call(f)),g[c]=i),i}var g={};return function(){return this.each(function(){"none"===this.style.display&&(this.style.display=""),""===this.style.display&&c(this)&&(this.style.display=f(this.nodeName))})}}),a("classes/dom/toggleclass",["classes/dom/addclass","classes/dom/core","classes/dom/is","classes/dom/removeclass"],function(a,b,c,d){return function(e){return e=e.split(/\s+/),this.each(function(){var f=b(this);e.forEach(function(b){c.call(f,"."+b)?d.call(f,b):a.call(f,b)})})}}),a("classes/dom",["classes/dom/addclass","classes/dom/append","classes/dom/appendto","classes/dom/core","classes/dom/data","classes/dom/emit","classes/dom/empty","classes/dom/hide","classes/dom/html","classes/dom/is","classes/dom/off","classes/dom/on","classes/dom/prepend","classes/dom/prependto","classes/dom/remove","classes/dom/removeclass","classes/dom/removedata","classes/dom/show","classes/dom/toggleclass"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s){return d.prototype.addClass=a,d.prototype.append=b,d.prototype.appendTo=c,d.prototype.data=e,d.prototype.emit=f,d.prototype.empty=g,d.prototype.hide=h,d.prototype.html=i,d.prototype.is=j,d.prototype.off=k,d.prototype.on=l,d.prototype.prepend=m,d.prototype.prependTo=n,d.prototype.remove=o,d.prototype.removeClass=p,d.prototype.removeData=q,d.prototype.show=r,d.prototype.toggleClass=s,d}),a("util/async",["type/type"],function(a){function b(){for(var a=0;a<k.length;++a)try{k[a]()}catch(b){}k=[]}function c(){var a,c,d;return h?h:(a=0,c=new MutationObserver(b),d=document.createTextNode(""),c.observe(d,{characterData:!0}),h=function(){d.data=a=++a%2})}function d(){return i?i:(window.addEventListener("message",function(a){a.source===window&&"ash-tick"===a.data&&(a.stopPropagation&&a.stopPropagation(),b())}),i=function(){window.postMessage("ash-tick","*")})}function e(){return j?j:j=function(){setTimeout(b,0)}}function f(b){if(!a.function(b))throw new TypeError("Ash.util.async argument must be a function");return 1===k.push(b)&&g[l]()(),this}var g,h,i,j,k=[],l="default";return g={MutationObserver:c,postMessage:d,setTimeout:e,"default":window.MutationObserver?c:window.postMessage?d:e},f.setMethod=function(a){return l=g.hasOwnProperty(a)?a:"default"},f.resetMethod=function(){return l="default"},f}),a("classes/promise",["core/ash","util/async","type/type"],function(a,b,c){function d(a,b,c){Object.defineProperty(a,b,{configurable:!1,enumerable:!1,writable:!0,value:c})}function e(a){switch(typeof a){case"undefined":case"boolean":case"string":case"number":return typeof a;default:return null===a?"null":"function"==typeof Symbol&&a instanceof Symbol?"symbol":"object"}}function f(a){var b=+a;return b!==b?0:0===b||1/0===b||b===-1/0?b:(b>=0?1:-1)*Math.floor(Math.abs(b))}function g(a){return c.string(a)?a:String(a)}function h(a){if(null==a)throw TypeError();return Object(a)}function i(a){var b=f(a);return 0>=b?0:Math.min(b,Math.pow(2,53)-1)}function j(a){return c.function(a)}function k(a,b){if(typeof a!=typeof b)return!1;if("undefined"===e(a))return!0;if("number"===e(a)){if(a!==a&&b!==b)return!0;if(0===a)return 1/a===1/b}return a===b}function l(a){return c.function(a)}function m(a){if("object"!==e(a))throw TypeError();return a[L]()}function n(a,b){var c=a.next(b);if("object"!==e(c))throw TypeError();return c}function o(a){if("object"!==e(a))throw TypeError();return!!a.done}function p(a){if("object"!==e(a))throw TypeError();return a.value}function q(a){var b=n(a);return o(b)===!0?!1:b}function r(a,b){if("boolean"!==e(b))throw TypeError();return{value:a,done:b}}function s(a,c){b(function(){a.apply(null,c)})}function t(a,b){var c=h(a),e=Object.create(M);return d(e,"[[IteratedObject]]",c),d(e,"[[ArrayIteratorNextIndex]]",0),d(e,"[[ArrayIteratorKind]]",b),e}function u(a,b){try{b["[[Reject]]"].call(void 0,[a])}catch(c){return c}return b}function v(a){var b=new w;return d(b,"[[Promise]]",a),b}function w(){return function a(b){var c,f=a["[[Promise]]"];if("object"!==e(f))throw TypeError();return"unresolved"!==f["[[PromiseStatus]]"]?void 0:(c=f["[[PromiseRejectReactions]]"],d(f,"[[PromiseResult]]",b),d(f,"[[PromiseResolveReactions]]",void 0),d(f,"[[PromiseRejectReactions]]",void 0),d(f,"[[PromiseStatus]]","has-rejection"),D(c,b))}}function x(a){var b=new y;return d(b,"[[Promise]]",a),b}function y(){return function a(b){var c,f=a["[[Promise]]"];if("object"!==e(f))throw TypeError();return"unresolved"!==f["[[PromiseStatus]]"]?void 0:(c=f["[[PromiseResolveReactions]]"],d(f,"[[PromiseResult]]",b),d(f,"[[PromiseResolveReactions]]",void 0),d(f,"[[PromiseRejectReactions]]",void 0),d(f,"[[PromiseStatus]]","has-resolution"),D(c,b))}}function z(a){var b;if(!l(a))throw TypeError();try{b=Object.create(a.prototype)}catch(c){return c}return A(b,a)}function A(a,b){var c,e,f={};d(f,"[[Promise]]",a),d(f,"[[Resolve]]",void 0),d(f,"[[Reject]]",void 0),c=new B,d(c,"[[Capability]]",f);try{e=b.call(a,c)}catch(g){return g}if(!j(f["[[Resolve]]"]))throw TypeError();if(!j(f["[[Reject]]"]))throw TypeError();if("object"==typeof e&&!k(a,e))throw TypeError();return f}function B(){return function a(b,c){var f=a["[[Capability]]"];if("undefined"!==e(f["[[Resolve]]"]))throw TypeError();if("undefined"!==e(f["[[Reject]]"]))throw TypeError();d(f,"[[Resolve]]",b),d(f,"[[Reject]]",c)}}function C(a){return"object"!==e(a)?!1:"undefined"===e(a["[[PromiseStatus]]"])?!1:!0}function D(a,b){a.forEach(function(a){s(F,[a,b])})}function E(a,b){var c,d,f;if("object"!==e(a))return"not a thenable";try{c=a.then}catch(g){return d=b["[[Reject]]"].call(void 0,g),null}if(!j(c))return"not a thenable";try{f=c.call(a,b["[[Resolve]]"],b["[[Reject]]"])}catch(g){return d=b["[[Reject]]"].call(void 0,g),null}return null}function F(a,b){var c,d,e,f=a["[[Capabilities]]"],g=a["[[Handler]]"];try{c=g.call(void 0,b)}catch(h){return f["[[Reject]]"].call(void 0,h)}return k(c,f["[[Promise]]"])?(d=TypeError(),f["[[Reject]]"].call(void 0,d)):(e=E(c,f),"not a thenable"===e?f["[[Resolve]]"].call(void 0,c):void 0)}function G(a,b){var c,f,g,h;if("undefined"!==e(a["[[PromiseStatus]]"]))throw TypeError();if(!j(b))throw TypeError();d(a,"[[PromiseStatus]]","unresolved"),d(a,"[[PromiseResolveReactions]]",[]),d(a,"[[PromiseRejectReactions]]",[]),c=x(a),f=v(a);try{g=b.call(void 0,c,f)}catch(i){try{h=f.call(void 0,i)}catch(k){return k}}return a}function H(){return function a(b){var c=a["[[Index]]"],d=a["[[Values]]"],e=a["[[Capabilities]]"],f=a["[[RemainingElements]]"];try{d[c]=b}catch(g){return u(g,e)}return f["[[value]]"]--,void(0===f["[[value]]"]&&e["[[Resolve]]"].call(void 0,d))}}function I(){return function(a){return a}}function J(){return function a(b){var c,d,e,f,g=a["[[Promise]]"],h=a["[[FulfillmentHandler]]"],i=a["[[RejectionHandler]]"];if(k(b,g))return c=TypeError(),i.call(void 0,c);d=g["[[PromiseConstructor]]"];try{e=z(d)}catch(j){return j}try{f=E(b,e)}catch(j){return j}return"not a thenable"!==f?e["[[Promise]]"].then(h,i):h.call(void 0,b)}}function K(){return function(a){throw a}}var L,M,N;return L="undefined"!=typeof Symbol&&Symbol.iterator||"_shim_iterator_",Array.prototype.values=function(){return t(h(this),"value")},Array.prototype[L]=Array.prototype.values,M={},M.next=function(){var a,b,c,f,h,j,k,l=this;if("object"!==e(l))throw TypeError();if(a=l["[[IteratedObject]]"],"undefined"===e(a))return r(void 0,!0);if(b=l["[[ArrayIteratorNextIndex]]"],c=l["[[ArrayIteratorKind]]"],f=i(a.length),b>=f)return d(l,"[[IteratedObject]]",void 0),r(void 0,!0);if(d(l,"[[ArrayIteratorNextIndex]]",b+1),-1!==c.indexOf("value")&&(h=g(b),j=a[h]),-1!==c.indexOf("key+value"))return k=[b,j],r(k,!1);if(-1!==c.indexOf("key"))return r(b,!1);if(-1===c.indexOf("value"))throw TypeError();return r(j,!1)},M[L]=function(){return this},N=a.subclass("Promise",{construct:function(a){var b=this;if(!j(a))throw TypeError("Invalid executor");if("object"!==e(b))throw TypeError("Invalid promise");if("undefined"!==e(b["[[PromiseStatus]]"]))throw TypeError();return d(this,"[[PromiseConstructor]]",N),G(b,a)},register:!1,unregister:!1}),N.all=function(a){var b,c,e,f,g,h,i,j,k,l,n,o=this;try{b=z(o)}catch(r){return r}try{c=m(a)}catch(r){return u(r,b)}for(e=[],f={"[[value]]":0},g=0;;){try{h=q(c)}catch(r){return u(r,b)}if(h===!1){if(0===g)try{i=b["[[Resolve]]"].call(void 0,e)}catch(r){return r}return b["[[Promise]]"]}try{j=p(h)}catch(r){return u(r,b)}try{k=o.cast(j)}catch(r){return u(r,b)}l=new H,d(l,"[[Index]]",g),d(l,"[[Values]]",e),d(l,"[[Capabilities]]",b),d(l,"[[RemainingElements]]",f);try{n=k.then(l,b["[[Reject]]"])}catch(r){return u(r,b)}g++,f["[[value]]"]++}},N.cast=function(a){var b,c,d,e=this;if(C(a)&&(d=a["[[PromiseConstructor]]"],k(d,e)))return a;try{b=z(e)}catch(f){return f}try{c=b["[[Resolve]]"].call(void 0,a)}catch(f){return f}return b["[[Promise]]"]},N.race=function(a){var b,c,d,e,f,g=this;try{b=z(g)}catch(h){return h}try{c=m(a)}catch(h){return u(h,b)}for(;;){try{f=q(c)}catch(h){return u(h,b)}if(f===!1)return b["[[Promise]]"];try{d=p(f)}catch(h){return u(h,b)}try{e=g.cast(d)}catch(h){return u(h,b)}try{e.then(b["[[Resolve]]"],b["[[Reject]]"])}catch(h){return u(h,b)}}},N.reject=function(a){var b,c,d=this;try{b=z(d)}catch(e){return e}try{c=b["[[Reject]]"].call(void 0,a)}catch(e){return e}return b["[[Promise]]"]},N.resolve=function(a){var b,c,d=this;try{b=z(d)}catch(e){return e}try{c=b["[[Resolve]]"].call(void 0,a)}catch(e){return e}return b["[[Promise]]"]},N.prototype["catch"]=function(a){var b=this;return b.then(void 0,a)},N.prototype.then=function(a,b){var c,e,f,g,h,i,k,l,m=this;if(!C(m))throw TypeError();try{c=m.constructor}catch(n){return n}try{e=z(c)}catch(n){return n}return f=j(b)?b:new K,g=j(a)?a:new I,h=new J,d(h,"[[Promise]]",m),d(h,"[[FulfillmentHandler]]",g),d(h,"[[RejectionHandler]]",f),i={"[[Capabilities]]":e,"[[Handler]]":h},k={"[[Capabilities]]":e,"[[Handler]]":f},"unresolved"===m["[[PromiseStatus]]"]&&(m["[[PromiseResolveReactions]]"].push(i),m["[[PromiseRejectReactions]]"].push(k)),"has-resolution"===m["[[PromiseStatus]]"]&&(l=m["[[PromiseResult]]"],s(F,[i,l])),"has-rejection"===m["[[PromiseStatus]]"]&&(l=m["[[PromiseResult]]"],s(F,[k,l])),e["[[Promise]]"]},N}),a("ajax/ajax",["classes/dom","classes/promise","core/ash","util/each","util/extend","type/type"],function(a,b,c,d,e,f){function g(a){a.processData&&a.data&&!f.string(a.data)&&(a.data=i(a.data)),a.data&&"GET"===a.type&&(a.url=h(a.url,a.data),a.data=void 0),!a.processData&&f.object(a.data)&&(a.data=JSON.stringify(a.data))}function h(a,b){return(a+"&"+b).replace(/[&?]{1,2}/,"?")}function i(a){var b=[],c=encodeURIComponent;return b.add=function(a,b){this.push(c(a)+"="+c(b))},j(b,a),b.join("&").replace(/%20/g,"+")}function j(a,b,c){var e,g,h=f.object(b);d.call(b,function(b,d){e=f(b),c&&(g=h||"object"===e||"array"===e,d=c+"["+(g?d:"")+"]"),"array"===e||"object"===e?j(a,b,d):a.add(d,b)})}function k(a,b,c,d,e){var f="success";try{c.success.call(b,a,f)}catch(g){return e(g||"callback error"),void m("callback error",b,c)}d(a),m(f,b,c)}function l(a,b,c,d,e){try{d.error.call(c,b,a)}catch(f){return void e(f)}e(a||b),m(b,c,d)}function m(a,b,c){c.complete.call(b,a)}function n(c){var d,e,f,g,h,i;return window.jsonpCallbacks||(window.jsonpCallbacks={}),d=q(),f=document.createElement("script"),h={abort:function(){f.__aborted__=!0,f.onerror({type:"error"},"abort")}},e=new b(function(b,e){f.onload=f.onerror=function(j,m){function n(){a(f).remove(),delete window.jsonpCallbacks[d]}clearTimeout(i),f.onerror=f.onload=r,"error"===j.type||!g||f.__aborted__?l(null,m||"error",h,c,e):k(g[0],h,c,b,e),f.__aborted__?window.jsonpCallbacks[d]=n:n()},window.jsonpCallbacks[d]=function(){g=arguments},f.src=c.url.replace(/\?(.+)=\?/,"?$1=jsonpCallbacks."+d),a(document.head).append(f),c.timeout>0&&(i=setTimeout(function(){h.abort()},c.timeout))}),h.then=e.then.bind(e),h.catch=e.catch.bind(e),h}function o(a,c){var i,j,m,q=new XMLHttpRequest;return f.object(a)&&(c=a,a=void 0),i=e.call({},o.settings,c||{}),i.url=i.url||a,i.type=(i.type||o.settings.type).toUpperCase(),g(i),"jsonp"===i.dataType?(i.url=h(i.url,"callback=?"),n(i)):(m=new b(function(a,b){f.string(i.url)||l(null,"urlerror",q,i,b),q.open(i.type,i.url,!0),d.call(i.headers||{},function(a,b){q.setRequestHeader(b,a)}),(i.contentType||i.data&&"GET"!==i.type)&&q.setRequestHeader("Content-Type",p[i.contentType]||p.form),q.onreadystatechange=function(){var c,d,e,f;if(4===this.readyState){this.onreadystatechange=r,clearTimeout(j);try{d=this.status}catch(g){return void l(null,"abort",this,i,b)}if(e=this.statusText,d>=200&&300>d||304===d){if(f=i.dataType||this.getResponseHeader("Content-Type"),c=this.responseText,/json/i.test(f))try{c=JSON.parse(c)}catch(h){return void l(h,"parseerror",this,i,b)}k(c,this,i,a,b)}else l(e||null,d?"error":"abort",this,i,b)}},f.undefined(i.data)?q.send():q.send(i.data),i.timeout>0&&(j=setTimeout(function(){q.onreadystatechange=r,q.abort(),l(null,"timeout",q,i,b)},i.timeout))}),q.then=m.then.bind(m),q.catch=m.catch.bind(m),q)}var p,q,r=function(){};return o.settings={type:"GET",timeout:0,processData:!0,success:r,error:r,complete:r,headers:{}},p={form:"application/x-www-form-urlencoded",json:"application/json",text:"text/html"},q=function(){var a=0;return function(){return"jsonpCallback"+ ++a}}(),o}),a("ajax/delete",["ajax/ajax","type/type"],function(a,b){return function(c,d,e,f){return b.function(d)&&(f=f||e,e=d,d=void 0),a({url:c,type:"DELETE",dataType:f,data:d,success:e})}}),a("ajax/get",["ajax/ajax","type/type"],function(a,b){return function(c,d,e,f){return b.function(d)&&(f=f||e,e=d,d=void 0),a({url:c,type:"GET",dataType:f,data:d,success:e})}}),a("ajax/post",["ajax/ajax","type/type"],function(a,b){return function(c,d,e,f){return b.function(d)&&(f=f||e,e=d,d=void 0),a({url:c,type:"POST",dataType:f,data:d,success:e})}}),a("ajax/put",["ajax/ajax","type/type"],function(a,b){return function(c,d,e,f){return b.function(d)&&(f=f||e,e=d,d=void 0),a({url:c,type:"PUT",dataType:f,data:d,success:e})}}),a("classes/list",["core/ash"],function(a){var b=Array.prototype.slice;return a.subclass("List",{construct:function(a){this.length=(this._internal=[]).length,this.push.apply(this,a)},push:function(){var a=b.apply(arguments);return this.length=Array.prototype.push.apply(this._internal,a),a.length&&this.emit("add",a),this},pop:function(){var a=this.length,b=this._internal.pop();return this.length=this._internal.length,this.length!==a&&this.emit("remove",[b]),b},unshift:function(){var a=b.apply(arguments);return this.length=Array.prototype.unshift.apply(this._internal,a),a.length&&this.emit("add",a),this},shift:function(){var a=this.length,b=this._internal.shift();return this.length=this._internal.length,this.length!==a&&this.emit("remove",[b]),b},indexOf:function(a){for(var b=0,c=this._internal.length,d=-1;c>b;b+=1)if(a===this._internal[b]){d=b;break}return d},slice:function(){var a,c=new this.constructor;return a=b.apply(this._internal,arguments),c._internal=a,c.length=a.length,c},nth:function(a){var b=this.length,c=a%b;return isNaN(c)?!1:this._internal[0>c?c+b:c]},remove:function(a){for(var b,c=0,d=this._internal.length,e=[];d>c;c+=1)b=this._internal[c],b!==a&&e.push(b);return e.length!==this.length&&(this.length=(this._internal=e).length,this.emit("remove",a)),this},each:function(a){for(var b=0,c=this._internal.length;c>b;b+=1)a.call(this,this._internal[b],b);return this},map:function(a){for(var b=0,c=this._internal.length,d=new Array(c);c>b;b+=1)d[b]=a.call(this,this._internal[b],b);return d},sort:function(a){return Array.prototype.sort.call(this._internal,a,this),this.emit("sort"),this},filter:function(a){for(var b,c=0,d=this._internal.length,e=new this.constructor,f=[];d>c;c+=1)b=this._internal[c],a.call(this,b)&&f.push(b);return e._internal=f,e.length=f.length,e},toJSON:function(){return this.map(function(a){return a&&a.toJSON?a.toJSON():a})}})}),a("classes/map",["core/ash","util/each","util/extend"],function(a,b,c){function d(a,b){var c=!1;return a=String(a),this.has(a)||this.size++,this._internal[a]!==b&&(this._changing||(this._previous={},this._changed={}),this._changing=!0,this._previous[a]=this._internal[a],this._internal[a]=b,this._changed[a]=b,c=!0,this.emit("change:"+a,b,this._previous[a])),c}function e(a){var b,c=!1;for(b in a)c=d.call(this,b,a[b])||c;return c}return a.subclass("Map",{construct:function(a){"object"==typeof a?(this._internal=c.call(Object.create(null),a),this.size=Object.keys(this._internal).length):(this._internal=Object.create(null),this.size=0)},get:function(a){return this.has(a)?this._internal[a]:this.defaults?this.defaults[a]:void 0},set:function(a,b){var c=!1,f=this._changing;if("string"==typeof a||"number"==typeof a)c=d.call(this,a,b);else{if("object"!=typeof a)throw new TypeError("Invalid arguments");c=e.call(this,a)}return c&&!f&&(this._changing=!1,this.emit("change",this._changed,this._previous)),this},has:function(a){return!!this._internal[a]||!!(a in this._internal)},"delete":function(a){var c=[];return arguments.length?this.has(a)&&c.push(a):c=Object.keys(this._internal),b.call(c,function(a){this.set(a,void 0),delete this._internal[a],this.size--},this),this},each:function(a){return b.call(this._internal,a,this),this},toJSON:function(){var a={};return b.call(this.defaults||{},function(b,c){a[c]=b}),c.call(a,this._internal)}})}),a("classes/model",["ajax/ajax","classes/map","core/cache","util/guid","type/type"],function(a,b,c,d,e){function f(b,c,d){var e=this;return a(c,{type:b,data:d}).then(function(a){e.parse(a),e.emit(g[b])},function(a){e.emit(g[b]+"error",a)}),this}var g={GET:"fetch",PUT:"save",POST:"save",DELETE:"destroy"};return b.subclass("Model",{key:"id",autoFetch:!1,construct:function(a,f){var g,h,i,j=this.constructor.name;return this.extend(f||{}),e.string(a)||e.number(a)?(g=!0,h=a,a={},a[this.key]=h):e.object(a)?h=a[this.key]:a={},h&&(i=c.get(j,j+"#"+h))?i.set(a):(this.tempID=d(),b.prototype.construct.call(this,a),g===!0&&this.autoFetch===!0&&this.fetch(),this.on("change:"+this.key,function(){this.unregister(),this.register()}),void this.init())},init:function(){},register:function(){var a=this.constructor.name,b=this.get(this.key);return this.guid=e.number(b)||e.string(b)?a+"#"+b:d(a+".temp"),c.set(a,this.guid,this),this},isNew:function(){return!this.get(this.key)},url:function(){var a=encodeURIComponent(this.get(this.key)||"");if(this.baseURL)return this.isNew()?this.baseURL:this.baseURL.replace(/\/+$/,"")+"/"+a;throw new Error("baseURL and a primary key required")},fetch:function(){return f.call(this,"GET",this.url())},save:function(){var a=this.isNew()?"POST":"PUT",b=this.toJSON();return f.call(this,a,this.url(),b)},destroy:function(){return f.call(this,"DELETE",this.url())},parse:function(a){return this.set(a),this}})}),a("classes/collection",["ajax/get","classes/list","classes/model","util/each"],function(a,b,c,d){function e(){var a=Array.prototype.slice.apply(arguments),b=this.model;return a.map(function(a){return a instanceof b?a:new b(a)})}function f(a,b){var c=e.apply(this,b),f=[];return d.call(c,function(b){var c=b.get(b.key);this._lookup[c]||this._lookup[b.tempID]||(this._lookup[b.tempID]=b,c&&(this._lookup[c]=b),f.push(b),this.on(b,"change:"+b.key,function(a,c){delete this._lookup[c],a&&(this._lookup[a]=b)}.bind(this)),this.on(b,"destroy",function(){this.remove(b)}),this.length=this._internal[a](b))
},this),f.length&&this.emit("add",f),this}function g(a){var b=this._internal.length,c=this._internal[a](),d=c&&c.get(c.key);return c&&(d&&delete this._lookup[d],delete this._lookup[c.tempID],this.off(c),(this.length=this._internal.length)!==b&&this.emit("remove",[c])),c}return b.subclass("Collection",{model:c,construct:function(a,c){this.extend(c||{}),this._lookup={},b.prototype.construct.call(this,a||[]),this.init()},init:function(){},get:function(a){var b;return(b=this._lookup[a])?b:(b=new this.model(a),this.push(b),b)},push:function(){return f.call(this,"push",arguments)},unshift:function(){return f.call(this,"unshift",arguments)},pop:function(){return g.call(this,"pop")},shift:function(){return g.call(this,"shift")},remove:function(a){var b,c;return a instanceof this.model&&(b=a,a=b.get(b.key)||b.tempID),c=this.indexOf(a),c>-1&&(b=this._lookup[a],delete this._lookup[a],delete this._lookup[b.tempID],this.off(b),this._internal.splice(c,1),this.length=this._internal.length,this.emit("remove",[b])),this},indexOf:function(a){for(var b=a instanceof this.model?a:this._lookup[a],c=0,d=this._internal.length,e=-1;d>c;c+=1)if(b===this._internal[c]){e=c;break}return e},slice:function(){var a=Array.prototype.slice.apply(this._internal,arguments);return new this.constructor(a,{model:this.model})},filter:function(a){for(var b,c=[],d=0,e=this._internal.length;e>d;d+=1)b=this._internal[d],a.call(this,b)&&c.push(b);return new this.constructor(c,{model:this.model})},fetch:function(){var b=this;if(!this.url)throw new Error("this.url is required");return a(this.url).then(function(a){b.parse(a),b.emit("fetch")},function(a){b.emit("fetcherror",a)}),this},parse:function(a){return this.push.apply(this,a),this}})}),a("template/var/template",[],function(){function a(a,b,c,d){var e,f,g,i,k,l,m;if(!b||!(e=b.length))return"";for(l="",f=d;f>=1;f--){for(i="context"+f,l+="( ( "+i,g=0;e>g;g++)k=b[g],"."!==k&&(k=/^\*.*\*$/.test(k)?k.replace(/\*/g,""):"'"+k+"'",i=i+"["+k+"]",l+=" != null ) && ( "+i);l+=" && ( !( "+i+" instanceof Array ) || "+i+".length ) ) ) ? "+i+" : "}return j=Math.max(j,d+1),m="var"+h++,"';if ( "+m+" = "+l+"'' ) {context"+(d+1)+" = "+m+";out += '"+a.template(c,d+1,1)+"';}out += '"}function b(a,b,c,d){var e,f,g,k,l,m,n,o,p;if(!b||!(e=b.length))return"";for(m="",f=d;f>=1;f--){for(k="context"+f,m+="( ( "+k,g=0;e>g;g++)l=b[g],""!==l&&(l=/^\*.*\*$/.test(l)?l.replace(/\*/g,""):"'"+l+"'",k=k+"["+l+"]",m+=" != null ) && ( "+k);m+=" && "+k+" instanceof Array && "+k+".length ) ) ? "+k+" : "}return j=Math.max(j,d+1),n="var"+h++,o="loop"+i,p="length"+i++,"';if ( "+n+" = "+m+"'' ) {for ( "+o+" = 0, "+p+" = "+n+".length; "+o+" < "+p+"; "+o+"++ ) {if ( context"+(d+1)+" = "+n+"[ "+o+" ] != null ) {context"+(d+1)+" = "+n+"[ "+o+" ];out += '"+a.template(c,d+1,1)+"';}}}out += '"}function c(a,b,c,d){var e,f,g,h,i,j,k;if(!b||!(e=b.length))return a.template(c,d,1);for(k=[],f=d;f>=1;f--){for(h="context"+f,j="( !"+h,g=0;e>g;g++)i=b[g],"."!==i&&(i=/^\*.*\*$/.test(i)?i.replace(/\*/g,""):"'"+i+"'",h=h+"["+i+"]",j+=" || ( "+h+" instanceof Array && "+h+".length === 0 ) ) || ( !"+h);j+=" || ( "+h+" instanceof Array && "+h+".length === 0 ) )",k.push(j)}return"';if ( ( "+k.join(" ) && ( ")+" ) ) {out += '"+a.template(c,d,1)+"';}out += '"}function d(a,b,c){var d,e,f,g,i,j,k;if(!a||!(d=a.length))return"";for(j="",e=b;e>=1;e--){for(g="context"+e,j+="( ( "+g,f=0;d>f;f++)i=a[f],""!==i&&(g=g+"['"+i+"']",j+=" != null ) && ( "+g);j+=" != null ) ) ? "+g+" : "}return c?(k="var"+h++,"';"+k+" = "+j+"'';out += ( toEncode.test("+k+") ? "+k+".replace( toEncode, encoded ) : "+k+" );out += '"):"' + ( "+j+"'' ) + '"}function e(a,b){return"';if ( this.partials['"+a+"'] ) {out += this.partials['"+a+"'].call( this, context"+b+" );}out += '"}function f(){var a=this,b=this.template.apply(this,arguments);this.evaluate=function(c){return b.call(a,c)}}var g={},h=1,i=1,j=1,k=new RegExp("\\{\\{\\s*(?:(?:([?!#])\\s*([\\w.]+)\\s*\\}\\}([\\s\\S]*)\\{\\{\\s*\\/\\s*\\2)|(?:(\\{)?\\s*([\\w.]+)\\s*(?:\\})?)|(?:\\s*@\\s*([\\w]+)))\\s*\\}\\}"),l=/[&<>'"]/g,m=function(a){return"&#"+a.charCodeAt(0)+";"};return f.prototype={toEncode:l,encodeHTML:m,partials:{},template:function(f,l,m){var n,o,p,q,r,s;if(p=this,l&&"string"!=typeof l||(l&&(q=l),l=1),!m){if(g[f])return g[f];f=f.replace(/\\/g,"\\").replace(/'/g,"\\'").replace(/\n/g,"\\n' + '"),h=1,i=1,j=1}for(r=f||"";s!==r&&k.test(r);)s=r,r=r.replace(k,function(f,g,h,i,j,k,m){var n,o,q,r,s,t;if(g){if(n="",o="{{"+g+h+"}}",q="{{/"+h+"}}",r=i.indexOf(o),s=i.indexOf(q),r>-1&&s>-1&&r>s&&(t=i.split(q),i=t.shift(),n=t.join(q)+q),"#"===g)return b(p,h.split("."),i,l)+n;if("?"===g)return a(p,h.split("."),i,l)+n;if("!"===g)return c(p,h.split("."),i,l)+n}else{if(m)return e(m,l);if(k)return d(k.split("."),l,j?0:1)}});if(!m){for(n="",o=1;h>o;o++)n+=" var"+o+",";for(o=1;i>o;o++)n+=" loop"+o+", length"+o+",";for(o=2;j>=o;o++)n+=" context"+o+",";r=new Function("context1","var"+n+" toEncode = this.toEncode, encoded = this.encodeHTML, out = '"+r+"';return out;"),g[f]=r,q&&(p.partials[q]=r)}return r}},f}),a("template/compile",["template/var/template"],function(a){return function(b){var c=new a(b);return c.evaluate}}),a("util/queuerender",[],function(){function a(a){window.setTimeout(a,1e3/60)}function b(){for(var a,b=e.slice(),c=b.length,d=0;c>d;++d){a=b[d];try{a.callback.call(a.context)}catch(g){}}e=[],f=!1}function c(a,c){e.push({callback:a,context:c}),f||(f=!0,d[g].call(window,b))}var d,e=[],f=!1,g="default";return d={requestAnimationFrame:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame,setTimeout:a,"default":window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||a},c.setMethod=function(a){return g=d.hasOwnProperty(a)?a:"default"},c.resetMethod=function(){return g="default"},c}),a("classes/view",["classes/dom","template/compile","core/ash","util/queuerender","type/type"],function(a,b,c,d,e){var f=/^(\S+)\s*(.*)$/;return c.subclass("View",{construct:function(a){this.extend(a),this.dataSource=this.model,this.setElement(),this.bindEvents(),this.on("render",this.addUIRefs.bind(this)),this.init()},init:function(){this.render()},setElement:function(){return this.el?this.el instanceof a||(this.el=a(this.el)):this.el=a(document.createElement(this.tagName||"div")),this.className&&this.el.addClass(this.className),this.startHidden&&this.hide(),this},bindEvents:function(){var a,b,c,d,g;if(this.events)for(a in this.events)if(b=a.match(f),e.function(this.events[a])?c=this.events[a].bind(this):e.array(this.events[a])?(d=[this].concat(this.events[a].slice(1)),c=this[this.events[a][0]],c=Function.prototype.bind.apply(c,d)):c=this[this.events[a]].bind(this),b[2]){if("@"===b[2].charAt(0)&&(g=this._ui||this.ui||{},!(b[2]=g[b[2].substr(1)])))continue;this.el.on(b[1],b[2],c)}else this.dataSource&&this.on(this.dataSource,b[1],c);return this},addUIRefs:function(){var a;if(this.ui){this._ui||(this._ui=this.ui),this.ui={};for(a in this._ui)this.ui[a]=this.el.find(this._ui[a])}return this},serialize:function(){var a={};return this.model&&(a=this.model.toJSON()),this.runHelpers(a)},runHelpers:function(a){var b;if(this.helpers)for(b in this.helpers)a[b]=this.helpers[b].call(this,a);return a},appendTo:function(a){return this.el.appendTo(a),this},prependTo:function(a){return this.el.prependTo(a),this},render:function(){var c,e,f,g;return this.el&&this.template&&!this.renderer&&(e=a("#"+this.template).html(),this.renderer=b(e)),this.el&&this.renderer&&(c=this.serialize(),f=this.renderer(c),g=function(){this.el.html(f),this.emit("render")}.bind(this),this.async?d(g):g()),this},show:function(){return this.el.show(),this},hide:function(){return this.el.hide(),this},destroy:function(){return this.el.off(),this.el.remove(),this.emit("destroy"),this.off(),this.unregister(),this}})}),a("classes/collectionview",["classes/view","util/each"],function(a,b){function c(a,b){return this.indexOf(a)-this.indexOf(b)}return a.subclass("CollectionView",{construct:function(a){if(this.extend(a),this.dataSource=this.collection,!this.collection)throw new Error("no collection specified");if(!this.view)throw new Error("no view class specified");this.setElement(),this.bindEvents(),this.createViews(),this.on("render",this.addUIRefs.bind(this)),this.on("render",this.appendViews.bind(this)),this.on(this.collection,"add",this.addViews.bind(this)),this.on(this.collection,"remove",this.removeViews.bind(this)),this.on(this.collection,"sort",this.sortViews.bind(this)),this.init()},serialize:function(){var a={};return a.total=this.collection.length,this.runHelpers(a)},createViews:function(){return this.views=[],this.collection.each(function(a){var b=new this.view({model:a}).render();this.views.push(b)}.bind(this)),this.appendViews(),this},addViews:function(a){var d,e,f,g,h;return 1===a.length?(d=new this.view({model:a[0]}).render(),e=this.collection.indexOf(a[0]),f=this.target?this.el.find(this.target):this.el,this.views.splice(e,0,d),h=this.views.length,e===h-1?f.append(d.el):(g=this.views[e+1].el[0],f[0].insertBefore(d.el[0],g)),this):(a.sort(c.bind(this.collection)),b.call(a,function(a){d=new this.view({model:a}).render(),e=this.collection.indexOf(a),this.views.splice(e,0,d)},this),this.appendViews(),this)},removeViews:function(a){return b.call(a,function(a){var b;this.views=this.views.filter(function(c){return c.model===a?(b=c,!1):!0},this),b&&b.destroy()},this),this},sortViews:function(){var a=!1,c=this.collection,d=new Array(this.views.length);return b.call(this.views,function(b){var e=c.indexOf(b.model);d[e]=b,a=a||b!==this.views[e]},this),a&&(this.views=d,this.appendViews()),this},appendViews:function(){var a=this.target?this.el.find(this.target):this.el;return a.empty(),b.call(this.views,function(b){b.el.appendTo(a)},this),this},destroy:function(){return b.call(this.views,function(a){a.destroy()}),this.views=[],this.el.off(),this.el.remove(),this.off(),this.unregister(),this}})}),a("classes/router",["classes/dom","core/ash","util/each","type/type"],function(a,b,c,d){var e="\\/",f="\\/(?:.*\\/)*",g="(?:.*\\/)*",h="(?:\\/.*)*",i="([^\\/]+)",j="[^\\/]*",k="\\$&",l=".*",m=/\//,n=/\/?\*\*(?:\/\*\*)*\/?/,o=/^(?:\*\*\/)+/,p=/(?:\/\*\*)+$/,q=/^:([^\/]+)$/,r=/\*/g,s=/[\-\[\]\{\}\(\)\+\?\.\\\^\$\|]/g,t=/(?:^\/+|\/+$)/g;return b.subclass("Router",{construct:function(a){this.extend(a),this.routes=this.routes||{},this.params=this.params||{},this.listen()},listen:function(){return a(window).on("hashchange",function(){this.navigate(location.hash.substr(1))}.bind(this),!1),this},param:function(a,b){return d.string(a)&&d.regexp(b)&&(this.params[a]=b),this},route:function(a,b,u){var v,w,x,y,z,A="",B=[],C=[];return d.regexp(a)&&d.function(b)?(this.routes[a]||(this.routes[a]={pattern:a,params:C,callbacks:[]})).callbacks.push({fn:b,context:u}):d.string(a)&&d.function(b)&&(a=a.replace(t,""),v=a,"**"===v?B.push(l):(o.test(v)&&(y=1,v=v.replace(o,"")),p.test(v)&&(z=1,v=v.replace(p,"")),w=v.split(n),c.call(w,function(a){x=a.split(m),c.call(x,function(a,b){q.test(a)?(C.push(a.substr(1)),a=i):(a=a.replace(s,k),a=a.replace(r,j)),x[b]=a},this),B.push(x.join(e))},this)),A=B.join(f),y&&(A=g+A),z&&(A+=h),(this.routes[a]||(this.routes[a]={pattern:new RegExp("^"+A+"$"),params:C,callbacks:[]})).callbacks.push({fn:b,context:u})),this},unroute:function(a,b,c){var e,f=d(a);return"string"===f&&(a=a.replace(t,"")),("string"===f||"regexp"===f)&&(b||c?(e=this.routes[a],e.callbacks=e.callbacks.filter(function(a){return b&&a.fn!==b||c&&a.context!==c})):delete this.routes[a]),this},navigate:function(a){return a=a.replace(t,""),c.call(this.routes,function(b){var d,e,f,g={},h=!0,i=!0;if(d=a.match(b.pattern),d&&d.length){if(b.params.length<d.length-1)for(e=b.params.length+1;e<d.length;e+=1)b.params.push("$"+e);if(c.call(b.params,function(a,b){var c=this.params[a];c&&!c.test(d[b+1])&&(h=!1),g[a]=d[b+1]},this),h)for(f=0;f<b.callbacks.length;f+=1)if(i=b.callbacks[f].fn.call(b.callbacks[f].context||window,a,g),i===!1)return!1}},this),this}})}),a("classes/layoutmanager",["classes/router","classes/view","util/each","type/type"],function(a,b,c,d){function e(b,e){return b.router instanceof a&&c.call(b.routes||{},function(a,c){a=d.function(a)?a:b[a],"unset"===e?b.router.unroute(c,a,b):b.router.route(c,a,b)},b),b}return b.subclass("LayoutManager",{construct:function(a){this.extend(a),this.dataSource=this.model,this.views=this.views||{},this.setElement(),this.bindEvents(),this.setRouteListeners(),this.addViews(this.views),this.on("render",this.appendViews.bind(this)),this.addUIRefs(),this.init()},setRouteListeners:function(){e(this,"set")},unsetRouteListeners:function(){e(this,"unset")},addView:function(a,c){var d=this.el.find(c.target),e=c.view instanceof b?c.view:new c.view(c.options||{});return c.view=e.appendTo(d),this.views[a]=c,this.on(e,"destroy",function(){delete this.views[a],this.emit("removeView",a)}),this.emit("addView",a),this},addViews:function(a){return c.call(a||{},function(a,b){this.addView(b,a)},this),this},removeView:function(a){var b=this.views[a];return b&&(this.off(b.view),delete this.views[a],b.view.el.remove(),this.emit("removeView",a)),this},appendViews:function(){return c.call(this.views,function(a){var b=this.el.find(a.target);a.view.appendTo(b)},this),this},destroy:function(){return this.unsetRouteListeners(),b.prototype.destroy.call(this),this}})}),a("classes/smartcollection",["classes/collection","util/each"],function(a,b){function c(a){return a.map(function(a){return a.guid}).join(",")}function d(a){var c=[];b.call(a,function(a){this.off(a),this.on(a,"change",f.bind(this,a)),this.on(a,"change:"+a.key,function(a,b){delete this._lookup[b]}.bind(this)),-1===this.indexOf(a)&&this.filter(a)&&c.push(a)},this),c.length&&!this.alwaysRefilter?(h.call(this,c),this.emit("add",c)):g.call(this)}function e(a){var c=[];b.call(a,function(a){this.off(a),-1!==this.indexOf(a)&&c.push(a)},this),c.length&&!this.alwaysRefilter?(i.call(this,c),this.emit("remove",c)):g.call(this)}function f(a){var b,d,e,f;return this.alwaysRefilter?g.call(this):(b=this.filter(a),d=this.indexOf(a)>-1,void(b&&!d?(h.call(this,[a]),this.emit("add",[a])):b&&d?(e=c(this._internal),this._internal.sort(this.sort.bind(this)),f=c(this._internal),e!==f&&this.emit("sort")):!b&&d&&(i.call(this,[a]),this.emit("remove",[a]))))}function g(){var a,b,d,e=this.collection._internal.slice(),f=c(this._internal),g=e.filter(this.filter);a=this._internal.filter(function(a){return-1===g.indexOf(a)}),i.call(this,a),b=g.filter(function(a){return-1===this.indexOf(a)},this),h.call(this,b),d=c(this._internal),b.length&&this.emit("add",b),a.length&&this.emit("remove",a),f!==d&&this.emit("sort")}function h(a){b.call(a,function(a){var b=a.get(a.key);this._lookup[a.guid]=a,b&&(this._lookup[b]=a),this._internal.push(a)},this),this.length=this._internal.length,this._internal.sort(this.sort.bind(this))}function i(a){b.call(a,function(a){var b=a.get(a.key),c=this.indexOf(a);delete this._lookup[a.guid],this._internal.splice(c,1),b&&delete this._lookup[b]},this),this.length=this._internal.length}return a.subclass("SmartCollection",{construct:function(a){if(this.extend(a||{}),!this.collection)throw new Error("No collection provided");this.model=this.collection.model,this.on(this.collection,"add",d.bind(this)),this.on(this.collection,"remove",e.bind(this)),this.length=(this._internal=[]).length,this._lookup={},d.call(this,this.collection._internal),this.init()},alwaysRefilter:!1,init:function(){},get:function(a){return this.collection.get(a)},push:void 0,pop:void 0,unshift:void 0,shift:void 0,remove:void 0,fetch:void 0,parse:void 0,slice:function(){var a=Array.prototype.slice.apply(this._internal,arguments);return new this.collection.constructor(a,{model:this.collection.model})},filter:function(){return!0},sort:function(){return 0}})}),a("storage/storage",["type/type"],function(a){function b(a){var b=a||window,f="ash";return i="localStorage"in b&&d(f,1)&&c(f)&&e(f),k.length=0,i&&Array.prototype.push.apply(k,Object.keys(b.localStorage)),this}function c(a){var b,c,d;try{if(b=window.localStorage.getItem(a),c=JSON.parse(b||"[]"),d=Date.now()-c[1]||0,j>d)return c[0];e(a)}catch(f){return}}function d(a,b){var c=[b,Date.now()],d=JSON.stringify(c);try{window.localStorage.setItem(a,d)}catch(e){f(d.length);try{window.localStorage.setItem(a,d)}catch(g){return!1}}return!0}function e(a){try{var b=window.localStorage.getItem(a);return window.localStorage.removeItem(a),b.length}catch(c){return 0}}function f(b){var c=0;if(b=b||k.length,a.number(b))for(;b>c&&k.length;)c+=e(k.shift());return c}function g(a){h(a),k.push(a)}function h(a){for(var b=0,c=k.length;c>b;++b)if(a==k[b]){k.splice(b,1);break}}var i,j=144e5,k=[];return b(),{init:b,index:k,get:function(a){var b;if(i)return b=c(a),null!=b&&g(a),b},set:function(a,b){return i?(d(a,b)&&g(a),this):this},unset:function(a){return i?(e(a)&&h(a),this):this},flush:function(a){return i?f(a):void 0}}}),a("template/var/partialcache",[],function(){return{}}),a("template/partial",["template/var/template","template/var/partialcache"],function(a){return function(b,c){new a(c,b)}}),a("template/render",["template/var/template"],function(a){return function(b,c){return new a(b).evaluate(c)}}),a("time/time",["type/type"],function(){function a(a){return a?(i.months=a.months||h.months,i.abbrMonths=a.abbrMonths||h.abbrMonths,i.weekdays=a.weekdays||h.weekdays,i.abbrWeekdays=a.abbrWeekdays||h.abbrWeekdays,i.meridiem=a.meridiem||h.meridiem,i.units=a.units||h.units,i.tense=a.tense||h.tense):(i.months=h.months,i.abbrMonths=h.abbrMonths,i.weekdays=h.weekdays,i.abbrWeekdays=h.abbrWeekdays,i.meridiem=h.meridiem,i.units=h.units,i.tense=h.tense),i}function b(a,b,c){for(a=""+a,b=b||0,c=c||"0";a.length<b;)a=c+a;return a}function c(){return new Date}function d(a,b,c){var d,e,f,g,h,i,j,l;if(+a!==+a||+b!==+b)throw"Invalid Supplied Date.";if(d=b-a,e=Math.round(Math.abs(d)/1e3),f=Math.round(e/60),g=Math.round(f/60),h=Math.round(g/24),i=Math.round(h/31),j=Math.round(i/12),l="",60>e){if(0===e)return k.second(e);l=k.second(e)}else l=60>f?k.minute(f):24>g?k.hour(g):31>h?k.day(h):12>i?k.month(i):k.year(j);return l+=c?" "+k.currentTense(d):" "+k.tense(d)}function e(a){return d(c(),a,!0)}function f(a,b){var c,d,e,f,g,h;if(+a!==+a||+b!==+b)throw"Invalid Supplied Date.";return c=b-a,d=Math.round(c/6e4),e=Math.round(d/60),f=Math.round(e/24),g=Math.round(f/31),h=Math.round(g/12),Math.abs(d)<60?k.minute(d):Math.abs(e)<24?k.hour(e):Math.abs(f)<31?k.day(f):Math.abs(g)<12?k.month(g):k.year(h)}function g(a,b){var c,d,e,f,g;if(+a!==+a)throw"Invalid Supplied Date.";c=b.split("");var h="";for(d=c.length,g="",e=0;d>e;){switch(f=c[e]){case" ":case"-":case"/":case":":case",":g+=f;break;case"[":for(;"]"!==c[e]&&d>e&&"]"!==c[e+1];)g+=c[e+1],e+=1;break;case"Y":case"M":case"D":case"h":case"H":case"m":case"s":for(h=f;c[e+1]===f&&d>e;)h+=f,e+=1;g+=j[h](a);break;case"a":case"A":g+=j[f](a);break;default:g+=""}e+=1}return g}var h,i,j,k;return h={months:["January","February","March","April","May","June","July","August","September","October","November","December"],abbrMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbrWeekdays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],meridiem:["am","pm"],units:{singular:{s:"second",m:"minute",h:"hour",d:"day",w:"week",M:"month",y:"year"},plural:{s:"seconds",m:"minutes",h:"hours",d:"days",w:"weeks",M:"months",y:"years"}},tense:{current:{future:"from now",past:"ago"},future:"later",present:"now",past:"earlier"}},i={months:h.months,abbrMonths:h.abbrMonths,weekdays:h.weekdays,abbrWeekdays:h.abbrWeekdays,meridiem:h.meridiem,units:h.units,tense:h.tense},j={YYYY:function(a){return b(a.getFullYear(),4)},YY:function(a){var c=a.getFullYear()+"";return c=c.substring(c.length-2,c.length),b(c,2)},MMMM:function(a){return i.months[a.getMonth()]},MMM:function(a){return i.abbrMonths[a.getMonth()]},MM:function(a){return b(a.getMonth()+1,2)},M:function(a){return a.getMonth()+1},DDDD:function(a){return i.weekdays[a.getDay()]},DDD:function(a){return i.abbrWeekdays[a.getDay()]},DD:function(a){return b(a.getDate(),2)},D:function(a){return a.getDate()},HH:function(a){return b(a.getHours(),2)},H:function(a){return a.getHours()},hh:function(a){return b(a.getHours()%12||12,2)},h:function(a){return a.getHours()%12||12},mm:function(a){return b(a.getMinutes(),2)},m:function(a){return a.getMinutes()},ss:function(a){return b(a.getSeconds(),2)},s:function(a){return a.getSeconds()},A:function(a){return i.meridiem[a.getHours()>11?1:0].toUpperCase()},a:function(a){return i.meridiem[a.getHours()>11?1:0]}},k={second:function(a){return 0===a?i.tense.present:1!==Math.abs(a)?a+" "+i.units.plural.s:a+" "+i.units.singular.s},minute:function(a){return 1!==Math.abs(a)?a+" "+i.units.plural.m:a+" "+i.units.singular.m},hour:function(a){return 1!==Math.abs(a)?a+" "+i.units.plural.h:a+" "+i.units.singular.h},day:function(a){return 1!==Math.abs(a)?a+" "+i.units.plural.d:a+" "+i.units.singular.d},week:function(a){return 1!==Math.abs(a)?a+" "+i.units.plural.w:a+" "+i.units.singular.w},month:function(a){return 1!==Math.abs(a)?a+" "+i.units.plural.M:a+" "+i.units.singular.M},year:function(a){return 1!==Math.abs(a)?a+" "+i.units.plural.y:a+" "+i.units.singular.y},tense:function(a){return a>0?i.tense.future:i.tense.past},currentTense:function(a){return a>0?i.tense.current.future:i.tense.current.past}},{setLocalization:a,now:c,from:d,fromNow:e,duration:f,format:g}}),a("util/pluck",["util/each","type/type"],function(a,b){return function(c,d){var e=[];return b.number(c.length)?(a.call(c,function(a){b.object(a)&&a[d]&&e.push(a[d])}),e):e}}),a("ash",["ajax/ajax","ajax/delete","ajax/get","ajax/post","ajax/put","classes/collection","classes/collectionview","classes/dom","classes/layoutmanager","classes/list","classes/map","classes/model","classes/promise","classes/router","classes/smartcollection","classes/view","core/ash","event/emit","event/off","event/on","storage/storage","template/compile","template/partial","template/render","time/time","type/type","util/arrayish","util/async","util/each","util/extend","util/guid","util/pluck","util/queuerender"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G){function H(a,b,c){return C.call(a,b,c)}function I(a){return D.apply(a,Array.prototype.slice.call(arguments,1))}return q.def("ajax",a),q.def("ajax.delete",b),q.def("ajax.get",c),q.def("ajax.post",d),q.def("ajax.put",e),q.def("Collection",f),q.def("CollectionView",g),q.def("Dom",h),q.def("LayoutManager",i),q.def("List",j),q.def("Map",k),q.def("Model",l),q.def("Promise",m),q.def("Router",n),q.def("SmartCollection",o),q.def("View",p),q.def("event.emit",r),q.def("event.off",s),q.def("event.on",t),q.def("storage",u),q.def("template.compile",v),q.def("template.partial",w),q.def("template.render",x),q.def("time",y),q.def("type",z),q.def("util.arrayish",A),q.def("util.async",B),q.def("util.each",H),q.def("util.extend",I),q.def("util.guid",E),q.def("util.pluck",F),q.def("util.queueRender",G),q}),b("ash")});</script>

<script>
  window.sharedVariables = {
    truthyInt: 1,
    falseyInt: 0,
    truthyText: "some <text>",
    falseyText: "",
    truthyArray: [ 1, 2, 3, 4, 5 ],
    falseyArray: [],
    truthyObject: {},
    null: null,
    undefined: undefined
  };

  window.mikePropertyTemplate = Ash.template.compile('{{truthyInt}} {{falseyInt}} {{truthyText}} {{falseyText}} {{truthyArray}} {{falseyArray}} {{truthyObject}} {{null}} {{undefined}}');

  window.artPropertyTemplate = AshArt.template.compile('{{truthyInt}} {{falseyInt}} {{truthyText}} {{falseyText}} {{truthyArray}} {{falseyArray}} {{truthyObject}} {{null}} {{undefined}}');

  window.mikeEncodeTemplate = Ash.template.compile('{{=truthyInt}} {{=falseyInt}} {{=truthyText}} {{=falseyText}} {{=truthyArray}} {{=falseyArray}} {{=truthyObject}} {{=null}} {{=undefined}}');

  window.artEncodeTemplate = AshArt.template.compile('{{truthyInt}} {{{falseyInt}}} {{{truthyText}}} {{{falseyText}}} {{{truthyArray}}} {{{falseyArray}}} {{{truthyObject}}} {{{null}}} {{{undefined}}}');

  window.mikeExistsTemplate = Ash.template.compile('{{?truthyInt}}truthyInt{{/truthyInt}} {{?falseyInt}}falseyInt{{/falseyInt}} {{?truthyText}}truthyText{{/truthyText}} {{?falseyText}}falseyText{{/falseyText}} {{?truthyArray}}truthyArray{{/truthyArray}} {{?falseyArray}}falseyArray{{/falseyArray}} {{?truthyObject}}truthyObject{{/truthyObject}} {{?null}}null{{/null}} {{?undefined}}undefined{{/undefined}}');

  window.artExistsTemplate = AshArt.template.compile('{{?truthyInt}}truthyInt{{/truthyInt}} {{?falseyInt}}falseyInt{{/falseyInt}} {{?truthyText}}truthyText{{/truthyText}} {{?falseyText}}falseyText{{/falseyText}} {{?truthyArray}}truthyArray{{/truthyArray}} {{?falseyArray}}falseyArray{{/falseyArray}} {{?truthyObject}}truthyObject{{/truthyObject}} {{?null}}null{{/null}} {{?undefined}}undefined{{/undefined}}');

  window.mikeNotTemplate = Ash.template.compile('{{!truthyInt}}truthyInt{{/truthyInt}} {{!falseyInt}}falseyInt{{/falseyInt}} {{!truthyText}}truthyText{{/truthyText}} {{!falseyText}}falseyText{{/falseyText}} {{!truthyArray}}truthyArray{{/truthyArray}} {{!falseyArray}}falseyArray{{/falseyArray}} {{!truthyObject}}truthyObject{{/truthyObject}} {{!null}}null{{/null}} {{!undefined}}undefined{{/undefined}}');

  window.artNotTemplate = AshArt.template.compile('{{!truthyInt}}truthyInt{{/truthyInt}} {{!falseyInt}}falseyInt{{/falseyInt}} {{!truthyText}}truthyText{{/truthyText}} {{!falseyText}}falseyText{{/falseyText}} {{!truthyArray}}truthyArray{{/truthyArray}} {{!falseyArray}}falseyArray{{/falseyArray}} {{!truthyObject}}truthyObject{{/truthyObject}} {{!null}}null{{/null}} {{!undefined}}undefined{{/undefined}}');

  window.mikeLoopTemplate = Ash.template.compile('{{#truthyArray}}truthyArray{{.}}truthyArray{{/truthyArray}} {{#null}}null{{/null}} {{#undefined}}undefined{{/undefined}}');

  window.artLoopTemplate = AshArt.template.compile('{{#truthyArray}}truthyArray{{.}}truthyArray{{/truthyArray}} {{#null}}null{{/null}} {{#undefined}}undefined{{/undefined}}');

</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Property (Mike)
mikePropertyTemplate(sharedVariables);
ready
Property (Art)
artPropertyTemplate(sharedVariables);
ready
Encode (Mike)
mikeEncodeTemplate(sharedVariables);
ready
Encode (Art)
artEncodeTemplate(sharedVariables);
ready
Exists (Mike)
mikeExistsTemplate(sharedVariables);
ready
Exists (Art)
artExistsTemplate(sharedVariables);
ready
Not (Mike)
mikeNotTemplate(sharedVariables);
ready
Not (Art)
artNotTemplate(sharedVariables);
ready
Loop (Mike)
mikeLoopTemplate(sharedVariables);
ready
Loop (Art)
artLoopTemplate(sharedVariables);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.