Modularized panels
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
*.sublime-*
|
||||
node_modules
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
test:
|
||||
@NODE_ENV=test ./node_modules/.bin/mocha
|
||||
|
||||
test-w:
|
||||
@NODE_ENV=test ./node_modules/.bin/mocha \
|
||||
--growl \
|
||||
--watch
|
||||
|
||||
.PHONY: test test-w
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
# Random Weighted Choice
|
||||
|
||||
[](http://travis-ci.org/parmentf/random-weighted-choice)
|
||||
|
||||
Node.js module to make a random choice among weighted elements of table.
|
||||
|
||||
## Installation
|
||||
|
||||
With [npm](http://npmjs.org) do:
|
||||
|
||||
$ npm install random-weighted-choice
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
Although you can add several times the same id
|
||||
|
||||
var rwc = require('random-weighted-choice');
|
||||
var table = [
|
||||
{ weight: 1, id: "item1"} // Element 1
|
||||
, { weight: 1, id: "item2"} // Element 2
|
||||
, { weight: 4, id: "item3"} // Element with a 4 times likelihood
|
||||
, { weight: 2, id: "item1"} // Element 1, weight added with 2 => 3
|
||||
];
|
||||
var choosenItem = rwc(table);
|
||||
var choosenUnlikely = rwc(table, 100); // The last shall be first
|
||||
var choosenDeterministically = rwc(table, 0);
|
||||
|
||||
It is better to not use the same twice, if you want a temperature other than
|
||||
the default one (50).
|
||||
|
||||
var rwc = require('random-weighted-choice');
|
||||
var table = [
|
||||
{ weight: 1, id: "item1"} // Element 1
|
||||
, { weight: 1, id: "item2"} // Element 2
|
||||
, { weight: 4, id: "item3"} // Element with a 4 times likelihood
|
||||
, { weight: 2, id: "item4"} // Element 4
|
||||
, { weight: 2, id: "item5"}
|
||||
];
|
||||
var choosenItem = rwc(table);
|
||||
var choosenUnlikely = rwc(table, 100); // The last shall be first
|
||||
var choosenDeterministically = rwc(table, 0);
|
||||
|
||||
Without temperature (second parameter) or a 50 value, likelihoods are:
|
||||
|
||||
{ item1: 10%, item2: 10%, item3: 40%, item4: 20%, item5: 20% }
|
||||
|
||||
With a temperature value of 100:
|
||||
|
||||
{ item1: 30%, item2: 30%, item3: 0%, item4: 20%, item5: 20% }
|
||||
|
||||
With a temperature value of 0, modified weights are:
|
||||
|
||||
{ item1: 0, item2: 0, item3: 8, item4: 2, item5: 2 }
|
||||
|
||||
## Usage
|
||||
|
||||
### random-weighted-choice(Array table, Number temperature = 50)
|
||||
|
||||
Return the ``id`` of the chosen item from ``table``.
|
||||
|
||||
The ``table`` parameter should contain an Array. Each item of that Array must
|
||||
bean object, with at least ``weight`` and ``id`` property.
|
||||
|
||||
Weight values are relative to each other. They are integers.
|
||||
|
||||
When the sum of the weight values is ``null``, ``null`` is returned (can't choose).
|
||||
|
||||
When the Array is empty, ``null`` is returned.
|
||||
|
||||
More explanations on how it works on [Everything2](http://everything2.com/title/Blackboard+temperature).
|
||||
|
||||
## Also
|
||||
|
||||
* https://github.com/Schoonology/weighted
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*jshint node:true, laxcomma:true */
|
||||
"use strict";
|
||||
|
||||
var debug = require('debug')('rwc');
|
||||
|
||||
var RandomWeightedChoice = function (table, temperature, randomFunction, influence) {
|
||||
influence = influence || 2; // Seems fine, difficult to tune
|
||||
if (typeof(temperature)=="undefined") temperature = 50; // in [0,100], 50 is neutral
|
||||
temperature = temperature | 50;
|
||||
debug('temperature', temperature);
|
||||
var T = (temperature - 50) / 50;
|
||||
if (typeof(randomFunction)=="undefined") randomFunction = Math.random;
|
||||
|
||||
var nb = table.length;
|
||||
if(!nb) return null; // No item given.
|
||||
|
||||
var total = 0;
|
||||
table.forEach(function(element, index) {
|
||||
total += element.weight;
|
||||
});
|
||||
|
||||
var avg = total / nb;
|
||||
debug('total', total);
|
||||
debug('nb', nb);
|
||||
debug('avg', avg);
|
||||
|
||||
// Compute amplified urgencies (depending on temperature)
|
||||
var ur = {};
|
||||
var urgencySum = 0;
|
||||
table.forEach(function(element, index) {
|
||||
var urgency = element.weight + T * influence * (avg - element.weight);
|
||||
if (urgency < 0) urgency = 0;
|
||||
urgencySum += urgency;
|
||||
ur[element.id] = (ur[element.id] || 0 ) + urgency;
|
||||
});
|
||||
|
||||
var cumulatedUrgencies = {};
|
||||
var currentUrgency = 0;
|
||||
Object.keys(ur).forEach(function(id, index) {
|
||||
currentUrgency += ur[id];
|
||||
cumulatedUrgencies[id] = currentUrgency;
|
||||
});
|
||||
|
||||
if(urgencySum < 1) return null; // No weight given
|
||||
|
||||
// Choose
|
||||
var choice = randomFunction() * urgencySum;
|
||||
|
||||
debug('ur', ur);
|
||||
debug('cumulatedUrgencies', cumulatedUrgencies);
|
||||
debug('urgencySum', urgencySum);
|
||||
debug('choice', choice);
|
||||
|
||||
var ids = Object.keys(cumulatedUrgencies);
|
||||
for(var i=0; i<ids.length; i++) {
|
||||
var id = ids[i];
|
||||
var urgency = cumulatedUrgencies[id];
|
||||
if(choice <= urgency) {
|
||||
debug('return', id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = RandomWeightedChoice;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
support
|
||||
test
|
||||
examples
|
||||
*.sock
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
|
||||
0.7.0 / 2012-05-04
|
||||
==================
|
||||
|
||||
* Added .component to package.json
|
||||
* Added debug.component.js build
|
||||
|
||||
0.6.0 / 2012-03-16
|
||||
==================
|
||||
|
||||
* Added support for "-" prefix in DEBUG [Vinay Pulim]
|
||||
* Added `.enabled` flag to the node version [TooTallNate]
|
||||
|
||||
0.5.0 / 2012-02-02
|
||||
==================
|
||||
|
||||
* Added: humanize diffs. Closes #8
|
||||
* Added `debug.disable()` to the CS variant
|
||||
* Removed padding. Closes #10
|
||||
* Fixed: persist client-side variant again. Closes #9
|
||||
|
||||
0.4.0 / 2012-02-01
|
||||
==================
|
||||
|
||||
* Added browser variant support for older browsers [TooTallNate]
|
||||
* Added `debug.enable('project:*')` to browser variant [TooTallNate]
|
||||
* Added padding to diff (moved it to the right)
|
||||
|
||||
0.3.0 / 2012-01-26
|
||||
==================
|
||||
|
||||
* Added millisecond diff when isatty, otherwise UTC string
|
||||
|
||||
0.2.0 / 2012-01-22
|
||||
==================
|
||||
|
||||
* Added wildcard support
|
||||
|
||||
0.1.0 / 2011-12-02
|
||||
==================
|
||||
|
||||
* Added: remove colors unless stderr isatty [TooTallNate]
|
||||
|
||||
0.0.1 / 2010-01-03
|
||||
==================
|
||||
|
||||
* Initial release
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
|
||||
debug.component.js: head.js debug.js tail.js
|
||||
cat $^ > $@
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
|
||||
# debug
|
||||
|
||||
tiny node.js debugging utility.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ npm install debug
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
This module is modelled after node core's debugging technique, allowing you to enable one or more topic-specific debugging functions, for example core does the following within many modules:
|
||||
|
||||
```js
|
||||
var debug;
|
||||
if (process.env.NODE_DEBUG && /cluster/.test(process.env.NODE_DEBUG)) {
|
||||
debug = function(x) {
|
||||
var prefix = process.pid + ',' +
|
||||
(process.env.NODE_WORKER_ID ? 'Worker' : 'Master');
|
||||
console.error(prefix, x);
|
||||
};
|
||||
} else {
|
||||
debug = function() { };
|
||||
}
|
||||
```
|
||||
|
||||
This concept is extremely simple but it works well. With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.
|
||||
|
||||
Example _app.js_:
|
||||
|
||||
```js
|
||||
var debug = require('debug')('http')
|
||||
, http = require('http')
|
||||
, name = 'My App';
|
||||
|
||||
// fake app
|
||||
|
||||
debug('booting %s', name);
|
||||
|
||||
http.createServer(function(req, res){
|
||||
debug(req.method + ' ' + req.url);
|
||||
res.end('hello\n');
|
||||
}).listen(3000, function(){
|
||||
debug('listening');
|
||||
});
|
||||
|
||||
// fake worker of some kind
|
||||
|
||||
require('./worker');
|
||||
```
|
||||
|
||||
Example _worker.js_:
|
||||
|
||||
```js
|
||||
var debug = require('debug')('worker');
|
||||
|
||||
setInterval(function(){
|
||||
debug('doing some work');
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Millisecond diff
|
||||
|
||||
When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
|
||||
|
||||

|
||||
|
||||
When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
|
||||
|
||||

|
||||
|
||||
## Conventions
|
||||
|
||||
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
|
||||
|
||||
## Wildcards
|
||||
|
||||
The "*" character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
|
||||
|
||||
You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with "connect:".
|
||||
|
||||
## Browser support
|
||||
|
||||
Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`.
|
||||
|
||||
```js
|
||||
a = debug('worker:a');
|
||||
b = debug('worker:b');
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1000);
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1200);
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Generated
Vendored
+120
@@ -0,0 +1,120 @@
|
||||
;(function(){
|
||||
|
||||
/**
|
||||
* Create a debugger with the given `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Type}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function debug(name) {
|
||||
if (!debug.enabled(name)) return function(){};
|
||||
|
||||
return function(fmt){
|
||||
var curr = new Date;
|
||||
var ms = curr - (debug[name] || curr);
|
||||
debug[name] = curr;
|
||||
|
||||
fmt = name
|
||||
+ ' '
|
||||
+ fmt
|
||||
+ ' +' + debug.humanize(ms);
|
||||
|
||||
// This hackery is required for IE8
|
||||
// where `console.log` doesn't have 'apply'
|
||||
window.console
|
||||
&& console.log
|
||||
&& Function.prototype.apply.call(console.log, console, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The currently active debug mode names.
|
||||
*/
|
||||
|
||||
debug.names = [];
|
||||
debug.skips = [];
|
||||
|
||||
/**
|
||||
* Enables a debug mode by name. This can include modes
|
||||
* separated by a colon and wildcards.
|
||||
*
|
||||
* @param {String} name
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.enable = function(name) {
|
||||
localStorage.debug = name;
|
||||
|
||||
var split = (name || '').split(/[\s,]+/)
|
||||
, len = split.length;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
name = split[i].replace('*', '.*?');
|
||||
if (name[0] === '-') {
|
||||
debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
|
||||
}
|
||||
else {
|
||||
debug.names.push(new RegExp('^' + name + '$'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable debug output.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.disable = function(){
|
||||
debug.enable('');
|
||||
};
|
||||
|
||||
/**
|
||||
* Humanize the given `ms`.
|
||||
*
|
||||
* @param {Number} m
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
debug.humanize = function(ms) {
|
||||
var sec = 1000
|
||||
, min = 60 * 1000
|
||||
, hour = 60 * min;
|
||||
|
||||
if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
|
||||
if (ms >= min) return (ms / min).toFixed(1) + 'm';
|
||||
if (ms >= sec) return (ms / sec | 0) + 's';
|
||||
return ms + 'ms';
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the given mode name is enabled, false otherwise.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.enabled = function(name) {
|
||||
for (var i = 0, len = debug.skips.length; i < len; i++) {
|
||||
if (debug.skips[i].test(name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (var i = 0, len = debug.names.length; i < len; i++) {
|
||||
if (debug.names[i].test(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// persist
|
||||
|
||||
if (window.localStorage) debug.enable(localStorage.debug);
|
||||
module.exports = debug;
|
||||
|
||||
})();
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
|
||||
/**
|
||||
* Create a debugger with the given `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Type}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function debug(name) {
|
||||
if (!debug.enabled(name)) return function(){};
|
||||
|
||||
return function(fmt){
|
||||
var curr = new Date;
|
||||
var ms = curr - (debug[name] || curr);
|
||||
debug[name] = curr;
|
||||
|
||||
fmt = name
|
||||
+ ' '
|
||||
+ fmt
|
||||
+ ' +' + debug.humanize(ms);
|
||||
|
||||
// This hackery is required for IE8
|
||||
// where `console.log` doesn't have 'apply'
|
||||
window.console
|
||||
&& console.log
|
||||
&& Function.prototype.apply.call(console.log, console, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The currently active debug mode names.
|
||||
*/
|
||||
|
||||
debug.names = [];
|
||||
debug.skips = [];
|
||||
|
||||
/**
|
||||
* Enables a debug mode by name. This can include modes
|
||||
* separated by a colon and wildcards.
|
||||
*
|
||||
* @param {String} name
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.enable = function(name) {
|
||||
localStorage.debug = name;
|
||||
|
||||
var split = (name || '').split(/[\s,]+/)
|
||||
, len = split.length;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
name = split[i].replace('*', '.*?');
|
||||
if (name[0] === '-') {
|
||||
debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
|
||||
}
|
||||
else {
|
||||
debug.names.push(new RegExp('^' + name + '$'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable debug output.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.disable = function(){
|
||||
debug.enable('');
|
||||
};
|
||||
|
||||
/**
|
||||
* Humanize the given `ms`.
|
||||
*
|
||||
* @param {Number} m
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
debug.humanize = function(ms) {
|
||||
var sec = 1000
|
||||
, min = 60 * 1000
|
||||
, hour = 60 * min;
|
||||
|
||||
if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
|
||||
if (ms >= min) return (ms / min).toFixed(1) + 'm';
|
||||
if (ms >= sec) return (ms / sec | 0) + 's';
|
||||
return ms + 'ms';
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the given mode name is enabled, false otherwise.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
debug.enabled = function(name) {
|
||||
for (var i = 0, len = debug.skips.length; i < len; i++) {
|
||||
if (debug.skips[i].test(name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (var i = 0, len = debug.names.length; i < len; i++) {
|
||||
if (debug.names[i].test(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// persist
|
||||
|
||||
if (window.localStorage) debug.enable(localStorage.debug);
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
|
||||
var debug = require('../')('http')
|
||||
, http = require('http')
|
||||
, name = 'My App';
|
||||
|
||||
// fake app
|
||||
|
||||
debug('booting %s', name);
|
||||
|
||||
http.createServer(function(req, res){
|
||||
debug(req.method + ' ' + req.url);
|
||||
res.end('hello\n');
|
||||
}).listen(3000, function(){
|
||||
debug('listening');
|
||||
});
|
||||
|
||||
// fake worker of some kind
|
||||
|
||||
require('./worker');
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>debug()</title>
|
||||
<script src="../debug.js"></script>
|
||||
<script>
|
||||
// type debug.enable('*') in
|
||||
// the console and refresh :)
|
||||
|
||||
a = debug('worker:a');
|
||||
b = debug('worker:b');
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1000);
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1200);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
|
||||
var debug = {
|
||||
foo: require('../')('test:foo'),
|
||||
bar: require('../')('test:bar'),
|
||||
baz: require('../')('test:baz')
|
||||
};
|
||||
|
||||
debug.foo('foo')
|
||||
debug.bar('bar')
|
||||
debug.baz('baz')
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
// DEBUG=* node example/worker
|
||||
// DEBUG=worker:* node example/worker
|
||||
// DEBUG=worker:a node example/worker
|
||||
// DEBUG=worker:b node example/worker
|
||||
|
||||
var a = require('../')('worker:a')
|
||||
, b = require('../')('worker:b');
|
||||
|
||||
function work() {
|
||||
a('doing lots of uninteresting work');
|
||||
setTimeout(work, Math.random() * 1000);
|
||||
}
|
||||
|
||||
work();
|
||||
|
||||
function workb() {
|
||||
b('doing some work');
|
||||
setTimeout(workb, Math.random() * 2000);
|
||||
}
|
||||
|
||||
workb();
|
||||
+1
@@ -0,0 +1 @@
|
||||
;(function(){
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
|
||||
module.exports = require('./lib/debug');
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var tty = require('tty');
|
||||
|
||||
/**
|
||||
* Expose `debug()` as the module.
|
||||
*/
|
||||
|
||||
module.exports = debug;
|
||||
|
||||
/**
|
||||
* Enabled debuggers.
|
||||
*/
|
||||
|
||||
var names = []
|
||||
, skips = [];
|
||||
|
||||
(process.env.DEBUG || '')
|
||||
.split(/[\s,]+/)
|
||||
.forEach(function(name){
|
||||
name = name.replace('*', '.*?');
|
||||
if (name[0] === '-') {
|
||||
skips.push(new RegExp('^' + name.substr(1) + '$'));
|
||||
} else {
|
||||
names.push(new RegExp('^' + name + '$'));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
||||
var colors = [6, 2, 3, 4, 5, 1];
|
||||
|
||||
/**
|
||||
* Previous debug() call.
|
||||
*/
|
||||
|
||||
var prev = {};
|
||||
|
||||
/**
|
||||
* Previously assigned color.
|
||||
*/
|
||||
|
||||
var prevColor = 0;
|
||||
|
||||
/**
|
||||
* Is stdout a TTY? Colored output is disabled when `true`.
|
||||
*/
|
||||
|
||||
var isatty = tty.isatty(2);
|
||||
|
||||
/**
|
||||
* Select a color.
|
||||
*
|
||||
* @return {Number}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function color() {
|
||||
return colors[prevColor++ % colors.length];
|
||||
}
|
||||
|
||||
/**
|
||||
* Humanize the given `ms`.
|
||||
*
|
||||
* @param {Number} m
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function humanize(ms) {
|
||||
var sec = 1000
|
||||
, min = 60 * 1000
|
||||
, hour = 60 * min;
|
||||
|
||||
if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
|
||||
if (ms >= min) return (ms / min).toFixed(1) + 'm';
|
||||
if (ms >= sec) return (ms / sec | 0) + 's';
|
||||
return ms + 'ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a debugger with the given `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Type}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function debug(name) {
|
||||
function disabled(){}
|
||||
disabled.enabled = false;
|
||||
|
||||
var match = skips.some(function(re){
|
||||
return re.test(name);
|
||||
});
|
||||
|
||||
if (match) return disabled;
|
||||
|
||||
match = names.some(function(re){
|
||||
return re.test(name);
|
||||
});
|
||||
|
||||
if (!match) return disabled;
|
||||
var c = color();
|
||||
|
||||
function colored(fmt) {
|
||||
var curr = new Date;
|
||||
var ms = curr - (prev[name] || curr);
|
||||
prev[name] = curr;
|
||||
|
||||
fmt = ' \033[9' + c + 'm' + name + ' '
|
||||
+ '\033[3' + c + 'm\033[90m'
|
||||
+ fmt + '\033[3' + c + 'm'
|
||||
+ ' +' + humanize(ms) + '\033[0m';
|
||||
|
||||
console.error.apply(this, arguments);
|
||||
}
|
||||
|
||||
function plain(fmt) {
|
||||
fmt = new Date().toUTCString()
|
||||
+ ' ' + name + ' ' + fmt;
|
||||
console.error.apply(this, arguments);
|
||||
}
|
||||
|
||||
colored.enabled = plain.enabled = true;
|
||||
|
||||
return isatty
|
||||
? colored
|
||||
: plain;
|
||||
}
|
||||
+32
File diff suppressed because one or more lines are too long
+4
@@ -0,0 +1,4 @@
|
||||
|
||||
module.exports = debug;
|
||||
|
||||
})();
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "random-weighted-choice",
|
||||
"version": "0.1.1",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"author": {
|
||||
"name": "François Parmentier"
|
||||
},
|
||||
"main": "lib/random-weighted-choice.js",
|
||||
"readmeFilename": "README.md",
|
||||
"description": "Node.js module to make a random choice among weighted elements of table.",
|
||||
"dependencies": {
|
||||
"debug": "0.7.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "1.7.x"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"homepage": "http://github.com/parmentf/random-weighted-choice",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/parmentf/random-weighted-choice.git"
|
||||
},
|
||||
"keywords": [
|
||||
"random",
|
||||
"weighted"
|
||||
],
|
||||
"license": "BSD",
|
||||
"readme": "# Random Weighted Choice\n\n[](http://travis-ci.org/parmentf/random-weighted-choice)\n\nNode.js module to make a random choice among weighted elements of table.\n\n## Installation\n\nWith [npm](http://npmjs.org) do:\n\n $ npm install random-weighted-choice\n\n\n## Examples\n\nAlthough you can add several times the same id\n\n var rwc = require('random-weighted-choice');\n var table = [\n { weight: 1, id: \"item1\"} // Element 1\n , { weight: 1, id: \"item2\"} // Element 2\n , { weight: 4, id: \"item3\"} // Element with a 4 times likelihood\n , { weight: 2, id: \"item1\"} // Element 1, weight added with 2 => 3\n ];\n var choosenItem = rwc(table);\n var choosenUnlikely = rwc(table, 100); // The last shall be first\n var choosenDeterministically = rwc(table, 0);\n\nIt is better to not use the same twice, if you want a temperature other than\nthe default one (50).\n\n var rwc = require('random-weighted-choice');\n var table = [\n { weight: 1, id: \"item1\"} // Element 1\n , { weight: 1, id: \"item2\"} // Element 2\n , { weight: 4, id: \"item3\"} // Element with a 4 times likelihood\n , { weight: 2, id: \"item4\"} // Element 4\n , { weight: 2, id: \"item5\"}\n ];\n var choosenItem = rwc(table);\n var choosenUnlikely = rwc(table, 100); // The last shall be first\n var choosenDeterministically = rwc(table, 0);\n\nWithout temperature (second parameter) or a 50 value, likelihoods are:\n\n { item1: 10%, item2: 10%, item3: 40%, item4: 20%, item5: 20% }\n\nWith a temperature value of 100:\n\n { item1: 30%, item2: 30%, item3: 0%, item4: 20%, item5: 20% }\n\nWith a temperature value of 0, modified weights are:\n\n { item1: 0, item2: 0, item3: 8, item4: 2, item5: 2 }\n\n## Usage\n\n### random-weighted-choice(Array table, Number temperature = 50)\n\nReturn the ``id`` of the chosen item from ``table``.\n\nThe ``table`` parameter should contain an Array. Each item of that Array must\nbean object, with at least ``weight`` and ``id`` property.\n\nWeight values are relative to each other. They are integers.\n\nWhen the sum of the weight values is ``null``, ``null`` is returned (can't choose).\n\nWhen the Array is empty, ``null`` is returned.\n\nMore explanations on how it works on [Everything2](http://everything2.com/title/Blackboard+temperature).\n\n## Also\n\n* https://github.com/Schoonology/weighted",
|
||||
"_id": "random-weighted-choice@0.1.1",
|
||||
"_from": "random-weighted-choice"
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*jshint node:true, laxcomma:true */
|
||||
/*global describe:true, it:true */
|
||||
"use strict";
|
||||
|
||||
var debug = require('debug')('rwc:test');
|
||||
var assert = require('assert');
|
||||
|
||||
var rwc = require('../lib/random-weighted-choice');
|
||||
|
||||
var randomCounter = 0;
|
||||
var randomValues = [0,0.19,0.5,0.7,0.9];
|
||||
var randomMock = function(values, reset) {
|
||||
if(typeof(values)=="undefined") values = randomValues;
|
||||
if (typeof(reset)=="undefined") reset = false;
|
||||
if (reset) randomCounter = 0;
|
||||
return values[randomCounter++];
|
||||
};
|
||||
|
||||
|
||||
describe('Temperature 50', function () {
|
||||
var table = [
|
||||
{ weight: 1, id: "item1"} // Element 1
|
||||
, { weight: 1, id: "item2"} // Element 2
|
||||
, { weight: 4, id: "item3"} // Element with a 4 times likelihood
|
||||
, { weight: 2, id: "item4"} // Element 4
|
||||
, { weight: 2, id: "item5"}
|
||||
];
|
||||
|
||||
it('should return "item1"', function (){
|
||||
assert.equal('item1', rwc(table,null,randomMock));
|
||||
});
|
||||
it('should return "item2"', function (){
|
||||
assert.equal('item2', rwc(table,null,randomMock));
|
||||
});
|
||||
it('should return "item3"', function (){
|
||||
assert.equal('item3', rwc(table,null,randomMock));
|
||||
});
|
||||
it('should return "item4"', function (){
|
||||
assert.equal('item4', rwc(table,null,randomMock));
|
||||
});
|
||||
it('should return "item5"', function (){
|
||||
assert.equal('item5', rwc(table,null,randomMock));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Empty table', function () {
|
||||
it('should return null', function () {
|
||||
assert.equal(null, rwc([]));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('One element', function () {
|
||||
it('should return the element', function () {
|
||||
assert.equal('a', rwc([{weight:1, id: 'a'}]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('No weight', function () {
|
||||
it('should return null', function () {
|
||||
assert.equal(null, rwc([{weight:0, id: 'a'}]));
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.random = randomMock;
|
||||
Reference in New Issue
Block a user