Comparing version 0.1.5 to 0.1.6
{ | ||
"name": "reflux", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"homepage": "https://github.com/spoike/reflux", | ||
@@ -5,0 +5,0 @@ "authors": [ |
@@ -218,2 +218,86 @@ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Reflux=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ | ||
},{}],3:[function(_dereq_,module,exports){ | ||
var createAction = _dereq_('./createAction'); | ||
var slice = Array.prototype.slice; | ||
/** | ||
* Track a set of Actions and Stores. Use Reflux.all if you need to handle | ||
* data coming in parallel. | ||
* | ||
* @param {...Action|Store} listenables Actions and Stores that should be | ||
* tracked. | ||
* @returns {Action} An action which tracks the provided Actions and Stores. | ||
* The action will emit once all of the provided listenables have emitted at | ||
* least once. | ||
*/ | ||
module.exports = function(/* listenables... */) { | ||
var numberOfListenables = arguments.length, | ||
// create a new array of the expected size. The initial | ||
// values will be falsy, which is fine for us. | ||
// Once each item in the array is truthy, the callback can be called | ||
listenablesEmitted, | ||
// these arguments will be used to *apply* the action. | ||
args, | ||
// this action combines all the listenables | ||
action = createAction(); | ||
action.hasListener = function(listenable) { | ||
var i = 0, listener; | ||
for (; i < args.length; ++i) { | ||
listener = args[i]; | ||
if (listener === listenable || listener.hasListener && listener.hasListener(listenable)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
reset(); | ||
for (var i = 0; i < numberOfListenables; i++) { | ||
arguments[i].listen(newListener(i), null); | ||
} | ||
return action; | ||
function reset() { | ||
listenablesEmitted = new Array(numberOfListenables); | ||
args = new Array(numberOfListenables); | ||
} | ||
function newListener(i) { | ||
return function() { | ||
listenablesEmitted[i] = true; | ||
// Reflux users should not need to care about Array and arguments | ||
// differences. This makes sure that they get the expected Array | ||
// interface | ||
args[i] = slice.call(arguments); | ||
emitWhenAllListenablesEmitted(); | ||
}; | ||
} | ||
function emitWhenAllListenablesEmitted() { | ||
if (didAllListenablesEmit()) { | ||
action.apply(action, args); | ||
reset(); | ||
} | ||
} | ||
function didAllListenablesEmit() { | ||
// reduce cannot be used because it only iterates over *present* | ||
// elements in the array. Initially the Array doesn't contain | ||
// elements. For this reason the usage of reduce would always indicate | ||
// that all listenables emitted. | ||
for (var i = 0; i < numberOfListenables; i++) { | ||
if (!listenablesEmitted[i]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
}; | ||
},{"./createAction":4}],4:[function(_dereq_,module,exports){ | ||
var _ = _dereq_('./utils'); | ||
@@ -231,6 +315,9 @@ | ||
functor = function() { | ||
functor.preEmit.apply(functor, arguments); | ||
if (functor.shouldEmit.apply(functor, arguments)) { | ||
action.emit(eventLabel, arguments); | ||
} | ||
var args = arguments; | ||
_.nextTick(function() { | ||
functor.preEmit.apply(functor, args); | ||
if (functor.shouldEmit.apply(functor, args)) { | ||
action.emit(eventLabel, args); | ||
} | ||
}); | ||
}; | ||
@@ -257,3 +344,3 @@ | ||
/** | ||
* Hook used by the action functor that is invoked before emitting | ||
* Hook used by the action functor that is invoked before emitting | ||
* and before `shouldEmit`. The arguments are the ones that the action | ||
@@ -277,3 +364,3 @@ * is invoked with. | ||
},{"./utils":6}],4:[function(_dereq_,module,exports){ | ||
},{"./utils":7}],5:[function(_dereq_,module,exports){ | ||
var _ = _dereq_('./utils'); | ||
@@ -291,2 +378,3 @@ | ||
function Store() { | ||
this.registered = []; | ||
if (this.init && _.isFunction(this.init)) { | ||
@@ -298,5 +386,12 @@ this.init(); | ||
Store.prototype.listenTo = function(listenable, callback) { | ||
if (listenable === this) { | ||
throw Error("Store is not able to listen to itself"); | ||
} | ||
if (!_.isFunction(listenable.listen)) { | ||
throw new TypeError(listenable + " is missing a listen method"); | ||
} | ||
if (this.hasListener(listenable)) { | ||
throw Error("Store cannot listen to this listenable because of circular loop"); | ||
} | ||
this.registered.push(listenable); | ||
return listenable.listen(callback, this); | ||
@@ -308,2 +403,3 @@ }; | ||
}; | ||
eventHandler.l = callback; | ||
store.addListener(eventLabel, eventHandler); | ||
@@ -318,7 +414,20 @@ | ||
}; | ||
Store.prototype.hasListener = function(listenable) { | ||
var i = 0, | ||
listener; | ||
for (;i < this.registered.length; ++i) { | ||
listener = this.registered[i]; | ||
if (listener === listenable || listener.hasListener && listener.hasListener(listenable)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
return new Store(); | ||
}; | ||
},{"./utils":6}],5:[function(_dereq_,module,exports){ | ||
},{"./utils":7}],6:[function(_dereq_,module,exports){ | ||
exports.createAction = _dereq_('./createAction'); | ||
@@ -330,2 +439,4 @@ | ||
exports.all = _dereq_('./all'); | ||
exports.createActions = function(actionNames) { | ||
@@ -344,5 +455,10 @@ var i = 0, actions = {}; | ||
},{"./ListenerMixin":2,"./createAction":3,"./createStore":4,"./utils":6}],6:[function(_dereq_,module,exports){ | ||
exports.nextTick = function(nextTick) { | ||
var _ = _dereq_('./utils'); | ||
_.nextTick = nextTick; | ||
}; | ||
},{"./ListenerMixin":2,"./all":3,"./createAction":4,"./createStore":5,"./utils":7}],7:[function(_dereq_,module,exports){ | ||
/* | ||
* isObject, extend and isFunction are taken from undescore/lodash in | ||
* isObject, extend and isFunction are taken from undescore/lodash in | ||
* order to remove the dependency | ||
@@ -375,4 +491,8 @@ */ | ||
module.exports.EventEmitter = _dereq_('eventemitter3'); | ||
},{"eventemitter3":1}]},{},[5]) | ||
(5) | ||
module.exports.nextTick = function(callback) { | ||
setTimeout(callback, 0); | ||
}; | ||
},{"eventemitter3":1}]},{},[6]) | ||
(6) | ||
}); |
@@ -1,1 +0,1 @@ | ||
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.Reflux=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b){"use strict";function c(){this._events={}}c.prototype.listeners=function(a){return Array.apply(this,this._events[a]||[])},c.prototype.emit=function(a,b,c,d,e,f){if(!this._events||!this._events[a])return!1;var g,h,i=this._events[a],j=i.length,k=arguments.length,l=i[0];if(1===j)switch(l.__EE3_once&&this.removeListener(a,l),k){case 1:l.call(l.__EE3_context||this);break;case 2:l.call(l.__EE3_context||this,b);break;case 3:l.call(l.__EE3_context||this,b,c);break;case 4:l.call(l.__EE3_context||this,b,c,d);break;case 5:l.call(l.__EE3_context||this,b,c,d,e);break;case 6:l.call(l.__EE3_context||this,b,c,d,e,f);break;default:for(h=1,g=new Array(k-1);k>h;h++)g[h-1]=arguments[h];l.apply(l.__EE3_context||this,g)}else{for(h=1,g=new Array(k-1);k>h;h++)g[h-1]=arguments[h];for(h=0;j>h;l=i[++h])l.__EE3_once&&this.removeListener(a,l),l.apply(l.__EE3_context||this,g)}return!0},c.prototype.on=function(a,b,c){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),b.__EE3_context=c,this._events[a].push(b),this},c.prototype.once=function(a,b,c){return b.__EE3_once=!0,this.on(a,b,c)},c.prototype.removeListener=function(a,b){if(!this._events||!this._events[a])return this;for(var c=this._events[a],d=[],e=0,f=c.length;f>e;e++)b&&c[e]!==b&&d.push(c[e]);return this._events[a]=d.length?d:null,this},c.prototype.removeAllListeners=function(a){return this._events?(a?this._events[a]=null:this._events={},this):this},c.prototype.off=c.prototype.removeListener,c.prototype.addListener=c.prototype.on,c.prototype.setMaxListeners=function(){return this},c.EventEmitter=c,c.EventEmitter2=c,c.EventEmitter3=c;try{b.exports=c}catch(d){}},{}],2:[function(a,b){b.exports={componentWillMount:function(){this.subscriptions=[]},listenTo:function(a,b){var c=a.listen(b,this);this.subscriptions.push(c)},componentWillUnmount:function(){this.subscriptions.forEach(function(a){a()}),this.subscriptions=[]}}},{}],3:[function(a,b){var c=a("./utils");b.exports=function(){var a,b=new c.EventEmitter,d="action";return a=function(){a.preEmit.apply(a,arguments),a.shouldEmit.apply(a,arguments)&&b.emit(d,arguments)},a.listen=function(a,c){var e=function(b){a.apply(c,b)};return b.addListener(d,e),function(){b.removeListener(d,e)}},a.preEmit=function(){},a.shouldEmit=function(){return!0},a}},{"./utils":6}],4:[function(a,b){var c=a("./utils");b.exports=function(a){function b(){this.init&&c.isFunction(this.init)&&this.init()}var d=new c.EventEmitter,e="change";return c.extend(b.prototype,a),b.prototype.listenTo=function(a,b){if(!c.isFunction(a.listen))throw new TypeError(a+" is missing a listen method");return a.listen(b,this)},b.prototype.listen=function(a,b){var c=function(c){a.apply(b,c)};return d.addListener(e,c),function(){d.removeListener(e,c)}},b.prototype.trigger=function(){d.emit(e,arguments)},new b}},{"./utils":6}],5:[function(a,b,c){c.createAction=a("./createAction"),c.createStore=a("./createStore"),c.ListenerMixin=a("./ListenerMixin"),c.createActions=function(a){for(var b=0,d={};b<a.length;b++)d[a[b]]=c.createAction();return d},c.setEventEmitter=function(b){var c=a("./utils");c.EventEmitter=b}},{"./ListenerMixin":2,"./createAction":3,"./createStore":4,"./utils":6}],6:[function(a,b){var c=b.exports.isObject=function(a){var b=typeof a;return"function"===b||"object"===b&&!!a};b.exports.extend=function(a){if(!c(a))return a;for(var b,d,e=1,f=arguments.length;f>e;e++){b=arguments[e];for(d in b)a[d]=b[d]}return a},b.exports.isFunction=function(a){return"function"==typeof a},b.exports.EventEmitter=a("eventemitter3")},{eventemitter3:1}]},{},[5])(5)}); | ||
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.Reflux=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b){"use strict";function c(){this._events={}}c.prototype.listeners=function(a){return Array.apply(this,this._events[a]||[])},c.prototype.emit=function(a,b,c,d,e,f){if(!this._events||!this._events[a])return!1;var g,h,i=this._events[a],j=i.length,k=arguments.length,l=i[0];if(1===j)switch(l.__EE3_once&&this.removeListener(a,l),k){case 1:l.call(l.__EE3_context||this);break;case 2:l.call(l.__EE3_context||this,b);break;case 3:l.call(l.__EE3_context||this,b,c);break;case 4:l.call(l.__EE3_context||this,b,c,d);break;case 5:l.call(l.__EE3_context||this,b,c,d,e);break;case 6:l.call(l.__EE3_context||this,b,c,d,e,f);break;default:for(h=1,g=new Array(k-1);k>h;h++)g[h-1]=arguments[h];l.apply(l.__EE3_context||this,g)}else{for(h=1,g=new Array(k-1);k>h;h++)g[h-1]=arguments[h];for(h=0;j>h;l=i[++h])l.__EE3_once&&this.removeListener(a,l),l.apply(l.__EE3_context||this,g)}return!0},c.prototype.on=function(a,b,c){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),b.__EE3_context=c,this._events[a].push(b),this},c.prototype.once=function(a,b,c){return b.__EE3_once=!0,this.on(a,b,c)},c.prototype.removeListener=function(a,b){if(!this._events||!this._events[a])return this;for(var c=this._events[a],d=[],e=0,f=c.length;f>e;e++)b&&c[e]!==b&&d.push(c[e]);return this._events[a]=d.length?d:null,this},c.prototype.removeAllListeners=function(a){return this._events?(a?this._events[a]=null:this._events={},this):this},c.prototype.off=c.prototype.removeListener,c.prototype.addListener=c.prototype.on,c.prototype.setMaxListeners=function(){return this},c.EventEmitter=c,c.EventEmitter2=c,c.EventEmitter3=c;try{b.exports=c}catch(d){}},{}],2:[function(a,b){b.exports={componentWillMount:function(){this.subscriptions=[]},listenTo:function(a,b){var c=a.listen(b,this);this.subscriptions.push(c)},componentWillUnmount:function(){this.subscriptions.forEach(function(a){a()}),this.subscriptions=[]}}},{}],3:[function(a,b){var c=a("./createAction"),d=Array.prototype.slice;b.exports=function(){function a(){g=new Array(i),h=new Array(i)}function b(a){return function(){g[a]=!0,h[a]=d.call(arguments),e()}}function e(){f()&&(j.apply(j,h),a())}function f(){for(var a=0;i>a;a++)if(!g[a])return!1;return!0}var g,h,i=arguments.length,j=c();j.hasListener=function(a){for(var b,c=0;c<h.length;++c)if(b=h[c],b===a||b.hasListener&&b.hasListener(a))return!0;return!1},a();for(var k=0;i>k;k++)arguments[k].listen(b(k),null);return j}},{"./createAction":4}],4:[function(a,b){var c=a("./utils");b.exports=function(){var a,b=new c.EventEmitter,d="action";return a=function(){var e=arguments;c.nextTick(function(){a.preEmit.apply(a,e),a.shouldEmit.apply(a,e)&&b.emit(d,e)})},a.listen=function(a,c){var e=function(b){a.apply(c,b)};return b.addListener(d,e),function(){b.removeListener(d,e)}},a.preEmit=function(){},a.shouldEmit=function(){return!0},a}},{"./utils":7}],5:[function(a,b){var c=a("./utils");b.exports=function(a){function b(){this.registered=[],this.init&&c.isFunction(this.init)&&this.init()}var d=new c.EventEmitter,e="change";return c.extend(b.prototype,a),b.prototype.listenTo=function(a,b){if(a===this)throw Error("Store is not able to listen to itself");if(!c.isFunction(a.listen))throw new TypeError(a+" is missing a listen method");if(this.hasListener(a))throw Error("Store cannot listen to this listenable because of circular loop");return this.registered.push(a),a.listen(b,this)},b.prototype.listen=function(a,b){var c=function(c){a.apply(b,c)};return c.l=a,d.addListener(e,c),function(){d.removeListener(e,c)}},b.prototype.trigger=function(){d.emit(e,arguments)},b.prototype.hasListener=function(a){for(var b,c=0;c<this.registered.length;++c)if(b=this.registered[c],b===a||b.hasListener&&b.hasListener(a))return!0;return!1},new b}},{"./utils":7}],6:[function(a,b,c){c.createAction=a("./createAction"),c.createStore=a("./createStore"),c.ListenerMixin=a("./ListenerMixin"),c.all=a("./all"),c.createActions=function(a){for(var b=0,d={};b<a.length;b++)d[a[b]]=c.createAction();return d},c.setEventEmitter=function(b){var c=a("./utils");c.EventEmitter=b},c.nextTick=function(b){var c=a("./utils");c.nextTick=b}},{"./ListenerMixin":2,"./all":3,"./createAction":4,"./createStore":5,"./utils":7}],7:[function(a,b){var c=b.exports.isObject=function(a){var b=typeof a;return"function"===b||"object"===b&&!!a};b.exports.extend=function(a){if(!c(a))return a;for(var b,d,e=1,f=arguments.length;f>e;e++){b=arguments[e];for(d in b)a[d]=b[d]}return a},b.exports.isFunction=function(a){return"function"==typeof a},b.exports.EventEmitter=a("eventemitter3"),b.exports.nextTick=function(a){setTimeout(a,0)}},{eventemitter3:1}]},{},[6])(6)}); |
{ | ||
"name": "reflux", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"description": "A simple library for uni-directional dataflow application architecture inspired by ReactJS Flux", | ||
@@ -15,8 +15,2 @@ "main": "src/index.js", | ||
}, | ||
"browserify": { | ||
"transform": [ | ||
"browserify-shim" | ||
] | ||
}, | ||
"browserify-shim": {}, | ||
"dependencies": { | ||
@@ -27,3 +21,2 @@ "eventemitter3": "^0.1.2" | ||
"browserify": "^4.2.0", | ||
"browserify-shim": "^3.6.0", | ||
"chai": "^1.9.1", | ||
@@ -30,0 +23,0 @@ "chai-as-promised": "^4.1.1", |
@@ -209,3 +209,3 @@ # Reflux | ||
A store may listen to another store's change, making it possible to safetly chain stores for aggregated data without affecting other parts of the application. A store may listen to other stores using the same `listenTo` function as with actions: | ||
A store may listen to another store's change, making it possible to safely chain stores for aggregated data without affecting other parts of the application. A store may listen to other stores using the same `listenTo` function as with actions: | ||
@@ -262,2 +262,35 @@ ```javascript | ||
### Joining parallel listeners with composed listenables | ||
Reflux makes it easy to listen to actions and stores that emit events in parallel. You can use this feature to compose and share listenable objects (composed listenables) among several stores. | ||
```javascript | ||
var theTide = Reflux.all(waveAction, timeStore); | ||
var clockStore = Reflux.createStore({ | ||
init: function() { | ||
this.listenTo(theTide, this.theTideCallback); | ||
}, | ||
theTideCallback: function(waveActionArgs, timeStoreArgs) { | ||
// ... | ||
} | ||
}); | ||
// node.js environment | ||
if (process.env.DEVELOPMENT) { | ||
theTide.listenTo(console.log.bind(console), window); | ||
} | ||
``` | ||
`Reflux.all` always passes the last arguments that a listenable emitted to your callback, discarding subsequent emits. Arguments are passed in order. This means that the first argument which the callback receives, is the set of arguments which was emitted by the first listenable that was passed to `Reflux.all` and so on for the other arguments. | ||
#### Comparison with Flux's `waitFor()` | ||
The `Reflux.all` functionality is similar to Flux's `waitFor()`, but differs in a few aspects: | ||
* Composed listenables may be reused by other stores | ||
* Composed listenables always emit asynchronously | ||
* Actions and stores may emit multiple times before the composed listenable (`theTide` in the example above) emits | ||
* Action and store callbacks are not executed in a single *synchronous* iteration | ||
## Colophon | ||
@@ -264,0 +297,0 @@ |
@@ -13,2 +13,3 @@ var _ = require('./utils'); | ||
function Store() { | ||
this.registered = []; | ||
if (this.init && _.isFunction(this.init)) { | ||
@@ -20,5 +21,12 @@ this.init(); | ||
Store.prototype.listenTo = function(listenable, callback) { | ||
if (listenable === this) { | ||
throw Error("Store is not able to listen to itself"); | ||
} | ||
if (!_.isFunction(listenable.listen)) { | ||
throw new TypeError(listenable + " is missing a listen method"); | ||
} | ||
if (this.hasListener(listenable)) { | ||
throw Error("Store cannot listen to this listenable because of circular loop"); | ||
} | ||
this.registered.push(listenable); | ||
return listenable.listen(callback, this); | ||
@@ -30,2 +38,3 @@ }; | ||
}; | ||
eventHandler.l = callback; | ||
store.addListener(eventLabel, eventHandler); | ||
@@ -40,4 +49,17 @@ | ||
}; | ||
Store.prototype.hasListener = function(listenable) { | ||
var i = 0, | ||
listener; | ||
for (;i < this.registered.length; ++i) { | ||
listener = this.registered[i]; | ||
if (listener === listenable || listener.hasListener && listener.hasListener(listenable)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
return new Store(); | ||
}; |
@@ -7,2 +7,4 @@ exports.createAction = require('./createAction'); | ||
exports.all = require('./all'); | ||
exports.createActions = function(actionNames) { | ||
@@ -9,0 +11,0 @@ var i = 0, actions = {}; |
@@ -13,3 +13,3 @@ var chai = require('chai'), | ||
describe('with one aggregate store listening to a store listening to a simple action', function() { | ||
var action, | ||
var action, | ||
store, | ||
@@ -24,3 +24,3 @@ aggregateStore, | ||
init: function() { | ||
this.listenTo(action, this.trigger); | ||
this.listenTo(action, this.trigger); | ||
// pass to the trigger function immediately | ||
@@ -51,4 +51,27 @@ } | ||
}); | ||
it('should throw error when circular dependency happens', function() { | ||
assert.throws(function() { | ||
aggregateStore.listenTo(store); | ||
}, Error); | ||
}); | ||
describe('with a third store', function() { | ||
var thirdStore; | ||
beforeEach(function() { | ||
thirdStore = Reflux.createStore({}); | ||
thirdStore.listenTo(aggregateStore, function() {}); | ||
}); | ||
it('should throw error when a longer circular dependency happens', function() { | ||
assert.throws(function() { | ||
thirdStore.listenTo(store, function() {}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -44,2 +44,8 @@ var chai = require('chai'), | ||
it('should throw an error when it listens on itself', function() { | ||
assert.throws(function() { | ||
store.listenTo(store, function() {}); | ||
}, Error); | ||
}); | ||
describe('and with listener unsubscribed', function() { | ||
@@ -46,0 +52,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
62718
14
24
1281
303