Initital commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
.vscode/
|
||||||
|
node_modules/
|
||||||
+125
@@ -0,0 +1,125 @@
|
|||||||
|
const { log } = require("console");
|
||||||
|
const RollCheck = require("./RollCheck");
|
||||||
|
const StatRoll = require("./StatRoll");
|
||||||
|
const { stat } = require("fs");
|
||||||
|
const ResultStatistics = require("./ResultStatistics");
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = class Checker {
|
||||||
|
/**
|
||||||
|
* @type {RollCheck[]}
|
||||||
|
*/
|
||||||
|
checks = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {int[]}
|
||||||
|
*/
|
||||||
|
amounts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {int}
|
||||||
|
*/
|
||||||
|
attemts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
#isPrepared = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ResultStatistics}
|
||||||
|
*/
|
||||||
|
statistic_all;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ResultStatistics}
|
||||||
|
*/
|
||||||
|
statistic_passed;
|
||||||
|
|
||||||
|
variants = {};
|
||||||
|
|
||||||
|
full_mask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} name
|
||||||
|
* @param {(roll: StatRoll) => boolean} fn
|
||||||
|
*/
|
||||||
|
addCheck(name, fn) {
|
||||||
|
if (this.#isPrepared) {
|
||||||
|
console.log("Cannot add check while prepared");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.checks.push(new RollCheck(name, fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
this.amounts = Array.from({length: Math.pow(2, this.checks.length)}, _ => 0);
|
||||||
|
this.#isPrepared = true;
|
||||||
|
this.attemts = 0;
|
||||||
|
|
||||||
|
this.statistic_all = new ResultStatistics();
|
||||||
|
this.statistic_passed = new ResultStatistics();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {StatRoll} statRoll
|
||||||
|
*/
|
||||||
|
test(statRoll) {
|
||||||
|
let mask = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < this.checks.length; i++) {
|
||||||
|
const check = this.checks[i];
|
||||||
|
const checkResult = check.test(statRoll);
|
||||||
|
|
||||||
|
mask += checkResult ? Math.pow(2, i) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.amounts[mask] += 1;
|
||||||
|
this.attemts += 1;
|
||||||
|
|
||||||
|
this.statistic_all.add(statRoll);
|
||||||
|
|
||||||
|
if (mask + 1 === this.amounts.length) {
|
||||||
|
this.statistic_passed.add(statRoll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printResults() {
|
||||||
|
this.statistic_all.print(this.attemts);
|
||||||
|
|
||||||
|
const resultPerCheck = [];
|
||||||
|
for (let i = 0; i < this.checks.length; i++) {
|
||||||
|
const check = this.checks[i];
|
||||||
|
const amount = this.amounts.filter((_, mask) => (mask >> i) % 2 > 0).reduce((a, s) => s + a);
|
||||||
|
|
||||||
|
resultPerCheck.push({
|
||||||
|
check: check.name,
|
||||||
|
successes: amount,
|
||||||
|
successes_percent: 100 * amount / this.attemts,
|
||||||
|
fails: this.attemts - amount,
|
||||||
|
fails_percent: 100 * (this.attemts - amount) / this.attemts,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.table(resultPerCheck);
|
||||||
|
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
|
||||||
|
for (let mask = 0; mask < this.amounts.length; mask++) {
|
||||||
|
const amount = this.amounts[mask];
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
mask: mask.toString(2),
|
||||||
|
successes: this.checks.filter((_, i) => (mask >> i) % 2 > 0).map(f => f.name).join(', '),
|
||||||
|
fails: this.checks.filter((_, i) => (mask >> i) % 2 === 0).map(f => f.name).join(', '),
|
||||||
|
amount: amount,
|
||||||
|
percent: 100 * amount / this.attemts,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.table(result);
|
||||||
|
|
||||||
|
this.statistic_passed.print(this.amounts[this.amounts.length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
const StatRoll = require("./StatRoll");
|
||||||
|
const { table } = require('table');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = class ResultStatistics {
|
||||||
|
dices = {};
|
||||||
|
stats = {};
|
||||||
|
counts = {};
|
||||||
|
sums = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.dices = {};
|
||||||
|
this.counts[0] = {};
|
||||||
|
for (let i = 1; i <= 6; i++) {
|
||||||
|
this.dices[i] = 0;
|
||||||
|
|
||||||
|
this.counts[i] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stats = {};
|
||||||
|
for (let j = 3; j <= 18; j++) {
|
||||||
|
this.stats[j] = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i <= 6; i++) {
|
||||||
|
this.counts[i][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sums = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {StatRoll} statRoll
|
||||||
|
*/
|
||||||
|
add(statRoll) {
|
||||||
|
for (let i = 0; i < statRoll.rolls.length; i++) {
|
||||||
|
const stat = statRoll.rolls[i];
|
||||||
|
|
||||||
|
// this.stats[stat.result] += 1;
|
||||||
|
|
||||||
|
for (const dice of stat.dices) {
|
||||||
|
this.dices[dice] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let j = 3; j <= 18; j++) {
|
||||||
|
let count = statRoll.rolls.filter(r => r.result === j).length;
|
||||||
|
|
||||||
|
this.counts[count][j] += 1;
|
||||||
|
|
||||||
|
this.stats[j] += count ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sums[statRoll.sum] = (this.sums[statRoll.sum] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print(norm = 1) {
|
||||||
|
const rows = [];
|
||||||
|
|
||||||
|
rows.push([ '', ...Object.keys(this.stats) ]);
|
||||||
|
|
||||||
|
rows.push([ 'Probability', ...Object.values(this.stats).map(v => perc(v, norm)) ]);
|
||||||
|
rows.push([ 'Missing', ...Object.values(this.counts[0]).map(v => perc(v, norm)) ]);
|
||||||
|
|
||||||
|
for (let i = 1; i <= 6; i++) {
|
||||||
|
const counts = this.counts[i];
|
||||||
|
|
||||||
|
rows.push([ i, ...Object.values(this.counts[i]).map(v => perc(v, norm)) ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(table(rows, {
|
||||||
|
drawHorizontalLine: (i, rc) => [0, 1, 3, rc].indexOf(i) >= 0,
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
const sums = {};
|
||||||
|
const spl = 5;
|
||||||
|
const from = Math.floor(Object.keys(this.sums).reduce((a, m) => Math.min(a, m)) / spl);
|
||||||
|
const to = Math.floor(Object.keys(this.sums).reduce((a, m) => Math.max(a, m)) / spl);
|
||||||
|
|
||||||
|
for (let i = from; i <= to; i++) {
|
||||||
|
const min = spl * i, max = spl * (i + 1) - 1;
|
||||||
|
const f = Object.entries(this.sums).filter(([sum, _]) => (sum >= min) && (sum <= max));
|
||||||
|
sums[`${min}-${max}`] = perc(f.length ? f.map(([_, count]) => count).reduce((count, sum) => sum + count) : 0, norm);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(table([ Object.keys(sums), Object.values(sums) ]))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function perc(a, N) {
|
||||||
|
return (a == 0) ? '' : `${(100 * a / N).toLocaleString('ru-RU', { maximumFractionDigits: 2, minimumFractionDigits: 2 })}%`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const StatRoll = require("./StatRoll");
|
||||||
|
|
||||||
|
module.exports = class RollCheck {
|
||||||
|
name;
|
||||||
|
fn;
|
||||||
|
|
||||||
|
constructor(name, fn) {
|
||||||
|
this.name = name;
|
||||||
|
this.fn = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {StatRoll} statRoll
|
||||||
|
*/
|
||||||
|
test(statRoll) {
|
||||||
|
return this.fn(statRoll);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Chance = require("chance");
|
||||||
|
|
||||||
|
module.exports = class Stat {
|
||||||
|
/**
|
||||||
|
* @type {number{4}}
|
||||||
|
*/
|
||||||
|
dices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
result
|
||||||
|
|
||||||
|
constructor(diceString) {
|
||||||
|
this.dices = Stat.chance(diceString);
|
||||||
|
// this.dices = Array.from({length: 4}, _ => Math.floor(Math.random() * 6 + 1));
|
||||||
|
|
||||||
|
this.dices.sort().reverse();
|
||||||
|
|
||||||
|
this.result = this.dices.reduce((a, s) => s + a, 0) - Math.min(...this.dices);
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return `${this.result} [${this.dices.join(',')}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static #chance;
|
||||||
|
|
||||||
|
static chance(diceString) {
|
||||||
|
if (!this.#chance) {
|
||||||
|
this.#chance = new Chance();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.#chance.rpg(diceString);
|
||||||
|
}
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Stat = require("./Stat.js");
|
||||||
|
|
||||||
|
module.exports = class StatRoll {
|
||||||
|
/**
|
||||||
|
* @prop {Stat[6]} rolls
|
||||||
|
*/
|
||||||
|
rolls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @prop {number} sum
|
||||||
|
*/
|
||||||
|
sum;
|
||||||
|
|
||||||
|
constructor(rolls) {
|
||||||
|
this.rolls = Array.from({length: 6}, _ => new Stat("4d6"));
|
||||||
|
|
||||||
|
this.rolls.sort((r1, r2) => r1.result - r2.result).reverse();
|
||||||
|
|
||||||
|
this.sum = this.rolls.map(r => r.result).reduce((r, s) => s += r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return `{${this.rolls.join(' / ')}}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
toShortString() {
|
||||||
|
return `{${this.rolls.map(r => r.result).join('/')}}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Checker = require("./Checker.js");
|
||||||
|
const StatRoll = require("./StatRoll.js");
|
||||||
|
const ProgressBar = require('progress');
|
||||||
|
|
||||||
|
const checker = new Checker();
|
||||||
|
|
||||||
|
checker.addCheck("min70", roll => roll.sum >= 70);
|
||||||
|
checker.addCheck("lows", roll => roll.rolls.filter(r => r.result < 10).length < 2);
|
||||||
|
checker.addCheck("highs", roll => roll.rolls.filter(r => r.result >= 15).length >= 2);
|
||||||
|
|
||||||
|
checker.prepare();
|
||||||
|
|
||||||
|
|
||||||
|
const N = 1000000;
|
||||||
|
// const N = 10;
|
||||||
|
|
||||||
|
const bar = new ProgressBar('[:bar] :rate/bps :percent :etas', { total: N });
|
||||||
|
|
||||||
|
for (let i = 0; i < N; i++) {
|
||||||
|
const roll = new StatRoll();
|
||||||
|
|
||||||
|
checker.test(roll);
|
||||||
|
|
||||||
|
bar.tick();
|
||||||
|
|
||||||
|
// console.log(roll.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(checker);
|
||||||
|
|
||||||
|
checker.printResults();
|
||||||
Generated
+199
@@ -0,0 +1,199 @@
|
|||||||
|
{
|
||||||
|
"name": "dnd_stat_roll_distribution",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "dnd_stat_roll_distribution",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"chance": "^1.1.11",
|
||||||
|
"progress": "^2.0.3",
|
||||||
|
"table": "^6.8.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ajv": {
|
||||||
|
"version": "8.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
|
||||||
|
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.1",
|
||||||
|
"json-schema-traverse": "^1.0.0",
|
||||||
|
"require-from-string": "^2.0.2",
|
||||||
|
"uri-js": "^4.2.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/astral-regex": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chance": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/chance/-/chance-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-kqTg3WWywappJPqtgrdvbA380VoXO2eu9VCV895JgbyHsaErXdyHK9LOZ911OvAk6L0obK7kDk9CGs8+oBawVA=="
|
||||||
|
},
|
||||||
|
"node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
|
},
|
||||||
|
"node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||||
|
},
|
||||||
|
"node_modules/fast-deep-equal": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
|
},
|
||||||
|
"node_modules/is-fullwidth-code-point": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/json-schema-traverse": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
|
||||||
|
},
|
||||||
|
"node_modules/lodash.truncate": {
|
||||||
|
"version": "4.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
|
||||||
|
"integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw=="
|
||||||
|
},
|
||||||
|
"node_modules/progress": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/punycode": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/require-from-string": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/slice-ansi": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.0.0",
|
||||||
|
"astral-regex": "^2.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-ansi": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/table": {
|
||||||
|
"version": "6.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz",
|
||||||
|
"integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "^8.0.1",
|
||||||
|
"lodash.truncate": "^4.4.2",
|
||||||
|
"slice-ansi": "^4.0.0",
|
||||||
|
"string-width": "^4.2.3",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uri-js": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": "^2.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "dnd_stat_roll_distribution",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"main": "node main.js"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"chance": "^1.1.11",
|
||||||
|
"progress": "^2.0.3",
|
||||||
|
"table": "^6.8.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user