* Object that represents a binding between a Signal and a listener function.
* <br />- <strong>This is an internal constructor and shouldn't be called by regular users.</strong>
* <br />- inspired by Joa Ebert AS3 SignalBinding and Robert Penner's Slot classes.
* @author Miller Medeiros
* @constructor
* @internal
* @name signals.SignalBinding
* @param {signals.Signal} signal Reference to Signal object that listener is currently bound to.
* @param {Function} listener Handler function bound to the signal.
* @param {boolean} isOnce If binding should be executed just once.
* @param {Object} [listenerContext] Context on which listener will be executed (object that should represent the `this` variable inside listener function).
* @param {Number} [priority] The priority level of the event listener. (default = 0).
* Default parameters passed to listener during `Signal.dispatch` and `SignalBinding.execute`. (curried parameters)
* @type Array|null
*/
params:null,
/**
* Call listener passing arbitrary parameters.
* <p>If binding was added using `Signal.addOnce()` it will be automatically removed from signal dispatch queue, this method is used internally for the signal dispatch.</p>
* @param {Array} [paramsArr] Array of parameters that should be passed to the listener
thrownewError('listener is a required param of {fn}() and should be a Function.'.replace('{fn}',fnName));
}
}
/**
* Custom event broadcaster
* <br />- inspired by Robert Penner's AS3 Signals.
* @author Miller Medeiros
* @constructor
*/
signals.Signal=function(){
/**
* @type Array.<SignalBinding>
* @private
*/
this._bindings=[];
};
signals.Signal.prototype={
/**
* @type boolean
* @private
*/
_shouldPropagate:true,
/**
* If Signal is active and should broadcast events.
* <p><strong>IMPORTANT:</strong> Setting this property during a dispatch will only affect the next dispatch, if you want to stop the propagation of a signal use `halt()` instead.</p>
* @param {Function} listener Signal handler function.
* @param {Object} [scope] Context on which listener will be executed (object that should represent the `this` variable inside listener function).
* @param {Number} [priority] The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0)
* @return {SignalBinding} An Object representing the binding between the Signal and listener.
* Add listener to the signal that should be removed after first execution (will be executed only once).
* @param {Function} listener Signal handler function.
* @param {Object} [scope] Context on which listener will be executed (object that should represent the `this` variable inside listener function).
* @param {Number} [priority] The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0)
* @return {SignalBinding} An Object representing the binding between the Signal and listener.
(function(a){a(["signals"],function(a){functiond(a,b){if(a.indexOf)returna.indexOf(b);varc=a.length;while(c--)if(a[c]===b)returnc;return-1}functione(a,b){return"[object "+b+"]"===Object.prototype.toString.call(a)}functionf(a){returne(a,"RegExp")}functiong(a){returne(a,"Array")}functionh(a){returntypeofa=="function"}functioni(a){varb;returna===null||a==="null"?b=null:a==="true"?b=!0:a==="false"?b=!1:a===c||a==="undefined"?b=c:a===""||isNaN(a)?b=a:b=parseFloat(a),b}functionj(a){varb=a.length,c=[];while(b--)c[b]=i(a[b]);returnc}functionk(a){varb=(a||"").replace("?","").split("&"),c=b.length,d={},e,f;while(c--)e=b[c].split("="),f=i(e[1]),d[e[0]]=typeoff=="string"?decodeURIComponent(f):f;returnd}functionl(){this._routes=[],this._prevRoutes=[],this.bypassed=newa.Signal,this.routed=newa.Signal}functionm(c,d,e,g){varh=f(c),i=b.patternLexer;this._router=g,this._pattern=c,this._paramsIds=h?null:i.getParamIds(this._pattern),this._optionalParamsIds=h?null:i.getOptionalParamsIds(this._pattern),this._matchRegexp=h?c:i.compilePattern(c),this.matched=newa.Signal,this.switched=newa.Signal,d&&this.matched.add(d),this._priority=e||0}varb,c;returnl.prototype={greedy:!1,greedyEnabled:!0,normalizeFn:null,create:function(){returnnewl},shouldTypecast:!1,addRoute:function(a,b,c){vard=newm(a,b,c,this);returnthis._sortedInsert(d),d},removeRoute:function(a){varb=d(this._routes,a);b!==-1&&this._routes.splice(b,1),a._destroy()},removeAllRoutes:function(){vara=this.getNumRoutes();while(a--)this._routes[a]._destroy();this._routes.length=0},parse:function(a,b){a=a||"",b=b||[];varc=this._getMatchedRoutes(a),d=0,e=c.length,f;if(e){this._notifyPrevRoutes(c,a),this._prevRoutes=c;while(d<e)f=c[d],f.route.matched.dispatch.apply(f.route.matched,b.concat(f.params)),f.isFirst=!d,this.routed.dispatch.apply(this.routed,b.concat([a,f])),d+=1}elsethis.bypassed.dispatch.apply(this.bypassed,b.concat([a]))},_notifyPrevRoutes:function(a,b){varc=0,d;while(d=this._prevRoutes[c++])d.route.switched&&this._didSwitch(d.route,a)&&d.route.switched.dispatch(b)},_didSwitch:function(a,b){varc,d=0;while(c=b[d++])if(c.route===a)return!1;return!0},getNumRoutes:function(){returnthis._routes.length},_sortedInsert:function(a){varb=this._routes,c=b.length;do--c;while(b[c]&&a._priority<=b[c]._priority);b.splice(c+1,0,a)},_getMatchedRoutes:function(a){varb=[],c=this._routes,d=c.length,e;while(e=c[--d]){(!b.length||this.greedy||e.greedy)&&e.match(a)&&b.push({route:e,params:e._getParamsArray(a)});if(!this.greedyEnabled&&b.length)break}returnb},toString:function(){return"[crossroads numRoutes:"+this.getNumRoutes()+"]"}},b=newl,b.VERSION="0.9.0",b.NORM_AS_ARRAY=function(a,b){return[b.vals_]},b.NORM_AS_OBJECT=function(a,b){return[b]},m.prototype={greedy:!1,rules:void0,match:function(a){returna=a||"",this._matchRegexp.test(a)&&this._validateParams(a)},_validateParams:function(a){varb=this.rules,c=this._getParamsObject(a),d;for(dinb)if(d!=="normalize_"&&b.hasOwnProperty(d)&&!this._isValidParam(a,d,c))return!1;return!0},_isValidParam:function(a,b,c){vare=this.rules[b],i=c[b],j=!1,k=b.indexOf("?")===0;returni==null&&this._optionalParamsIds&&d(this._optionalParamsIds,b)!==-1?j=!0:f(e)?(k&&(i=c[b+"_"]),j=e.test(i)):g(e)?(k&&(i=c[b+"_"]),j=d(e,i)!==-1):h(e)&&(j=e(i,a,c)),j},_getParamsObject:function(a){varc=this._router.shouldTypecast,d=b.patternLexer.getParamValues(a,this._matchRegexp,c),e={},f=d.length,g,h;while(f--)h=d[f],this._paramsIds&&(g=this._paramsIds[f],g.indexOf("?")===0&&h&&(e[g+"_"]=h,h=k(h),d[f]=h),e[g]=h),e[f]=h;returne.request_=c?i(a):a,e.vals_=d,e},_getParamsArray:function(a){varb=this.rules?this.rules.normalize_:null,c;returnb=b||this._router.normalizeFn,b&&h(b)?c=b(a,this._getParamsObject(a)):c=this._getParamsObject(a).vals_,c},interpolate:function(a){varc=b.patternLexer.interpolate(this._pattern,a);if(!this._validateParams(c))thrownewError("Generated string doesn't validate against `Route.rules`.");returnc},dispose:function(){this._router.removeRoute(this)},_destroy:function(){this.matched.dispose(),this.switched.dispose(),this.matched=this.switched=this._pattern=this._matchRegexp=null},toString:function(){return'[Route pattern:"'+this._pattern+'", numListeners:'+this.matched.getNumListeners()+"]"}},b.patternLexer=function(){functionk(){vara,b;for(aine)e.hasOwnProperty(a)&&(b=e[a],b.id="__CR_"+a+"__",b.save="save"inb?b.save.replace("{{id}}",b.id):b.id,b.rRestore=newRegExp(b.id,"g"))}functionl(a,b){varc=[],d;while(d=a.exec(b))c.push(d[1]);returnc}functionm(a){returnl(d,a)}functionn(a){returnl(e.OP.rgx,a)}functiono(d){returnd=d||"",d&&(i===f?d=d.replace(b,""):i===h&&(d=d.replace(c,"")),d=p(d,"rgx","save"),d=d.replace(a,"\\$&"),d=p(d,"rRestore","res"),i===f&&(d="\\/?"+d)),i!==g&&(d+="\\/?"),newRegExp("^"+d+"$")}functionp(a,b,c){vard,f;for(fine)e.hasOwnProperty(f)&&(d=e[f],a=a.replace(d[b],d[c]));returna}functionq(a,b,c){vard=b.exec(a);returnd&&(d.shift(),c&&(d=j(d))),d}functionr(a,b){if(typeofa!="string")thrownewError("Route pattern should be a string.");varc=function(a,c){vard;if(cinb){d=b[c];if(a.indexOf("*")===-1&&d.indexOf("/")!==-1)thrownewError('Invalid value "'+d+'" for segment "'+a+'".')}else{if(a.indexOf("{")!==-1)thrownewError("The segment "+a+" is required.");d=""}returnd};returne.OS.trail||(e.OS.trail=newRegExp("(?:"+e.OS.id+")+$")),a.replace(e.OS.rgx,e.OS.save).replace(d,c).replace(e.OS.trail,"").replace(e.OS.rRestore,"/")}vara=/[\\.+*?\^$\[\](){}\/'#]/g,b=/^\/|\/$/g,c=/\/$/g,d=/(?:\{|:)([^}:]+)(?:\}|:)/g,e={OS:{rgx:/([:}]|\w(?=\/))\/?(:|(?:\{\?))/g,save:"$1{{id}}$2",res:"\\/?"},RS:{rgx:/([:}])\/?(\{)/g,save:"$1{{id}}$2",res:"\\/"},RQ:{rgx:/\{\?([^}]+)\}/g,res:"\\?([^#]+)"},OQ:{rgx:/:\?([^:]+):/g,res:"(?:\\?([^#]*))?"},OR:{rgx:/:([^:]+)\*:/g,res:"(.*)?"},RR:{rgx:/\{([^}]+)\*\}/g,res:"(.+)"},RP:{rgx:/\{([^}]+)\}/g,res:"([^\\/?]+)"},OP:{rgx:/:([^:]+):/g,res:"([^\\/?]+)?/?"}},f=1,g=2,h=3,i=f;returnk(),{strict:function(){i=g},loose:function(){i=f},legacy:function(){i=h},getParamIds:m,getOptionalParamsIds:n,getParamValues:q,compilePattern:o,interpolate:r}}(),b})})(typeofdefine=="function"&&define.amd?define:function(a,b){typeofmodule!="undefined"&&module.exports?module.exports=b(require(a[0])):window.crossroads=b(window[a[0]])})
(function(h){functiong(a,b,c,d,e){this._listener=b;this._isOnce=c;this.context=d;this._signal=a;this._priority=e||0}functionf(a,b){if(typeofa!=="function")throwError("listener is a required param of {fn}() and should be a Function.".replace("{fn}",b));}vare={VERSION:"0.7.4"};g.prototype={active:!0,params:null,execute:function(a){varb;this.active&&this._listener&&(a=this.params?this.params.concat(a):a,b=this._listener.apply(this.context,a),this._isOnce&&this.detach());returnb},detach:function(){returnthis.isBound()?
active:!0,_registerListener:function(a,b,c,d){vare=this._indexOfListener(a,c);if(e!==-1){if(a=this._bindings[e],a.isOnce()!==b)throwError("You cannot add"+(b?"":"Once")+"() then add"+(!b?"":"Once")+"() the same listener without removing the relationship first.");}elsea=newg(this,a,b,c,d),this._addBinding(a);this.memorize&&this._prevParams&&a.execute(this._prevParams);returna},_addBinding:function(a){varb=this._bindings.length;do--b;while(this._bindings[b]&&a._priority<=this._bindings[b]._priority);