mirror of
https://github.com/Hopiu/postal.js.git
synced 2026-05-20 04:41:51 +00:00
Finished conversion to gulp, added npm scripts, updated bower.json and package.json
This commit is contained in:
parent
43b7f5fe75
commit
ae29f952fd
47 changed files with 231 additions and 38266 deletions
3
.bowerrc
Normal file
3
.bowerrc
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"directory": "bower"
|
||||||
|
}
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -14,3 +14,4 @@ desktop.ini
|
||||||
*node_modules
|
*node_modules
|
||||||
*npm-debug*
|
*npm-debug*
|
||||||
report/
|
report/
|
||||||
|
bower/
|
||||||
|
|
@ -13,3 +13,4 @@ header.js
|
||||||
component.json
|
component.json
|
||||||
.npmignore
|
.npmignore
|
||||||
classic-resolver*
|
classic-resolver*
|
||||||
|
bower*
|
||||||
14
README.md
14
README.md
|
|
@ -130,6 +130,20 @@ There are four main ways you can extend Postal:
|
||||||
|
|
||||||
It's also possible to extend the monitoring of messages passing through Postal by adding a "wire tap". A wire tap is a callback that will get invoked for any published message (even if no actual subscriptions would bind to the message's topic). Wire taps should _not_ be used in lieu of an actual subscription - but instead should be used for diagnostics, logging, forwarding (to a websocket publisher or a local storage wrapper, for example) or other concerns that fall along those lines. This repository used to include a console logging wiretap called postal.diagnostics.js - you can now find it [here in it's own repo](https://github.com/postaljs/postal.diagnostics). This diagnostics wiretap can be configured with filters to limit the firehose of message data to specific channels/topics and more.
|
It's also possible to extend the monitoring of messages passing through Postal by adding a "wire tap". A wire tap is a callback that will get invoked for any published message (even if no actual subscriptions would bind to the message's topic). Wire taps should _not_ be used in lieu of an actual subscription - but instead should be used for diagnostics, logging, forwarding (to a websocket publisher or a local storage wrapper, for example) or other concerns that fall along those lines. This repository used to include a console logging wiretap called postal.diagnostics.js - you can now find it [here in it's own repo](https://github.com/postaljs/postal.diagnostics). This diagnostics wiretap can be configured with filters to limit the firehose of message data to specific channels/topics and more.
|
||||||
|
|
||||||
|
## Build, Dependencies, etc.
|
||||||
|
|
||||||
|
* postal depends on [underscore.js](http://underscorejs.org/)
|
||||||
|
* postal uses [gulp.js](http://gulpjs.com/) for building, running tests and examples.
|
||||||
|
* To build
|
||||||
|
* run `npm install` (to install all deps)
|
||||||
|
* run `npm run build` - then check the lib folder for the output
|
||||||
|
* To run tests & examples
|
||||||
|
* To run node-based tests: `npm run test`
|
||||||
|
* To run browser-based tests & examples:
|
||||||
|
* run `npm start`
|
||||||
|
* navigate in your browser to <http://localhost:3080/>
|
||||||
|
|
||||||
|
|
||||||
## Can I contribute?
|
## Can I contribute?
|
||||||
Please - by all means! While I hope the API is relatively stable, I'm open to pull requests. (Hint - if you want a feature implemented, a pull request gives it a much higher probability of being included than simply asking me.) As I said, pull requests are most certainly welcome - but please include tests for your additions. Otherwise, it will disappear into the ether.
|
Please - by all means! While I hope the API is relatively stable, I'm open to pull requests. (Hint - if you want a feature implemented, a pull request gives it a much higher probability of being included than simply asking me.) As I said, pull requests are most certainly welcome - but please include tests for your additions. Otherwise, it will disappear into the ether.
|
||||||
|
|
||||||
|
|
|
||||||
69
bower.json
69
bower.json
|
|
@ -1,31 +1,42 @@
|
||||||
{
|
{
|
||||||
"name": "postal.js",
|
"name": "postal.js",
|
||||||
"description": "Client-side messaging library.",
|
"version": "0.8.11",
|
||||||
"homepage": "https://github.com/postaljs/postal.js",
|
"description": "Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.",
|
||||||
"keywords": [
|
"homepage": "https://github.com/postaljs/postal.js",
|
||||||
"pub/sub",
|
"keywords": [
|
||||||
"pub",
|
"pub/sub",
|
||||||
"sub",
|
"pub",
|
||||||
"messaging",
|
"sub",
|
||||||
"message",
|
"messaging",
|
||||||
"bus",
|
"message",
|
||||||
"event",
|
"bus",
|
||||||
"eventing",
|
"event",
|
||||||
"mediator",
|
"eventing",
|
||||||
"broker",
|
"mediator",
|
||||||
"envelope"
|
"broker",
|
||||||
],
|
"envelope"
|
||||||
"author": "Jim Cowart <jim@ifandelse.com>",
|
],
|
||||||
"repository": {
|
"author": "Jim Cowart <jim@ifandelse.com>",
|
||||||
"type": "git",
|
"repository": {
|
||||||
"url": "git://github.com/postaljs/postal.js.git"
|
"type": "git",
|
||||||
},
|
"url": "git://github.com/postaljs/postal.js.git"
|
||||||
"version": "0.8.11",
|
},
|
||||||
"main": [
|
"main": [
|
||||||
"lib/postal.min.js",
|
"lib/postal.min.js",
|
||||||
"lib/postal.js"
|
"lib/postal.js"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"underscore": "~1.3.0"
|
"underscore": "~1.5.2"
|
||||||
}
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"jquery": "~1.10.2",
|
||||||
|
"bootstrap": "~3.0.3",
|
||||||
|
"expect": "0.1.2",
|
||||||
|
"mocha": "~1.17.0",
|
||||||
|
"requirejs": "~2.1.10",
|
||||||
|
"postal.diagnostics": "~0.7.0"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"underscore": "~1.5.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Postal Examples (AMD/require.js Lib Format)</title>
|
<title>Postal Examples (AMD/require.js Lib Format)</title>
|
||||||
<link rel="stylesheet" type="text/css" href="style.css">
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
<script data-main="js/main" src="js/libs/require/require.js"></script>
|
<script data-main="js/main" src="../../bower/requirejs/require.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
3320
example/amd/js/libs/jquery/jquery-min.js
vendored
3320
example/amd/js/libs/jquery/jquery-min.js
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -1,89 +0,0 @@
|
||||||
// This is the amd module version of postal.diagnostics.js
|
|
||||||
// If you need the standard lib version, go to http://github.com/ifandelse/postal.js
|
|
||||||
define( [ "postal", "underscore" ], function ( postal, _, undefined ) {
|
|
||||||
|
|
||||||
var filters = [],
|
|
||||||
applyFilter = function ( filter, env ) {
|
|
||||||
var match = 0, possible = 0;
|
|
||||||
_.each( filter, function ( item, key ) {
|
|
||||||
if ( env[key] ) {
|
|
||||||
possible++;
|
|
||||||
if ( _.isRegExp( item ) && item.test( env[key] ) ) {
|
|
||||||
match++;
|
|
||||||
}
|
|
||||||
else if ( _.isObject( env[key] ) && !_.isArray( env[key] ) ) {
|
|
||||||
if ( applyFilter( item, env[key] ) ) {
|
|
||||||
match++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( _.isEqual( env[key], item ) ) {
|
|
||||||
match++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return match === possible;
|
|
||||||
};
|
|
||||||
|
|
||||||
// this returns a callback that, if invoked, removes the wireTap
|
|
||||||
var wireTap = postal.addWireTap( function ( data, envelope ) {
|
|
||||||
if ( !filters.length || _.any( filters, function ( filter ) {
|
|
||||||
return applyFilter( filter, envelope );
|
|
||||||
} ) ) {
|
|
||||||
if ( !JSON ) {
|
|
||||||
throw "This browser or environment does not provide JSON support";
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
console.log( JSON.stringify( envelope ) );
|
|
||||||
}
|
|
||||||
catch ( exception ) {
|
|
||||||
try {
|
|
||||||
var env = _.extend( {}, envelope );
|
|
||||||
delete env.data;
|
|
||||||
console.log( JSON.stringify( env ) + "\n\t" + "JSON.stringify Error: " + exception.message );
|
|
||||||
}
|
|
||||||
catch ( ex ) {
|
|
||||||
console.log( "Unable to parse data to JSON: " + exception );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
postal.diagnostics = postal.diagnostics || {};
|
|
||||||
|
|
||||||
postal.diagnostics.console = {
|
|
||||||
clearFilters : function () {
|
|
||||||
filters = [];
|
|
||||||
},
|
|
||||||
removeFilter : function ( filter ) {
|
|
||||||
filters = _.filter( filters, function ( item ) {
|
|
||||||
return !_.isEqual( item, filter );
|
|
||||||
} );
|
|
||||||
},
|
|
||||||
addFilter : function ( constraint ) {
|
|
||||||
if ( !_.isArray( constraint ) ) {
|
|
||||||
constraint = [ constraint ];
|
|
||||||
}
|
|
||||||
_.each( constraint, function ( item ) {
|
|
||||||
if ( filters.length === 0 || !_.any( filters, function ( filter ) {
|
|
||||||
return _.isEqual( filter, item );
|
|
||||||
} ) ) {
|
|
||||||
filters.push( item );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
},
|
|
||||||
getCurrentFilters : function () {
|
|
||||||
return filters;
|
|
||||||
},
|
|
||||||
removeWireTap : function () {
|
|
||||||
if ( wireTap ) {
|
|
||||||
wireTap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
define(["postal","underscore"],function(a,b,c){var d=[],e=function(a,c){var d=0,f=0;return b.each(a,function(a,g){c[g]&&(f++,b.isRegExp(a)&&a.test(c[g])?d++:b.isObject(c[g])&&!b.isArray(c[g])?e(a,c[g])&&d++:b.isEqual(c[g],a)&&d++)}),d===f},f=a.addWireTap(function(a,c){if(!d.length||b.any(d,function(a){return e(a,c)})){if(!JSON)throw"This browser or environment does not provide JSON support";try{console.log(JSON.stringify(c))}catch(f){try{var g=b.extend({},c);delete g.data,console.log(JSON.stringify(g)+"\n "+"JSON.stringify Error: "+f.message)}catch(h){console.log("Unable to parse data to JSON: "+f)}}}});a.diagnostics=a.diagnostics||{},a.diagnostics.console={clearFilters:function(){d=[]},removeFilter:function(a){d=b.filter(d,function(c){return!b.isEqual(c,a)})},addFilter:function(a){b.isArray(a)||(a=[a]),b.each(a,function(a){(d.length===0||!b.any(d,function(c){return b.isEqual(c,a)}))&&d.push(a)})},getCurrentFilters:function(){return d},removeWireTap:function(){f&&f()}}})
|
|
||||||
|
|
@ -1,457 +0,0 @@
|
||||||
/**
|
|
||||||
* postal - Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.
|
|
||||||
* Author: Jim Cowart (http://freshbrewedcode.com/jimcowart)
|
|
||||||
* Version: v0.8.11
|
|
||||||
* Url: http://github.com/postaljs/postal.js
|
|
||||||
* License(s): MIT, GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function (root, factory) {
|
|
||||||
if (typeof module === "object" && module.exports) {
|
|
||||||
// Node, or CommonJS-Like environments
|
|
||||||
module.exports = function (_) {
|
|
||||||
_ = _ || require("underscore");
|
|
||||||
return factory(_);
|
|
||||||
};
|
|
||||||
} else if (typeof define === "function" && define.amd) {
|
|
||||||
// AMD. Register as an anonymous module.
|
|
||||||
define(["underscore"], function (_) {
|
|
||||||
return factory(_, root);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Browser globals
|
|
||||||
root.postal = factory(root._, root);
|
|
||||||
}
|
|
||||||
}(this, function (_, global, undefined) {
|
|
||||||
|
|
||||||
var postal;
|
|
||||||
|
|
||||||
|
|
||||||
var ConsecutiveDistinctPredicate = function () {
|
|
||||||
var previous;
|
|
||||||
return function (data) {
|
|
||||||
var eq = false;
|
|
||||||
if (_.isString(data)) {
|
|
||||||
eq = data === previous;
|
|
||||||
previous = data;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eq = _.isEqual(data, previous);
|
|
||||||
previous = _.clone(data);
|
|
||||||
}
|
|
||||||
return !eq;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var DistinctPredicate = function () {
|
|
||||||
var previous = [];
|
|
||||||
|
|
||||||
return function (data) {
|
|
||||||
var isDistinct = !_.any(previous, function (p) {
|
|
||||||
if (_.isObject(data) || _.isArray(data)) {
|
|
||||||
return _.isEqual(data, p);
|
|
||||||
}
|
|
||||||
return data === p;
|
|
||||||
});
|
|
||||||
if (isDistinct) {
|
|
||||||
previous.push(data);
|
|
||||||
}
|
|
||||||
return isDistinct;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var ChannelDefinition = function (channelName) {
|
|
||||||
this.channel = channelName || postal.configuration.DEFAULT_CHANNEL;
|
|
||||||
};
|
|
||||||
|
|
||||||
ChannelDefinition.prototype.subscribe = function () {
|
|
||||||
return arguments.length === 1 ? new SubscriptionDefinition(this.channel, arguments[0].topic, arguments[0].callback) : new SubscriptionDefinition(this.channel, arguments[0], arguments[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
ChannelDefinition.prototype.publish = function () {
|
|
||||||
var envelope = arguments.length === 1 ? (Object.prototype.toString.call(arguments[0]) === "[object String]" ? {
|
|
||||||
topic: arguments[0]
|
|
||||||
} : arguments[0]) : {
|
|
||||||
topic: arguments[0],
|
|
||||||
data: arguments[1]
|
|
||||||
};
|
|
||||||
envelope.channel = this.channel;
|
|
||||||
return postal.configuration.bus.publish(envelope);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var SubscriptionDefinition = function (channel, topic, callback) {
|
|
||||||
if (arguments.length !== 3) {
|
|
||||||
throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");
|
|
||||||
}
|
|
||||||
if (topic.length === 0) {
|
|
||||||
throw new Error("Topics cannot be empty");
|
|
||||||
}
|
|
||||||
this.channel = channel;
|
|
||||||
this.topic = topic;
|
|
||||||
this.callback = callback;
|
|
||||||
this.constraints = [];
|
|
||||||
this.context = null;
|
|
||||||
postal.configuration.bus.publish({
|
|
||||||
channel: postal.configuration.SYSTEM_CHANNEL,
|
|
||||||
topic: "subscription.created",
|
|
||||||
data: {
|
|
||||||
event: "subscription.created",
|
|
||||||
channel: channel,
|
|
||||||
topic: topic
|
|
||||||
}
|
|
||||||
});
|
|
||||||
postal.configuration.bus.subscribe(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
SubscriptionDefinition.prototype = {
|
|
||||||
unsubscribe: function () {
|
|
||||||
if (!this.inactive) {
|
|
||||||
this.inactive = true;
|
|
||||||
postal.configuration.bus.unsubscribe(this);
|
|
||||||
postal.configuration.bus.publish({
|
|
||||||
channel: postal.configuration.SYSTEM_CHANNEL,
|
|
||||||
topic: "subscription.removed",
|
|
||||||
data: {
|
|
||||||
event: "subscription.removed",
|
|
||||||
channel: this.channel,
|
|
||||||
topic: this.topic
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
defer: function () {
|
|
||||||
var self = this;
|
|
||||||
var fn = this.callback;
|
|
||||||
this.callback = function (data, env) {
|
|
||||||
setTimeout(function () {
|
|
||||||
fn.call(self.context, data, env);
|
|
||||||
}, 0);
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
disposeAfter: function (maxCalls) {
|
|
||||||
if (_.isNaN(maxCalls) || maxCalls <= 0) {
|
|
||||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
|
||||||
}
|
|
||||||
var self = this;
|
|
||||||
var fn = this.callback;
|
|
||||||
var dispose = _.after(maxCalls, _.bind(function () {
|
|
||||||
this.unsubscribe();
|
|
||||||
}, this));
|
|
||||||
|
|
||||||
this.callback = function () {
|
|
||||||
fn.apply(self.context, arguments);
|
|
||||||
dispose();
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
distinctUntilChanged: function () {
|
|
||||||
this.withConstraint(new ConsecutiveDistinctPredicate());
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
distinct: function () {
|
|
||||||
this.withConstraint(new DistinctPredicate());
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
once: function () {
|
|
||||||
this.disposeAfter(1);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withConstraint: function (predicate) {
|
|
||||||
if (!_.isFunction(predicate)) {
|
|
||||||
throw "Predicate constraint must be a function";
|
|
||||||
}
|
|
||||||
this.constraints.push(predicate);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withConstraints: function (predicates) {
|
|
||||||
var self = this;
|
|
||||||
if (_.isArray(predicates)) {
|
|
||||||
_.each(predicates, function (predicate) {
|
|
||||||
self.withConstraint(predicate);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
},
|
|
||||||
|
|
||||||
withContext: function (context) {
|
|
||||||
this.context = context;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withDebounce: function (milliseconds, immediate) {
|
|
||||||
if (_.isNaN(milliseconds)) {
|
|
||||||
throw "Milliseconds must be a number";
|
|
||||||
}
|
|
||||||
var fn = this.callback;
|
|
||||||
this.callback = _.debounce(fn, milliseconds, !! immediate);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withDelay: function (milliseconds) {
|
|
||||||
if (_.isNaN(milliseconds)) {
|
|
||||||
throw "Milliseconds must be a number";
|
|
||||||
}
|
|
||||||
var self = this;
|
|
||||||
var fn = this.callback;
|
|
||||||
this.callback = function (data, env) {
|
|
||||||
setTimeout(function () {
|
|
||||||
fn.call(self.context, data, env);
|
|
||||||
}, milliseconds);
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withThrottle: function (milliseconds) {
|
|
||||||
if (_.isNaN(milliseconds)) {
|
|
||||||
throw "Milliseconds must be a number";
|
|
||||||
}
|
|
||||||
var fn = this.callback;
|
|
||||||
this.callback = _.throttle(fn, milliseconds);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
subscribe: function (callback) {
|
|
||||||
this.callback = callback;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var bindingsResolver = {
|
|
||||||
cache: {},
|
|
||||||
regex: {},
|
|
||||||
|
|
||||||
compare: function (binding, topic) {
|
|
||||||
var pattern, rgx, prevSegment, result = (this.cache[topic] && this.cache[topic][binding]);
|
|
||||||
if (typeof result !== "undefined") {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (!(rgx = this.regex[binding])) {
|
|
||||||
pattern = "^" + _.map(binding.split("."), function (segment) {
|
|
||||||
var res = "";
|
|
||||||
if ( !! prevSegment) {
|
|
||||||
res = prevSegment !== "#" ? "\\.\\b" : "\\b";
|
|
||||||
}
|
|
||||||
if (segment === "#") {
|
|
||||||
res += "[\\s\\S]*";
|
|
||||||
} else if (segment === "*") {
|
|
||||||
res += "[^.]+";
|
|
||||||
} else {
|
|
||||||
res += segment;
|
|
||||||
}
|
|
||||||
prevSegment = segment;
|
|
||||||
return res;
|
|
||||||
}).join("") + "$";
|
|
||||||
rgx = this.regex[binding] = new RegExp(pattern);
|
|
||||||
}
|
|
||||||
this.cache[topic] = this.cache[topic] || {};
|
|
||||||
this.cache[topic][binding] = result = rgx.test(topic);
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function () {
|
|
||||||
this.cache = {};
|
|
||||||
this.regex = {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var fireSub = function (subDef, envelope) {
|
|
||||||
if (!subDef.inactive && postal.configuration.resolver.compare(subDef.topic, envelope.topic)) {
|
|
||||||
if (_.all(subDef.constraints, function (constraint) {
|
|
||||||
return constraint.call(subDef.context, envelope.data, envelope);
|
|
||||||
})) {
|
|
||||||
if (typeof subDef.callback === "function") {
|
|
||||||
subDef.callback.call(subDef.context, envelope.data, envelope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var pubInProgress = 0;
|
|
||||||
var unSubQueue = [];
|
|
||||||
var clearUnSubQueue = function () {
|
|
||||||
while (unSubQueue.length) {
|
|
||||||
localBus.unsubscribe(unSubQueue.shift());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var localBus = {
|
|
||||||
addWireTap: function (callback) {
|
|
||||||
var self = this;
|
|
||||||
self.wireTaps.push(callback);
|
|
||||||
return function () {
|
|
||||||
var idx = self.wireTaps.indexOf(callback);
|
|
||||||
if (idx !== -1) {
|
|
||||||
self.wireTaps.splice(idx, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
publish: function (envelope) {
|
|
||||||
++pubInProgress;
|
|
||||||
envelope.timeStamp = new Date();
|
|
||||||
_.each(this.wireTaps, function (tap) {
|
|
||||||
tap(envelope.data, envelope);
|
|
||||||
});
|
|
||||||
if (this.subscriptions[envelope.channel]) {
|
|
||||||
_.each(this.subscriptions[envelope.channel], function (subscribers) {
|
|
||||||
var idx = 0,
|
|
||||||
len = subscribers.length,
|
|
||||||
subDef;
|
|
||||||
while (idx < len) {
|
|
||||||
if (subDef = subscribers[idx++]) {
|
|
||||||
fireSub(subDef, envelope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (--pubInProgress === 0) {
|
|
||||||
clearUnSubQueue();
|
|
||||||
}
|
|
||||||
return envelope;
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function () {
|
|
||||||
if (this.subscriptions) {
|
|
||||||
_.each(this.subscriptions, function (channel) {
|
|
||||||
_.each(channel, function (topic) {
|
|
||||||
while (topic.length) {
|
|
||||||
topic.pop().unsubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this.subscriptions = {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
subscribe: function (subDef) {
|
|
||||||
var channel = this.subscriptions[subDef.channel],
|
|
||||||
subs;
|
|
||||||
if (!channel) {
|
|
||||||
channel = this.subscriptions[subDef.channel] = {};
|
|
||||||
}
|
|
||||||
subs = this.subscriptions[subDef.channel][subDef.topic];
|
|
||||||
if (!subs) {
|
|
||||||
subs = this.subscriptions[subDef.channel][subDef.topic] = [];
|
|
||||||
}
|
|
||||||
subs.push(subDef);
|
|
||||||
return subDef;
|
|
||||||
},
|
|
||||||
|
|
||||||
subscriptions: {},
|
|
||||||
|
|
||||||
wireTaps: [],
|
|
||||||
|
|
||||||
unsubscribe: function (config) {
|
|
||||||
if (pubInProgress) {
|
|
||||||
unSubQueue.push(config);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.subscriptions[config.channel][config.topic]) {
|
|
||||||
var len = this.subscriptions[config.channel][config.topic].length,
|
|
||||||
idx = 0;
|
|
||||||
while (idx < len) {
|
|
||||||
if (this.subscriptions[config.channel][config.topic][idx] === config) {
|
|
||||||
this.subscriptions[config.channel][config.topic].splice(idx, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
postal = {
|
|
||||||
configuration: {
|
|
||||||
bus: localBus,
|
|
||||||
resolver: bindingsResolver,
|
|
||||||
DEFAULT_CHANNEL: "/",
|
|
||||||
SYSTEM_CHANNEL: "postal"
|
|
||||||
},
|
|
||||||
|
|
||||||
ChannelDefinition: ChannelDefinition,
|
|
||||||
SubscriptionDefinition: SubscriptionDefinition,
|
|
||||||
|
|
||||||
channel: function (channelName) {
|
|
||||||
return new ChannelDefinition(channelName);
|
|
||||||
},
|
|
||||||
|
|
||||||
subscribe: function (options) {
|
|
||||||
return new SubscriptionDefinition(options.channel || postal.configuration.DEFAULT_CHANNEL, options.topic, options.callback);
|
|
||||||
},
|
|
||||||
|
|
||||||
publish: function (envelope) {
|
|
||||||
envelope.channel = envelope.channel || postal.configuration.DEFAULT_CHANNEL;
|
|
||||||
return postal.configuration.bus.publish(envelope);
|
|
||||||
},
|
|
||||||
|
|
||||||
addWireTap: function (callback) {
|
|
||||||
return this.configuration.bus.addWireTap(callback);
|
|
||||||
},
|
|
||||||
|
|
||||||
linkChannels: function (sources, destinations) {
|
|
||||||
var result = [];
|
|
||||||
sources = !_.isArray(sources) ? [sources] : sources;
|
|
||||||
destinations = !_.isArray(destinations) ? [destinations] : destinations;
|
|
||||||
_.each(sources, function (source) {
|
|
||||||
var sourceTopic = source.topic || "#";
|
|
||||||
_.each(destinations, function (destination) {
|
|
||||||
var destChannel = destination.channel || postal.configuration.DEFAULT_CHANNEL;
|
|
||||||
result.push(
|
|
||||||
postal.subscribe({
|
|
||||||
channel: source.channel || postal.configuration.DEFAULT_CHANNEL,
|
|
||||||
topic: sourceTopic,
|
|
||||||
callback: function (data, env) {
|
|
||||||
var newEnv = _.clone(env);
|
|
||||||
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
|
|
||||||
newEnv.channel = destChannel;
|
|
||||||
newEnv.data = data;
|
|
||||||
postal.publish(newEnv);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
utils: {
|
|
||||||
getSubscribersFor: function () {
|
|
||||||
var channel = arguments[0],
|
|
||||||
tpc = arguments[1];
|
|
||||||
if (arguments.length === 1) {
|
|
||||||
channel = arguments[0].channel || postal.configuration.DEFAULT_CHANNEL;
|
|
||||||
tpc = arguments[0].topic;
|
|
||||||
}
|
|
||||||
if (postal.configuration.bus.subscriptions[channel] && Object.prototype.hasOwnProperty.call(postal.configuration.bus.subscriptions[channel], tpc)) {
|
|
||||||
return postal.configuration.bus.subscriptions[channel][tpc];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function () {
|
|
||||||
postal.configuration.bus.reset();
|
|
||||||
postal.configuration.resolver.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
localBus.subscriptions[postal.configuration.SYSTEM_CHANNEL] = {};
|
|
||||||
|
|
||||||
|
|
||||||
if (global && Object.prototype.hasOwnProperty.call(global, "__postalReady__") && _.isArray(global.__postalReady__)) {
|
|
||||||
while (global.__postalReady__.length) {
|
|
||||||
global.__postalReady__.shift().onReady(postal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return postal;
|
|
||||||
}));
|
|
||||||
8
example/amd/js/libs/postal/postal.min.js
vendored
8
example/amd/js/libs/postal/postal.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,621 +0,0 @@
|
||||||
/*
|
|
||||||
RequireJS 1.0.2 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
|
|
||||||
Available via the MIT or new BSD license.
|
|
||||||
see: http://github.com/jrburke/requirejs for details
|
|
||||||
*/
|
|
||||||
var requirejs, require, define;
|
|
||||||
(function () {
|
|
||||||
function J( a ) {
|
|
||||||
return M.call( a ) === "[object Function]"
|
|
||||||
}
|
|
||||||
|
|
||||||
function E( a ) {
|
|
||||||
return M.call( a ) === "[object Array]"
|
|
||||||
}
|
|
||||||
|
|
||||||
function Z( a, c, h ) {
|
|
||||||
for ( var k in c ) {
|
|
||||||
if ( !(k in K) && (!(k in a) || h) ) {
|
|
||||||
a[k] = c[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
function N( a, c, d ) {
|
|
||||||
a = Error( c + "\nhttp://requirejs.org/docs/errors.html#" + a );
|
|
||||||
if ( d ) {
|
|
||||||
a.originalError = d;
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
function $( a, c, d ) {
|
|
||||||
var k, j, q;
|
|
||||||
for ( k = 0; q = c[k]; k++ ) {
|
|
||||||
q = typeof q === "string" ? {name : q} : q;
|
|
||||||
j = q.location;
|
|
||||||
if ( d && (!j || j.indexOf( "/" ) !== 0 && j.indexOf( ":" ) === -1) ) {
|
|
||||||
j = d + "/" + (j || q.name);
|
|
||||||
}
|
|
||||||
a[q.name] = {name : q.name, location : j ||
|
|
||||||
q.name, main : (q.main || "main").replace( ea, "" ).replace( aa, "" )}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function V( a, c ) {
|
|
||||||
a.holdReady ? a.holdReady( c ) : c ? a.readyWait += 1 : a.ready( !0 )
|
|
||||||
}
|
|
||||||
|
|
||||||
function fa( a ) {
|
|
||||||
function c( b, l ) {
|
|
||||||
var f, a;
|
|
||||||
if ( b && b.charAt( 0 ) === "." ) {
|
|
||||||
if ( l ) {
|
|
||||||
p.pkgs[l] ? l = [l] : (l = l.split( "/" ), l = l.slice( 0, l.length - 1 ));
|
|
||||||
f = b = l.concat( b.split( "/" ) );
|
|
||||||
var c;
|
|
||||||
for ( a = 0; c = f[a]; a++ ) {
|
|
||||||
if ( c === "." ) {
|
|
||||||
f.splice( a, 1 ), a -= 1;
|
|
||||||
} else if ( c === ".." ) {
|
|
||||||
if ( a === 1 && (f[2] === ".." || f[0] === "..") ) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
a > 0 && (f.splice( a - 1, 2 ), a -= 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a = p.pkgs[f = b[0]];
|
|
||||||
b = b.join( "/" );
|
|
||||||
a && b === f + "/" + a.main && (b = f)
|
|
||||||
} else {
|
|
||||||
b.indexOf( "./" ) ===
|
|
||||||
0 && (b = b.substring( 2 ));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
function h( b, l ) {
|
|
||||||
var f = b ? b.indexOf( "!" ) : -1, a = null, d = l ? l.name : null, i = b, e, h;
|
|
||||||
f !== -1 && (a = b.substring( 0, f ), b = b.substring( f + 1, b.length ));
|
|
||||||
a && (a = c( a, d ));
|
|
||||||
b && (a ? e = (f = m[a]) && f.normalize ? f.normalize( b, function ( b ) {
|
|
||||||
return c( b, d )
|
|
||||||
} ) : c( b, d ) : (e = c( b, d ), h = E[e], h || (h = g.nameToUrl( e, null, l ), E[e] = h)));
|
|
||||||
return{prefix : a, name : e, parentMap : l, url : h, originalName : i, fullName : a ? a + "!" + (e || "") : e}
|
|
||||||
}
|
|
||||||
|
|
||||||
function k() {
|
|
||||||
var b = !0, l = p.priorityWait, f, a;
|
|
||||||
if ( l ) {
|
|
||||||
for ( a = 0; f = l[a]; a++ ) {
|
|
||||||
if ( !s[f] ) {
|
|
||||||
b = !1;
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b && delete p.priorityWait
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
function j( b, l, f ) {
|
|
||||||
return function () {
|
|
||||||
var a = ga.call( arguments, 0 ), c;
|
|
||||||
if ( f && J( c = a[a.length - 1] ) ) {
|
|
||||||
c.__requireJsBuild = !0;
|
|
||||||
}
|
|
||||||
a.push( l );
|
|
||||||
return b.apply( null, a )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function q( b, l ) {
|
|
||||||
var a = j( g.require, b, l );
|
|
||||||
Z( a, {nameToUrl : j( g.nameToUrl, b ), toUrl : j( g.toUrl, b ), defined : j( g.requireDefined, b ), specified : j( g.requireSpecified, b ), isBrowser : d.isBrowser} );
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
function o( b ) {
|
|
||||||
var l, a, c, C = b.callback, i = b.map, e = i.fullName, ba = b.deps;
|
|
||||||
c = b.listeners;
|
|
||||||
if ( C && J( C ) ) {
|
|
||||||
if ( p.catchError.define ) {
|
|
||||||
try {
|
|
||||||
a = d.execCb( e, b.callback, ba, m[e] )
|
|
||||||
} catch ( k ) {
|
|
||||||
l = k
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
a =
|
|
||||||
d.execCb( e, b.callback, ba, m[e] );
|
|
||||||
}
|
|
||||||
if ( e ) {
|
|
||||||
(C = b.cjsModule) && C.exports !== void 0 && C.exports !== m[e] ? a = m[e] = b.cjsModule.exports : a === void 0 && b.usingExports ? a = m[e] : (m[e] = a, F[e] && (Q[e] = !0))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e && (a = m[e] = C, F[e] && (Q[e] = !0));
|
|
||||||
}
|
|
||||||
if ( D[b.id] ) {
|
|
||||||
delete D[b.id], b.isDone = !0, g.waitCount -= 1, g.waitCount === 0 && (I = []);
|
|
||||||
}
|
|
||||||
delete R[e];
|
|
||||||
if ( d.onResourceLoad && !b.placeholder ) {
|
|
||||||
d.onResourceLoad( g, i, b.depArray );
|
|
||||||
}
|
|
||||||
if ( l ) {
|
|
||||||
return a = (e ? h( e ).url : "") || l.fileName || l.sourceURL, c = l.moduleTree, l = N( "defineerror", 'Error evaluating module "' + e + '" at location "' +
|
|
||||||
a + '":\n' + l + "\nfileName:" + a + "\nlineNumber: " + (l.lineNumber || l.line), l ), l.moduleName = e, l.moduleTree = c, d.onError( l );
|
|
||||||
}
|
|
||||||
for ( l = 0; C = c[l]; l++ ) {
|
|
||||||
C( a )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function r( b, a ) {
|
|
||||||
return function ( f ) {
|
|
||||||
b.depDone[a] || (b.depDone[a] = !0, b.deps[a] = f, b.depCount -= 1, b.depCount || o( b ))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function u( b, a ) {
|
|
||||||
var f = a.map, c = f.fullName, h = f.name, i = L[b] || (L[b] = m[b]), e;
|
|
||||||
if ( !a.loading ) {
|
|
||||||
a.loading = !0, e = function ( b ) {
|
|
||||||
a.callback = function () {
|
|
||||||
return b
|
|
||||||
};
|
|
||||||
o( a );
|
|
||||||
s[a.id] = !0;
|
|
||||||
w()
|
|
||||||
}, e.fromText = function ( b, a ) {
|
|
||||||
var l = O;
|
|
||||||
s[b] = !1;
|
|
||||||
g.scriptCount += 1;
|
|
||||||
g.fake[b] = !0;
|
|
||||||
l && (O = !1);
|
|
||||||
d.exec( a );
|
|
||||||
l && (O = !0);
|
|
||||||
g.completeLoad( b )
|
|
||||||
}, c in m ? e( m[c] ) : i.load( h, q( f.parentMap, !0 ), e, p )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function v( b ) {
|
|
||||||
D[b.id] || (D[b.id] = b, I.push( b ), g.waitCount += 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
function B( b ) {
|
|
||||||
this.listeners.push( b )
|
|
||||||
}
|
|
||||||
|
|
||||||
function t( b, a ) {
|
|
||||||
var f = b.fullName, c = b.prefix, d = c ? L[c] || (L[c] = m[c]) : null, i, e;
|
|
||||||
f && (i = R[f]);
|
|
||||||
if ( !i && (e = !0, i = {id : (c && !d ? M++ + "__p@:" : "") + (f || "__r@" + M++), map : b, depCount : 0, depDone : [], depCallbacks : [], deps : [], listeners : [], add : B}, y[i.id] = !0, f && (!c || L[c])) ) {
|
|
||||||
R[f] = i;
|
|
||||||
}
|
|
||||||
c && !d ? (f = t( h( c ), !0 ), f.add( function () {
|
|
||||||
var a = h( b.originalName, b.parentMap ), a = t( a,
|
|
||||||
!0 );
|
|
||||||
i.placeholder = !0;
|
|
||||||
a.add( function ( b ) {
|
|
||||||
i.callback = function () {
|
|
||||||
return b
|
|
||||||
};
|
|
||||||
o( i )
|
|
||||||
} )
|
|
||||||
} )) : e && a && (s[i.id] = !1, g.paused.push( i ), v( i ));
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
function x( b, a, f, c ) {
|
|
||||||
var b = h( b, c ), d = b.name, i = b.fullName, e = t( b ), k = e.id, j = e.deps, n;
|
|
||||||
if ( i ) {
|
|
||||||
if ( i in m || s[k] === !0 || i === "jquery" && p.jQuery && p.jQuery !== f().fn.jquery ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
y[k] = !0;
|
|
||||||
s[k] = !0;
|
|
||||||
i === "jquery" && f && S( f() )
|
|
||||||
}
|
|
||||||
e.depArray = a;
|
|
||||||
e.callback = f;
|
|
||||||
for ( f = 0; f < a.length; f++ ) {
|
|
||||||
if ( k = a[f] ) {
|
|
||||||
k = h( k, d ? b : c ), n = k.fullName, a[f] = n, n === "require" ? j[f] = q( b ) : n === "exports" ? (j[f] = m[i] = {}, e.usingExports = !0) : n ===
|
|
||||||
"module" ? e.cjsModule = j[f] = {id : d, uri : d ? g.nameToUrl( d, null, c ) : void 0, exports : m[i]} : n in m && !(n in D) && (!(i in F) || i in F && Q[n]) ? j[f] = m[n] : (i in F && (F[n] = !0, delete m[n], T[k.url] = !1), e.depCount += 1, e.depCallbacks[f] = r( e, f ), t( k, !0 ).add( e.depCallbacks[f] ));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e.depCount ? v( e ) : o( e )
|
|
||||||
}
|
|
||||||
|
|
||||||
function n( b ) {
|
|
||||||
x.apply( null, b )
|
|
||||||
}
|
|
||||||
|
|
||||||
function z( b, a ) {
|
|
||||||
if ( !b.isDone ) {
|
|
||||||
var c = b.map.fullName, d = b.depArray, g, i, e, k;
|
|
||||||
if ( c ) {
|
|
||||||
if ( a[c] ) {
|
|
||||||
return m[c];
|
|
||||||
}
|
|
||||||
a[c] = !0
|
|
||||||
}
|
|
||||||
if ( d ) {
|
|
||||||
for ( g = 0; g < d.length; g++ ) {
|
|
||||||
if ( i = d[g] ) {
|
|
||||||
if ( (e = h( i ).prefix) && (k = D[e]) && z( k, a ), (e = D[i]) && !e.isDone &&
|
|
||||||
s[i] ) {
|
|
||||||
i = z( e, a ), b.depCallbacks[g]( i );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c ? m[c] : void 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function A() {
|
|
||||||
var b = p.waitSeconds * 1E3, a = b && g.startTime + b < (new Date).getTime(), b = "", c = !1, h = !1, j;
|
|
||||||
if ( !(g.pausedCount > 0) ) {
|
|
||||||
if ( p.priorityWait ) {
|
|
||||||
if ( k() ) {
|
|
||||||
w();
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ( j in s ) {
|
|
||||||
if ( !(j in K) && (c = !0, !s[j]) ) {
|
|
||||||
if ( a ) {
|
|
||||||
b += j + " ";
|
|
||||||
} else {
|
|
||||||
h = !0;
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( c || g.waitCount ) {
|
|
||||||
if ( a && b ) {
|
|
||||||
return j = N( "timeout", "Load timeout for modules: " + b ), j.requireType = "timeout", j.requireModules = b, d.onError( j );
|
|
||||||
}
|
|
||||||
if ( h || g.scriptCount ) {
|
|
||||||
if ( (G || ca) && !W ) {
|
|
||||||
W = setTimeout( function () {
|
|
||||||
W = 0;
|
|
||||||
A()
|
|
||||||
}, 50 )
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( g.waitCount ) {
|
|
||||||
for ( H =
|
|
||||||
0; b = I[H]; H++ ) {
|
|
||||||
z( b, {} );
|
|
||||||
}
|
|
||||||
g.paused.length && w();
|
|
||||||
X < 5 && (X += 1, A())
|
|
||||||
}
|
|
||||||
X = 0;
|
|
||||||
d.checkReadyState()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var g, w, p = {waitSeconds : 7, baseUrl : "./", paths : {}, pkgs : {}, catchError : {}}, P = [], y = {require : !0, exports : !0, module : !0}, E = {}, m = {}, s = {}, D = {}, I = [], T = {}, M = 0, R = {}, L = {}, F = {}, Q = {}, Y = 0;
|
|
||||||
S = function ( b ) {
|
|
||||||
if ( !g.jQuery && (b = b || (typeof jQuery !== "undefined" ? jQuery : null)) && !(p.jQuery && b.fn.jquery !== p.jQuery) && ("holdReady"in b || "readyWait"in b) ) {
|
|
||||||
if ( g.jQuery = b, n( ["jquery", [], function () {
|
|
||||||
return jQuery
|
|
||||||
}] ), g.scriptCount ) {
|
|
||||||
V( b, !0 ), g.jQueryIncremented =
|
|
||||||
!0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
w = function () {
|
|
||||||
var b, a, c, h, j, i;
|
|
||||||
Y += 1;
|
|
||||||
if ( g.scriptCount <= 0 ) {
|
|
||||||
g.scriptCount = 0;
|
|
||||||
}
|
|
||||||
for ( ; P.length; ) {
|
|
||||||
if ( b = P.shift(), b[0] === null ) {
|
|
||||||
return d.onError( N( "mismatch", "Mismatched anonymous define() module: " + b[b.length - 1] ) );
|
|
||||||
} else {
|
|
||||||
n( b );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( !p.priorityWait || k() ) {
|
|
||||||
for ( ; g.paused.length; ) {
|
|
||||||
j = g.paused;
|
|
||||||
g.pausedCount += j.length;
|
|
||||||
g.paused = [];
|
|
||||||
for ( h = 0; b = j[h]; h++ ) {
|
|
||||||
a = b.map, c = a.url, i = a.fullName, a.prefix ? u( a.prefix, b ) : !T[c] && !s[i] && (d.load( g, i, c ), c.indexOf( "empty:" ) !== 0 && (T[c] = !0));
|
|
||||||
}
|
|
||||||
g.startTime = (new Date).getTime();
|
|
||||||
g.pausedCount -= j.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Y ===
|
|
||||||
1 && A();
|
|
||||||
Y -= 1
|
|
||||||
};
|
|
||||||
g = {contextName : a, config : p, defQueue : P, waiting : D, waitCount : 0, specified : y, loaded : s, urlMap : E, urlFetched : T, scriptCount : 0, defined : m, paused : [], pausedCount : 0, plugins : L, needFullExec : F, fake : {}, fullExec : Q, managerCallbacks : R, makeModuleMap : h, normalize : c, configure : function ( b ) {
|
|
||||||
var a, c, d;
|
|
||||||
b.baseUrl && b.baseUrl.charAt( b.baseUrl.length - 1 ) !== "/" && (b.baseUrl += "/");
|
|
||||||
a = p.paths;
|
|
||||||
d = p.pkgs;
|
|
||||||
Z( p, b, !0 );
|
|
||||||
if ( b.paths ) {
|
|
||||||
for ( c in b.paths ) {
|
|
||||||
c in K || (a[c] = b.paths[c]);
|
|
||||||
}
|
|
||||||
p.paths = a
|
|
||||||
}
|
|
||||||
if ( (a = b.packagePaths) || b.packages ) {
|
|
||||||
if ( a ) {
|
|
||||||
for ( c in a ) {
|
|
||||||
c in
|
|
||||||
K || $( d, a[c], c );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.packages && $( d, b.packages );
|
|
||||||
p.pkgs = d
|
|
||||||
}
|
|
||||||
if ( b.priority ) {
|
|
||||||
c = g.requireWait, g.requireWait = !1, g.takeGlobalQueue(), w(), g.require( b.priority ), w(), g.requireWait = c, p.priorityWait = b.priority;
|
|
||||||
}
|
|
||||||
if ( b.deps || b.callback ) {
|
|
||||||
g.require( b.deps || [], b.callback )
|
|
||||||
}
|
|
||||||
}, requireDefined : function ( b, a ) {
|
|
||||||
return h( b, a ).fullName in m
|
|
||||||
}, requireSpecified : function ( b, a ) {
|
|
||||||
return h( b, a ).fullName in y
|
|
||||||
}, require : function ( b, c, f ) {
|
|
||||||
if ( typeof b === "string" ) {
|
|
||||||
if ( J( c ) ) {
|
|
||||||
return d.onError( N( "requireargs", "Invalid require call" ) );
|
|
||||||
}
|
|
||||||
if ( d.get ) {
|
|
||||||
return d.get( g,
|
|
||||||
b, c );
|
|
||||||
}
|
|
||||||
c = h( b, c );
|
|
||||||
b = c.fullName;
|
|
||||||
return!(b in m) ? d.onError( N( "notloaded", "Module name '" + c.fullName + "' has not been loaded yet for context: " + a ) ) : m[b]
|
|
||||||
}
|
|
||||||
(b && b.length || c) && x( null, b, c, f );
|
|
||||||
if ( !g.requireWait ) {
|
|
||||||
for ( ; !g.scriptCount && g.paused.length; ) {
|
|
||||||
g.takeGlobalQueue(), w();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return g.require
|
|
||||||
}, takeGlobalQueue : function () {
|
|
||||||
U.length && (ha.apply( g.defQueue, [g.defQueue.length - 1, 0].concat( U ) ), U = [])
|
|
||||||
}, completeLoad : function ( b ) {
|
|
||||||
var a;
|
|
||||||
for ( g.takeGlobalQueue(); P.length; ) {
|
|
||||||
if ( a = P.shift(), a[0] === null ) {
|
|
||||||
a[0] = b;
|
|
||||||
break
|
|
||||||
} else if ( a[0] === b ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
n( a ), a = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a ? n( a ) : n( [b, [], b === "jquery" && typeof jQuery !== "undefined" ? function () {
|
|
||||||
return jQuery
|
|
||||||
} : null] );
|
|
||||||
S();
|
|
||||||
d.isAsync && (g.scriptCount -= 1);
|
|
||||||
w();
|
|
||||||
d.isAsync || (g.scriptCount -= 1)
|
|
||||||
}, toUrl : function ( a, c ) {
|
|
||||||
var d = a.lastIndexOf( "." ), h = null;
|
|
||||||
d !== -1 && (h = a.substring( d, a.length ), a = a.substring( 0, d ));
|
|
||||||
return g.nameToUrl( a, h, c )
|
|
||||||
}, nameToUrl : function ( a, h, f ) {
|
|
||||||
var j, k, i, e, m = g.config, a = c( a, f && f.fullName );
|
|
||||||
if ( d.jsExtRegExp.test( a ) ) {
|
|
||||||
h = a + (h ? h : "");
|
|
||||||
} else {
|
|
||||||
j = m.paths;
|
|
||||||
k = m.pkgs;
|
|
||||||
f = a.split( "/" );
|
|
||||||
for ( e = f.length; e > 0; e-- ) {
|
|
||||||
if ( i = f.slice( 0, e ).join( "/" ),
|
|
||||||
j[i] ) {
|
|
||||||
f.splice( 0, e, j[i] );
|
|
||||||
break
|
|
||||||
} else if ( i = k[i] ) {
|
|
||||||
a = a === i.name ? i.location + "/" + i.main : i.location;
|
|
||||||
f.splice( 0, e, a );
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h = f.join( "/" ) + (h || ".js");
|
|
||||||
h = (h.charAt( 0 ) === "/" || h.match( /^\w+:/ ) ? "" : m.baseUrl) + h
|
|
||||||
}
|
|
||||||
return m.urlArgs ? h + ((h.indexOf( "?" ) === -1 ? "?" : "&") + m.urlArgs) : h
|
|
||||||
}};
|
|
||||||
g.jQueryCheck = S;
|
|
||||||
g.resume = w;
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
|
|
||||||
function ia() {
|
|
||||||
var a, c, d;
|
|
||||||
if ( n && n.readyState === "interactive" ) {
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
a = document.getElementsByTagName( "script" );
|
|
||||||
for ( c = a.length - 1; c > -1 && (d = a[c]); c-- ) {
|
|
||||||
if ( d.readyState === "interactive" ) {
|
|
||||||
return n = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
var ja =
|
|
||||||
/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, ka = /require\(\s*["']([^'"\s]+)["']\s*\)/g, ea = /^\.\//, aa = /\.js$/, M = Object.prototype.toString, r = Array.prototype, ga = r.slice, ha = r.splice, G = !!(typeof window !== "undefined" && navigator && document), ca = !G && typeof importScripts !== "undefined", la = G && navigator.platform === "PLAYSTATION 3" ? /^complete$/ : /^(complete|loaded)$/, da = typeof opera !== "undefined" && opera.toString() === "[object Opera]", K = {}, t = {}, U = [], n = null, X = 0, O = !1, d, r = {}, I, v, x, y, u, z, A, H, B, S, W;
|
|
||||||
if ( typeof define === "undefined" ) {
|
|
||||||
if ( typeof requirejs !==
|
|
||||||
"undefined" ) {
|
|
||||||
if ( J( requirejs ) ) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
r = requirejs, requirejs = void 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
typeof require !== "undefined" && !J( require ) && (r = require, require = void 0);
|
|
||||||
d = requirejs = function ( a, c, d ) {
|
|
||||||
var k = "_", j;
|
|
||||||
!E( a ) && typeof a !== "string" && (j = a, E( c ) ? (a = c, c = d) : a = []);
|
|
||||||
if ( j && j.context ) {
|
|
||||||
k = j.context;
|
|
||||||
}
|
|
||||||
d = t[k] || (t[k] = fa( k ));
|
|
||||||
j && d.configure( j );
|
|
||||||
return d.require( a, c )
|
|
||||||
};
|
|
||||||
d.config = function ( a ) {
|
|
||||||
return d( a )
|
|
||||||
};
|
|
||||||
require || (require = d);
|
|
||||||
d.toUrl = function ( a ) {
|
|
||||||
return t._.toUrl( a )
|
|
||||||
};
|
|
||||||
d.version = "1.0.2";
|
|
||||||
d.jsExtRegExp = /^\/|:|\?|\.js$/;
|
|
||||||
v = d.s = {contexts : t, skipAsync : {}};
|
|
||||||
if ( d.isAsync =
|
|
||||||
d.isBrowser = G ) {
|
|
||||||
if ( x = v.head = document.getElementsByTagName( "head" )[0], y = document.getElementsByTagName( "base" )[0] ) {
|
|
||||||
x = v.head = y.parentNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.onError = function ( a ) {
|
|
||||||
throw a;
|
|
||||||
};
|
|
||||||
d.load = function ( a, c, h ) {
|
|
||||||
d.resourcesReady( !1 );
|
|
||||||
a.scriptCount += 1;
|
|
||||||
d.attach( h, a, c );
|
|
||||||
if ( a.jQuery && !a.jQueryIncremented ) {
|
|
||||||
V( a.jQuery, !0 ), a.jQueryIncremented = !0
|
|
||||||
}
|
|
||||||
};
|
|
||||||
define = function ( a, c, d ) {
|
|
||||||
var k, j;
|
|
||||||
typeof a !== "string" && (d = c, c = a, a = null);
|
|
||||||
E( c ) || (d = c, c = []);
|
|
||||||
!c.length && J( d ) && d.length && (d.toString().replace( ja, "" ).replace( ka, function ( a, d ) {
|
|
||||||
c.push( d )
|
|
||||||
} ), c = (d.length ===
|
|
||||||
1 ? ["require"] : ["require", "exports", "module"]).concat( c ));
|
|
||||||
if ( O && (k = I || ia()) ) {
|
|
||||||
a || (a = k.getAttribute( "data-requiremodule" )), j = t[k.getAttribute( "data-requirecontext" )];
|
|
||||||
}
|
|
||||||
(j ? j.defQueue : U).push( [a, c, d] )
|
|
||||||
};
|
|
||||||
define.amd = {multiversion : !0, plugins : !0, jQuery : !0};
|
|
||||||
d.exec = function ( a ) {
|
|
||||||
return eval( a )
|
|
||||||
};
|
|
||||||
d.execCb = function ( a, c, d, k ) {
|
|
||||||
return c.apply( k, d )
|
|
||||||
};
|
|
||||||
d.addScriptToDom = function ( a ) {
|
|
||||||
I = a;
|
|
||||||
y ? x.insertBefore( a, y ) : x.appendChild( a );
|
|
||||||
I = null
|
|
||||||
};
|
|
||||||
d.onScriptLoad = function ( a ) {
|
|
||||||
var c = a.currentTarget || a.srcElement, h;
|
|
||||||
if ( a.type === "load" || c && la.test( c.readyState ) ) {
|
|
||||||
n =
|
|
||||||
null, a = c.getAttribute( "data-requirecontext" ), h = c.getAttribute( "data-requiremodule" ), t[a].completeLoad( h ), c.detachEvent && !da ? c.detachEvent( "onreadystatechange", d.onScriptLoad ) : c.removeEventListener( "load", d.onScriptLoad, !1 )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
d.attach = function ( a, c, h, k, j, n ) {
|
|
||||||
var o;
|
|
||||||
if ( G ) {
|
|
||||||
return k = k || d.onScriptLoad, o = c && c.config && c.config.xhtml ? document.createElementNS( "http://www.w3.org/1999/xhtml", "html:script" ) : document.createElement( "script" ), o.type = j || "text/javascript", o.charset = "utf-8", o.async = !v.skipAsync[a], c && o.setAttribute( "data-requirecontext",
|
|
||||||
c.contextName ), o.setAttribute( "data-requiremodule", h ), o.attachEvent && !da ? (O = !0, n ? o.onreadystatechange = function () {
|
|
||||||
if ( o.readyState === "loaded" ) {
|
|
||||||
o.onreadystatechange = null, o.attachEvent( "onreadystatechange", k ), n( o )
|
|
||||||
}
|
|
||||||
} : o.attachEvent( "onreadystatechange", k )) : o.addEventListener( "load", k, !1 ), o.src = a, n || d.addScriptToDom( o ), o;
|
|
||||||
} else {
|
|
||||||
ca && (importScripts( a ), c.completeLoad( h ));
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
};
|
|
||||||
if ( G ) {
|
|
||||||
u = document.getElementsByTagName( "script" );
|
|
||||||
for ( H = u.length - 1; H > -1 && (z = u[H]); H-- ) {
|
|
||||||
if ( !x ) {
|
|
||||||
x = z.parentNode;
|
|
||||||
}
|
|
||||||
if ( A = z.getAttribute( "data-main" ) ) {
|
|
||||||
if ( !r.baseUrl ) {
|
|
||||||
u =
|
|
||||||
A.split( "/" ), z = u.pop(), u = u.length ? u.join( "/" ) + "/" : "./", r.baseUrl = u, A = z.replace( aa, "" );
|
|
||||||
}
|
|
||||||
r.deps = r.deps ? r.deps.concat( A ) : [A];
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.checkReadyState = function () {
|
|
||||||
var a = v.contexts, c;
|
|
||||||
for ( c in a ) {
|
|
||||||
if ( !(c in K) && a[c].waitCount ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.resourcesReady( !0 )
|
|
||||||
};
|
|
||||||
d.resourcesReady = function ( a ) {
|
|
||||||
var c, h;
|
|
||||||
d.resourcesDone = a;
|
|
||||||
if ( d.resourcesDone ) {
|
|
||||||
for ( h in a = v.contexts, a ) {
|
|
||||||
if ( !(h in K) && (c = a[h], c.jQueryIncremented) ) {
|
|
||||||
V( c.jQuery, !1 ), c.jQueryIncremented = !1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
d.pageLoaded = function () {
|
|
||||||
if ( document.readyState !== "complete" ) {
|
|
||||||
document.readyState =
|
|
||||||
"complete"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if ( G && document.addEventListener && !document.readyState ) {
|
|
||||||
document.readyState = "loading", window.addEventListener( "load", d.pageLoaded, !1 );
|
|
||||||
}
|
|
||||||
d( r );
|
|
||||||
if ( d.isAsync && typeof setTimeout !== "undefined" ) {
|
|
||||||
B = v.contexts[r.context || "_"], B.requireWait = !0, setTimeout( function () {
|
|
||||||
B.requireWait = !1;
|
|
||||||
B.takeGlobalQueue();
|
|
||||||
B.jQueryCheck();
|
|
||||||
B.scriptCount || B.resume();
|
|
||||||
d.checkReadyState()
|
|
||||||
}, 0 )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
695
example/amd/js/libs/underscore/underscore-min.js
vendored
695
example/amd/js/libs/underscore/underscore-min.js
vendored
|
|
@ -1,695 +0,0 @@
|
||||||
// Underscore.js 1.2.2
|
|
||||||
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
|
||||||
// Underscore is freely distributable under the MIT license.
|
|
||||||
// Portions of Underscore are inspired or borrowed from Prototype,
|
|
||||||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
|
||||||
// For all details and documentation:
|
|
||||||
// http://documentcloud.github.com/underscore
|
|
||||||
(function () {
|
|
||||||
function r( a, c, d ) {
|
|
||||||
if ( a === c ) {
|
|
||||||
return a !== 0 || 1 / a == 1 / c;
|
|
||||||
}
|
|
||||||
if ( a == null || c == null ) {
|
|
||||||
return a === c;
|
|
||||||
}
|
|
||||||
if ( a._chain ) {
|
|
||||||
a = a._wrapped;
|
|
||||||
}
|
|
||||||
if ( c._chain ) {
|
|
||||||
c = c._wrapped;
|
|
||||||
}
|
|
||||||
if ( b.isFunction( a.isEqual ) ) {
|
|
||||||
return a.isEqual( c );
|
|
||||||
}
|
|
||||||
if ( b.isFunction( c.isEqual ) ) {
|
|
||||||
return c.isEqual( a );
|
|
||||||
}
|
|
||||||
var e = l.call( a );
|
|
||||||
if ( e != l.call( c ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
switch ( e ) {
|
|
||||||
case "[object String]":
|
|
||||||
return String( a ) == String( c );
|
|
||||||
case "[object Number]":
|
|
||||||
return a = +a, c = +c, a != a ? c != c : a == 0 ? 1 / a == 1 / c : a == c;
|
|
||||||
case "[object Date]":
|
|
||||||
case "[object Boolean]":
|
|
||||||
return+a == +c;
|
|
||||||
case "[object RegExp]":
|
|
||||||
return a.source ==
|
|
||||||
c.source && a.global == c.global && a.multiline == c.multiline && a.ignoreCase == c.ignoreCase
|
|
||||||
}
|
|
||||||
if ( typeof a != "object" || typeof c != "object" ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for ( var f = d.length; f--; ) {
|
|
||||||
if ( d[f] == a ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.push( a );
|
|
||||||
var f = 0, g = true;
|
|
||||||
if ( e == "[object Array]" ) {
|
|
||||||
if ( f = a.length, g = f == c.length ) {
|
|
||||||
for ( ; f--; ) {
|
|
||||||
if ( !(g = f in a == f in c && r( a[f], c[f], d )) ) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( "constructor"in a != "constructor"in c || a.constructor != c.constructor ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for ( var h in a ) {
|
|
||||||
if ( m.call( a, h ) && (f++, !(g = m.call( c, h ) && r( a[h], c[h], d ))) ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( g ) {
|
|
||||||
for ( h in c ) {
|
|
||||||
if ( m.call( c,
|
|
||||||
h ) && !f-- ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g = !f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.pop();
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
|
|
||||||
var s = this, F = s._, o = {}, k = Array.prototype, p = Object.prototype, i = k.slice, G = k.unshift, l = p.toString, m = p.hasOwnProperty, v = k.forEach, w = k.map, x = k.reduce, y = k.reduceRight, z = k.filter, A = k.every, B = k.some, q = k.indexOf, C = k.lastIndexOf, p = Array.isArray, H = Object.keys, t = Function.prototype.bind, b = function ( a ) {
|
|
||||||
return new n( a )
|
|
||||||
};
|
|
||||||
if ( typeof exports !== "undefined" ) {
|
|
||||||
if ( typeof module !== "undefined" && module.exports ) {
|
|
||||||
exports = module.exports = b;
|
|
||||||
}
|
|
||||||
exports._ = b
|
|
||||||
} else {
|
|
||||||
typeof define === "function" && define.amd ?
|
|
||||||
define( "underscore", function () {
|
|
||||||
return b
|
|
||||||
} ) : s._ = b;
|
|
||||||
}
|
|
||||||
b.VERSION = "1.2.2";
|
|
||||||
var j = b.each = b.forEach = function ( a, c, b ) {
|
|
||||||
if ( a != null ) {
|
|
||||||
if ( v && a.forEach === v ) {
|
|
||||||
a.forEach( c, b );
|
|
||||||
} else if ( a.length === +a.length ) {
|
|
||||||
for ( var e = 0, f = a.length; e < f; e++ ) {
|
|
||||||
if ( e in a && c.call( b, a[e], e, a ) === o ) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for ( e in a ) {
|
|
||||||
if ( m.call( a, e ) && c.call( b, a[e], e, a ) === o ) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.map = function ( a, c, b ) {
|
|
||||||
var e = [];
|
|
||||||
if ( a == null ) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
if ( w && a.map === w ) {
|
|
||||||
return a.map( c, b );
|
|
||||||
}
|
|
||||||
j( a, function ( a, g, h ) {
|
|
||||||
e[e.length] = c.call( b, a, g, h )
|
|
||||||
} );
|
|
||||||
return e
|
|
||||||
};
|
|
||||||
b.reduce = b.foldl = b.inject = function ( a, c, d, e ) {
|
|
||||||
var f =
|
|
||||||
d !== void 0;
|
|
||||||
a == null && (a = []);
|
|
||||||
if ( x && a.reduce === x ) {
|
|
||||||
return e && (c = b.bind( c, e )), f ? a.reduce( c, d ) : a.reduce( c );
|
|
||||||
}
|
|
||||||
j( a, function ( a, b, i ) {
|
|
||||||
f ? d = c.call( e, d, a, b, i ) : (d = a, f = true)
|
|
||||||
} );
|
|
||||||
if ( !f ) {
|
|
||||||
throw new TypeError( "Reduce of empty array with no initial value" );
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
};
|
|
||||||
b.reduceRight = b.foldr = function ( a, c, d, e ) {
|
|
||||||
a == null && (a = []);
|
|
||||||
if ( y && a.reduceRight === y ) {
|
|
||||||
return e && (c = b.bind( c, e )), d !== void 0 ? a.reduceRight( c, d ) : a.reduceRight( c );
|
|
||||||
}
|
|
||||||
a = (b.isArray( a ) ? a.slice() : b.toArray( a )).reverse();
|
|
||||||
return b.reduce( a, c, d, e )
|
|
||||||
};
|
|
||||||
b.find = b.detect = function ( a, c, b ) {
|
|
||||||
var e;
|
|
||||||
D( a, function ( a, g, h ) {
|
|
||||||
if ( c.call( b, a, g, h ) ) {
|
|
||||||
return e = a, true
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return e
|
|
||||||
};
|
|
||||||
b.filter = b.select = function ( a, c, b ) {
|
|
||||||
var e = [];
|
|
||||||
if ( a == null ) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
if ( z && a.filter === z ) {
|
|
||||||
return a.filter( c, b );
|
|
||||||
}
|
|
||||||
j( a, function ( a, g, h ) {
|
|
||||||
c.call( b, a, g, h ) && (e[e.length] = a)
|
|
||||||
} );
|
|
||||||
return e
|
|
||||||
};
|
|
||||||
b.reject = function ( a, c, b ) {
|
|
||||||
var e = [];
|
|
||||||
if ( a == null ) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
j( a, function ( a, g, h ) {
|
|
||||||
c.call( b, a, g, h ) || (e[e.length] = a)
|
|
||||||
} );
|
|
||||||
return e
|
|
||||||
};
|
|
||||||
b.every = b.all = function ( a, c, b ) {
|
|
||||||
var e = true;
|
|
||||||
if ( a == null ) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
if ( A && a.every === A ) {
|
|
||||||
return a.every( c, b );
|
|
||||||
}
|
|
||||||
j( a, function ( a, g, h ) {
|
|
||||||
if ( !(e = e && c.call( b, a, g, h )) ) {
|
|
||||||
return o
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return e
|
|
||||||
};
|
|
||||||
var D = b.some = b.any = function ( a, c, d ) {
|
|
||||||
var c = c || b.identity, e = false;
|
|
||||||
if ( a == null ) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
if ( B && a.some === B ) {
|
|
||||||
return a.some( c, d );
|
|
||||||
}
|
|
||||||
j( a, function ( a, b, h ) {
|
|
||||||
if ( e || (e = c.call( d, a, b, h )) ) {
|
|
||||||
return o
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return!!e
|
|
||||||
};
|
|
||||||
b.include = b.contains = function ( a, c ) {
|
|
||||||
var b = false;
|
|
||||||
if ( a == null ) {
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
return q && a.indexOf === q ? a.indexOf( c ) != -1 : b = D( a, function ( a ) {
|
|
||||||
return a === c
|
|
||||||
} )
|
|
||||||
};
|
|
||||||
b.invoke = function ( a, c ) {
|
|
||||||
var d = i.call( arguments, 2 );
|
|
||||||
return b.map( a, function ( a ) {
|
|
||||||
return(c.call ? c || a : a[c]).apply( a, d )
|
|
||||||
} )
|
|
||||||
};
|
|
||||||
b.pluck = function ( a, c ) {
|
|
||||||
return b.map( a, function ( a ) {
|
|
||||||
return a[c]
|
|
||||||
} )
|
|
||||||
};
|
|
||||||
b.max = function ( a, c, d ) {
|
|
||||||
if ( !c && b.isArray( a ) ) {
|
|
||||||
return Math.max.apply( Math, a );
|
|
||||||
}
|
|
||||||
if ( !c && b.isEmpty( a ) ) {
|
|
||||||
return-Infinity;
|
|
||||||
}
|
|
||||||
var e = {computed : -Infinity};
|
|
||||||
j( a, function ( a, b, h ) {
|
|
||||||
b = c ? c.call( d, a, b, h ) : a;
|
|
||||||
b >= e.computed && (e = {value : a, computed : b})
|
|
||||||
} );
|
|
||||||
return e.value
|
|
||||||
};
|
|
||||||
b.min = function ( a, c, d ) {
|
|
||||||
if ( !c && b.isArray( a ) ) {
|
|
||||||
return Math.min.apply( Math, a );
|
|
||||||
}
|
|
||||||
if ( !c && b.isEmpty( a ) ) {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
var e = {computed : Infinity};
|
|
||||||
j( a, function ( a, b, h ) {
|
|
||||||
b = c ? c.call( d, a, b, h ) : a;
|
|
||||||
b < e.computed && (e = {value : a, computed : b})
|
|
||||||
} );
|
|
||||||
return e.value
|
|
||||||
};
|
|
||||||
b.shuffle = function ( a ) {
|
|
||||||
var c = [], b;
|
|
||||||
j( a, function ( a, f ) {
|
|
||||||
f == 0 ? c[0] = a : (b = Math.floor( Math.random() * (f + 1) ), c[f] = c[b], c[b] = a)
|
|
||||||
} );
|
|
||||||
return c
|
|
||||||
};
|
|
||||||
b.sortBy = function ( a, c, d ) {
|
|
||||||
return b.pluck( b.map( a,
|
|
||||||
function ( a, b, g ) {
|
|
||||||
return{value : a, criteria : c.call( d, a, b, g )}
|
|
||||||
} ).sort( function ( a, c ) {
|
|
||||||
var b = a.criteria, d = c.criteria;
|
|
||||||
return b < d ? -1 : b > d ? 1 : 0
|
|
||||||
} ), "value" )
|
|
||||||
};
|
|
||||||
b.groupBy = function ( a, c ) {
|
|
||||||
var d = {}, e = b.isFunction( c ) ? c : function ( a ) {
|
|
||||||
return a[c]
|
|
||||||
};
|
|
||||||
j( a, function ( a, c ) {
|
|
||||||
var b = e( a, c );
|
|
||||||
(d[b] || (d[b] = [])).push( a )
|
|
||||||
} );
|
|
||||||
return d
|
|
||||||
};
|
|
||||||
b.sortedIndex = function ( a, c, d ) {
|
|
||||||
d || (d = b.identity);
|
|
||||||
for ( var e = 0, f = a.length; e <
|
|
||||||
f; ) {
|
|
||||||
var g = e + f >> 1;
|
|
||||||
d( a[g] ) < d( c ) ? e = g + 1 : f = g
|
|
||||||
}
|
|
||||||
return e
|
|
||||||
};
|
|
||||||
b.toArray = function ( a ) {
|
|
||||||
return!a ? [] : a.toArray ? a.toArray() : b.isArray( a ) ? i.call( a ) : b.isArguments( a ) ? i.call( a ) : b.values( a )
|
|
||||||
};
|
|
||||||
b.size = function ( a ) {
|
|
||||||
return b.toArray( a ).length
|
|
||||||
};
|
|
||||||
b.first = b.head = function ( a, b, d ) {
|
|
||||||
return b != null && !d ? i.call( a, 0, b ) : a[0]
|
|
||||||
};
|
|
||||||
b.initial = function ( a, b, d ) {
|
|
||||||
return i.call( a, 0, a.length - (b == null || d ? 1 : b) )
|
|
||||||
};
|
|
||||||
b.last = function ( a, b, d ) {
|
|
||||||
return b != null && !d ? i.call( a, Math.max( a.length - b, 0 ) ) : a[a.length - 1]
|
|
||||||
};
|
|
||||||
b.rest = b.tail = function ( a, b, d ) {
|
|
||||||
return i.call( a, b == null ||
|
|
||||||
d ? 1 : b )
|
|
||||||
};
|
|
||||||
b.compact = function ( a ) {
|
|
||||||
return b.filter( a, function ( a ) {
|
|
||||||
return!!a
|
|
||||||
} )
|
|
||||||
};
|
|
||||||
b.flatten = function ( a, c ) {
|
|
||||||
return b.reduce( a, function ( a, e ) {
|
|
||||||
if ( b.isArray( e ) ) {
|
|
||||||
return a.concat( c ? e : b.flatten( e ) );
|
|
||||||
}
|
|
||||||
a[a.length] = e;
|
|
||||||
return a
|
|
||||||
}, [] )
|
|
||||||
};
|
|
||||||
b.without = function ( a ) {
|
|
||||||
return b.difference( a, i.call( arguments, 1 ) )
|
|
||||||
};
|
|
||||||
b.uniq = b.unique = function ( a, c, d ) {
|
|
||||||
var d = d ? b.map( a, d ) : a, e = [];
|
|
||||||
b.reduce( d, function ( d, g, h ) {
|
|
||||||
if ( 0 == h || (c === true ? b.last( d ) != g : !b.include( d, g )) ) {
|
|
||||||
d[d.length] = g, e[e.length] = a[h];
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}, [] );
|
|
||||||
return e
|
|
||||||
};
|
|
||||||
b.union = function () {
|
|
||||||
return b.uniq( b.flatten( arguments,
|
|
||||||
true ) )
|
|
||||||
};
|
|
||||||
b.intersection = b.intersect = function ( a ) {
|
|
||||||
var c = i.call( arguments, 1 );
|
|
||||||
return b.filter( b.uniq( a ), function ( a ) {
|
|
||||||
return b.every( c, function ( c ) {
|
|
||||||
return b.indexOf( c, a ) >= 0
|
|
||||||
} )
|
|
||||||
} )
|
|
||||||
};
|
|
||||||
b.difference = function ( a, c ) {
|
|
||||||
return b.filter( a, function ( a ) {
|
|
||||||
return!b.include( c, a )
|
|
||||||
} )
|
|
||||||
};
|
|
||||||
b.zip = function () {
|
|
||||||
for ( var a = i.call( arguments ), c = b.max( b.pluck( a, "length" ) ), d = Array( c ), e = 0; e < c; e++ ) {
|
|
||||||
d[e] = b.pluck( a, "" + e );
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
};
|
|
||||||
b.indexOf = function ( a, c, d ) {
|
|
||||||
if ( a == null ) {
|
|
||||||
return-1;
|
|
||||||
}
|
|
||||||
var e;
|
|
||||||
if ( d ) {
|
|
||||||
return d = b.sortedIndex( a, c ), a[d] === c ? d : -1;
|
|
||||||
}
|
|
||||||
if ( q && a.indexOf === q ) {
|
|
||||||
return a.indexOf( c );
|
|
||||||
}
|
|
||||||
for ( d = 0, e = a.length; d < e; d++ ) {
|
|
||||||
if ( a[d] === c ) {
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return-1
|
|
||||||
};
|
|
||||||
b.lastIndexOf = function ( a, b ) {
|
|
||||||
if ( a == null ) {
|
|
||||||
return-1;
|
|
||||||
}
|
|
||||||
if ( C && a.lastIndexOf === C ) {
|
|
||||||
return a.lastIndexOf( b );
|
|
||||||
}
|
|
||||||
for ( var d = a.length; d--; ) {
|
|
||||||
if ( a[d] === b ) {
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return-1
|
|
||||||
};
|
|
||||||
b.range = function ( a, b, d ) {
|
|
||||||
arguments.length <= 1 && (b = a || 0, a = 0);
|
|
||||||
for ( var d = arguments[2] || 1, e = Math.max( Math.ceil( (b - a) / d ), 0 ), f = 0, g = Array( e ); f < e; ) {
|
|
||||||
g[f++] = a, a += d;
|
|
||||||
}
|
|
||||||
return g
|
|
||||||
};
|
|
||||||
var E = function () {
|
|
||||||
};
|
|
||||||
b.bind = function ( a, c ) {
|
|
||||||
var d, e;
|
|
||||||
if ( a.bind === t && t ) {
|
|
||||||
return t.apply( a, i.call( arguments, 1 ) );
|
|
||||||
}
|
|
||||||
if ( !b.isFunction( a ) ) {
|
|
||||||
throw new TypeError;
|
|
||||||
}
|
|
||||||
e = i.call( arguments, 2 );
|
|
||||||
return d = function () {
|
|
||||||
if ( !(this instanceof d) ) {
|
|
||||||
return a.apply( c, e.concat( i.call( arguments ) ) );
|
|
||||||
}
|
|
||||||
E.prototype = a.prototype;
|
|
||||||
var b = new E, g = a.apply( b, e.concat( i.call( arguments ) ) );
|
|
||||||
return Object( g ) === g ? g : b
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.bindAll = function ( a ) {
|
|
||||||
var c = i.call( arguments, 1 );
|
|
||||||
c.length == 0 && (c = b.functions( a ));
|
|
||||||
j( c, function ( c ) {
|
|
||||||
a[c] = b.bind( a[c], a )
|
|
||||||
} );
|
|
||||||
return a
|
|
||||||
};
|
|
||||||
b.memoize = function ( a, c ) {
|
|
||||||
var d = {};
|
|
||||||
c || (c = b.identity);
|
|
||||||
return function () {
|
|
||||||
var b = c.apply( this, arguments );
|
|
||||||
return m.call( d, b ) ? d[b] : d[b] = a.apply( this, arguments )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.delay =
|
|
||||||
function ( a, b ) {
|
|
||||||
var d = i.call( arguments, 2 );
|
|
||||||
return setTimeout( function () {
|
|
||||||
return a.apply( a, d )
|
|
||||||
}, b )
|
|
||||||
};
|
|
||||||
b.defer = function ( a ) {
|
|
||||||
return b.delay.apply( b, [a, 1].concat( i.call( arguments, 1 ) ) )
|
|
||||||
};
|
|
||||||
b.throttle = function ( a, c ) {
|
|
||||||
var d, e, f, g, h, i = b.debounce( function () {
|
|
||||||
h = g = false
|
|
||||||
}, c );
|
|
||||||
return function () {
|
|
||||||
d = this;
|
|
||||||
e = arguments;
|
|
||||||
var b;
|
|
||||||
f || (f = setTimeout( function () {
|
|
||||||
f = null;
|
|
||||||
h && a.apply( d, e );
|
|
||||||
i()
|
|
||||||
}, c ));
|
|
||||||
g ? h = true : a.apply( d, e );
|
|
||||||
i();
|
|
||||||
g = true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.debounce = function ( a, b ) {
|
|
||||||
var d;
|
|
||||||
return function () {
|
|
||||||
var e = this, f = arguments;
|
|
||||||
clearTimeout( d );
|
|
||||||
d = setTimeout( function () {
|
|
||||||
d =
|
|
||||||
null;
|
|
||||||
a.apply( e, f )
|
|
||||||
}, b )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.once = function ( a ) {
|
|
||||||
var b = false, d;
|
|
||||||
return function () {
|
|
||||||
if ( b ) {
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
b = true;
|
|
||||||
return d = a.apply( this, arguments )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.wrap = function ( a, b ) {
|
|
||||||
return function () {
|
|
||||||
var d = [a].concat( i.call( arguments ) );
|
|
||||||
return b.apply( this, d )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.compose = function () {
|
|
||||||
var a = i.call( arguments );
|
|
||||||
return function () {
|
|
||||||
for ( var b = i.call( arguments ), d = a.length - 1; d >= 0; d-- ) {
|
|
||||||
b = [a[d].apply( this, b )];
|
|
||||||
}
|
|
||||||
return b[0]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.after = function ( a, b ) {
|
|
||||||
return a <= 0 ? b() : function () {
|
|
||||||
if ( --a < 1 ) {
|
|
||||||
return b.apply( this, arguments )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.keys = H || function ( a ) {
|
|
||||||
if ( a !==
|
|
||||||
Object( a ) ) {
|
|
||||||
throw new TypeError( "Invalid object" );
|
|
||||||
}
|
|
||||||
var b = [], d;
|
|
||||||
for ( d in a ) {
|
|
||||||
m.call( a, d ) && (b[b.length] = d);
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
};
|
|
||||||
b.values = function ( a ) {
|
|
||||||
return b.map( a, b.identity )
|
|
||||||
};
|
|
||||||
b.functions = b.methods = function ( a ) {
|
|
||||||
var c = [], d;
|
|
||||||
for ( d in a ) {
|
|
||||||
b.isFunction( a[d] ) && c.push( d );
|
|
||||||
}
|
|
||||||
return c.sort()
|
|
||||||
};
|
|
||||||
b.extend = function ( a ) {
|
|
||||||
j( i.call( arguments, 1 ), function ( b ) {
|
|
||||||
for ( var d in b ) {
|
|
||||||
b[d] !== void 0 && (a[d] = b[d])
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return a
|
|
||||||
};
|
|
||||||
b.defaults = function ( a ) {
|
|
||||||
j( i.call( arguments, 1 ), function ( b ) {
|
|
||||||
for ( var d in b ) {
|
|
||||||
a[d] == null && (a[d] = b[d])
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return a
|
|
||||||
};
|
|
||||||
b.clone = function ( a ) {
|
|
||||||
return!b.isObject( a ) ?
|
|
||||||
a : b.isArray( a ) ? a.slice() : b.extend( {}, a )
|
|
||||||
};
|
|
||||||
b.tap = function ( a, b ) {
|
|
||||||
b( a );
|
|
||||||
return a
|
|
||||||
};
|
|
||||||
b.isEqual = function ( a, b ) {
|
|
||||||
return r( a, b, [] )
|
|
||||||
};
|
|
||||||
b.isEmpty = function ( a ) {
|
|
||||||
if ( b.isArray( a ) || b.isString( a ) ) {
|
|
||||||
return a.length === 0;
|
|
||||||
}
|
|
||||||
for ( var c in a ) {
|
|
||||||
if ( m.call( a, c ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
};
|
|
||||||
b.isElement = function ( a ) {
|
|
||||||
return!!(a && a.nodeType == 1)
|
|
||||||
};
|
|
||||||
b.isArray = p || function ( a ) {
|
|
||||||
return l.call( a ) == "[object Array]"
|
|
||||||
};
|
|
||||||
b.isObject = function ( a ) {
|
|
||||||
return a === Object( a )
|
|
||||||
};
|
|
||||||
b.isArguments = l.call( arguments ) == "[object Arguments]" ? function ( a ) {
|
|
||||||
return l.call( a ) == "[object Arguments]"
|
|
||||||
} :
|
|
||||||
function ( a ) {
|
|
||||||
return!(!a || !m.call( a, "callee" ))
|
|
||||||
};
|
|
||||||
b.isFunction = function ( a ) {
|
|
||||||
return l.call( a ) == "[object Function]"
|
|
||||||
};
|
|
||||||
b.isString = function ( a ) {
|
|
||||||
return l.call( a ) == "[object String]"
|
|
||||||
};
|
|
||||||
b.isNumber = function ( a ) {
|
|
||||||
return l.call( a ) == "[object Number]"
|
|
||||||
};
|
|
||||||
b.isNaN = function ( a ) {
|
|
||||||
return a !== a
|
|
||||||
};
|
|
||||||
b.isBoolean = function ( a ) {
|
|
||||||
return a === true || a === false || l.call( a ) == "[object Boolean]"
|
|
||||||
};
|
|
||||||
b.isDate = function ( a ) {
|
|
||||||
return l.call( a ) == "[object Date]"
|
|
||||||
};
|
|
||||||
b.isRegExp = function ( a ) {
|
|
||||||
return l.call( a ) == "[object RegExp]"
|
|
||||||
};
|
|
||||||
b.isNull = function ( a ) {
|
|
||||||
return a === null
|
|
||||||
};
|
|
||||||
b.isUndefined = function ( a ) {
|
|
||||||
return a === void 0
|
|
||||||
};
|
|
||||||
b.noConflict = function () {
|
|
||||||
s._ = F;
|
|
||||||
return this
|
|
||||||
};
|
|
||||||
b.identity = function ( a ) {
|
|
||||||
return a
|
|
||||||
};
|
|
||||||
b.times = function ( a, b, d ) {
|
|
||||||
for ( var e = 0; e < a; e++ ) {
|
|
||||||
b.call( d, e )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.escape = function ( a ) {
|
|
||||||
return("" + a).replace( /&/g, "&" ).replace( /</g, "<" ).replace( />/g, ">" ).replace( /"/g, """ ).replace( /'/g, "'" ).replace( /\//g, "/" )
|
|
||||||
};
|
|
||||||
b.mixin = function ( a ) {
|
|
||||||
j( b.functions( a ), function ( c ) {
|
|
||||||
I( c, b[c] = a[c] )
|
|
||||||
} )
|
|
||||||
};
|
|
||||||
var J = 0;
|
|
||||||
b.uniqueId = function ( a ) {
|
|
||||||
var b = J++;
|
|
||||||
return a ? a + b : b
|
|
||||||
};
|
|
||||||
b.templateSettings = {evaluate : /<%([\s\S]+?)%>/g,
|
|
||||||
interpolate : /<%=([\s\S]+?)%>/g, escape : /<%-([\s\S]+?)%>/g};
|
|
||||||
b.template = function ( a, c ) {
|
|
||||||
var d = b.templateSettings, d = "var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('" + a.replace( /\\/g, "\\\\" ).replace( /'/g, "\\'" ).replace( d.escape,
|
|
||||||
function ( a, b ) {
|
|
||||||
return"',_.escape(" + b.replace( /\\'/g, "'" ) + "),'"
|
|
||||||
} ).replace( d.interpolate,
|
|
||||||
function ( a, b ) {
|
|
||||||
return"'," + b.replace( /\\'/g, "'" ) + ",'"
|
|
||||||
} ).replace( d.evaluate || null,
|
|
||||||
function ( a, b ) {
|
|
||||||
return"');" + b.replace( /\\'/g, "'" ).replace( /[\r\n\t]/g, " " ) + ";__p.push('"
|
|
||||||
} ).replace( /\r/g,
|
|
||||||
"\\r" ).replace( /\n/g, "\\n" ).replace( /\t/g, "\\t" ) + "');}return __p.join('');", e = new Function( "obj", "_", d );
|
|
||||||
return c ? e( c, b ) : function ( a ) {
|
|
||||||
return e( a, b )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var n = function ( a ) {
|
|
||||||
this._wrapped = a
|
|
||||||
};
|
|
||||||
b.prototype = n.prototype;
|
|
||||||
var u = function ( a, c ) {
|
|
||||||
return c ? b( a ).chain() : a
|
|
||||||
}, I = function ( a, c ) {
|
|
||||||
n.prototype[a] = function () {
|
|
||||||
var a = i.call( arguments );
|
|
||||||
G.call( a, this._wrapped );
|
|
||||||
return u( c.apply( b, a ), this._chain )
|
|
||||||
}
|
|
||||||
};
|
|
||||||
b.mixin( b );
|
|
||||||
j( "pop,push,reverse,shift,sort,splice,unshift".split( "," ), function ( a ) {
|
|
||||||
var b = k[a];
|
|
||||||
n.prototype[a] = function () {
|
|
||||||
b.apply( this._wrapped,
|
|
||||||
arguments );
|
|
||||||
return u( this._wrapped, this._chain )
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
j( ["concat", "join", "slice"], function ( a ) {
|
|
||||||
var b = k[a];
|
|
||||||
n.prototype[a] = function () {
|
|
||||||
return u( b.apply( this._wrapped, arguments ), this._chain )
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
n.prototype.chain = function () {
|
|
||||||
this._chain = true;
|
|
||||||
return this
|
|
||||||
};
|
|
||||||
n.prototype.value = function () {
|
|
||||||
return this._wrapped
|
|
||||||
}
|
|
||||||
}).call( this );
|
|
||||||
|
|
@ -1,10 +1,15 @@
|
||||||
require.config( {
|
require.config( {
|
||||||
paths : {
|
paths : {
|
||||||
underscore : "libs/underscore/underscore-min",
|
underscore : "../../../bower/underscore/underscore-min",
|
||||||
postal : "libs/postal/postal",
|
postal : "../../../lib/postal",
|
||||||
postaldiags : "libs/postal/postal.diagnostics",
|
postaldiags : "../../../bower/postal.diagnostics/lib/postal.diagnostics",
|
||||||
jquery : "libs/jquery/jquery-min"
|
jquery : "../../../bower/jquery/jquery.min"
|
||||||
}
|
},
|
||||||
|
shim : {
|
||||||
|
underscore: {
|
||||||
|
exports: "_"
|
||||||
|
}
|
||||||
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
require( [ "jquery" ], function ( $ ) {
|
require( [ "jquery" ], function ( $ ) {
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Postal Examples (Standard Lib Format)</title>
|
<title>Postal Examples (Standard Lib Format)</title>
|
||||||
<link rel="stylesheet" type="text/css" href="style.css">
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
<script type="text/javascript" src="js/underscore.js"></script>
|
<script type="text/javascript" src="../../bower/underscore/underscore-min.js"></script>
|
||||||
<script type="text/javascript" src="js/jquery-1.7.1.js"></script>
|
<script type="text/javascript" src="../../bower/jquery/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="js/postal.js"></script>
|
<script type="text/javascript" src="../../lib/postal.js"></script>
|
||||||
<script type="text/javascript" src="js/postal.diagnostics.js"></script>
|
<script type="text/javascript" src="../../bower/postal.diagnostics/lib/postal.diagnostics.js"></script>
|
||||||
<script type="text/javascript" src="js/main.js"></script>
|
<script type="text/javascript" src="js/main.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
9262
example/standard/js/jquery-1.7.1.js
vendored
9262
example/standard/js/jquery-1.7.1.js
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -1,89 +0,0 @@
|
||||||
// This is the standard lib version of postal.diagnostics.js
|
|
||||||
// If you need the amd-module style version, go to http://github.com/ifandelse/postal.js
|
|
||||||
(function ( postal, _, undefined ) {
|
|
||||||
|
|
||||||
var filters = [],
|
|
||||||
applyFilter = function ( filter, env ) {
|
|
||||||
var match = 0, possible = 0;
|
|
||||||
_.each( filter, function ( item, key ) {
|
|
||||||
if ( env[key] ) {
|
|
||||||
possible++;
|
|
||||||
if ( _.isRegExp( item ) && item.test( env[key] ) ) {
|
|
||||||
match++;
|
|
||||||
}
|
|
||||||
else if ( _.isObject( env[key] ) && !_.isArray( env[key] ) ) {
|
|
||||||
if ( applyFilter( item, env[key] ) ) {
|
|
||||||
match++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( _.isEqual( env[key], item ) ) {
|
|
||||||
match++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return match === possible;
|
|
||||||
};
|
|
||||||
|
|
||||||
// this returns a callback that, if invoked, removes the wireTap
|
|
||||||
var wireTap = postal.addWireTap( function ( data, envelope ) {
|
|
||||||
if ( !filters.length || _.any( filters, function ( filter ) {
|
|
||||||
return applyFilter( filter, envelope );
|
|
||||||
} ) ) {
|
|
||||||
if ( !JSON ) {
|
|
||||||
throw "This browser or environment does not provide JSON support";
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
console.log( JSON.stringify( envelope ) );
|
|
||||||
}
|
|
||||||
catch ( exception ) {
|
|
||||||
try {
|
|
||||||
var env = _.extend( {}, envelope );
|
|
||||||
delete env.data;
|
|
||||||
console.log( JSON.stringify( env ) + "\n\t" + "JSON.stringify Error: " + exception.message );
|
|
||||||
}
|
|
||||||
catch ( ex ) {
|
|
||||||
console.log( "Unable to parse data to JSON: " + exception );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
postal.diagnostics = postal.diagnostics || {};
|
|
||||||
|
|
||||||
postal.diagnostics.console = {
|
|
||||||
clearFilters : function () {
|
|
||||||
filters = [];
|
|
||||||
},
|
|
||||||
removeFilter : function ( filter ) {
|
|
||||||
filters = _.filter( filters, function ( item ) {
|
|
||||||
return !_.isEqual( item, filter );
|
|
||||||
} );
|
|
||||||
},
|
|
||||||
addFilter : function ( constraint ) {
|
|
||||||
if ( !_.isArray( constraint ) ) {
|
|
||||||
constraint = [ constraint ];
|
|
||||||
}
|
|
||||||
_.each( constraint, function ( item ) {
|
|
||||||
if ( filters.length === 0 || !_.any( filters, function ( filter ) {
|
|
||||||
return _.isEqual( filter, item );
|
|
||||||
} ) ) {
|
|
||||||
filters.push( item );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
},
|
|
||||||
getCurrentFilters : function () {
|
|
||||||
return filters;
|
|
||||||
},
|
|
||||||
removeWireTap : function () {
|
|
||||||
if ( wireTap ) {
|
|
||||||
wireTap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})( postal, _ );
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
(function(a,b,c){var d=[],e=function(a,c){var d=0,f=0;return b.each(a,function(a,g){c[g]&&(f++,b.isRegExp(a)&&a.test(c[g])?d++:b.isObject(c[g])&&!b.isArray(c[g])?e(a,c[g])&&d++:b.isEqual(c[g],a)&&d++)}),d===f},f=a.addWireTap(function(a,c){if(!d.length||b.any(d,function(a){return e(a,c)})){if(!JSON)throw"This browser or environment does not provide JSON support";try{console.log(JSON.stringify(c))}catch(f){try{var g=b.extend({},c);delete g.data,console.log(JSON.stringify(g)+"\n "+"JSON.stringify Error: "+f.message)}catch(h){console.log("Unable to parse data to JSON: "+f)}}}});a.diagnostics=a.diagnostics||{},a.diagnostics.console={clearFilters:function(){d=[]},removeFilter:function(a){d=b.filter(d,function(c){return!b.isEqual(c,a)})},addFilter:function(a){b.isArray(a)||(a=[a]),b.each(a,function(a){(d.length===0||!b.any(d,function(c){return b.isEqual(c,a)}))&&d.push(a)})},getCurrentFilters:function(){return d},removeWireTap:function(){f&&f()}}})(postal,_)
|
|
||||||
|
|
@ -1,457 +0,0 @@
|
||||||
/**
|
|
||||||
* postal - Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.
|
|
||||||
* Author: Jim Cowart (http://freshbrewedcode.com/jimcowart)
|
|
||||||
* Version: v0.8.11
|
|
||||||
* Url: http://github.com/postaljs/postal.js
|
|
||||||
* License(s): MIT, GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function (root, factory) {
|
|
||||||
if (typeof module === "object" && module.exports) {
|
|
||||||
// Node, or CommonJS-Like environments
|
|
||||||
module.exports = function (_) {
|
|
||||||
_ = _ || require("underscore");
|
|
||||||
return factory(_);
|
|
||||||
};
|
|
||||||
} else if (typeof define === "function" && define.amd) {
|
|
||||||
// AMD. Register as an anonymous module.
|
|
||||||
define(["underscore"], function (_) {
|
|
||||||
return factory(_, root);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Browser globals
|
|
||||||
root.postal = factory(root._, root);
|
|
||||||
}
|
|
||||||
}(this, function (_, global, undefined) {
|
|
||||||
|
|
||||||
var postal;
|
|
||||||
|
|
||||||
|
|
||||||
var ConsecutiveDistinctPredicate = function () {
|
|
||||||
var previous;
|
|
||||||
return function (data) {
|
|
||||||
var eq = false;
|
|
||||||
if (_.isString(data)) {
|
|
||||||
eq = data === previous;
|
|
||||||
previous = data;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eq = _.isEqual(data, previous);
|
|
||||||
previous = _.clone(data);
|
|
||||||
}
|
|
||||||
return !eq;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var DistinctPredicate = function () {
|
|
||||||
var previous = [];
|
|
||||||
|
|
||||||
return function (data) {
|
|
||||||
var isDistinct = !_.any(previous, function (p) {
|
|
||||||
if (_.isObject(data) || _.isArray(data)) {
|
|
||||||
return _.isEqual(data, p);
|
|
||||||
}
|
|
||||||
return data === p;
|
|
||||||
});
|
|
||||||
if (isDistinct) {
|
|
||||||
previous.push(data);
|
|
||||||
}
|
|
||||||
return isDistinct;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var ChannelDefinition = function (channelName) {
|
|
||||||
this.channel = channelName || postal.configuration.DEFAULT_CHANNEL;
|
|
||||||
};
|
|
||||||
|
|
||||||
ChannelDefinition.prototype.subscribe = function () {
|
|
||||||
return arguments.length === 1 ? new SubscriptionDefinition(this.channel, arguments[0].topic, arguments[0].callback) : new SubscriptionDefinition(this.channel, arguments[0], arguments[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
ChannelDefinition.prototype.publish = function () {
|
|
||||||
var envelope = arguments.length === 1 ? (Object.prototype.toString.call(arguments[0]) === "[object String]" ? {
|
|
||||||
topic: arguments[0]
|
|
||||||
} : arguments[0]) : {
|
|
||||||
topic: arguments[0],
|
|
||||||
data: arguments[1]
|
|
||||||
};
|
|
||||||
envelope.channel = this.channel;
|
|
||||||
return postal.configuration.bus.publish(envelope);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var SubscriptionDefinition = function (channel, topic, callback) {
|
|
||||||
if (arguments.length !== 3) {
|
|
||||||
throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");
|
|
||||||
}
|
|
||||||
if (topic.length === 0) {
|
|
||||||
throw new Error("Topics cannot be empty");
|
|
||||||
}
|
|
||||||
this.channel = channel;
|
|
||||||
this.topic = topic;
|
|
||||||
this.callback = callback;
|
|
||||||
this.constraints = [];
|
|
||||||
this.context = null;
|
|
||||||
postal.configuration.bus.publish({
|
|
||||||
channel: postal.configuration.SYSTEM_CHANNEL,
|
|
||||||
topic: "subscription.created",
|
|
||||||
data: {
|
|
||||||
event: "subscription.created",
|
|
||||||
channel: channel,
|
|
||||||
topic: topic
|
|
||||||
}
|
|
||||||
});
|
|
||||||
postal.configuration.bus.subscribe(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
SubscriptionDefinition.prototype = {
|
|
||||||
unsubscribe: function () {
|
|
||||||
if (!this.inactive) {
|
|
||||||
this.inactive = true;
|
|
||||||
postal.configuration.bus.unsubscribe(this);
|
|
||||||
postal.configuration.bus.publish({
|
|
||||||
channel: postal.configuration.SYSTEM_CHANNEL,
|
|
||||||
topic: "subscription.removed",
|
|
||||||
data: {
|
|
||||||
event: "subscription.removed",
|
|
||||||
channel: this.channel,
|
|
||||||
topic: this.topic
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
defer: function () {
|
|
||||||
var self = this;
|
|
||||||
var fn = this.callback;
|
|
||||||
this.callback = function (data, env) {
|
|
||||||
setTimeout(function () {
|
|
||||||
fn.call(self.context, data, env);
|
|
||||||
}, 0);
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
disposeAfter: function (maxCalls) {
|
|
||||||
if (_.isNaN(maxCalls) || maxCalls <= 0) {
|
|
||||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
|
||||||
}
|
|
||||||
var self = this;
|
|
||||||
var fn = this.callback;
|
|
||||||
var dispose = _.after(maxCalls, _.bind(function () {
|
|
||||||
this.unsubscribe();
|
|
||||||
}, this));
|
|
||||||
|
|
||||||
this.callback = function () {
|
|
||||||
fn.apply(self.context, arguments);
|
|
||||||
dispose();
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
distinctUntilChanged: function () {
|
|
||||||
this.withConstraint(new ConsecutiveDistinctPredicate());
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
distinct: function () {
|
|
||||||
this.withConstraint(new DistinctPredicate());
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
once: function () {
|
|
||||||
this.disposeAfter(1);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withConstraint: function (predicate) {
|
|
||||||
if (!_.isFunction(predicate)) {
|
|
||||||
throw "Predicate constraint must be a function";
|
|
||||||
}
|
|
||||||
this.constraints.push(predicate);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withConstraints: function (predicates) {
|
|
||||||
var self = this;
|
|
||||||
if (_.isArray(predicates)) {
|
|
||||||
_.each(predicates, function (predicate) {
|
|
||||||
self.withConstraint(predicate);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
},
|
|
||||||
|
|
||||||
withContext: function (context) {
|
|
||||||
this.context = context;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withDebounce: function (milliseconds, immediate) {
|
|
||||||
if (_.isNaN(milliseconds)) {
|
|
||||||
throw "Milliseconds must be a number";
|
|
||||||
}
|
|
||||||
var fn = this.callback;
|
|
||||||
this.callback = _.debounce(fn, milliseconds, !! immediate);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withDelay: function (milliseconds) {
|
|
||||||
if (_.isNaN(milliseconds)) {
|
|
||||||
throw "Milliseconds must be a number";
|
|
||||||
}
|
|
||||||
var self = this;
|
|
||||||
var fn = this.callback;
|
|
||||||
this.callback = function (data, env) {
|
|
||||||
setTimeout(function () {
|
|
||||||
fn.call(self.context, data, env);
|
|
||||||
}, milliseconds);
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
withThrottle: function (milliseconds) {
|
|
||||||
if (_.isNaN(milliseconds)) {
|
|
||||||
throw "Milliseconds must be a number";
|
|
||||||
}
|
|
||||||
var fn = this.callback;
|
|
||||||
this.callback = _.throttle(fn, milliseconds);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
subscribe: function (callback) {
|
|
||||||
this.callback = callback;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var bindingsResolver = {
|
|
||||||
cache: {},
|
|
||||||
regex: {},
|
|
||||||
|
|
||||||
compare: function (binding, topic) {
|
|
||||||
var pattern, rgx, prevSegment, result = (this.cache[topic] && this.cache[topic][binding]);
|
|
||||||
if (typeof result !== "undefined") {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (!(rgx = this.regex[binding])) {
|
|
||||||
pattern = "^" + _.map(binding.split("."), function (segment) {
|
|
||||||
var res = "";
|
|
||||||
if ( !! prevSegment) {
|
|
||||||
res = prevSegment !== "#" ? "\\.\\b" : "\\b";
|
|
||||||
}
|
|
||||||
if (segment === "#") {
|
|
||||||
res += "[\\s\\S]*";
|
|
||||||
} else if (segment === "*") {
|
|
||||||
res += "[^.]+";
|
|
||||||
} else {
|
|
||||||
res += segment;
|
|
||||||
}
|
|
||||||
prevSegment = segment;
|
|
||||||
return res;
|
|
||||||
}).join("") + "$";
|
|
||||||
rgx = this.regex[binding] = new RegExp(pattern);
|
|
||||||
}
|
|
||||||
this.cache[topic] = this.cache[topic] || {};
|
|
||||||
this.cache[topic][binding] = result = rgx.test(topic);
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function () {
|
|
||||||
this.cache = {};
|
|
||||||
this.regex = {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var fireSub = function (subDef, envelope) {
|
|
||||||
if (!subDef.inactive && postal.configuration.resolver.compare(subDef.topic, envelope.topic)) {
|
|
||||||
if (_.all(subDef.constraints, function (constraint) {
|
|
||||||
return constraint.call(subDef.context, envelope.data, envelope);
|
|
||||||
})) {
|
|
||||||
if (typeof subDef.callback === "function") {
|
|
||||||
subDef.callback.call(subDef.context, envelope.data, envelope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var pubInProgress = 0;
|
|
||||||
var unSubQueue = [];
|
|
||||||
var clearUnSubQueue = function () {
|
|
||||||
while (unSubQueue.length) {
|
|
||||||
localBus.unsubscribe(unSubQueue.shift());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var localBus = {
|
|
||||||
addWireTap: function (callback) {
|
|
||||||
var self = this;
|
|
||||||
self.wireTaps.push(callback);
|
|
||||||
return function () {
|
|
||||||
var idx = self.wireTaps.indexOf(callback);
|
|
||||||
if (idx !== -1) {
|
|
||||||
self.wireTaps.splice(idx, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
publish: function (envelope) {
|
|
||||||
++pubInProgress;
|
|
||||||
envelope.timeStamp = new Date();
|
|
||||||
_.each(this.wireTaps, function (tap) {
|
|
||||||
tap(envelope.data, envelope);
|
|
||||||
});
|
|
||||||
if (this.subscriptions[envelope.channel]) {
|
|
||||||
_.each(this.subscriptions[envelope.channel], function (subscribers) {
|
|
||||||
var idx = 0,
|
|
||||||
len = subscribers.length,
|
|
||||||
subDef;
|
|
||||||
while (idx < len) {
|
|
||||||
if (subDef = subscribers[idx++]) {
|
|
||||||
fireSub(subDef, envelope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (--pubInProgress === 0) {
|
|
||||||
clearUnSubQueue();
|
|
||||||
}
|
|
||||||
return envelope;
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function () {
|
|
||||||
if (this.subscriptions) {
|
|
||||||
_.each(this.subscriptions, function (channel) {
|
|
||||||
_.each(channel, function (topic) {
|
|
||||||
while (topic.length) {
|
|
||||||
topic.pop().unsubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this.subscriptions = {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
subscribe: function (subDef) {
|
|
||||||
var channel = this.subscriptions[subDef.channel],
|
|
||||||
subs;
|
|
||||||
if (!channel) {
|
|
||||||
channel = this.subscriptions[subDef.channel] = {};
|
|
||||||
}
|
|
||||||
subs = this.subscriptions[subDef.channel][subDef.topic];
|
|
||||||
if (!subs) {
|
|
||||||
subs = this.subscriptions[subDef.channel][subDef.topic] = [];
|
|
||||||
}
|
|
||||||
subs.push(subDef);
|
|
||||||
return subDef;
|
|
||||||
},
|
|
||||||
|
|
||||||
subscriptions: {},
|
|
||||||
|
|
||||||
wireTaps: [],
|
|
||||||
|
|
||||||
unsubscribe: function (config) {
|
|
||||||
if (pubInProgress) {
|
|
||||||
unSubQueue.push(config);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.subscriptions[config.channel][config.topic]) {
|
|
||||||
var len = this.subscriptions[config.channel][config.topic].length,
|
|
||||||
idx = 0;
|
|
||||||
while (idx < len) {
|
|
||||||
if (this.subscriptions[config.channel][config.topic][idx] === config) {
|
|
||||||
this.subscriptions[config.channel][config.topic].splice(idx, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
postal = {
|
|
||||||
configuration: {
|
|
||||||
bus: localBus,
|
|
||||||
resolver: bindingsResolver,
|
|
||||||
DEFAULT_CHANNEL: "/",
|
|
||||||
SYSTEM_CHANNEL: "postal"
|
|
||||||
},
|
|
||||||
|
|
||||||
ChannelDefinition: ChannelDefinition,
|
|
||||||
SubscriptionDefinition: SubscriptionDefinition,
|
|
||||||
|
|
||||||
channel: function (channelName) {
|
|
||||||
return new ChannelDefinition(channelName);
|
|
||||||
},
|
|
||||||
|
|
||||||
subscribe: function (options) {
|
|
||||||
return new SubscriptionDefinition(options.channel || postal.configuration.DEFAULT_CHANNEL, options.topic, options.callback);
|
|
||||||
},
|
|
||||||
|
|
||||||
publish: function (envelope) {
|
|
||||||
envelope.channel = envelope.channel || postal.configuration.DEFAULT_CHANNEL;
|
|
||||||
return postal.configuration.bus.publish(envelope);
|
|
||||||
},
|
|
||||||
|
|
||||||
addWireTap: function (callback) {
|
|
||||||
return this.configuration.bus.addWireTap(callback);
|
|
||||||
},
|
|
||||||
|
|
||||||
linkChannels: function (sources, destinations) {
|
|
||||||
var result = [];
|
|
||||||
sources = !_.isArray(sources) ? [sources] : sources;
|
|
||||||
destinations = !_.isArray(destinations) ? [destinations] : destinations;
|
|
||||||
_.each(sources, function (source) {
|
|
||||||
var sourceTopic = source.topic || "#";
|
|
||||||
_.each(destinations, function (destination) {
|
|
||||||
var destChannel = destination.channel || postal.configuration.DEFAULT_CHANNEL;
|
|
||||||
result.push(
|
|
||||||
postal.subscribe({
|
|
||||||
channel: source.channel || postal.configuration.DEFAULT_CHANNEL,
|
|
||||||
topic: sourceTopic,
|
|
||||||
callback: function (data, env) {
|
|
||||||
var newEnv = _.clone(env);
|
|
||||||
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
|
|
||||||
newEnv.channel = destChannel;
|
|
||||||
newEnv.data = data;
|
|
||||||
postal.publish(newEnv);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
utils: {
|
|
||||||
getSubscribersFor: function () {
|
|
||||||
var channel = arguments[0],
|
|
||||||
tpc = arguments[1];
|
|
||||||
if (arguments.length === 1) {
|
|
||||||
channel = arguments[0].channel || postal.configuration.DEFAULT_CHANNEL;
|
|
||||||
tpc = arguments[0].topic;
|
|
||||||
}
|
|
||||||
if (postal.configuration.bus.subscriptions[channel] && Object.prototype.hasOwnProperty.call(postal.configuration.bus.subscriptions[channel], tpc)) {
|
|
||||||
return postal.configuration.bus.subscriptions[channel][tpc];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function () {
|
|
||||||
postal.configuration.bus.reset();
|
|
||||||
postal.configuration.resolver.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
localBus.subscriptions[postal.configuration.SYSTEM_CHANNEL] = {};
|
|
||||||
|
|
||||||
|
|
||||||
if (global && Object.prototype.hasOwnProperty.call(global, "__postalReady__") && _.isArray(global.__postalReady__)) {
|
|
||||||
while (global.__postalReady__.length) {
|
|
||||||
global.__postalReady__.shift().onReady(postal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return postal;
|
|
||||||
}));
|
|
||||||
8
example/standard/js/postal.min.js
vendored
8
example/standard/js/postal.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,999 +0,0 @@
|
||||||
// Underscore.js 1.1.7
|
|
||||||
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
|
||||||
// Underscore is freely distributable under the MIT license.
|
|
||||||
// Portions of Underscore are inspired or borrowed from Prototype,
|
|
||||||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
|
||||||
// For all details and documentation:
|
|
||||||
// http://documentcloud.github.com/underscore
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
// Baseline setup
|
|
||||||
// --------------
|
|
||||||
|
|
||||||
// Establish the root object, `window` in the browser, or `global` on the server.
|
|
||||||
var root = this;
|
|
||||||
|
|
||||||
// Save the previous value of the `_` variable.
|
|
||||||
var previousUnderscore = root._;
|
|
||||||
|
|
||||||
// Establish the object that gets returned to break out of a loop iteration.
|
|
||||||
var breaker = {};
|
|
||||||
|
|
||||||
// Save bytes in the minified (but not gzipped) version:
|
|
||||||
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
|
||||||
|
|
||||||
// Create quick reference variables for speed access to core prototypes.
|
|
||||||
var slice = ArrayProto.slice,
|
|
||||||
unshift = ArrayProto.unshift,
|
|
||||||
toString = ObjProto.toString,
|
|
||||||
hasOwnProperty = ObjProto.hasOwnProperty;
|
|
||||||
|
|
||||||
// All **ECMAScript 5** native function implementations that we hope to use
|
|
||||||
// are declared here.
|
|
||||||
var
|
|
||||||
nativeForEach = ArrayProto.forEach,
|
|
||||||
nativeMap = ArrayProto.map,
|
|
||||||
nativeReduce = ArrayProto.reduce,
|
|
||||||
nativeReduceRight = ArrayProto.reduceRight,
|
|
||||||
nativeFilter = ArrayProto.filter,
|
|
||||||
nativeEvery = ArrayProto.every,
|
|
||||||
nativeSome = ArrayProto.some,
|
|
||||||
nativeIndexOf = ArrayProto.indexOf,
|
|
||||||
nativeLastIndexOf = ArrayProto.lastIndexOf,
|
|
||||||
nativeIsArray = Array.isArray,
|
|
||||||
nativeKeys = Object.keys,
|
|
||||||
nativeBind = FuncProto.bind;
|
|
||||||
|
|
||||||
// Create a safe reference to the Underscore object for use below.
|
|
||||||
var _ = function ( obj ) {
|
|
||||||
return new wrapper( obj );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Export the Underscore object for **CommonJS**, with backwards-compatibility
|
|
||||||
// for the old `require()` API. If we're not in CommonJS, add `_` to the
|
|
||||||
// global object.
|
|
||||||
if ( typeof module !== 'undefined' && module.exports ) {
|
|
||||||
module.exports = _;
|
|
||||||
_._ = _;
|
|
||||||
} else {
|
|
||||||
// Exported as a string, for Closure Compiler "advanced" mode.
|
|
||||||
root['_'] = _;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Current version.
|
|
||||||
_.VERSION = '1.1.7';
|
|
||||||
|
|
||||||
// Collection Functions
|
|
||||||
// --------------------
|
|
||||||
|
|
||||||
// The cornerstone, an `each` implementation, aka `forEach`.
|
|
||||||
// Handles objects with the built-in `forEach`, arrays, and raw objects.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
|
||||||
var each = _.each = _.forEach = function ( obj, iterator, context ) {
|
|
||||||
if ( obj == null ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( nativeForEach && obj.forEach === nativeForEach ) {
|
|
||||||
obj.forEach( iterator, context );
|
|
||||||
} else if ( obj.length === +obj.length ) {
|
|
||||||
for ( var i = 0, l = obj.length; i < l; i++ ) {
|
|
||||||
if ( i in obj && iterator.call( context, obj[i], i, obj ) === breaker ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for ( var key in obj ) {
|
|
||||||
if ( hasOwnProperty.call( obj, key ) ) {
|
|
||||||
if ( iterator.call( context, obj[key], key, obj ) === breaker ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the results of applying the iterator to each element.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `map` if available.
|
|
||||||
_.map = function ( obj, iterator, context ) {
|
|
||||||
var results = [];
|
|
||||||
if ( obj == null ) {
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
if ( nativeMap && obj.map === nativeMap ) {
|
|
||||||
return obj.map( iterator, context );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
results[results.length] = iterator.call( context, value, index, list );
|
|
||||||
} );
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
|
||||||
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
|
||||||
_.reduce = _.foldl = _.inject = function ( obj, iterator, memo, context ) {
|
|
||||||
var initial = memo !== void 0;
|
|
||||||
if ( obj == null ) {
|
|
||||||
obj = [];
|
|
||||||
}
|
|
||||||
if ( nativeReduce && obj.reduce === nativeReduce ) {
|
|
||||||
if ( context ) {
|
|
||||||
iterator = _.bind( iterator, context );
|
|
||||||
}
|
|
||||||
return initial ? obj.reduce( iterator, memo ) : obj.reduce( iterator );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( !initial ) {
|
|
||||||
memo = value;
|
|
||||||
initial = true;
|
|
||||||
} else {
|
|
||||||
memo = iterator.call( context, memo, value, index, list );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
if ( !initial ) {
|
|
||||||
throw new TypeError( "Reduce of empty array with no initial value" );
|
|
||||||
}
|
|
||||||
return memo;
|
|
||||||
};
|
|
||||||
|
|
||||||
// The right-associative version of reduce, also known as `foldr`.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
|
|
||||||
_.reduceRight = _.foldr = function ( obj, iterator, memo, context ) {
|
|
||||||
if ( obj == null ) {
|
|
||||||
obj = [];
|
|
||||||
}
|
|
||||||
if ( nativeReduceRight && obj.reduceRight === nativeReduceRight ) {
|
|
||||||
if ( context ) {
|
|
||||||
iterator = _.bind( iterator, context );
|
|
||||||
}
|
|
||||||
return memo !== void 0 ? obj.reduceRight( iterator, memo ) : obj.reduceRight( iterator );
|
|
||||||
}
|
|
||||||
var reversed = (_.isArray( obj ) ? obj.slice() : _.toArray( obj )).reverse();
|
|
||||||
return _.reduce( reversed, iterator, memo, context );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the first value which passes a truth test. Aliased as `detect`.
|
|
||||||
_.find = _.detect = function ( obj, iterator, context ) {
|
|
||||||
var result;
|
|
||||||
any( obj, function ( value, index, list ) {
|
|
||||||
if ( iterator.call( context, value, index, list ) ) {
|
|
||||||
result = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return all the elements that pass a truth test.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `filter` if available.
|
|
||||||
// Aliased as `select`.
|
|
||||||
_.filter = _.select = function ( obj, iterator, context ) {
|
|
||||||
var results = [];
|
|
||||||
if ( obj == null ) {
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
if ( nativeFilter && obj.filter === nativeFilter ) {
|
|
||||||
return obj.filter( iterator, context );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( iterator.call( context, value, index, list ) ) {
|
|
||||||
results[results.length] = value;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return all the elements for which a truth test fails.
|
|
||||||
_.reject = function ( obj, iterator, context ) {
|
|
||||||
var results = [];
|
|
||||||
if ( obj == null ) {
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( !iterator.call( context, value, index, list ) ) {
|
|
||||||
results[results.length] = value;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine whether all of the elements match a truth test.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `every` if available.
|
|
||||||
// Aliased as `all`.
|
|
||||||
_.every = _.all = function ( obj, iterator, context ) {
|
|
||||||
var result = true;
|
|
||||||
if ( obj == null ) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if ( nativeEvery && obj.every === nativeEvery ) {
|
|
||||||
return obj.every( iterator, context );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( !(result = result && iterator.call( context, value, index, list )) ) {
|
|
||||||
return breaker;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine if at least one element in the object matches a truth test.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `some` if available.
|
|
||||||
// Aliased as `any`.
|
|
||||||
var any = _.some = _.any = function ( obj, iterator, context ) {
|
|
||||||
iterator = iterator || _.identity;
|
|
||||||
var result = false;
|
|
||||||
if ( obj == null ) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if ( nativeSome && obj.some === nativeSome ) {
|
|
||||||
return obj.some( iterator, context );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( result |= iterator.call( context, value, index, list ) ) {
|
|
||||||
return breaker;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return !!result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine if a given value is included in the array or object using `===`.
|
|
||||||
// Aliased as `contains`.
|
|
||||||
_.include = _.contains = function ( obj, target ) {
|
|
||||||
var found = false;
|
|
||||||
if ( obj == null ) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
if ( nativeIndexOf && obj.indexOf === nativeIndexOf ) {
|
|
||||||
return obj.indexOf( target ) != -1;
|
|
||||||
}
|
|
||||||
any( obj, function ( value ) {
|
|
||||||
if ( found = value === target ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return found;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Invoke a method (with arguments) on every item in a collection.
|
|
||||||
_.invoke = function ( obj, method ) {
|
|
||||||
var args = slice.call( arguments, 2 );
|
|
||||||
return _.map( obj, function ( value ) {
|
|
||||||
return (method.call ? method || value : value[method]).apply( value, args );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convenience version of a common use case of `map`: fetching a property.
|
|
||||||
_.pluck = function ( obj, key ) {
|
|
||||||
return _.map( obj, function ( value ) {
|
|
||||||
return value[key];
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the maximum element or (element-based computation).
|
|
||||||
_.max = function ( obj, iterator, context ) {
|
|
||||||
if ( !iterator && _.isArray( obj ) ) {
|
|
||||||
return Math.max.apply( Math, obj );
|
|
||||||
}
|
|
||||||
var result = {computed : -Infinity};
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
var computed = iterator ? iterator.call( context, value, index, list ) : value;
|
|
||||||
computed >= result.computed && (result = {value : value, computed : computed});
|
|
||||||
} );
|
|
||||||
return result.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the minimum element (or element-based computation).
|
|
||||||
_.min = function ( obj, iterator, context ) {
|
|
||||||
if ( !iterator && _.isArray( obj ) ) {
|
|
||||||
return Math.min.apply( Math, obj );
|
|
||||||
}
|
|
||||||
var result = {computed : Infinity};
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
var computed = iterator ? iterator.call( context, value, index, list ) : value;
|
|
||||||
computed < result.computed && (result = {value : value, computed : computed});
|
|
||||||
} );
|
|
||||||
return result.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sort the object's values by a criterion produced by an iterator.
|
|
||||||
_.sortBy = function ( obj, iterator, context ) {
|
|
||||||
return _.pluck( _.map( obj,
|
|
||||||
function ( value, index, list ) {
|
|
||||||
return {
|
|
||||||
value : value,
|
|
||||||
criteria : iterator.call( context, value, index, list )
|
|
||||||
};
|
|
||||||
} ).sort( function ( left, right ) {
|
|
||||||
var a = left.criteria, b = right.criteria;
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
|
||||||
} ), 'value' );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Groups the object's values by a criterion produced by an iterator
|
|
||||||
_.groupBy = function ( obj, iterator ) {
|
|
||||||
var result = {};
|
|
||||||
each( obj, function ( value, index ) {
|
|
||||||
var key = iterator( value, index );
|
|
||||||
(result[key] || (result[key] = [])).push( value );
|
|
||||||
} );
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use a comparator function to figure out at what index an object should
|
|
||||||
// be inserted so as to maintain order. Uses binary search.
|
|
||||||
_.sortedIndex = function ( array, obj, iterator ) {
|
|
||||||
iterator || (iterator = _.identity);
|
|
||||||
var low = 0, high = array.length;
|
|
||||||
while ( low < high ) {
|
|
||||||
var mid = (low + high) >> 1;
|
|
||||||
iterator( array[mid] ) < iterator( obj ) ? low = mid + 1 : high = mid;
|
|
||||||
}
|
|
||||||
return low;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Safely convert anything iterable into a real, live array.
|
|
||||||
_.toArray = function ( iterable ) {
|
|
||||||
if ( !iterable ) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
if ( iterable.toArray ) {
|
|
||||||
return iterable.toArray();
|
|
||||||
}
|
|
||||||
if ( _.isArray( iterable ) ) {
|
|
||||||
return slice.call( iterable );
|
|
||||||
}
|
|
||||||
if ( _.isArguments( iterable ) ) {
|
|
||||||
return slice.call( iterable );
|
|
||||||
}
|
|
||||||
return _.values( iterable );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the number of elements in an object.
|
|
||||||
_.size = function ( obj ) {
|
|
||||||
return _.toArray( obj ).length;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Array Functions
|
|
||||||
// ---------------
|
|
||||||
|
|
||||||
// Get the first element of an array. Passing **n** will return the first N
|
|
||||||
// values in the array. Aliased as `head`. The **guard** check allows it to work
|
|
||||||
// with `_.map`.
|
|
||||||
_.first = _.head = function ( array, n, guard ) {
|
|
||||||
return (n != null) && !guard ? slice.call( array, 0, n ) : array[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns everything but the first entry of the array. Aliased as `tail`.
|
|
||||||
// Especially useful on the arguments object. Passing an **index** will return
|
|
||||||
// the rest of the values in the array from that index onward. The **guard**
|
|
||||||
// check allows it to work with `_.map`.
|
|
||||||
_.rest = _.tail = function ( array, index, guard ) {
|
|
||||||
return slice.call( array, (index == null) || guard ? 1 : index );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the last element of an array.
|
|
||||||
_.last = function ( array ) {
|
|
||||||
return array[array.length - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Trim out all falsy values from an array.
|
|
||||||
_.compact = function ( array ) {
|
|
||||||
return _.filter( array, function ( value ) {
|
|
||||||
return !!value;
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return a completely flattened version of an array.
|
|
||||||
_.flatten = function ( array ) {
|
|
||||||
return _.reduce( array, function ( memo, value ) {
|
|
||||||
if ( _.isArray( value ) ) {
|
|
||||||
return memo.concat( _.flatten( value ) );
|
|
||||||
}
|
|
||||||
memo[memo.length] = value;
|
|
||||||
return memo;
|
|
||||||
}, [] );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return a version of the array that does not contain the specified value(s).
|
|
||||||
_.without = function ( array ) {
|
|
||||||
return _.difference( array, slice.call( arguments, 1 ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Produce a duplicate-free version of the array. If the array has already
|
|
||||||
// been sorted, you have the option of using a faster algorithm.
|
|
||||||
// Aliased as `unique`.
|
|
||||||
_.uniq = _.unique = function ( array, isSorted ) {
|
|
||||||
return _.reduce( array, function ( memo, el, i ) {
|
|
||||||
if ( 0 == i || (isSorted === true ? _.last( memo ) != el : !_.include( memo, el )) ) {
|
|
||||||
memo[memo.length] = el;
|
|
||||||
}
|
|
||||||
return memo;
|
|
||||||
}, [] );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Produce an array that contains the union: each distinct element from all of
|
|
||||||
// the passed-in arrays.
|
|
||||||
_.union = function () {
|
|
||||||
return _.uniq( _.flatten( arguments ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Produce an array that contains every item shared between all the
|
|
||||||
// passed-in arrays. (Aliased as "intersect" for back-compat.)
|
|
||||||
_.intersection = _.intersect = function ( array ) {
|
|
||||||
var rest = slice.call( arguments, 1 );
|
|
||||||
return _.filter( _.uniq( array ), function ( item ) {
|
|
||||||
return _.every( rest, function ( other ) {
|
|
||||||
return _.indexOf( other, item ) >= 0;
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Take the difference between one array and another.
|
|
||||||
// Only the elements present in just the first array will remain.
|
|
||||||
_.difference = function ( array, other ) {
|
|
||||||
return _.filter( array, function ( value ) {
|
|
||||||
return !_.include( other, value );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Zip together multiple lists into a single array -- elements that share
|
|
||||||
// an index go together.
|
|
||||||
_.zip = function () {
|
|
||||||
var args = slice.call( arguments );
|
|
||||||
var length = _.max( _.pluck( args, 'length' ) );
|
|
||||||
var results = new Array( length );
|
|
||||||
for ( var i = 0; i < length; i++ ) {
|
|
||||||
results[i] = _.pluck( args, "" + i );
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
|
|
||||||
// we need this function. Return the position of the first occurrence of an
|
|
||||||
// item in an array, or -1 if the item is not included in the array.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
|
|
||||||
// If the array is large and already in sort order, pass `true`
|
|
||||||
// for **isSorted** to use binary search.
|
|
||||||
_.indexOf = function ( array, item, isSorted ) {
|
|
||||||
if ( array == null ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
var i, l;
|
|
||||||
if ( isSorted ) {
|
|
||||||
i = _.sortedIndex( array, item );
|
|
||||||
return array[i] === item ? i : -1;
|
|
||||||
}
|
|
||||||
if ( nativeIndexOf && array.indexOf === nativeIndexOf ) {
|
|
||||||
return array.indexOf( item );
|
|
||||||
}
|
|
||||||
for ( i = 0, l = array.length; i < l; i++ ) {
|
|
||||||
if ( array[i] === item ) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
|
||||||
_.lastIndexOf = function ( array, item ) {
|
|
||||||
if ( array == null ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if ( nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf ) {
|
|
||||||
return array.lastIndexOf( item );
|
|
||||||
}
|
|
||||||
var i = array.length;
|
|
||||||
while ( i-- ) {
|
|
||||||
if ( array[i] === item ) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate an integer Array containing an arithmetic progression. A port of
|
|
||||||
// the native Python `range()` function. See
|
|
||||||
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
|
||||||
_.range = function ( start, stop, step ) {
|
|
||||||
if ( arguments.length <= 1 ) {
|
|
||||||
stop = start || 0;
|
|
||||||
start = 0;
|
|
||||||
}
|
|
||||||
step = arguments[2] || 1;
|
|
||||||
|
|
||||||
var len = Math.max( Math.ceil( (stop - start) / step ), 0 );
|
|
||||||
var idx = 0;
|
|
||||||
var range = new Array( len );
|
|
||||||
|
|
||||||
while ( idx < len ) {
|
|
||||||
range[idx++] = start;
|
|
||||||
start += step;
|
|
||||||
}
|
|
||||||
|
|
||||||
return range;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function (ahem) Functions
|
|
||||||
// ------------------
|
|
||||||
|
|
||||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
|
||||||
// optionally). Binding with arguments is also known as `curry`.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
|
||||||
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
|
||||||
_.bind = function ( func, obj ) {
|
|
||||||
if ( func.bind === nativeBind && nativeBind ) {
|
|
||||||
return nativeBind.apply( func, slice.call( arguments, 1 ) );
|
|
||||||
}
|
|
||||||
var args = slice.call( arguments, 2 );
|
|
||||||
return function () {
|
|
||||||
return func.apply( obj, args.concat( slice.call( arguments ) ) );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Bind all of an object's methods to that object. Useful for ensuring that
|
|
||||||
// all callbacks defined on an object belong to it.
|
|
||||||
_.bindAll = function ( obj ) {
|
|
||||||
var funcs = slice.call( arguments, 1 );
|
|
||||||
if ( funcs.length == 0 ) {
|
|
||||||
funcs = _.functions( obj );
|
|
||||||
}
|
|
||||||
each( funcs, function ( f ) {
|
|
||||||
obj[f] = _.bind( obj[f], obj );
|
|
||||||
} );
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Memoize an expensive function by storing its results.
|
|
||||||
_.memoize = function ( func, hasher ) {
|
|
||||||
var memo = {};
|
|
||||||
hasher || (hasher = _.identity);
|
|
||||||
return function () {
|
|
||||||
var key = hasher.apply( this, arguments );
|
|
||||||
return hasOwnProperty.call( memo, key ) ? memo[key] : (memo[key] = func.apply( this, arguments ));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delays a function for the given number of milliseconds, and then calls
|
|
||||||
// it with the arguments supplied.
|
|
||||||
_.delay = function ( func, wait ) {
|
|
||||||
var args = slice.call( arguments, 2 );
|
|
||||||
return setTimeout( function () {
|
|
||||||
return func.apply( func, args );
|
|
||||||
}, wait );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Defers a function, scheduling it to run after the current call stack has
|
|
||||||
// cleared.
|
|
||||||
_.defer = function ( func ) {
|
|
||||||
return _.delay.apply( _, [func, 1].concat( slice.call( arguments, 1 ) ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Internal function used to implement `_.throttle` and `_.debounce`.
|
|
||||||
var limit = function ( func, wait, debounce ) {
|
|
||||||
var timeout;
|
|
||||||
return function () {
|
|
||||||
var context = this, args = arguments;
|
|
||||||
var throttler = function () {
|
|
||||||
timeout = null;
|
|
||||||
func.apply( context, args );
|
|
||||||
};
|
|
||||||
if ( debounce ) {
|
|
||||||
clearTimeout( timeout );
|
|
||||||
}
|
|
||||||
if ( debounce || !timeout ) {
|
|
||||||
timeout = setTimeout( throttler, wait );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function, that, when invoked, will only be triggered at most once
|
|
||||||
// during a given window of time.
|
|
||||||
_.throttle = function ( func, wait ) {
|
|
||||||
return limit( func, wait, false );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function, that, as long as it continues to be invoked, will not
|
|
||||||
// be triggered. The function will be called after it stops being called for
|
|
||||||
// N milliseconds.
|
|
||||||
_.debounce = function ( func, wait ) {
|
|
||||||
return limit( func, wait, true );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function that will be executed at most one time, no matter how
|
|
||||||
// often you call it. Useful for lazy initialization.
|
|
||||||
_.once = function ( func ) {
|
|
||||||
var ran = false, memo;
|
|
||||||
return function () {
|
|
||||||
if ( ran ) {
|
|
||||||
return memo;
|
|
||||||
}
|
|
||||||
ran = true;
|
|
||||||
return memo = func.apply( this, arguments );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the first function passed as an argument to the second,
|
|
||||||
// allowing you to adjust arguments, run code before and after, and
|
|
||||||
// conditionally execute the original function.
|
|
||||||
_.wrap = function ( func, wrapper ) {
|
|
||||||
return function () {
|
|
||||||
var args = [func].concat( slice.call( arguments ) );
|
|
||||||
return wrapper.apply( this, args );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function that is the composition of a list of functions, each
|
|
||||||
// consuming the return value of the function that follows.
|
|
||||||
_.compose = function () {
|
|
||||||
var funcs = slice.call( arguments );
|
|
||||||
return function () {
|
|
||||||
var args = slice.call( arguments );
|
|
||||||
for ( var i = funcs.length - 1; i >= 0; i-- ) {
|
|
||||||
args = [funcs[i].apply( this, args )];
|
|
||||||
}
|
|
||||||
return args[0];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function that will only be executed after being called N times.
|
|
||||||
_.after = function ( times, func ) {
|
|
||||||
return function () {
|
|
||||||
if ( --times < 1 ) {
|
|
||||||
return func.apply( this, arguments );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Object Functions
|
|
||||||
// ----------------
|
|
||||||
|
|
||||||
// Retrieve the names of an object's properties.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
|
||||||
_.keys = nativeKeys || function ( obj ) {
|
|
||||||
if ( obj !== Object( obj ) ) {
|
|
||||||
throw new TypeError( 'Invalid object' );
|
|
||||||
}
|
|
||||||
var keys = [];
|
|
||||||
for ( var key in obj ) {
|
|
||||||
if ( hasOwnProperty.call( obj, key ) ) {
|
|
||||||
keys[keys.length] = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keys;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Retrieve the values of an object's properties.
|
|
||||||
_.values = function ( obj ) {
|
|
||||||
return _.map( obj, _.identity );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return a sorted list of the function names available on the object.
|
|
||||||
// Aliased as `methods`
|
|
||||||
_.functions = _.methods = function ( obj ) {
|
|
||||||
var names = [];
|
|
||||||
for ( var key in obj ) {
|
|
||||||
if ( _.isFunction( obj[key] ) ) {
|
|
||||||
names.push( key );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return names.sort();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extend a given object with all the properties in passed-in object(s).
|
|
||||||
_.extend = function ( obj ) {
|
|
||||||
each( slice.call( arguments, 1 ), function ( source ) {
|
|
||||||
for ( var prop in source ) {
|
|
||||||
if ( source[prop] !== void 0 ) {
|
|
||||||
obj[prop] = source[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fill in a given object with default properties.
|
|
||||||
_.defaults = function ( obj ) {
|
|
||||||
each( slice.call( arguments, 1 ), function ( source ) {
|
|
||||||
for ( var prop in source ) {
|
|
||||||
if ( obj[prop] == null ) {
|
|
||||||
obj[prop] = source[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a (shallow-cloned) duplicate of an object.
|
|
||||||
_.clone = function ( obj ) {
|
|
||||||
return _.isArray( obj ) ? obj.slice() : _.extend( {}, obj );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Invokes interceptor with the obj, and then returns obj.
|
|
||||||
// The primary purpose of this method is to "tap into" a method chain, in
|
|
||||||
// order to perform operations on intermediate results within the chain.
|
|
||||||
_.tap = function ( obj, interceptor ) {
|
|
||||||
interceptor( obj );
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Perform a deep comparison to check if two objects are equal.
|
|
||||||
_.isEqual = function ( a, b ) {
|
|
||||||
// Check object identity.
|
|
||||||
if ( a === b ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Different types?
|
|
||||||
var atype = typeof(a), btype = typeof(b);
|
|
||||||
if ( atype != btype ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Basic equality test (watch out for coercions).
|
|
||||||
if ( a == b ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// One is falsy and the other truthy.
|
|
||||||
if ( (!a && b) || (a && !b) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Unwrap any wrapped objects.
|
|
||||||
if ( a._chain ) {
|
|
||||||
a = a._wrapped;
|
|
||||||
}
|
|
||||||
if ( b._chain ) {
|
|
||||||
b = b._wrapped;
|
|
||||||
}
|
|
||||||
// One of them implements an isEqual()?
|
|
||||||
if ( a.isEqual ) {
|
|
||||||
return a.isEqual( b );
|
|
||||||
}
|
|
||||||
if ( b.isEqual ) {
|
|
||||||
return b.isEqual( a );
|
|
||||||
}
|
|
||||||
// Check dates' integer values.
|
|
||||||
if ( _.isDate( a ) && _.isDate( b ) ) {
|
|
||||||
return a.getTime() === b.getTime();
|
|
||||||
}
|
|
||||||
// Both are NaN?
|
|
||||||
if ( _.isNaN( a ) && _.isNaN( b ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Compare regular expressions.
|
|
||||||
if ( _.isRegExp( a ) && _.isRegExp( b ) ) {
|
|
||||||
return a.source === b.source &&
|
|
||||||
a.global === b.global &&
|
|
||||||
a.ignoreCase === b.ignoreCase &&
|
|
||||||
a.multiline === b.multiline;
|
|
||||||
}
|
|
||||||
// If a is not an object by this point, we can't handle it.
|
|
||||||
if ( atype !== 'object' ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check for different array lengths before comparing contents.
|
|
||||||
if ( a.length && (a.length !== b.length) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Nothing else worked, deep compare the contents.
|
|
||||||
var aKeys = _.keys( a ), bKeys = _.keys( b );
|
|
||||||
// Different object sizes?
|
|
||||||
if ( aKeys.length != bKeys.length ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Recursive comparison of contents.
|
|
||||||
for ( var key in a ) {
|
|
||||||
if ( !(key in b) || !_.isEqual( a[key], b[key] ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given array or object empty?
|
|
||||||
_.isEmpty = function ( obj ) {
|
|
||||||
if ( _.isArray( obj ) || _.isString( obj ) ) {
|
|
||||||
return obj.length === 0;
|
|
||||||
}
|
|
||||||
for ( var key in obj ) {
|
|
||||||
if ( hasOwnProperty.call( obj, key ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a DOM element?
|
|
||||||
_.isElement = function ( obj ) {
|
|
||||||
return !!(obj && obj.nodeType == 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value an array?
|
|
||||||
// Delegates to ECMA5's native Array.isArray
|
|
||||||
_.isArray = nativeIsArray || function ( obj ) {
|
|
||||||
return toString.call( obj ) === '[object Array]';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given variable an object?
|
|
||||||
_.isObject = function ( obj ) {
|
|
||||||
return obj === Object( obj );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given variable an arguments object?
|
|
||||||
_.isArguments = function ( obj ) {
|
|
||||||
return !!(obj && hasOwnProperty.call( obj, 'callee' ));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a function?
|
|
||||||
_.isFunction = function ( obj ) {
|
|
||||||
return !!(obj && obj.constructor && obj.call && obj.apply);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a string?
|
|
||||||
_.isString = function ( obj ) {
|
|
||||||
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a number?
|
|
||||||
_.isNumber = function ( obj ) {
|
|
||||||
return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
|
|
||||||
// that does not equal itself.
|
|
||||||
_.isNaN = function ( obj ) {
|
|
||||||
return obj !== obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a boolean?
|
|
||||||
_.isBoolean = function ( obj ) {
|
|
||||||
return obj === true || obj === false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a date?
|
|
||||||
_.isDate = function ( obj ) {
|
|
||||||
return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is the given value a regular expression?
|
|
||||||
_.isRegExp = function ( obj ) {
|
|
||||||
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value equal to null?
|
|
||||||
_.isNull = function ( obj ) {
|
|
||||||
return obj === null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given variable undefined?
|
|
||||||
_.isUndefined = function ( obj ) {
|
|
||||||
return obj === void 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Utility Functions
|
|
||||||
// -----------------
|
|
||||||
|
|
||||||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
|
||||||
// previous owner. Returns a reference to the Underscore object.
|
|
||||||
_.noConflict = function () {
|
|
||||||
root._ = previousUnderscore;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Keep the identity function around for default iterators.
|
|
||||||
_.identity = function ( value ) {
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Run a function **n** times.
|
|
||||||
_.times = function ( n, iterator, context ) {
|
|
||||||
for ( var i = 0; i < n; i++ ) {
|
|
||||||
iterator.call( context, i );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add your own custom functions to the Underscore object, ensuring that
|
|
||||||
// they're correctly added to the OOP wrapper as well.
|
|
||||||
_.mixin = function ( obj ) {
|
|
||||||
each( _.functions( obj ), function ( name ) {
|
|
||||||
addToWrapper( name, _[name] = obj[name] );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate a unique integer id (unique within the entire client session).
|
|
||||||
// Useful for temporary DOM ids.
|
|
||||||
var idCounter = 0;
|
|
||||||
_.uniqueId = function ( prefix ) {
|
|
||||||
var id = idCounter++;
|
|
||||||
return prefix ? prefix + id : id;
|
|
||||||
};
|
|
||||||
|
|
||||||
// By default, Underscore uses ERB-style template delimiters, change the
|
|
||||||
// following template settings to use alternative delimiters.
|
|
||||||
_.templateSettings = {
|
|
||||||
evaluate : /<%([\s\S]+?)%>/g,
|
|
||||||
interpolate : /<%=([\s\S]+?)%>/g
|
|
||||||
};
|
|
||||||
|
|
||||||
// JavaScript micro-templating, similar to John Resig's implementation.
|
|
||||||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
|
||||||
// and correctly escapes quotes within interpolated code.
|
|
||||||
_.template = function ( str, data ) {
|
|
||||||
var c = _.templateSettings;
|
|
||||||
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
|
|
||||||
'with(obj||{}){__p.push(\'' +
|
|
||||||
str.replace( /\\/g, '\\\\' )
|
|
||||||
.replace( /'/g, "\\'" )
|
|
||||||
.replace( c.interpolate, function ( match, code ) {
|
|
||||||
return "'," + code.replace( /\\'/g, "'" ) + ",'";
|
|
||||||
} )
|
|
||||||
.replace( c.evaluate || null, function ( match, code ) {
|
|
||||||
return "');" + code.replace( /\\'/g, "'" )
|
|
||||||
.replace( /[\r\n\t]/g, ' ' ) + "__p.push('";
|
|
||||||
} )
|
|
||||||
.replace( /\r/g, '\\r' )
|
|
||||||
.replace( /\n/g, '\\n' )
|
|
||||||
.replace( /\t/g, '\\t' )
|
|
||||||
+ "');}return __p.join('');";
|
|
||||||
var func = new Function( 'obj', tmpl );
|
|
||||||
return data ? func( data ) : func;
|
|
||||||
};
|
|
||||||
|
|
||||||
// The OOP Wrapper
|
|
||||||
// ---------------
|
|
||||||
|
|
||||||
// If Underscore is called as a function, it returns a wrapped object that
|
|
||||||
// can be used OO-style. This wrapper holds altered versions of all the
|
|
||||||
// underscore functions. Wrapped objects may be chained.
|
|
||||||
var wrapper = function ( obj ) {
|
|
||||||
this._wrapped = obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expose `wrapper.prototype` as `_.prototype`
|
|
||||||
_.prototype = wrapper.prototype;
|
|
||||||
|
|
||||||
// Helper function to continue chaining intermediate results.
|
|
||||||
var result = function ( obj, chain ) {
|
|
||||||
return chain ? _( obj ).chain() : obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A method to easily add functions to the OOP wrapper.
|
|
||||||
var addToWrapper = function ( name, func ) {
|
|
||||||
wrapper.prototype[name] = function () {
|
|
||||||
var args = slice.call( arguments );
|
|
||||||
unshift.call( args, this._wrapped );
|
|
||||||
return result( func.apply( _, args ), this._chain );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add all of the Underscore functions to the wrapper object.
|
|
||||||
_.mixin( _ );
|
|
||||||
|
|
||||||
// Add all mutator Array functions to the wrapper.
|
|
||||||
each( ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function ( name ) {
|
|
||||||
var method = ArrayProto[name];
|
|
||||||
wrapper.prototype[name] = function () {
|
|
||||||
method.apply( this._wrapped, arguments );
|
|
||||||
return result( this._wrapped, this._chain );
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Add all accessor Array functions to the wrapper.
|
|
||||||
each( ['concat', 'join', 'slice'], function ( name ) {
|
|
||||||
var method = ArrayProto[name];
|
|
||||||
wrapper.prototype[name] = function () {
|
|
||||||
return result( method.apply( this._wrapped, arguments ), this._chain );
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Start chaining a wrapped Underscore object.
|
|
||||||
wrapper.prototype.chain = function () {
|
|
||||||
this._chain = true;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extracts the result from a wrapped and chained object.
|
|
||||||
wrapper.prototype.value = function () {
|
|
||||||
return this._wrapped;
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
/*!
|
|
||||||
* Amplify Core @VERSION
|
|
||||||
*
|
|
||||||
* Copyright 2011 appendTo LLC. (http://appendto.com/team)
|
|
||||||
* Dual licensed under the MIT or GPL licenses.
|
|
||||||
* http://appendto.com/open-source-licenses
|
|
||||||
*
|
|
||||||
* http://amplifyjs.com
|
|
||||||
*/
|
|
||||||
(function ( global, undefined ) {
|
|
||||||
|
|
||||||
var slice = [].slice,
|
|
||||||
subscriptions = {};
|
|
||||||
|
|
||||||
var amplify = global.amplify = {
|
|
||||||
publish : function ( topic ) {
|
|
||||||
var args = slice.call( arguments, 1 ),
|
|
||||||
subscription,
|
|
||||||
length,
|
|
||||||
i = 0,
|
|
||||||
ret;
|
|
||||||
|
|
||||||
if ( !subscriptions[ topic ] ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( length = subscriptions[ topic ].length; i < length; i++ ) {
|
|
||||||
subscription = subscriptions[ topic ][ i ];
|
|
||||||
ret = subscription.callback.apply( subscription.context, args );
|
|
||||||
if ( ret === false ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret !== false;
|
|
||||||
},
|
|
||||||
|
|
||||||
subscribe : function ( topic, context, callback, priority ) {
|
|
||||||
if ( arguments.length === 3 && typeof callback === "number" ) {
|
|
||||||
priority = callback;
|
|
||||||
callback = context;
|
|
||||||
context = null;
|
|
||||||
}
|
|
||||||
if ( arguments.length === 2 ) {
|
|
||||||
callback = context;
|
|
||||||
context = null;
|
|
||||||
}
|
|
||||||
priority = priority || 10;
|
|
||||||
|
|
||||||
var topicIndex = 0,
|
|
||||||
topics = topic.split( /\s/ ),
|
|
||||||
topicLength = topics.length,
|
|
||||||
added;
|
|
||||||
for ( ; topicIndex < topicLength; topicIndex++ ) {
|
|
||||||
topic = topics[ topicIndex ];
|
|
||||||
added = false;
|
|
||||||
if ( !subscriptions[ topic ] ) {
|
|
||||||
subscriptions[ topic ] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
var i = subscriptions[ topic ].length - 1,
|
|
||||||
subscriptionInfo = {
|
|
||||||
callback : callback,
|
|
||||||
context : context,
|
|
||||||
priority : priority
|
|
||||||
};
|
|
||||||
|
|
||||||
for ( ; i >= 0; i-- ) {
|
|
||||||
if ( subscriptions[ topic ][ i ].priority <= priority ) {
|
|
||||||
subscriptions[ topic ].splice( i + 1, 0, subscriptionInfo );
|
|
||||||
added = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !added ) {
|
|
||||||
subscriptions[ topic ].unshift( subscriptionInfo );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback;
|
|
||||||
},
|
|
||||||
|
|
||||||
unsubscribe : function ( topic, callback ) {
|
|
||||||
if ( !subscriptions[ topic ] ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var length = subscriptions[ topic ].length,
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for ( ; i < length; i++ ) {
|
|
||||||
if ( subscriptions[ topic ][ i ].callback === callback ) {
|
|
||||||
subscriptions[ topic ].splice( i, 1 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}( this ) );
|
|
||||||
|
|
@ -1,281 +0,0 @@
|
||||||
/*!
|
|
||||||
* Amplify Store - Persistent Client-Side Storage @VERSION
|
|
||||||
*
|
|
||||||
* Copyright 2011 appendTo LLC. (http://appendto.com/team)
|
|
||||||
* Dual licensed under the MIT or GPL licenses.
|
|
||||||
* http://appendto.com/open-source-licenses
|
|
||||||
*
|
|
||||||
* http://amplifyjs.com
|
|
||||||
*/
|
|
||||||
(function ( amplify, undefined ) {
|
|
||||||
|
|
||||||
var store = amplify.store = function ( key, value, options, type ) {
|
|
||||||
var type = store.type;
|
|
||||||
if ( options && options.type && options.type in store.types ) {
|
|
||||||
type = options.type;
|
|
||||||
}
|
|
||||||
return store.types[ type ]( key, value, options || {} );
|
|
||||||
};
|
|
||||||
|
|
||||||
store.types = {};
|
|
||||||
store.type = null;
|
|
||||||
store.addType = function ( type, storage ) {
|
|
||||||
if ( !store.type ) {
|
|
||||||
store.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
store.types[ type ] = storage;
|
|
||||||
store[ type ] = function ( key, value, options ) {
|
|
||||||
options = options || {};
|
|
||||||
options.type = type;
|
|
||||||
return store( key, value, options );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
store.error = function () {
|
|
||||||
return "amplify.store quota exceeded";
|
|
||||||
};
|
|
||||||
|
|
||||||
var rprefix = /^__amplify__/;
|
|
||||||
|
|
||||||
function createFromStorageInterface( storageType, storage ) {
|
|
||||||
store.addType( storageType, function ( key, value, options ) {
|
|
||||||
var storedValue, parsed, i, remove,
|
|
||||||
ret = value,
|
|
||||||
now = (new Date()).getTime();
|
|
||||||
|
|
||||||
if ( !key ) {
|
|
||||||
ret = {};
|
|
||||||
remove = [];
|
|
||||||
i = 0;
|
|
||||||
try {
|
|
||||||
// accessing the length property works around a localStorage bug
|
|
||||||
// in Firefox 4.0 where the keys don't update cross-page
|
|
||||||
// we assign to key just to avoid Closure Compiler from removing
|
|
||||||
// the access as "useless code"
|
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=662511
|
|
||||||
key = storage.length;
|
|
||||||
|
|
||||||
while ( key = storage.key( i++ ) ) {
|
|
||||||
if ( rprefix.test( key ) ) {
|
|
||||||
parsed = JSON.parse( storage.getItem( key ) );
|
|
||||||
if ( parsed.expires && parsed.expires <= now ) {
|
|
||||||
remove.push( key );
|
|
||||||
} else {
|
|
||||||
ret[ key.replace( rprefix, "" ) ] = parsed.data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ( key = remove.pop() ) {
|
|
||||||
storage.removeItem( key );
|
|
||||||
}
|
|
||||||
} catch ( error ) {
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// protect against name collisions with direct storage
|
|
||||||
key = "__amplify__" + key;
|
|
||||||
|
|
||||||
if ( value === undefined ) {
|
|
||||||
storedValue = storage.getItem( key );
|
|
||||||
parsed = storedValue ? JSON.parse( storedValue ) : { expires : -1 };
|
|
||||||
if ( parsed.expires && parsed.expires <= now ) {
|
|
||||||
storage.removeItem( key );
|
|
||||||
} else {
|
|
||||||
return parsed.data;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( value === null ) {
|
|
||||||
storage.removeItem( key );
|
|
||||||
} else {
|
|
||||||
parsed = JSON.stringify( {
|
|
||||||
data : value,
|
|
||||||
expires : options.expires ? now + options.expires : null
|
|
||||||
} );
|
|
||||||
try {
|
|
||||||
storage.setItem( key, parsed );
|
|
||||||
// quota exceeded
|
|
||||||
} catch ( error ) {
|
|
||||||
// expire old data and try again
|
|
||||||
store[ storageType ]();
|
|
||||||
try {
|
|
||||||
storage.setItem( key, parsed );
|
|
||||||
} catch ( error ) {
|
|
||||||
throw store.error();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
// localStorage + sessionStorage
|
|
||||||
// IE 8+, Firefox 3.5+, Safari 4+, Chrome 4+, Opera 10.5+, iPhone 2+, Android 2+
|
|
||||||
for ( var webStorageType in { localStorage : 1, sessionStorage : 1 } ) {
|
|
||||||
// try/catch for file protocol in Firefox
|
|
||||||
try {
|
|
||||||
if ( window[ webStorageType ].getItem ) {
|
|
||||||
createFromStorageInterface( webStorageType, window[ webStorageType ] );
|
|
||||||
}
|
|
||||||
} catch ( e ) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// globalStorage
|
|
||||||
// non-standard: Firefox 2+
|
|
||||||
// https://developer.mozilla.org/en/dom/storage#globalStorage
|
|
||||||
if ( window.globalStorage ) {
|
|
||||||
// try/catch for file protocol in Firefox
|
|
||||||
try {
|
|
||||||
createFromStorageInterface( "globalStorage",
|
|
||||||
window.globalStorage[ window.location.hostname ] );
|
|
||||||
// Firefox 2.0 and 3.0 have sessionStorage and globalStorage
|
|
||||||
// make sure we default to globalStorage
|
|
||||||
// but don't default to globalStorage in 3.5+ which also has localStorage
|
|
||||||
if ( store.type === "sessionStorage" ) {
|
|
||||||
store.type = "globalStorage";
|
|
||||||
}
|
|
||||||
} catch ( e ) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// userData
|
|
||||||
// non-standard: IE 5+
|
|
||||||
// http://msdn.microsoft.com/en-us/library/ms531424(v=vs.85).aspx
|
|
||||||
(function () {
|
|
||||||
// IE 9 has quirks in userData that are a huge pain
|
|
||||||
// rather than finding a way to detect these quirks
|
|
||||||
// we just don't register userData if we have localStorage
|
|
||||||
if ( store.types.localStorage ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// append to html instead of body so we can do this from the head
|
|
||||||
var div = document.createElement( "div" ),
|
|
||||||
attrKey = "amplify";
|
|
||||||
div.style.display = "none";
|
|
||||||
document.getElementsByTagName( "head" )[ 0 ].appendChild( div );
|
|
||||||
if ( div.addBehavior ) {
|
|
||||||
div.addBehavior( "#default#userdata" );
|
|
||||||
|
|
||||||
store.addType( "userData", function ( key, value, options ) {
|
|
||||||
div.load( attrKey );
|
|
||||||
var attr, parsed, prevValue, i, remove,
|
|
||||||
ret = value,
|
|
||||||
now = (new Date()).getTime();
|
|
||||||
|
|
||||||
if ( !key ) {
|
|
||||||
ret = {};
|
|
||||||
remove = [];
|
|
||||||
i = 0;
|
|
||||||
while ( attr = div.XMLDocument.documentElement.attributes[ i++ ] ) {
|
|
||||||
parsed = JSON.parse( attr.value );
|
|
||||||
if ( parsed.expires && parsed.expires <= now ) {
|
|
||||||
remove.push( attr.name );
|
|
||||||
} else {
|
|
||||||
ret[ attr.name ] = parsed.data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ( key = remove.pop() ) {
|
|
||||||
div.removeAttribute( key );
|
|
||||||
}
|
|
||||||
div.save( attrKey );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert invalid characters to dashes
|
|
||||||
// http://www.w3.org/TR/REC-xml/#NT-Name
|
|
||||||
// simplified to assume the starting character is valid
|
|
||||||
// also removed colon as it is invalid in HTML attribute names
|
|
||||||
key = key.replace( /[^-._0-9A-Za-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u37f-\u1fff\u200c-\u200d\u203f\u2040\u2070-\u218f]/g, "-" );
|
|
||||||
|
|
||||||
if ( value === undefined ) {
|
|
||||||
attr = div.getAttribute( key );
|
|
||||||
parsed = attr ? JSON.parse( attr ) : { expires : -1 };
|
|
||||||
if ( parsed.expires && parsed.expires <= now ) {
|
|
||||||
div.removeAttribute( key );
|
|
||||||
} else {
|
|
||||||
return parsed.data;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( value === null ) {
|
|
||||||
div.removeAttribute( key );
|
|
||||||
} else {
|
|
||||||
// we need to get the previous value in case we need to rollback
|
|
||||||
prevValue = div.getAttribute( key );
|
|
||||||
parsed = JSON.stringify( {
|
|
||||||
data : value,
|
|
||||||
expires : (options.expires ? (now + options.expires) : null)
|
|
||||||
} );
|
|
||||||
div.setAttribute( key, parsed );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
div.save( attrKey );
|
|
||||||
// quota exceeded
|
|
||||||
} catch ( error ) {
|
|
||||||
// roll the value back to the previous value
|
|
||||||
if ( prevValue === null ) {
|
|
||||||
div.removeAttribute( key );
|
|
||||||
} else {
|
|
||||||
div.setAttribute( key, prevValue );
|
|
||||||
}
|
|
||||||
|
|
||||||
// expire old data and try again
|
|
||||||
store.userData();
|
|
||||||
try {
|
|
||||||
div.setAttribute( key, parsed );
|
|
||||||
div.save( attrKey );
|
|
||||||
} catch ( error ) {
|
|
||||||
// roll the value back to the previous value
|
|
||||||
if ( prevValue === null ) {
|
|
||||||
div.removeAttribute( key );
|
|
||||||
} else {
|
|
||||||
div.setAttribute( key, prevValue );
|
|
||||||
}
|
|
||||||
throw store.error();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}() );
|
|
||||||
|
|
||||||
// in-memory storage
|
|
||||||
// fallback for all browsers to enable the API even if we can't persist data
|
|
||||||
(function () {
|
|
||||||
var memory = {};
|
|
||||||
|
|
||||||
function copy( obj ) {
|
|
||||||
return obj === undefined ? undefined : JSON.parse( JSON.stringify( obj ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
store.addType( "memory", function ( key, value, options ) {
|
|
||||||
if ( !key ) {
|
|
||||||
return copy( memory );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( value === undefined ) {
|
|
||||||
return copy( memory[ key ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( value === null ) {
|
|
||||||
delete memory[ key ];
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
memory[ key ] = value;
|
|
||||||
if ( options.expires ) {
|
|
||||||
setTimeout( function () {
|
|
||||||
delete memory[ key ];
|
|
||||||
}, options.expires );
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
} );
|
|
||||||
}() );
|
|
||||||
|
|
||||||
}( this.amplify = this.amplify || {} ) );
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
var socket, port;
|
|
||||||
|
|
||||||
$( function () {
|
|
||||||
port = window.location.port
|
|
||||||
socket = io.connect( "http://" + document.domain + ':' + port + '/' );
|
|
||||||
socket.on( 'connect', function () {
|
|
||||||
socket.on( 'refresh', function () {
|
|
||||||
window.location.reload();
|
|
||||||
} );
|
|
||||||
socket.on( 'reconnecting', function () {
|
|
||||||
console.log( 'Lost connection to anvil, attempting to reconnect', 'warning' );
|
|
||||||
} );
|
|
||||||
socket.on( 'reconnect', function () {
|
|
||||||
alert( 'Reconnection to anvil succeeded' );
|
|
||||||
} );
|
|
||||||
socket.on( 'reconnect_failed', function () {
|
|
||||||
console.log( 'Reconnected to anvil failed', 'error' );
|
|
||||||
} );
|
|
||||||
socket.on( 'connect_failed', function () {
|
|
||||||
console.log( 'Could not connect to anvil', 'error' );
|
|
||||||
} );
|
|
||||||
socket.on( 'disconnect', function () {
|
|
||||||
alert( 'Anvil server has disconnected', 'error' );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
9
ext/bootstrap-responsive.min.css
vendored
9
ext/bootstrap-responsive.min.css
vendored
File diff suppressed because one or more lines are too long
9
ext/bootstrap.min.css
vendored
9
ext/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
6
ext/bootstrap.min.js
vendored
6
ext/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
1284
ext/expect.js
1284
ext/expect.js
File diff suppressed because it is too large
Load diff
9266
ext/jquery-1.7.1.js
vendored
9266
ext/jquery-1.7.1.js
vendored
File diff suppressed because it is too large
Load diff
3320
ext/jquery.js
vendored
3320
ext/jquery.js
vendored
File diff suppressed because it is too large
Load diff
270
ext/mocha.css
270
ext/mocha.css
|
|
@ -1,270 +0,0 @@
|
||||||
@charset "utf-8";
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha {
|
|
||||||
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
margin: 60px 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha ul,
|
|
||||||
#mocha li {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha ul {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha h1,
|
|
||||||
#mocha h2 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha h1 {
|
|
||||||
margin-top: 15px;
|
|
||||||
font-size: 1em;
|
|
||||||
font-weight: 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha h1 a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha h1 a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .suite .suite h1 {
|
|
||||||
margin-top: 0;
|
|
||||||
font-size: .8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha h2 {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: normal;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .suite {
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test {
|
|
||||||
margin-left: 15px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.pending:hover h2::after {
|
|
||||||
content: '(pending)';
|
|
||||||
font-family: arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.pass.medium .duration {
|
|
||||||
background: #c09853;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.pass.slow .duration {
|
|
||||||
background: #b94a48;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.pass::before {
|
|
||||||
content: '✓';
|
|
||||||
font-size: 12px;
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
margin-right: 5px;
|
|
||||||
color: #00d6b2;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.pass .duration {
|
|
||||||
font-size: 9px;
|
|
||||||
margin-left: 5px;
|
|
||||||
padding: 2px 5px;
|
|
||||||
color: #fff;
|
|
||||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
|
||||||
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
|
||||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
-ms-border-radius: 5px;
|
|
||||||
-o-border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.pass.fast .duration {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.pending {
|
|
||||||
color: #0b97c4;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.pending::before {
|
|
||||||
content: '◦';
|
|
||||||
color: #0b97c4;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.fail {
|
|
||||||
color: #c00;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.fail pre {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test.fail::before {
|
|
||||||
content: '✖';
|
|
||||||
font-size: 12px;
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
margin-right: 5px;
|
|
||||||
color: #c00;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test pre.error {
|
|
||||||
color: #c00;
|
|
||||||
max-height: 300px;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (1): approximate for browsers not supporting calc
|
|
||||||
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
|
|
||||||
* ^^ seriously
|
|
||||||
*/
|
|
||||||
#mocha .test pre {
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
clear: left;
|
|
||||||
font: 12px/1.5 monaco, monospace;
|
|
||||||
margin: 5px;
|
|
||||||
padding: 15px;
|
|
||||||
border: 1px solid #eee;
|
|
||||||
max-width: 85%; /*(1)*/
|
|
||||||
max-width: calc(100% - 42px); /*(2)*/
|
|
||||||
word-wrap: break-word;
|
|
||||||
border-bottom-color: #ddd;
|
|
||||||
-webkit-border-radius: 3px;
|
|
||||||
-webkit-box-shadow: 0 1px 3px #eee;
|
|
||||||
-moz-border-radius: 3px;
|
|
||||||
-moz-box-shadow: 0 1px 3px #eee;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test h2 {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test a.replay {
|
|
||||||
position: absolute;
|
|
||||||
top: 3px;
|
|
||||||
right: 0;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: middle;
|
|
||||||
display: block;
|
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
line-height: 15px;
|
|
||||||
text-align: center;
|
|
||||||
background: #eee;
|
|
||||||
font-size: 15px;
|
|
||||||
-moz-border-radius: 15px;
|
|
||||||
border-radius: 15px;
|
|
||||||
-webkit-transition: opacity 200ms;
|
|
||||||
-moz-transition: opacity 200ms;
|
|
||||||
transition: opacity 200ms;
|
|
||||||
opacity: 0.3;
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha .test:hover a.replay {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-report.pass .test.fail {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-report.fail .test.pass {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-report.pending .test.pass,
|
|
||||||
#mocha-report.pending .test.fail {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#mocha-report.pending .test.pass.pending {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-error {
|
|
||||||
color: #c00;
|
|
||||||
font-size: 1.5em;
|
|
||||||
font-weight: 100;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-stats {
|
|
||||||
position: fixed;
|
|
||||||
top: 15px;
|
|
||||||
right: 10px;
|
|
||||||
font-size: 12px;
|
|
||||||
margin: 0;
|
|
||||||
color: #888;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-stats .progress {
|
|
||||||
float: right;
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-stats em {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-stats a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-stats a:hover {
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-stats li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 5px;
|
|
||||||
list-style: none;
|
|
||||||
padding-top: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha-stats canvas {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha code .comment { color: #ddd; }
|
|
||||||
#mocha code .init { color: #2f6fad; }
|
|
||||||
#mocha code .string { color: #5890ad; }
|
|
||||||
#mocha code .keyword { color: #8a6343; }
|
|
||||||
#mocha code .number { color: #2f6fad; }
|
|
||||||
|
|
||||||
@media screen and (max-device-width: 480px) {
|
|
||||||
#mocha {
|
|
||||||
margin: 60px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mocha #stats {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
5791
ext/mocha.js
5791
ext/mocha.js
File diff suppressed because it is too large
Load diff
723
ext/moment.js
723
ext/moment.js
|
|
@ -1,723 +0,0 @@
|
||||||
// moment.js
|
|
||||||
// version : 1.5.0
|
|
||||||
// author : Tim Wood
|
|
||||||
// license : MIT
|
|
||||||
// momentjs.com
|
|
||||||
(function ( Date, undefined ) {
|
|
||||||
|
|
||||||
var moment, round = Math.round,
|
|
||||||
languages = {},
|
|
||||||
hasModule = (typeof module !== 'undefined'),
|
|
||||||
paramsToParse = 'months|monthsShort|monthsParse|weekdays|weekdaysShort|longDateFormat|calendar|relativeTime|ordinal|meridiem'.split( '|' ),
|
|
||||||
i, jsonRegex = /^\/?Date\((\-?\d+)/i,
|
|
||||||
charactersToReplace = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?|ZZ?|LT|LL?L?L?)/g,
|
|
||||||
nonuppercaseLetters = /[^A-Z]/g,
|
|
||||||
timezoneRegex = /\([A-Za-z ]+\)|:[0-9]{2} [A-Z]{3} /g,
|
|
||||||
tokenCharacters = /(\\)?(MM?M?M?|dd?d?d|DD?D?D?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|ZZ?|T)/g,
|
|
||||||
inputCharacters = /(\\)?([0-9]+|([a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+|([\+\-]\d\d:?\d\d))/gi,
|
|
||||||
isoRegex = /\d{4}.\d\d.\d\d(T(\d\d(.\d\d(.\d\d)?)?)?([\+\-]\d\d:?\d\d)?)?/,
|
|
||||||
isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
|
|
||||||
isoTimes = [
|
|
||||||
['HH:mm:ss', /T\d\d:\d\d:\d\d/],
|
|
||||||
['HH:mm', /T\d\d:\d\d/],
|
|
||||||
['HH', /T\d\d/]
|
|
||||||
],
|
|
||||||
timezoneParseRegex = /([\+\-]|\d\d)/gi,
|
|
||||||
VERSION = "1.5.0",
|
|
||||||
shortcuts = 'Month|Date|Hours|Minutes|Seconds|Milliseconds'.split( '|' );
|
|
||||||
|
|
||||||
// Moment prototype object
|
|
||||||
|
|
||||||
|
|
||||||
function Moment( date, isUTC ) {
|
|
||||||
this._d = date;
|
|
||||||
this._isUTC = !!isUTC;
|
|
||||||
}
|
|
||||||
|
|
||||||
// left zero fill a number
|
|
||||||
// see http://jsperf.com/left-zero-filling for performance comparison
|
|
||||||
|
|
||||||
|
|
||||||
function leftZeroFill( number, targetLength ) {
|
|
||||||
var output = number + '';
|
|
||||||
while ( output.length < targetLength ) {
|
|
||||||
output = '0' + output;
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function for _.addTime and _.subtractTime
|
|
||||||
|
|
||||||
|
|
||||||
function dateAddRemove( date, _input, adding, val ) {
|
|
||||||
var isString = (typeof _input === 'string'),
|
|
||||||
input = isString ? {} : _input,
|
|
||||||
ms, d, M, currentDate;
|
|
||||||
if ( isString && val ) {
|
|
||||||
input[_input] = +val;
|
|
||||||
}
|
|
||||||
ms = (input.ms || input.milliseconds || 0) + (input.s || input.seconds || 0) * 1e3 + // 1000
|
|
||||||
(input.m || input.minutes || 0) * 6e4 + // 1000 * 60
|
|
||||||
(input.h || input.hours || 0) * 36e5; // 1000 * 60 * 60
|
|
||||||
d = (input.d || input.days || 0) + (input.w || input.weeks || 0) * 7;
|
|
||||||
M = (input.M || input.months || 0) + (input.y || input.years || 0) * 12;
|
|
||||||
if ( ms ) {
|
|
||||||
date.setTime( +date + ms * adding );
|
|
||||||
}
|
|
||||||
if ( d ) {
|
|
||||||
date.setDate( date.getDate() + d * adding );
|
|
||||||
}
|
|
||||||
if ( M ) {
|
|
||||||
currentDate = date.getDate();
|
|
||||||
date.setDate( 1 );
|
|
||||||
date.setMonth( date.getMonth() + M * adding );
|
|
||||||
date.setDate( Math.min( new Date( date.getFullYear(), date.getMonth() + 1, 0 ).getDate(), currentDate ) );
|
|
||||||
}
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if is an array
|
|
||||||
|
|
||||||
|
|
||||||
function isArray( input ) {
|
|
||||||
return Object.prototype.toString.call( input ) === '[object Array]';
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert an array to a date.
|
|
||||||
// the array should mirror the parameters below
|
|
||||||
// note: all values past the year are optional and will default to the lowest possible value.
|
|
||||||
// [year, month, day , hour, minute, second, millisecond]
|
|
||||||
|
|
||||||
|
|
||||||
function dateFromArray( input ) {
|
|
||||||
return new Date( input[0], input[1] || 0, input[2] || 1, input[3] || 0, input[4] || 0, input[5] || 0, input[6] || 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// format date using native date object
|
|
||||||
|
|
||||||
|
|
||||||
function formatMoment( m, inputString ) {
|
|
||||||
var currentMonth = m.month(),
|
|
||||||
currentDate = m.date(),
|
|
||||||
currentYear = m.year(),
|
|
||||||
currentDay = m.day(),
|
|
||||||
currentHours = m.hours(),
|
|
||||||
currentMinutes = m.minutes(),
|
|
||||||
currentSeconds = m.seconds(),
|
|
||||||
currentZone = -m.zone(),
|
|
||||||
ordinal = moment.ordinal,
|
|
||||||
meridiem = moment.meridiem;
|
|
||||||
// check if the character is a format
|
|
||||||
// return formatted string or non string.
|
|
||||||
//
|
|
||||||
// uses switch/case instead of an object of named functions (like http://phpjs.org/functions/date:380)
|
|
||||||
// for minification and performance
|
|
||||||
// see http://jsperf.com/object-of-functions-vs-switch for performance comparison
|
|
||||||
|
|
||||||
|
|
||||||
function replaceFunction( input ) {
|
|
||||||
// create a couple variables to be used later inside one of the cases.
|
|
||||||
var a, b;
|
|
||||||
switch ( input ) {
|
|
||||||
// MONTH
|
|
||||||
case 'M':
|
|
||||||
return currentMonth + 1;
|
|
||||||
case 'Mo':
|
|
||||||
return (currentMonth + 1) + ordinal( currentMonth + 1 );
|
|
||||||
case 'MM':
|
|
||||||
return leftZeroFill( currentMonth + 1, 2 );
|
|
||||||
case 'MMM':
|
|
||||||
return moment.monthsShort[currentMonth];
|
|
||||||
case 'MMMM':
|
|
||||||
return moment.months[currentMonth];
|
|
||||||
// DAY OF MONTH
|
|
||||||
case 'D':
|
|
||||||
return currentDate;
|
|
||||||
case 'Do':
|
|
||||||
return currentDate + ordinal( currentDate );
|
|
||||||
case 'DD':
|
|
||||||
return leftZeroFill( currentDate, 2 );
|
|
||||||
// DAY OF YEAR
|
|
||||||
case 'DDD':
|
|
||||||
a = new Date( currentYear, currentMonth, currentDate );
|
|
||||||
b = new Date( currentYear, 0, 1 );
|
|
||||||
return ~~(((a - b) / 864e5) + 1.5);
|
|
||||||
case 'DDDo':
|
|
||||||
a = replaceFunction( 'DDD' );
|
|
||||||
return a + ordinal( a );
|
|
||||||
case 'DDDD':
|
|
||||||
return leftZeroFill( replaceFunction( 'DDD' ), 3 );
|
|
||||||
// WEEKDAY
|
|
||||||
case 'd':
|
|
||||||
return currentDay;
|
|
||||||
case 'do':
|
|
||||||
return currentDay + ordinal( currentDay );
|
|
||||||
case 'ddd':
|
|
||||||
return moment.weekdaysShort[currentDay];
|
|
||||||
case 'dddd':
|
|
||||||
return moment.weekdays[currentDay];
|
|
||||||
// WEEK OF YEAR
|
|
||||||
case 'w':
|
|
||||||
a = new Date( currentYear, currentMonth, currentDate - currentDay + 5 );
|
|
||||||
b = new Date( a.getFullYear(), 0, 4 );
|
|
||||||
return ~~((a - b) / 864e5 / 7 + 1.5);
|
|
||||||
case 'wo':
|
|
||||||
a = replaceFunction( 'w' );
|
|
||||||
return a + ordinal( a );
|
|
||||||
case 'ww':
|
|
||||||
return leftZeroFill( replaceFunction( 'w' ), 2 );
|
|
||||||
// YEAR
|
|
||||||
case 'YY':
|
|
||||||
return leftZeroFill( currentYear % 100, 2 );
|
|
||||||
case 'YYYY':
|
|
||||||
return currentYear;
|
|
||||||
// AM / PM
|
|
||||||
case 'a':
|
|
||||||
return currentHours > 11 ? meridiem.pm : meridiem.am;
|
|
||||||
case 'A':
|
|
||||||
return currentHours > 11 ? meridiem.PM : meridiem.AM;
|
|
||||||
// 24 HOUR
|
|
||||||
case 'H':
|
|
||||||
return currentHours;
|
|
||||||
case 'HH':
|
|
||||||
return leftZeroFill( currentHours, 2 );
|
|
||||||
// 12 HOUR
|
|
||||||
case 'h':
|
|
||||||
return currentHours % 12 || 12;
|
|
||||||
case 'hh':
|
|
||||||
return leftZeroFill( currentHours % 12 || 12, 2 );
|
|
||||||
// MINUTE
|
|
||||||
case 'm':
|
|
||||||
return currentMinutes;
|
|
||||||
case 'mm':
|
|
||||||
return leftZeroFill( currentMinutes, 2 );
|
|
||||||
// SECOND
|
|
||||||
case 's':
|
|
||||||
return currentSeconds;
|
|
||||||
case 'ss':
|
|
||||||
return leftZeroFill( currentSeconds, 2 );
|
|
||||||
// TIMEZONE
|
|
||||||
case 'zz':
|
|
||||||
// depreciating 'zz' fall through to 'z'
|
|
||||||
case 'z':
|
|
||||||
return (m._d.toString().match( timezoneRegex ) || [''])[0].replace( nonuppercaseLetters, '' );
|
|
||||||
case 'Z':
|
|
||||||
return (currentZone < 0 ? '-' : '+') + leftZeroFill( ~~(Math.abs( currentZone ) / 60), 2 ) + ':' + leftZeroFill( ~~(Math.abs( currentZone ) % 60), 2 );
|
|
||||||
case 'ZZ':
|
|
||||||
return (currentZone < 0 ? '-' : '+') + leftZeroFill( ~~(10 * Math.abs( currentZone ) / 6), 4 );
|
|
||||||
// LONG DATES
|
|
||||||
case 'L':
|
|
||||||
case 'LL':
|
|
||||||
case 'LLL':
|
|
||||||
case 'LLLL':
|
|
||||||
case 'LT':
|
|
||||||
return formatMoment( m, moment.longDateFormat[input] );
|
|
||||||
// DEFAULT
|
|
||||||
default:
|
|
||||||
return input.replace( /(^\[)|(\\)|\]$/g, "" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return inputString.replace( charactersToReplace, replaceFunction );
|
|
||||||
}
|
|
||||||
|
|
||||||
// date from string and format string
|
|
||||||
|
|
||||||
|
|
||||||
function makeDateFromStringAndFormat( string, format ) {
|
|
||||||
var inArray = [0, 0, 1, 0, 0, 0, 0],
|
|
||||||
timezoneHours = 0,
|
|
||||||
timezoneMinutes = 0,
|
|
||||||
isUsingUTC = false,
|
|
||||||
inputParts = string.match( inputCharacters ),
|
|
||||||
formatParts = format.match( tokenCharacters ),
|
|
||||||
len = Math.min( inputParts.length, formatParts.length ),
|
|
||||||
i, isPm;
|
|
||||||
|
|
||||||
// function to convert string input to date
|
|
||||||
|
|
||||||
|
|
||||||
function addTime( format, input ) {
|
|
||||||
var a;
|
|
||||||
switch ( format ) {
|
|
||||||
// MONTH
|
|
||||||
case 'M':
|
|
||||||
// fall through to MM
|
|
||||||
case 'MM':
|
|
||||||
inArray[1] = ~~input - 1;
|
|
||||||
break;
|
|
||||||
case 'MMM':
|
|
||||||
// fall through to MMMM
|
|
||||||
case 'MMMM':
|
|
||||||
for ( a = 0; a < 12; a++ ) {
|
|
||||||
if ( moment.monthsParse[a].test( input ) ) {
|
|
||||||
inArray[1] = a;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// DAY OF MONTH
|
|
||||||
case 'D':
|
|
||||||
// fall through to DDDD
|
|
||||||
case 'DD':
|
|
||||||
// fall through to DDDD
|
|
||||||
case 'DDD':
|
|
||||||
// fall through to DDDD
|
|
||||||
case 'DDDD':
|
|
||||||
inArray[2] = ~~input;
|
|
||||||
break;
|
|
||||||
// YEAR
|
|
||||||
case 'YY':
|
|
||||||
input = ~~input;
|
|
||||||
inArray[0] = input + (input > 70 ? 1900 : 2000);
|
|
||||||
break;
|
|
||||||
case 'YYYY':
|
|
||||||
inArray[0] = ~~Math.abs( input );
|
|
||||||
break;
|
|
||||||
// AM / PM
|
|
||||||
case 'a':
|
|
||||||
// fall through to A
|
|
||||||
case 'A':
|
|
||||||
isPm = (input.toLowerCase() === 'pm');
|
|
||||||
break;
|
|
||||||
// 24 HOUR
|
|
||||||
case 'H':
|
|
||||||
// fall through to hh
|
|
||||||
case 'HH':
|
|
||||||
// fall through to hh
|
|
||||||
case 'h':
|
|
||||||
// fall through to hh
|
|
||||||
case 'hh':
|
|
||||||
inArray[3] = ~~input;
|
|
||||||
break;
|
|
||||||
// MINUTE
|
|
||||||
case 'm':
|
|
||||||
// fall through to mm
|
|
||||||
case 'mm':
|
|
||||||
inArray[4] = ~~input;
|
|
||||||
break;
|
|
||||||
// SECOND
|
|
||||||
case 's':
|
|
||||||
// fall through to ss
|
|
||||||
case 'ss':
|
|
||||||
inArray[5] = ~~input;
|
|
||||||
break;
|
|
||||||
// TIMEZONE
|
|
||||||
case 'Z':
|
|
||||||
// fall through to ZZ
|
|
||||||
case 'ZZ':
|
|
||||||
isUsingUTC = true;
|
|
||||||
a = (input || '').match( timezoneParseRegex );
|
|
||||||
if ( a && a[1] ) {
|
|
||||||
timezoneHours = ~~a[1];
|
|
||||||
}
|
|
||||||
if ( a && a[2] ) {
|
|
||||||
timezoneMinutes = ~~a[2];
|
|
||||||
}
|
|
||||||
// reverse offsets
|
|
||||||
if ( a && a[0] === '+' ) {
|
|
||||||
timezoneHours = -timezoneHours;
|
|
||||||
timezoneMinutes = -timezoneMinutes;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0; i < len; i++ ) {
|
|
||||||
addTime( formatParts[i], inputParts[i] );
|
|
||||||
}
|
|
||||||
// handle am pm
|
|
||||||
if ( isPm && inArray[3] < 12 ) {
|
|
||||||
inArray[3] += 12;
|
|
||||||
}
|
|
||||||
// if is 12 am, change hours to 0
|
|
||||||
if ( isPm === false && inArray[3] === 12 ) {
|
|
||||||
inArray[3] = 0;
|
|
||||||
}
|
|
||||||
// handle timezone
|
|
||||||
inArray[3] += timezoneHours;
|
|
||||||
inArray[4] += timezoneMinutes;
|
|
||||||
// return
|
|
||||||
return isUsingUTC ? new Date( Date.UTC.apply( {}, inArray ) ) : dateFromArray( inArray );
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare two arrays, return the number of differences
|
|
||||||
|
|
||||||
|
|
||||||
function compareArrays( array1, array2 ) {
|
|
||||||
var len = Math.min( array1.length, array2.length ),
|
|
||||||
lengthDiff = Math.abs( array1.length - array2.length ),
|
|
||||||
diffs = 0,
|
|
||||||
i;
|
|
||||||
for ( i = 0; i < len; i++ ) {
|
|
||||||
if ( ~~array1[i] !== ~~array2[i] ) {
|
|
||||||
diffs++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return diffs + lengthDiff;
|
|
||||||
}
|
|
||||||
|
|
||||||
// date from string and array of format strings
|
|
||||||
|
|
||||||
|
|
||||||
function makeDateFromStringAndArray( string, formats ) {
|
|
||||||
var output, inputParts = string.match( inputCharacters ),
|
|
||||||
scores = [],
|
|
||||||
scoreToBeat = 99,
|
|
||||||
i, curDate, curScore;
|
|
||||||
for ( i = 0; i < formats.length; i++ ) {
|
|
||||||
curDate = makeDateFromStringAndFormat( string, formats[i] );
|
|
||||||
curScore = compareArrays( inputParts, formatMoment( new Moment( curDate ), formats[i] ).match( inputCharacters ) );
|
|
||||||
if ( curScore < scoreToBeat ) {
|
|
||||||
scoreToBeat = curScore;
|
|
||||||
output = curDate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
// date from iso format
|
|
||||||
|
|
||||||
|
|
||||||
function makeDateFromString( string ) {
|
|
||||||
var format = 'YYYY-MM-DDT',
|
|
||||||
i;
|
|
||||||
if ( isoRegex.exec( string ) ) {
|
|
||||||
for ( i = 0; i < 3; i++ ) {
|
|
||||||
if ( isoTimes[i][1].exec( string ) ) {
|
|
||||||
format += isoTimes[i][0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return makeDateFromStringAndFormat( string, format + 'Z' );
|
|
||||||
}
|
|
||||||
return new Date( string );
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function for _date.from() and _date.fromNow()
|
|
||||||
|
|
||||||
|
|
||||||
function substituteTimeAgo( string, number, withoutSuffix ) {
|
|
||||||
var rt = moment.relativeTime[string];
|
|
||||||
return (typeof rt === 'function') ? rt( number || 1, !!withoutSuffix, string ) : rt.replace( /%d/i, number || 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
function relativeTime( milliseconds, withoutSuffix ) {
|
|
||||||
var seconds = round( Math.abs( milliseconds ) / 1000 ),
|
|
||||||
minutes = round( seconds / 60 ),
|
|
||||||
hours = round( minutes / 60 ),
|
|
||||||
days = round( hours / 24 ),
|
|
||||||
years = round( days / 365 ),
|
|
||||||
args = seconds < 45 && ['s', seconds] || minutes === 1 && ['m'] || minutes < 45 && ['mm', minutes] || hours === 1 && ['h'] || hours < 22 && ['hh', hours] || days === 1 && ['d'] || days <= 25 && ['dd', days] || days <= 45 && ['M'] || days < 345 && ['MM', round( days / 30 )] || years === 1 && ['y'] || ['yy', years];
|
|
||||||
args[2] = withoutSuffix;
|
|
||||||
return substituteTimeAgo.apply( {}, args );
|
|
||||||
}
|
|
||||||
|
|
||||||
moment = function ( input, format ) {
|
|
||||||
if ( input === null || input === '' ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
var date, matched;
|
|
||||||
// parse Moment object
|
|
||||||
if ( input && input._d instanceof Date ) {
|
|
||||||
date = new Date( +input._d );
|
|
||||||
// parse string and format
|
|
||||||
} else if ( format ) {
|
|
||||||
if ( isArray( format ) ) {
|
|
||||||
date = makeDateFromStringAndArray( input, format );
|
|
||||||
} else {
|
|
||||||
date = makeDateFromStringAndFormat( input, format );
|
|
||||||
}
|
|
||||||
// evaluate it as a JSON-encoded date
|
|
||||||
} else {
|
|
||||||
matched = jsonRegex.exec( input );
|
|
||||||
date = input === undefined ? new Date() : matched ? new Date( +matched[1] ) : input instanceof Date ? input : isArray( input ) ? dateFromArray( input ) : typeof input === 'string' ? makeDateFromString( input ) : new Date( input );
|
|
||||||
}
|
|
||||||
return new Moment( date );
|
|
||||||
};
|
|
||||||
|
|
||||||
// creating with utc
|
|
||||||
moment.utc = function ( input, format ) {
|
|
||||||
if ( isArray( input ) ) {
|
|
||||||
return new Moment( new Date( Date.UTC.apply( {}, input ) ), true );
|
|
||||||
}
|
|
||||||
return (format && input) ? moment( input + ' 0', format + ' Z' ).utc() : moment( input ).utc();
|
|
||||||
};
|
|
||||||
|
|
||||||
// humanizeDuration
|
|
||||||
moment.humanizeDuration = function ( num, type, withSuffix ) {
|
|
||||||
var difference = +num,
|
|
||||||
rel = moment.relativeTime,
|
|
||||||
output;
|
|
||||||
switch ( type ) {
|
|
||||||
case "seconds":
|
|
||||||
difference *= 1000; // 1000
|
|
||||||
break;
|
|
||||||
case "minutes":
|
|
||||||
difference *= 60000; // 60 * 1000
|
|
||||||
break;
|
|
||||||
case "hours":
|
|
||||||
difference *= 3600000; // 60 * 60 * 1000
|
|
||||||
break;
|
|
||||||
case "days":
|
|
||||||
difference *= 86400000; // 24 * 60 * 60 * 1000
|
|
||||||
break;
|
|
||||||
case "weeks":
|
|
||||||
difference *= 604800000; // 7 * 24 * 60 * 60 * 1000
|
|
||||||
break;
|
|
||||||
case "months":
|
|
||||||
difference *= 2592000000; // 30 * 24 * 60 * 60 * 1000
|
|
||||||
break;
|
|
||||||
case "years":
|
|
||||||
difference *= 31536000000; // 365 * 24 * 60 * 60 * 1000
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
withSuffix = !!type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
output = relativeTime( difference, !withSuffix );
|
|
||||||
return withSuffix ? (difference <= 0 ? rel.past : rel.future).replace( /%s/i, output ) : output;
|
|
||||||
};
|
|
||||||
|
|
||||||
// version number
|
|
||||||
moment.version = VERSION;
|
|
||||||
|
|
||||||
// default format
|
|
||||||
moment.defaultFormat = isoFormat;
|
|
||||||
|
|
||||||
// language switching and caching
|
|
||||||
moment.lang = function ( key, values ) {
|
|
||||||
var i, param, req, parse = [];
|
|
||||||
if ( values ) {
|
|
||||||
for ( i = 0; i < 12; i++ ) {
|
|
||||||
parse[i] = new RegExp( '^' + values.months[i] + '|^' + values.monthsShort[i].replace( '.', '' ), 'i' );
|
|
||||||
}
|
|
||||||
values.monthsParse = values.monthsParse || parse;
|
|
||||||
languages[key] = values;
|
|
||||||
}
|
|
||||||
if ( languages[key] ) {
|
|
||||||
for ( i = 0; i < paramsToParse.length; i++ ) {
|
|
||||||
param = paramsToParse[i];
|
|
||||||
moment[param] = languages[key][param] || moment[param];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( hasModule ) {
|
|
||||||
req = require( './lang/' + key );
|
|
||||||
moment.lang( key, req );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// set default language
|
|
||||||
moment.lang( 'en', {
|
|
||||||
months : "January_February_March_April_May_June_July_August_September_October_November_December".split( "_" ),
|
|
||||||
monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split( "_" ),
|
|
||||||
weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split( "_" ),
|
|
||||||
weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split( "_" ),
|
|
||||||
longDateFormat : {
|
|
||||||
LT : "h:mm A",
|
|
||||||
L : "MM/DD/YYYY",
|
|
||||||
LL : "MMMM D YYYY",
|
|
||||||
LLL : "MMMM D YYYY LT",
|
|
||||||
LLLL : "dddd, MMMM D YYYY LT"
|
|
||||||
},
|
|
||||||
meridiem : {
|
|
||||||
AM : 'AM',
|
|
||||||
am : 'am',
|
|
||||||
PM : 'PM',
|
|
||||||
pm : 'pm'
|
|
||||||
},
|
|
||||||
calendar : {
|
|
||||||
sameDay : '[Today at] LT',
|
|
||||||
nextDay : '[Tomorrow at] LT',
|
|
||||||
nextWeek : 'dddd [at] LT',
|
|
||||||
lastDay : '[Yesterday at] LT',
|
|
||||||
lastWeek : '[last] dddd [at] LT',
|
|
||||||
sameElse : 'L'
|
|
||||||
},
|
|
||||||
relativeTime : {
|
|
||||||
future : "in %s",
|
|
||||||
past : "%s ago",
|
|
||||||
s : "a few seconds",
|
|
||||||
m : "a minute",
|
|
||||||
mm : "%d minutes",
|
|
||||||
h : "an hour",
|
|
||||||
hh : "%d hours",
|
|
||||||
d : "a day",
|
|
||||||
dd : "%d days",
|
|
||||||
M : "a month",
|
|
||||||
MM : "%d months",
|
|
||||||
y : "a year",
|
|
||||||
yy : "%d years"
|
|
||||||
},
|
|
||||||
ordinal : function ( number ) {
|
|
||||||
var b = number % 10;
|
|
||||||
return (~~(number % 100 / 10) === 1) ? 'th' : (b === 1) ? 'st' : (b === 2) ? 'nd' : (b === 3) ? 'rd' : 'th';
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
// compare moment object
|
|
||||||
moment.isMoment = function ( obj ) {
|
|
||||||
return obj instanceof Moment;
|
|
||||||
};
|
|
||||||
|
|
||||||
// shortcut for prototype
|
|
||||||
moment.fn = Moment.prototype = {
|
|
||||||
|
|
||||||
clone : function () {
|
|
||||||
return moment( this );
|
|
||||||
},
|
|
||||||
|
|
||||||
valueOf : function () {
|
|
||||||
return +this._d;
|
|
||||||
},
|
|
||||||
|
|
||||||
'native' : function () {
|
|
||||||
return this._d;
|
|
||||||
},
|
|
||||||
|
|
||||||
toString : function () {
|
|
||||||
return this._d.toString();
|
|
||||||
},
|
|
||||||
|
|
||||||
toDate : function () {
|
|
||||||
return this._d;
|
|
||||||
},
|
|
||||||
|
|
||||||
utc : function () {
|
|
||||||
this._isUTC = true;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
local : function () {
|
|
||||||
this._isUTC = false;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
format : function ( inputString ) {
|
|
||||||
return formatMoment( this, inputString ? inputString : moment.defaultFormat );
|
|
||||||
},
|
|
||||||
|
|
||||||
add : function ( input, val ) {
|
|
||||||
this._d = dateAddRemove( this._d, input, 1, val );
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
subtract : function ( input, val ) {
|
|
||||||
this._d = dateAddRemove( this._d, input, -1, val );
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
diff : function ( input, val, asFloat ) {
|
|
||||||
var inputMoment = moment( input ),
|
|
||||||
zoneDiff = (this.zone() - inputMoment.zone()) * 6e4,
|
|
||||||
diff = this._d - inputMoment._d - zoneDiff,
|
|
||||||
year = this.year() - inputMoment.year(),
|
|
||||||
month = this.month() - inputMoment.month(),
|
|
||||||
date = this.date() - inputMoment.date(),
|
|
||||||
output;
|
|
||||||
if ( val === 'months' ) {
|
|
||||||
output = year * 12 + month + date / 30;
|
|
||||||
} else if ( val === 'years' ) {
|
|
||||||
output = year + month / 12;
|
|
||||||
} else {
|
|
||||||
output = val === 'seconds' ? diff / 1e3 : // 1000
|
|
||||||
val === 'minutes' ? diff / 6e4 : // 1000 * 60
|
|
||||||
val === 'hours' ? diff / 36e5 : // 1000 * 60 * 60
|
|
||||||
val === 'days' ? diff / 864e5 : // 1000 * 60 * 60 * 24
|
|
||||||
val === 'weeks' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7
|
|
||||||
diff;
|
|
||||||
}
|
|
||||||
return asFloat ? output : round( output );
|
|
||||||
},
|
|
||||||
|
|
||||||
from : function ( time, withoutSuffix ) {
|
|
||||||
return moment.humanizeDuration( this.diff( time ), !withoutSuffix );
|
|
||||||
},
|
|
||||||
|
|
||||||
fromNow : function ( withoutSuffix ) {
|
|
||||||
return this.from( moment(), withoutSuffix );
|
|
||||||
},
|
|
||||||
|
|
||||||
calendar : function () {
|
|
||||||
var diff = this.diff( moment().sod(), 'days', true ),
|
|
||||||
calendar = moment.calendar,
|
|
||||||
allElse = calendar.sameElse,
|
|
||||||
format = diff < -6 ? allElse : diff < -1 ? calendar.lastWeek : diff < 0 ? calendar.lastDay : diff < 1 ? calendar.sameDay : diff < 2 ? calendar.nextDay : diff < 7 ? calendar.nextWeek : allElse;
|
|
||||||
return this.format( typeof format === 'function' ? format.apply( this ) : format );
|
|
||||||
},
|
|
||||||
|
|
||||||
isLeapYear : function () {
|
|
||||||
var year = this.year();
|
|
||||||
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
isDST : function () {
|
|
||||||
return (this.zone() < moment( [this.year()] ).zone() || this.zone() < moment( [this.year(), 5] ).zone());
|
|
||||||
},
|
|
||||||
|
|
||||||
day : function ( input ) {
|
|
||||||
var day = this._d.getDay();
|
|
||||||
return input == null ? day : this.add( {
|
|
||||||
d : input - day
|
|
||||||
} );
|
|
||||||
},
|
|
||||||
|
|
||||||
sod : function () {
|
|
||||||
return this.clone().hours( 0 ).minutes( 0 ).seconds( 0 ).milliseconds( 0 );
|
|
||||||
},
|
|
||||||
|
|
||||||
eod : function () {
|
|
||||||
// end of day = start of day plus 1 day, minus 1 millisecond
|
|
||||||
return this.sod().add( {
|
|
||||||
d : 1,
|
|
||||||
ms : -1
|
|
||||||
} );
|
|
||||||
},
|
|
||||||
|
|
||||||
zone : function () {
|
|
||||||
return this._isUTC ? 0 : this._d.getTimezoneOffset();
|
|
||||||
},
|
|
||||||
|
|
||||||
daysInMonth : function () {
|
|
||||||
return this.clone().month( this.month() + 1 ).date( 0 ).date();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// helper for adding shortcuts
|
|
||||||
|
|
||||||
|
|
||||||
function makeShortcut( name, key ) {
|
|
||||||
moment.fn[name] = function ( input ) {
|
|
||||||
var utc = this._isUTC ? 'UTC' : '';
|
|
||||||
if ( input != null ) {
|
|
||||||
this._d['set' + utc + key]( input );
|
|
||||||
return this;
|
|
||||||
} else {
|
|
||||||
return this._d['get' + utc + key]();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
|
|
||||||
for ( i = 0; i < shortcuts.length; i++ ) {
|
|
||||||
makeShortcut( shortcuts[i].toLowerCase(), shortcuts[i] );
|
|
||||||
}
|
|
||||||
|
|
||||||
// add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
|
|
||||||
makeShortcut( 'year', 'FullYear' );
|
|
||||||
|
|
||||||
// CommonJS module is defined
|
|
||||||
if ( hasModule ) {
|
|
||||||
module.exports = moment;
|
|
||||||
}
|
|
||||||
if ( typeof window !== 'undefined' ) {
|
|
||||||
window.moment = moment;
|
|
||||||
}
|
|
||||||
/*global define:false */
|
|
||||||
if ( typeof define === "function" && define.amd ) {
|
|
||||||
define( "moment", [], function () {
|
|
||||||
return moment;
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
})( Date );
|
|
||||||
|
|
@ -1,999 +0,0 @@
|
||||||
// Underscore.js 1.1.7
|
|
||||||
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
|
||||||
// Underscore is freely distributable under the MIT license.
|
|
||||||
// Portions of Underscore are inspired or borrowed from Prototype,
|
|
||||||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
|
||||||
// For all details and documentation:
|
|
||||||
// http://documentcloud.github.com/underscore
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
// Baseline setup
|
|
||||||
// --------------
|
|
||||||
|
|
||||||
// Establish the root object, `window` in the browser, or `global` on the server.
|
|
||||||
var root = this;
|
|
||||||
|
|
||||||
// Save the previous value of the `_` variable.
|
|
||||||
var previousUnderscore = root._;
|
|
||||||
|
|
||||||
// Establish the object that gets returned to break out of a loop iteration.
|
|
||||||
var breaker = {};
|
|
||||||
|
|
||||||
// Save bytes in the minified (but not gzipped) version:
|
|
||||||
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
|
||||||
|
|
||||||
// Create quick reference variables for speed access to core prototypes.
|
|
||||||
var slice = ArrayProto.slice,
|
|
||||||
unshift = ArrayProto.unshift,
|
|
||||||
toString = ObjProto.toString,
|
|
||||||
hasOwnProperty = ObjProto.hasOwnProperty;
|
|
||||||
|
|
||||||
// All **ECMAScript 5** native function implementations that we hope to use
|
|
||||||
// are declared here.
|
|
||||||
var
|
|
||||||
nativeForEach = ArrayProto.forEach,
|
|
||||||
nativeMap = ArrayProto.map,
|
|
||||||
nativeReduce = ArrayProto.reduce,
|
|
||||||
nativeReduceRight = ArrayProto.reduceRight,
|
|
||||||
nativeFilter = ArrayProto.filter,
|
|
||||||
nativeEvery = ArrayProto.every,
|
|
||||||
nativeSome = ArrayProto.some,
|
|
||||||
nativeIndexOf = ArrayProto.indexOf,
|
|
||||||
nativeLastIndexOf = ArrayProto.lastIndexOf,
|
|
||||||
nativeIsArray = Array.isArray,
|
|
||||||
nativeKeys = Object.keys,
|
|
||||||
nativeBind = FuncProto.bind;
|
|
||||||
|
|
||||||
// Create a safe reference to the Underscore object for use below.
|
|
||||||
var _ = function ( obj ) {
|
|
||||||
return new wrapper( obj );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Export the Underscore object for **CommonJS**, with backwards-compatibility
|
|
||||||
// for the old `require()` API. If we're not in CommonJS, add `_` to the
|
|
||||||
// global object.
|
|
||||||
if ( typeof module !== 'undefined' && module.exports ) {
|
|
||||||
module.exports = _;
|
|
||||||
_._ = _;
|
|
||||||
} else {
|
|
||||||
// Exported as a string, for Closure Compiler "advanced" mode.
|
|
||||||
root['_'] = _;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Current version.
|
|
||||||
_.VERSION = '1.1.7';
|
|
||||||
|
|
||||||
// Collection Functions
|
|
||||||
// --------------------
|
|
||||||
|
|
||||||
// The cornerstone, an `each` implementation, aka `forEach`.
|
|
||||||
// Handles objects with the built-in `forEach`, arrays, and raw objects.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
|
||||||
var each = _.each = _.forEach = function ( obj, iterator, context ) {
|
|
||||||
if ( obj == null ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( nativeForEach && obj.forEach === nativeForEach ) {
|
|
||||||
obj.forEach( iterator, context );
|
|
||||||
} else if ( obj.length === +obj.length ) {
|
|
||||||
for ( var i = 0, l = obj.length; i < l; i++ ) {
|
|
||||||
if ( i in obj && iterator.call( context, obj[i], i, obj ) === breaker ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for ( var key in obj ) {
|
|
||||||
if ( hasOwnProperty.call( obj, key ) ) {
|
|
||||||
if ( iterator.call( context, obj[key], key, obj ) === breaker ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the results of applying the iterator to each element.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `map` if available.
|
|
||||||
_.map = function ( obj, iterator, context ) {
|
|
||||||
var results = [];
|
|
||||||
if ( obj == null ) {
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
if ( nativeMap && obj.map === nativeMap ) {
|
|
||||||
return obj.map( iterator, context );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
results[results.length] = iterator.call( context, value, index, list );
|
|
||||||
} );
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
|
||||||
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
|
||||||
_.reduce = _.foldl = _.inject = function ( obj, iterator, memo, context ) {
|
|
||||||
var initial = memo !== void 0;
|
|
||||||
if ( obj == null ) {
|
|
||||||
obj = [];
|
|
||||||
}
|
|
||||||
if ( nativeReduce && obj.reduce === nativeReduce ) {
|
|
||||||
if ( context ) {
|
|
||||||
iterator = _.bind( iterator, context );
|
|
||||||
}
|
|
||||||
return initial ? obj.reduce( iterator, memo ) : obj.reduce( iterator );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( !initial ) {
|
|
||||||
memo = value;
|
|
||||||
initial = true;
|
|
||||||
} else {
|
|
||||||
memo = iterator.call( context, memo, value, index, list );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
if ( !initial ) {
|
|
||||||
throw new TypeError( "Reduce of empty array with no initial value" );
|
|
||||||
}
|
|
||||||
return memo;
|
|
||||||
};
|
|
||||||
|
|
||||||
// The right-associative version of reduce, also known as `foldr`.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
|
|
||||||
_.reduceRight = _.foldr = function ( obj, iterator, memo, context ) {
|
|
||||||
if ( obj == null ) {
|
|
||||||
obj = [];
|
|
||||||
}
|
|
||||||
if ( nativeReduceRight && obj.reduceRight === nativeReduceRight ) {
|
|
||||||
if ( context ) {
|
|
||||||
iterator = _.bind( iterator, context );
|
|
||||||
}
|
|
||||||
return memo !== void 0 ? obj.reduceRight( iterator, memo ) : obj.reduceRight( iterator );
|
|
||||||
}
|
|
||||||
var reversed = (_.isArray( obj ) ? obj.slice() : _.toArray( obj )).reverse();
|
|
||||||
return _.reduce( reversed, iterator, memo, context );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the first value which passes a truth test. Aliased as `detect`.
|
|
||||||
_.find = _.detect = function ( obj, iterator, context ) {
|
|
||||||
var result;
|
|
||||||
any( obj, function ( value, index, list ) {
|
|
||||||
if ( iterator.call( context, value, index, list ) ) {
|
|
||||||
result = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return all the elements that pass a truth test.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `filter` if available.
|
|
||||||
// Aliased as `select`.
|
|
||||||
_.filter = _.select = function ( obj, iterator, context ) {
|
|
||||||
var results = [];
|
|
||||||
if ( obj == null ) {
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
if ( nativeFilter && obj.filter === nativeFilter ) {
|
|
||||||
return obj.filter( iterator, context );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( iterator.call( context, value, index, list ) ) {
|
|
||||||
results[results.length] = value;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return all the elements for which a truth test fails.
|
|
||||||
_.reject = function ( obj, iterator, context ) {
|
|
||||||
var results = [];
|
|
||||||
if ( obj == null ) {
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( !iterator.call( context, value, index, list ) ) {
|
|
||||||
results[results.length] = value;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine whether all of the elements match a truth test.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `every` if available.
|
|
||||||
// Aliased as `all`.
|
|
||||||
_.every = _.all = function ( obj, iterator, context ) {
|
|
||||||
var result = true;
|
|
||||||
if ( obj == null ) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if ( nativeEvery && obj.every === nativeEvery ) {
|
|
||||||
return obj.every( iterator, context );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( !(result = result && iterator.call( context, value, index, list )) ) {
|
|
||||||
return breaker;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine if at least one element in the object matches a truth test.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `some` if available.
|
|
||||||
// Aliased as `any`.
|
|
||||||
var any = _.some = _.any = function ( obj, iterator, context ) {
|
|
||||||
iterator = iterator || _.identity;
|
|
||||||
var result = false;
|
|
||||||
if ( obj == null ) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if ( nativeSome && obj.some === nativeSome ) {
|
|
||||||
return obj.some( iterator, context );
|
|
||||||
}
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
if ( result |= iterator.call( context, value, index, list ) ) {
|
|
||||||
return breaker;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return !!result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine if a given value is included in the array or object using `===`.
|
|
||||||
// Aliased as `contains`.
|
|
||||||
_.include = _.contains = function ( obj, target ) {
|
|
||||||
var found = false;
|
|
||||||
if ( obj == null ) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
if ( nativeIndexOf && obj.indexOf === nativeIndexOf ) {
|
|
||||||
return obj.indexOf( target ) != -1;
|
|
||||||
}
|
|
||||||
any( obj, function ( value ) {
|
|
||||||
if ( found = value === target ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return found;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Invoke a method (with arguments) on every item in a collection.
|
|
||||||
_.invoke = function ( obj, method ) {
|
|
||||||
var args = slice.call( arguments, 2 );
|
|
||||||
return _.map( obj, function ( value ) {
|
|
||||||
return (method.call ? method || value : value[method]).apply( value, args );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convenience version of a common use case of `map`: fetching a property.
|
|
||||||
_.pluck = function ( obj, key ) {
|
|
||||||
return _.map( obj, function ( value ) {
|
|
||||||
return value[key];
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the maximum element or (element-based computation).
|
|
||||||
_.max = function ( obj, iterator, context ) {
|
|
||||||
if ( !iterator && _.isArray( obj ) ) {
|
|
||||||
return Math.max.apply( Math, obj );
|
|
||||||
}
|
|
||||||
var result = {computed : -Infinity};
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
var computed = iterator ? iterator.call( context, value, index, list ) : value;
|
|
||||||
computed >= result.computed && (result = {value : value, computed : computed});
|
|
||||||
} );
|
|
||||||
return result.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the minimum element (or element-based computation).
|
|
||||||
_.min = function ( obj, iterator, context ) {
|
|
||||||
if ( !iterator && _.isArray( obj ) ) {
|
|
||||||
return Math.min.apply( Math, obj );
|
|
||||||
}
|
|
||||||
var result = {computed : Infinity};
|
|
||||||
each( obj, function ( value, index, list ) {
|
|
||||||
var computed = iterator ? iterator.call( context, value, index, list ) : value;
|
|
||||||
computed < result.computed && (result = {value : value, computed : computed});
|
|
||||||
} );
|
|
||||||
return result.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sort the object's values by a criterion produced by an iterator.
|
|
||||||
_.sortBy = function ( obj, iterator, context ) {
|
|
||||||
return _.pluck( _.map( obj,
|
|
||||||
function ( value, index, list ) {
|
|
||||||
return {
|
|
||||||
value : value,
|
|
||||||
criteria : iterator.call( context, value, index, list )
|
|
||||||
};
|
|
||||||
} ).sort( function ( left, right ) {
|
|
||||||
var a = left.criteria, b = right.criteria;
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
|
||||||
} ), 'value' );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Groups the object's values by a criterion produced by an iterator
|
|
||||||
_.groupBy = function ( obj, iterator ) {
|
|
||||||
var result = {};
|
|
||||||
each( obj, function ( value, index ) {
|
|
||||||
var key = iterator( value, index );
|
|
||||||
(result[key] || (result[key] = [])).push( value );
|
|
||||||
} );
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use a comparator function to figure out at what index an object should
|
|
||||||
// be inserted so as to maintain order. Uses binary search.
|
|
||||||
_.sortedIndex = function ( array, obj, iterator ) {
|
|
||||||
iterator || (iterator = _.identity);
|
|
||||||
var low = 0, high = array.length;
|
|
||||||
while ( low < high ) {
|
|
||||||
var mid = (low + high) >> 1;
|
|
||||||
iterator( array[mid] ) < iterator( obj ) ? low = mid + 1 : high = mid;
|
|
||||||
}
|
|
||||||
return low;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Safely convert anything iterable into a real, live array.
|
|
||||||
_.toArray = function ( iterable ) {
|
|
||||||
if ( !iterable ) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
if ( iterable.toArray ) {
|
|
||||||
return iterable.toArray();
|
|
||||||
}
|
|
||||||
if ( _.isArray( iterable ) ) {
|
|
||||||
return slice.call( iterable );
|
|
||||||
}
|
|
||||||
if ( _.isArguments( iterable ) ) {
|
|
||||||
return slice.call( iterable );
|
|
||||||
}
|
|
||||||
return _.values( iterable );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the number of elements in an object.
|
|
||||||
_.size = function ( obj ) {
|
|
||||||
return _.toArray( obj ).length;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Array Functions
|
|
||||||
// ---------------
|
|
||||||
|
|
||||||
// Get the first element of an array. Passing **n** will return the first N
|
|
||||||
// values in the array. Aliased as `head`. The **guard** check allows it to work
|
|
||||||
// with `_.map`.
|
|
||||||
_.first = _.head = function ( array, n, guard ) {
|
|
||||||
return (n != null) && !guard ? slice.call( array, 0, n ) : array[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns everything but the first entry of the array. Aliased as `tail`.
|
|
||||||
// Especially useful on the arguments object. Passing an **index** will return
|
|
||||||
// the rest of the values in the array from that index onward. The **guard**
|
|
||||||
// check allows it to work with `_.map`.
|
|
||||||
_.rest = _.tail = function ( array, index, guard ) {
|
|
||||||
return slice.call( array, (index == null) || guard ? 1 : index );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the last element of an array.
|
|
||||||
_.last = function ( array ) {
|
|
||||||
return array[array.length - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Trim out all falsy values from an array.
|
|
||||||
_.compact = function ( array ) {
|
|
||||||
return _.filter( array, function ( value ) {
|
|
||||||
return !!value;
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return a completely flattened version of an array.
|
|
||||||
_.flatten = function ( array ) {
|
|
||||||
return _.reduce( array, function ( memo, value ) {
|
|
||||||
if ( _.isArray( value ) ) {
|
|
||||||
return memo.concat( _.flatten( value ) );
|
|
||||||
}
|
|
||||||
memo[memo.length] = value;
|
|
||||||
return memo;
|
|
||||||
}, [] );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return a version of the array that does not contain the specified value(s).
|
|
||||||
_.without = function ( array ) {
|
|
||||||
return _.difference( array, slice.call( arguments, 1 ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Produce a duplicate-free version of the array. If the array has already
|
|
||||||
// been sorted, you have the option of using a faster algorithm.
|
|
||||||
// Aliased as `unique`.
|
|
||||||
_.uniq = _.unique = function ( array, isSorted ) {
|
|
||||||
return _.reduce( array, function ( memo, el, i ) {
|
|
||||||
if ( 0 == i || (isSorted === true ? _.last( memo ) != el : !_.include( memo, el )) ) {
|
|
||||||
memo[memo.length] = el;
|
|
||||||
}
|
|
||||||
return memo;
|
|
||||||
}, [] );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Produce an array that contains the union: each distinct element from all of
|
|
||||||
// the passed-in arrays.
|
|
||||||
_.union = function () {
|
|
||||||
return _.uniq( _.flatten( arguments ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Produce an array that contains every item shared between all the
|
|
||||||
// passed-in arrays. (Aliased as "intersect" for back-compat.)
|
|
||||||
_.intersection = _.intersect = function ( array ) {
|
|
||||||
var rest = slice.call( arguments, 1 );
|
|
||||||
return _.filter( _.uniq( array ), function ( item ) {
|
|
||||||
return _.every( rest, function ( other ) {
|
|
||||||
return _.indexOf( other, item ) >= 0;
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Take the difference between one array and another.
|
|
||||||
// Only the elements present in just the first array will remain.
|
|
||||||
_.difference = function ( array, other ) {
|
|
||||||
return _.filter( array, function ( value ) {
|
|
||||||
return !_.include( other, value );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Zip together multiple lists into a single array -- elements that share
|
|
||||||
// an index go together.
|
|
||||||
_.zip = function () {
|
|
||||||
var args = slice.call( arguments );
|
|
||||||
var length = _.max( _.pluck( args, 'length' ) );
|
|
||||||
var results = new Array( length );
|
|
||||||
for ( var i = 0; i < length; i++ ) {
|
|
||||||
results[i] = _.pluck( args, "" + i );
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
|
|
||||||
// we need this function. Return the position of the first occurrence of an
|
|
||||||
// item in an array, or -1 if the item is not included in the array.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
|
|
||||||
// If the array is large and already in sort order, pass `true`
|
|
||||||
// for **isSorted** to use binary search.
|
|
||||||
_.indexOf = function ( array, item, isSorted ) {
|
|
||||||
if ( array == null ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
var i, l;
|
|
||||||
if ( isSorted ) {
|
|
||||||
i = _.sortedIndex( array, item );
|
|
||||||
return array[i] === item ? i : -1;
|
|
||||||
}
|
|
||||||
if ( nativeIndexOf && array.indexOf === nativeIndexOf ) {
|
|
||||||
return array.indexOf( item );
|
|
||||||
}
|
|
||||||
for ( i = 0, l = array.length; i < l; i++ ) {
|
|
||||||
if ( array[i] === item ) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
|
||||||
_.lastIndexOf = function ( array, item ) {
|
|
||||||
if ( array == null ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if ( nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf ) {
|
|
||||||
return array.lastIndexOf( item );
|
|
||||||
}
|
|
||||||
var i = array.length;
|
|
||||||
while ( i-- ) {
|
|
||||||
if ( array[i] === item ) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate an integer Array containing an arithmetic progression. A port of
|
|
||||||
// the native Python `range()` function. See
|
|
||||||
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
|
||||||
_.range = function ( start, stop, step ) {
|
|
||||||
if ( arguments.length <= 1 ) {
|
|
||||||
stop = start || 0;
|
|
||||||
start = 0;
|
|
||||||
}
|
|
||||||
step = arguments[2] || 1;
|
|
||||||
|
|
||||||
var len = Math.max( Math.ceil( (stop - start) / step ), 0 );
|
|
||||||
var idx = 0;
|
|
||||||
var range = new Array( len );
|
|
||||||
|
|
||||||
while ( idx < len ) {
|
|
||||||
range[idx++] = start;
|
|
||||||
start += step;
|
|
||||||
}
|
|
||||||
|
|
||||||
return range;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function (ahem) Functions
|
|
||||||
// ------------------
|
|
||||||
|
|
||||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
|
||||||
// optionally). Binding with arguments is also known as `curry`.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
|
||||||
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
|
||||||
_.bind = function ( func, obj ) {
|
|
||||||
if ( func.bind === nativeBind && nativeBind ) {
|
|
||||||
return nativeBind.apply( func, slice.call( arguments, 1 ) );
|
|
||||||
}
|
|
||||||
var args = slice.call( arguments, 2 );
|
|
||||||
return function () {
|
|
||||||
return func.apply( obj, args.concat( slice.call( arguments ) ) );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Bind all of an object's methods to that object. Useful for ensuring that
|
|
||||||
// all callbacks defined on an object belong to it.
|
|
||||||
_.bindAll = function ( obj ) {
|
|
||||||
var funcs = slice.call( arguments, 1 );
|
|
||||||
if ( funcs.length == 0 ) {
|
|
||||||
funcs = _.functions( obj );
|
|
||||||
}
|
|
||||||
each( funcs, function ( f ) {
|
|
||||||
obj[f] = _.bind( obj[f], obj );
|
|
||||||
} );
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Memoize an expensive function by storing its results.
|
|
||||||
_.memoize = function ( func, hasher ) {
|
|
||||||
var memo = {};
|
|
||||||
hasher || (hasher = _.identity);
|
|
||||||
return function () {
|
|
||||||
var key = hasher.apply( this, arguments );
|
|
||||||
return hasOwnProperty.call( memo, key ) ? memo[key] : (memo[key] = func.apply( this, arguments ));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delays a function for the given number of milliseconds, and then calls
|
|
||||||
// it with the arguments supplied.
|
|
||||||
_.delay = function ( func, wait ) {
|
|
||||||
var args = slice.call( arguments, 2 );
|
|
||||||
return setTimeout( function () {
|
|
||||||
return func.apply( func, args );
|
|
||||||
}, wait );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Defers a function, scheduling it to run after the current call stack has
|
|
||||||
// cleared.
|
|
||||||
_.defer = function ( func ) {
|
|
||||||
return _.delay.apply( _, [func, 1].concat( slice.call( arguments, 1 ) ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Internal function used to implement `_.throttle` and `_.debounce`.
|
|
||||||
var limit = function ( func, wait, debounce ) {
|
|
||||||
var timeout;
|
|
||||||
return function () {
|
|
||||||
var context = this, args = arguments;
|
|
||||||
var throttler = function () {
|
|
||||||
timeout = null;
|
|
||||||
func.apply( context, args );
|
|
||||||
};
|
|
||||||
if ( debounce ) {
|
|
||||||
clearTimeout( timeout );
|
|
||||||
}
|
|
||||||
if ( debounce || !timeout ) {
|
|
||||||
timeout = setTimeout( throttler, wait );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function, that, when invoked, will only be triggered at most once
|
|
||||||
// during a given window of time.
|
|
||||||
_.throttle = function ( func, wait ) {
|
|
||||||
return limit( func, wait, false );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function, that, as long as it continues to be invoked, will not
|
|
||||||
// be triggered. The function will be called after it stops being called for
|
|
||||||
// N milliseconds.
|
|
||||||
_.debounce = function ( func, wait ) {
|
|
||||||
return limit( func, wait, true );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function that will be executed at most one time, no matter how
|
|
||||||
// often you call it. Useful for lazy initialization.
|
|
||||||
_.once = function ( func ) {
|
|
||||||
var ran = false, memo;
|
|
||||||
return function () {
|
|
||||||
if ( ran ) {
|
|
||||||
return memo;
|
|
||||||
}
|
|
||||||
ran = true;
|
|
||||||
return memo = func.apply( this, arguments );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the first function passed as an argument to the second,
|
|
||||||
// allowing you to adjust arguments, run code before and after, and
|
|
||||||
// conditionally execute the original function.
|
|
||||||
_.wrap = function ( func, wrapper ) {
|
|
||||||
return function () {
|
|
||||||
var args = [func].concat( slice.call( arguments ) );
|
|
||||||
return wrapper.apply( this, args );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function that is the composition of a list of functions, each
|
|
||||||
// consuming the return value of the function that follows.
|
|
||||||
_.compose = function () {
|
|
||||||
var funcs = slice.call( arguments );
|
|
||||||
return function () {
|
|
||||||
var args = slice.call( arguments );
|
|
||||||
for ( var i = funcs.length - 1; i >= 0; i-- ) {
|
|
||||||
args = [funcs[i].apply( this, args )];
|
|
||||||
}
|
|
||||||
return args[0];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function that will only be executed after being called N times.
|
|
||||||
_.after = function ( times, func ) {
|
|
||||||
return function () {
|
|
||||||
if ( --times < 1 ) {
|
|
||||||
return func.apply( this, arguments );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Object Functions
|
|
||||||
// ----------------
|
|
||||||
|
|
||||||
// Retrieve the names of an object's properties.
|
|
||||||
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
|
||||||
_.keys = nativeKeys || function ( obj ) {
|
|
||||||
if ( obj !== Object( obj ) ) {
|
|
||||||
throw new TypeError( 'Invalid object' );
|
|
||||||
}
|
|
||||||
var keys = [];
|
|
||||||
for ( var key in obj ) {
|
|
||||||
if ( hasOwnProperty.call( obj, key ) ) {
|
|
||||||
keys[keys.length] = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keys;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Retrieve the values of an object's properties.
|
|
||||||
_.values = function ( obj ) {
|
|
||||||
return _.map( obj, _.identity );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return a sorted list of the function names available on the object.
|
|
||||||
// Aliased as `methods`
|
|
||||||
_.functions = _.methods = function ( obj ) {
|
|
||||||
var names = [];
|
|
||||||
for ( var key in obj ) {
|
|
||||||
if ( _.isFunction( obj[key] ) ) {
|
|
||||||
names.push( key );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return names.sort();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extend a given object with all the properties in passed-in object(s).
|
|
||||||
_.extend = function ( obj ) {
|
|
||||||
each( slice.call( arguments, 1 ), function ( source ) {
|
|
||||||
for ( var prop in source ) {
|
|
||||||
if ( source[prop] !== void 0 ) {
|
|
||||||
obj[prop] = source[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fill in a given object with default properties.
|
|
||||||
_.defaults = function ( obj ) {
|
|
||||||
each( slice.call( arguments, 1 ), function ( source ) {
|
|
||||||
for ( var prop in source ) {
|
|
||||||
if ( obj[prop] == null ) {
|
|
||||||
obj[prop] = source[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a (shallow-cloned) duplicate of an object.
|
|
||||||
_.clone = function ( obj ) {
|
|
||||||
return _.isArray( obj ) ? obj.slice() : _.extend( {}, obj );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Invokes interceptor with the obj, and then returns obj.
|
|
||||||
// The primary purpose of this method is to "tap into" a method chain, in
|
|
||||||
// order to perform operations on intermediate results within the chain.
|
|
||||||
_.tap = function ( obj, interceptor ) {
|
|
||||||
interceptor( obj );
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Perform a deep comparison to check if two objects are equal.
|
|
||||||
_.isEqual = function ( a, b ) {
|
|
||||||
// Check object identity.
|
|
||||||
if ( a === b ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Different types?
|
|
||||||
var atype = typeof(a), btype = typeof(b);
|
|
||||||
if ( atype != btype ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Basic equality test (watch out for coercions).
|
|
||||||
if ( a == b ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// One is falsy and the other truthy.
|
|
||||||
if ( (!a && b) || (a && !b) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Unwrap any wrapped objects.
|
|
||||||
if ( a._chain ) {
|
|
||||||
a = a._wrapped;
|
|
||||||
}
|
|
||||||
if ( b._chain ) {
|
|
||||||
b = b._wrapped;
|
|
||||||
}
|
|
||||||
// One of them implements an isEqual()?
|
|
||||||
if ( a.isEqual ) {
|
|
||||||
return a.isEqual( b );
|
|
||||||
}
|
|
||||||
if ( b.isEqual ) {
|
|
||||||
return b.isEqual( a );
|
|
||||||
}
|
|
||||||
// Check dates' integer values.
|
|
||||||
if ( _.isDate( a ) && _.isDate( b ) ) {
|
|
||||||
return a.getTime() === b.getTime();
|
|
||||||
}
|
|
||||||
// Both are NaN?
|
|
||||||
if ( _.isNaN( a ) && _.isNaN( b ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Compare regular expressions.
|
|
||||||
if ( _.isRegExp( a ) && _.isRegExp( b ) ) {
|
|
||||||
return a.source === b.source &&
|
|
||||||
a.global === b.global &&
|
|
||||||
a.ignoreCase === b.ignoreCase &&
|
|
||||||
a.multiline === b.multiline;
|
|
||||||
}
|
|
||||||
// If a is not an object by this point, we can't handle it.
|
|
||||||
if ( atype !== 'object' ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check for different array lengths before comparing contents.
|
|
||||||
if ( a.length && (a.length !== b.length) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Nothing else worked, deep compare the contents.
|
|
||||||
var aKeys = _.keys( a ), bKeys = _.keys( b );
|
|
||||||
// Different object sizes?
|
|
||||||
if ( aKeys.length != bKeys.length ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Recursive comparison of contents.
|
|
||||||
for ( var key in a ) {
|
|
||||||
if ( !(key in b) || !_.isEqual( a[key], b[key] ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given array or object empty?
|
|
||||||
_.isEmpty = function ( obj ) {
|
|
||||||
if ( _.isArray( obj ) || _.isString( obj ) ) {
|
|
||||||
return obj.length === 0;
|
|
||||||
}
|
|
||||||
for ( var key in obj ) {
|
|
||||||
if ( hasOwnProperty.call( obj, key ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a DOM element?
|
|
||||||
_.isElement = function ( obj ) {
|
|
||||||
return !!(obj && obj.nodeType == 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value an array?
|
|
||||||
// Delegates to ECMA5's native Array.isArray
|
|
||||||
_.isArray = nativeIsArray || function ( obj ) {
|
|
||||||
return toString.call( obj ) === '[object Array]';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given variable an object?
|
|
||||||
_.isObject = function ( obj ) {
|
|
||||||
return obj === Object( obj );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given variable an arguments object?
|
|
||||||
_.isArguments = function ( obj ) {
|
|
||||||
return !!(obj && hasOwnProperty.call( obj, 'callee' ));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a function?
|
|
||||||
_.isFunction = function ( obj ) {
|
|
||||||
return !!(obj && obj.constructor && obj.call && obj.apply);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a string?
|
|
||||||
_.isString = function ( obj ) {
|
|
||||||
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a number?
|
|
||||||
_.isNumber = function ( obj ) {
|
|
||||||
return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
|
|
||||||
// that does not equal itself.
|
|
||||||
_.isNaN = function ( obj ) {
|
|
||||||
return obj !== obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a boolean?
|
|
||||||
_.isBoolean = function ( obj ) {
|
|
||||||
return obj === true || obj === false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value a date?
|
|
||||||
_.isDate = function ( obj ) {
|
|
||||||
return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is the given value a regular expression?
|
|
||||||
_.isRegExp = function ( obj ) {
|
|
||||||
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given value equal to null?
|
|
||||||
_.isNull = function ( obj ) {
|
|
||||||
return obj === null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Is a given variable undefined?
|
|
||||||
_.isUndefined = function ( obj ) {
|
|
||||||
return obj === void 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Utility Functions
|
|
||||||
// -----------------
|
|
||||||
|
|
||||||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
|
||||||
// previous owner. Returns a reference to the Underscore object.
|
|
||||||
_.noConflict = function () {
|
|
||||||
root._ = previousUnderscore;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Keep the identity function around for default iterators.
|
|
||||||
_.identity = function ( value ) {
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Run a function **n** times.
|
|
||||||
_.times = function ( n, iterator, context ) {
|
|
||||||
for ( var i = 0; i < n; i++ ) {
|
|
||||||
iterator.call( context, i );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add your own custom functions to the Underscore object, ensuring that
|
|
||||||
// they're correctly added to the OOP wrapper as well.
|
|
||||||
_.mixin = function ( obj ) {
|
|
||||||
each( _.functions( obj ), function ( name ) {
|
|
||||||
addToWrapper( name, _[name] = obj[name] );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate a unique integer id (unique within the entire client session).
|
|
||||||
// Useful for temporary DOM ids.
|
|
||||||
var idCounter = 0;
|
|
||||||
_.uniqueId = function ( prefix ) {
|
|
||||||
var id = idCounter++;
|
|
||||||
return prefix ? prefix + id : id;
|
|
||||||
};
|
|
||||||
|
|
||||||
// By default, Underscore uses ERB-style template delimiters, change the
|
|
||||||
// following template settings to use alternative delimiters.
|
|
||||||
_.templateSettings = {
|
|
||||||
evaluate : /<%([\s\S]+?)%>/g,
|
|
||||||
interpolate : /<%=([\s\S]+?)%>/g
|
|
||||||
};
|
|
||||||
|
|
||||||
// JavaScript micro-templating, similar to John Resig's implementation.
|
|
||||||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
|
||||||
// and correctly escapes quotes within interpolated code.
|
|
||||||
_.template = function ( str, data ) {
|
|
||||||
var c = _.templateSettings;
|
|
||||||
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
|
|
||||||
'with(obj||{}){__p.push(\'' +
|
|
||||||
str.replace( /\\/g, '\\\\' )
|
|
||||||
.replace( /'/g, "\\'" )
|
|
||||||
.replace( c.interpolate, function ( match, code ) {
|
|
||||||
return "'," + code.replace( /\\'/g, "'" ) + ",'";
|
|
||||||
} )
|
|
||||||
.replace( c.evaluate || null, function ( match, code ) {
|
|
||||||
return "');" + code.replace( /\\'/g, "'" )
|
|
||||||
.replace( /[\r\n\t]/g, ' ' ) + "__p.push('";
|
|
||||||
} )
|
|
||||||
.replace( /\r/g, '\\r' )
|
|
||||||
.replace( /\n/g, '\\n' )
|
|
||||||
.replace( /\t/g, '\\t' )
|
|
||||||
+ "');}return __p.join('');";
|
|
||||||
var func = new Function( 'obj', tmpl );
|
|
||||||
return data ? func( data ) : func;
|
|
||||||
};
|
|
||||||
|
|
||||||
// The OOP Wrapper
|
|
||||||
// ---------------
|
|
||||||
|
|
||||||
// If Underscore is called as a function, it returns a wrapped object that
|
|
||||||
// can be used OO-style. This wrapper holds altered versions of all the
|
|
||||||
// underscore functions. Wrapped objects may be chained.
|
|
||||||
var wrapper = function ( obj ) {
|
|
||||||
this._wrapped = obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expose `wrapper.prototype` as `_.prototype`
|
|
||||||
_.prototype = wrapper.prototype;
|
|
||||||
|
|
||||||
// Helper function to continue chaining intermediate results.
|
|
||||||
var result = function ( obj, chain ) {
|
|
||||||
return chain ? _( obj ).chain() : obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A method to easily add functions to the OOP wrapper.
|
|
||||||
var addToWrapper = function ( name, func ) {
|
|
||||||
wrapper.prototype[name] = function () {
|
|
||||||
var args = slice.call( arguments );
|
|
||||||
unshift.call( args, this._wrapped );
|
|
||||||
return result( func.apply( _, args ), this._chain );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add all of the Underscore functions to the wrapper object.
|
|
||||||
_.mixin( _ );
|
|
||||||
|
|
||||||
// Add all mutator Array functions to the wrapper.
|
|
||||||
each( ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function ( name ) {
|
|
||||||
var method = ArrayProto[name];
|
|
||||||
wrapper.prototype[name] = function () {
|
|
||||||
method.apply( this._wrapped, arguments );
|
|
||||||
return result( this._wrapped, this._chain );
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Add all accessor Array functions to the wrapper.
|
|
||||||
each( ['concat', 'join', 'slice'], function ( name ) {
|
|
||||||
var method = ArrayProto[name];
|
|
||||||
wrapper.prototype[name] = function () {
|
|
||||||
return result( method.apply( this._wrapped, arguments ), this._chain );
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Start chaining a wrapped Underscore object.
|
|
||||||
wrapper.prototype.chain = function () {
|
|
||||||
this._chain = true;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extracts the result from a wrapped and chained object.
|
|
||||||
wrapper.prototype.value = function () {
|
|
||||||
return this._wrapped;
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
@ -31,14 +31,10 @@ gulp.task("combine", function() {
|
||||||
.pipe(hintNot())
|
.pipe(hintNot())
|
||||||
.pipe(beautify({indentSize: 4}))
|
.pipe(beautify({indentSize: 4}))
|
||||||
.pipe(gulp.dest("./lib/"))
|
.pipe(gulp.dest("./lib/"))
|
||||||
.pipe(gulp.dest("./example/amd/js/libs/postal"))
|
|
||||||
.pipe(gulp.dest("./example/standard/js"))
|
|
||||||
.pipe(uglify({ compress: { negate_iife: false }}))
|
.pipe(uglify({ compress: { negate_iife: false }}))
|
||||||
.pipe(header(banner, { pkg : pkg }))
|
.pipe(header(banner, { pkg : pkg }))
|
||||||
.pipe(rename("postal.min.js"))
|
.pipe(rename("postal.min.js"))
|
||||||
.pipe(gulp.dest("./lib/"))
|
.pipe(gulp.dest("./lib/"));
|
||||||
.pipe(gulp.dest("./example/amd/js/libs/postal"))
|
|
||||||
.pipe(gulp.dest("./example/standard/js"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("default", function() {
|
gulp.task("default", function() {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>postal.js</title>
|
<title>postal.js</title>
|
||||||
<link rel="stylesheet" href="ext/bootstrap-responsive.min.css" type="text/css">
|
<link rel="stylesheet" href="bower/bootstrap/dist/css/bootstrap.min.css" type="text/css">
|
||||||
<link rel="stylesheet" href="ext/bootstrap.min.css" type="text/css">
|
<link rel="stylesheet" href="bower/bootstrap/dist/css/bootstrap-theme.min.css" type="text/css">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.banner {
|
.banner {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
@ -36,8 +36,8 @@
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript" src="/ext/jquery-1.7.1.js"></script>
|
<script type="text/javascript" src="bower/jquery/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="/ext/bootstrap.min.js"></script>
|
<script type="text/javascript" src="bower/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="banner">
|
<header class="banner">
|
||||||
|
|
|
||||||
|
|
@ -210,12 +210,13 @@
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
withThrottle: function (milliseconds) {
|
withThrottle: function (milliseconds, options) {
|
||||||
|
options = options || {};
|
||||||
if (_.isNaN(milliseconds)) {
|
if (_.isNaN(milliseconds)) {
|
||||||
throw "Milliseconds must be a number";
|
throw "Milliseconds must be a number";
|
||||||
}
|
}
|
||||||
var fn = this.callback;
|
var fn = this.callback;
|
||||||
this.callback = _.throttle(fn, milliseconds);
|
this.callback = _.throttle(fn, milliseconds, options);
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
2
lib/postal.min.js
vendored
2
lib/postal.min.js
vendored
File diff suppressed because one or more lines are too long
201
package.json
201
package.json
|
|
@ -1,106 +1,113 @@
|
||||||
{
|
{
|
||||||
"name": "postal",
|
"name": "postal",
|
||||||
"description": "Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.",
|
"description": "Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.",
|
||||||
"version": "0.8.11",
|
"version": "0.8.11",
|
||||||
"homepage": "http://github.com/postaljs/postal.js",
|
"homepage": "http://github.com/postaljs/postal.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/postaljs/postal.js.git"
|
"url": "git://github.com/postaljs/postal.js.git"
|
||||||
},
|
|
||||||
"author": "Jim Cowart (http://freshbrewedcode.com/jimcowart)",
|
|
||||||
"contributors": [
|
|
||||||
{
|
|
||||||
"name": "Jim Cowart",
|
|
||||||
"email": "WhyNotJustComment@OnMyBlog.com",
|
|
||||||
"url": "http://freshbrewedcode.com/jimcowart"
|
|
||||||
},
|
},
|
||||||
{
|
"author": "Jim Cowart (http://freshbrewedcode.com/jimcowart)",
|
||||||
"name": "Alex Robson",
|
"contributors": [
|
||||||
"email": "WhyNotJustComment@OnMyBlog.com",
|
{
|
||||||
"url": "http://freshbrewedcode.com/alexrobson"
|
"name": "Jim Cowart",
|
||||||
|
"email": "WhyNotJustComment@OnMyBlog.com",
|
||||||
|
"url": "http://freshbrewedcode.com/jimcowart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Alex Robson",
|
||||||
|
"email": "WhyNotJustComment@OnMyBlog.com",
|
||||||
|
"url": "http://freshbrewedcode.com/alexrobson"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nicholas Cloud",
|
||||||
|
"email": "WhyNotJustComment@OnMyBlog.com",
|
||||||
|
"url": "http://nicholascloud.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Doug Neiner",
|
||||||
|
"email": "WhyNotJustComment@OnMyBlog.com",
|
||||||
|
"url": "http://dougneiner.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Creamer",
|
||||||
|
"email": "WhyNotJustComment@OnMyBlog.com",
|
||||||
|
"url": "http://freshbrewedcode.com/jonathancreamer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Elijah Manor",
|
||||||
|
"email": "WhyNotJustComment@OnMyBlog.com",
|
||||||
|
"url": "http://www.elijahmanor.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ger Hobbelt",
|
||||||
|
"email": "ger@hobbelt.com",
|
||||||
|
"url": "http://hebbut.net/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Christian Haas",
|
||||||
|
"url": "http://github.com/dertseha"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"keywords": [
|
||||||
|
"pub/sub",
|
||||||
|
"pub",
|
||||||
|
"sub",
|
||||||
|
"messaging",
|
||||||
|
"message",
|
||||||
|
"bus",
|
||||||
|
"event",
|
||||||
|
"mediator",
|
||||||
|
"broker",
|
||||||
|
"envelope"
|
||||||
|
],
|
||||||
|
"bugs": {
|
||||||
|
"email": "PleaseJustUseTheIssuesPage@github.com",
|
||||||
|
"url": "http://github.com/postaljs/postal.js/issues"
|
||||||
},
|
},
|
||||||
{
|
"directories": {
|
||||||
"name": "Nicholas Cloud",
|
"lib": "lib"
|
||||||
"email": "WhyNotJustComment@OnMyBlog.com",
|
|
||||||
"url": "http://nicholascloud.com"
|
|
||||||
},
|
},
|
||||||
{
|
"main": "lib/postal.js",
|
||||||
"name": "Doug Neiner",
|
"engines": {
|
||||||
"email": "WhyNotJustComment@OnMyBlog.com",
|
"node": ">=0.4.0"
|
||||||
"url": "http://dougneiner.com"
|
|
||||||
},
|
},
|
||||||
{
|
"dependencies": {
|
||||||
"name": "Jonathan Creamer",
|
"underscore": "~1.5.2"
|
||||||
"email": "WhyNotJustComment@OnMyBlog.com",
|
|
||||||
"url": "http://freshbrewedcode.com/jonathancreamer"
|
|
||||||
},
|
},
|
||||||
{
|
"bundleDependencies": [
|
||||||
"name": "Elijah Manor",
|
"underscore"
|
||||||
"email": "WhyNotJustComment@OnMyBlog.com",
|
],
|
||||||
"url": "http://www.elijahmanor.com"
|
"devDependencies": {
|
||||||
|
"bower": "~1.2.8",
|
||||||
|
"gulp-util": "~2.2.9",
|
||||||
|
"gulp": "~3.3.1",
|
||||||
|
"gulp-imports": "~0.0.1",
|
||||||
|
"gulp-header": "~1.0.2",
|
||||||
|
"gulp-hint-not": "~0.0.3",
|
||||||
|
"gulp-uglify": "~0.1.0",
|
||||||
|
"gulp-rename": "~0.2.1",
|
||||||
|
"gulp-plato": "~0.1.0",
|
||||||
|
"gulp-beautify": "~1.0.3",
|
||||||
|
"tiny-lr": "0.0.5",
|
||||||
|
"express": "~3.4.7",
|
||||||
|
"gulp-rimraf": "0.0.8",
|
||||||
|
"open": "~0.0.4",
|
||||||
|
"expect.js": "~0.2.0"
|
||||||
},
|
},
|
||||||
{
|
"licenses": [
|
||||||
"name": "Ger Hobbelt",
|
{
|
||||||
"email": "ger@hobbelt.com",
|
"type": "MIT",
|
||||||
"url": "http://hebbut.net/"
|
"url": "http://www.opensource.org/licenses/mit-license.php"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Christian Haas",
|
"type": "GPL",
|
||||||
"url": "http://github.com/dertseha"
|
"url": "http://www.opensource.org/licenses/gpl-3.0.html"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"test": "mocha ./spec/*.js",
|
||||||
|
"build": "gulp",
|
||||||
|
"start": "gulp server"
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"keywords": [
|
|
||||||
"pub/sub",
|
|
||||||
"pub",
|
|
||||||
"sub",
|
|
||||||
"messaging",
|
|
||||||
"message",
|
|
||||||
"bus",
|
|
||||||
"event",
|
|
||||||
"mediator",
|
|
||||||
"broker",
|
|
||||||
"envelope"
|
|
||||||
],
|
|
||||||
"bugs": {
|
|
||||||
"email": "PleaseJustUseTheIssuesPage@github.com",
|
|
||||||
"url": "http://github.com/postaljs/postal.js/issues"
|
|
||||||
},
|
|
||||||
"directories": {
|
|
||||||
"lib": "lib"
|
|
||||||
},
|
|
||||||
"main": "lib/postal.js",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.4.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"underscore": ">=1.1.7"
|
|
||||||
},
|
|
||||||
"bundleDependencies": [
|
|
||||||
"underscore"
|
|
||||||
],
|
|
||||||
"devDependencies": {
|
|
||||||
"gulp-util": "~2.2.9",
|
|
||||||
"gulp": "~3.3.1",
|
|
||||||
"gulp-imports": "~0.0.1",
|
|
||||||
"gulp-header": "~1.0.2",
|
|
||||||
"gulp-hint-not": "~0.0.3",
|
|
||||||
"gulp-uglify": "~0.1.0",
|
|
||||||
"gulp-rename": "~0.2.1",
|
|
||||||
"gulp-plato": "~0.1.0",
|
|
||||||
"gulp-beautify": "~1.0.3",
|
|
||||||
"tiny-lr": "0.0.5",
|
|
||||||
"express": "~3.4.7",
|
|
||||||
"gulp-rimraf": "0.0.8",
|
|
||||||
"open": "~0.0.4"
|
|
||||||
},
|
|
||||||
"licenses": [
|
|
||||||
{
|
|
||||||
"type": "MIT",
|
|
||||||
"url": "http://www.opensource.org/licenses/mit-license.php"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GPL",
|
|
||||||
"url": "http://www.opensource.org/licenses/gpl-3.0.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
/* global describe, postal, it, after, before, expect */
|
/* global describe, postal, it, after, before, expect */
|
||||||
(function(){
|
(function(){
|
||||||
|
var postal = typeof window === "undefined" ? require("../lib/postal.js")() : window.postal;
|
||||||
|
var expect = typeof window === "undefined" ? require("expect.js") : window.expect;
|
||||||
var bindingsResolver = postal.configuration.resolver;
|
var bindingsResolver = postal.configuration.resolver;
|
||||||
describe( "amqpBindingsResolver", function () {
|
describe( "amqpBindingsResolver", function () {
|
||||||
describe( "When calling compare", function () {
|
describe( "When calling compare", function () {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
/* global describe, postal, it, after, before, expect */
|
/* global describe, postal, it, after, before, expect */
|
||||||
(function(){
|
(function(){
|
||||||
|
var postal = typeof window === "undefined" ? require("../lib/postal.js")() : window.postal;
|
||||||
|
var expect = typeof window === "undefined" ? require("expect.js") : window.expect;
|
||||||
var ChannelDefinition = postal.ChannelDefinition;
|
var ChannelDefinition = postal.ChannelDefinition;
|
||||||
describe( "channel definition", function () {
|
describe( "channel definition", function () {
|
||||||
describe( "When using global channel api", function () {
|
describe( "When using global channel api", function () {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
|
<link rel="stylesheet" href="../bower/mocha/mocha.css" />
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="mocha"></div>
|
<div id="mocha"></div>
|
||||||
<script type="text/javascript" src="../ext/jquery-1.7.1.js"></script>
|
<script type="text/javascript" src="../bower/jquery/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../ext/underscore.js"></script>
|
<script type="text/javascript" src="../bower/underscore/underscore-min.js"></script>
|
||||||
<script type="text/javascript" src="../ext/expect.js"></script>
|
<script type="text/javascript" src="../bower/expect/expect.js"></script>
|
||||||
<script type="text/javascript" src="../node_modules/mocha/mocha.js"></script>
|
<script type="text/javascript" src="../bower/mocha/mocha.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
mocha.setup({ ui: 'bdd', timeout: 60000 });
|
mocha.setup({ ui: 'bdd', timeout: 60000 });
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
/* global describe, postal, it, after, before, expect */
|
/* global describe, postal, it, after, before, expect */
|
||||||
(function() {
|
(function() {
|
||||||
|
var postal = typeof window === "undefined" ? require("../lib/postal.js")() : window.postal;
|
||||||
|
var expect = typeof window === "undefined" ? require("expect.js") : window.expect;
|
||||||
var subscription;
|
var subscription;
|
||||||
describe("linked channels", function () {
|
describe("linked channels", function () {
|
||||||
describe( "When binding channel - one source to one destination", function () {
|
describe( "When binding channel - one source to one destination", function () {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
/* global describe, postal, it, after, before, expect */
|
/* global describe, postal, it, after, before, expect */
|
||||||
(function() {
|
(function() {
|
||||||
|
var postal = typeof window === "undefined" ? require("../lib/postal.js")() : window.postal;
|
||||||
|
var expect = typeof window === "undefined" ? require("expect.js") : window.expect;
|
||||||
|
var _ = typeof window === "undefined" ? require("underscore") : window._;
|
||||||
var subscription;
|
var subscription;
|
||||||
var sub;
|
var sub;
|
||||||
var channel;
|
var channel;
|
||||||
|
|
@ -15,9 +18,9 @@
|
||||||
topic : "subscription.created",
|
topic : "subscription.created",
|
||||||
callback : function ( data, envelope ) {
|
callback : function ( data, envelope ) {
|
||||||
if ( data.event &&
|
if ( data.event &&
|
||||||
data.event == "subscription.created" &&
|
data.event === "subscription.created" &&
|
||||||
data.channel == "MyChannel" &&
|
data.channel === "MyChannel" &&
|
||||||
data.topic == "MyTopic" ) {
|
data.topic === "MyTopic" ) {
|
||||||
caughtSubscribeEvent = true;
|
caughtSubscribeEvent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +238,7 @@
|
||||||
expect( results[0] ).to.be( 6 );
|
expect( results[0] ).to.be( 6 );
|
||||||
expect( results.length ).to.be( 1 );
|
expect( results.length ).to.be( 1 );
|
||||||
done();
|
done();
|
||||||
}, 2400 );
|
}, 1900 );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
describe( "When subscribing with defer", function () {
|
describe( "When subscribing with defer", function () {
|
||||||
|
|
@ -450,8 +453,8 @@
|
||||||
}
|
}
|
||||||
setTimeout( function () {
|
setTimeout( function () {
|
||||||
expect( results[0] ).to.be( 1 );
|
expect( results[0] ).to.be( 1 );
|
||||||
expect( results[1] ).to.be( 800 );
|
expect( results[2] ).to.be( 800 );
|
||||||
expect( results.length ).to.be( 2 );
|
expect( results.length ).to.be( 3 );
|
||||||
done();
|
done();
|
||||||
}, 1500 );
|
}, 1500 );
|
||||||
} );
|
} );
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
/* global describe, postal, it, after, before, expect */
|
/* global describe, postal, it, after, before, expect */
|
||||||
(function() {
|
(function() {
|
||||||
|
var postal = typeof window === "undefined" ? require("../lib/postal.js")() : window.postal;
|
||||||
|
var expect = typeof window === "undefined" ? require("expect.js") : window.expect;
|
||||||
var NO_OP = function () {};
|
var NO_OP = function () {};
|
||||||
var SubscriptionDefinition = postal.SubscriptionDefinition;
|
var SubscriptionDefinition = postal.SubscriptionDefinition;
|
||||||
describe( "SubscriptionDefinition", function () {
|
describe( "SubscriptionDefinition", function () {
|
||||||
|
|
@ -85,7 +87,7 @@
|
||||||
return true;
|
return true;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
postal.publish( { channel : "TestChannel", topic : "TestTopic", data : "Oh, hai"} )
|
postal.publish( { channel : "TestChannel", topic : "TestTopic", data : "Oh, hai"} );
|
||||||
|
|
||||||
it( "Should set context", function () {
|
it( "Should set context", function () {
|
||||||
expect( sDefd.context ).to.be( obj );
|
expect( sDefd.context ).to.be( obj );
|
||||||
|
|
@ -146,17 +148,16 @@
|
||||||
} );
|
} );
|
||||||
|
|
||||||
describe( "When throttling the callback", function () {
|
describe( "When throttling the callback", function () {
|
||||||
var results = [],
|
|
||||||
sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function ( data ) {
|
|
||||||
results.push( data );
|
|
||||||
} ).withThrottle( 500 );
|
|
||||||
var timeout1, timeout2;
|
|
||||||
|
|
||||||
it( "should have only invoked throttled callback twice", function ( done ) {
|
it( "should have only invoked throttled callback twice", function ( done ) {
|
||||||
sDefe.callback( 1 ); // starts the two second clock on debounce
|
var results = [], timeout1, timeout2;
|
||||||
|
var sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function ( data ) {
|
||||||
|
results.push( data );
|
||||||
|
} ).withThrottle( 1200, { leading: true } );
|
||||||
|
sDefe.callback( 1 ); // starts the clock on throttle
|
||||||
timeout1 = setTimeout( function () {
|
timeout1 = setTimeout( function () {
|
||||||
sDefe.callback( 800 );
|
sDefe.callback( 700 );
|
||||||
}, 900 ); // should invoke callback
|
}, 700 ); // should invoke callback
|
||||||
for ( var i = 0; i < 20; i++ ) {
|
for ( var i = 0; i < 20; i++ ) {
|
||||||
(function ( x ) {
|
(function ( x ) {
|
||||||
sDefe.callback( x );
|
sDefe.callback( x );
|
||||||
|
|
@ -164,13 +165,16 @@
|
||||||
}
|
}
|
||||||
timeout2 = setTimeout( function () {
|
timeout2 = setTimeout( function () {
|
||||||
expect( results[0] ).to.be( 1 );
|
expect( results[0] ).to.be( 1 );
|
||||||
expect( results[1] ).to.be( 800 );
|
|
||||||
expect( results.length ).to.be( 2 );
|
expect( results.length ).to.be( 2 );
|
||||||
done();
|
done();
|
||||||
}, 1500 );
|
}, 1500 );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
it( "Should keep the context intact", function( done ) {
|
it( "Should keep the context intact", function( done ) {
|
||||||
|
var results = [], timeout1, timeout2;
|
||||||
|
var sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function ( data ) {
|
||||||
|
results.push( data );
|
||||||
|
} ).withThrottle( 1000, { leading: true } );
|
||||||
var context = {
|
var context = {
|
||||||
key : 'abcd'
|
key : 'abcd'
|
||||||
};
|
};
|
||||||
|
|
@ -231,7 +235,7 @@
|
||||||
expect( results[0] ).to.be( 6 );
|
expect( results[0] ).to.be( 6 );
|
||||||
expect( results.length ).to.be( 1 );
|
expect( results.length ).to.be( 1 );
|
||||||
done();
|
done();
|
||||||
}, 2300 );
|
}, 1800 );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
it( "Should keep the context intact", function ( done ) {
|
it( "Should keep the context intact", function ( done ) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
/* global describe, postal, it, after, before, expect */
|
/* global describe, postal, it, after, before, expect */
|
||||||
(function() {
|
(function() {
|
||||||
|
var postal = typeof window === "undefined" ? require("../lib/postal.js")() : window.postal;
|
||||||
|
var expect = typeof window === "undefined" ? require("expect.js") : window.expect;
|
||||||
|
var _ = typeof window === "undefined" ? require("underscore") : window._;
|
||||||
var NO_OP = function() {};
|
var NO_OP = function() {};
|
||||||
var subscription;
|
var subscription;
|
||||||
var sub;
|
var sub;
|
||||||
|
|
|
||||||
|
|
@ -130,12 +130,13 @@ SubscriptionDefinition.prototype = {
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
withThrottle : function ( milliseconds ) {
|
withThrottle : function ( milliseconds, options ) {
|
||||||
|
options = options || { };
|
||||||
if ( _.isNaN( milliseconds ) ) {
|
if ( _.isNaN( milliseconds ) ) {
|
||||||
throw "Milliseconds must be a number";
|
throw "Milliseconds must be a number";
|
||||||
}
|
}
|
||||||
var fn = this.callback;
|
var fn = this.callback;
|
||||||
this.callback = _.throttle( fn, milliseconds );
|
this.callback = _.throttle( fn, milliseconds, options );
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue