@randsum/mcp
Version:
Model Context Protocol stdio server exposing the RANDSUM dice rolling ecosystem to AI agents
1,482 lines (1,470 loc) • 155 kB
JavaScript
#!/usr/bin/env node
// src/index.ts
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z as z3 } from "zod";
// package.json
var version = "2.0.0";
// ../roller/dist/shared/chunk-b1m8anm6.js
var A = { INVALID_NOTATION: "INVALID_NOTATION", MODIFIER_ERROR: "MODIFIER_ERROR", VALIDATION_ERROR: "VALIDATION_ERROR", ROLL_ERROR: "ROLL_ERROR" };
class z extends Error {
code;
context;
constructor(j, k, q) {
super(j);
this.name = "RandsumError", this.code = k, this.context = q;
}
}
class H extends z {
suggestion;
constructor(j, k, q, B) {
let F = q ? `Invalid notation "${j}": ${k}. Did you mean "${q}"?` : `Invalid notation "${j}": ${k}`, G = { notation: j, ...B };
super(F, A.INVALID_NOTATION, G);
this.name = "NotationParseError", this.suggestion = q;
}
}
class I extends z {
constructor(j, k, q) {
super(`Modifier error for "${j}": ${k}`, A.MODIFIER_ERROR, q);
this.name = "ModifierError";
}
}
class J extends z {
constructor(j, k) {
super(`Validation error: ${j}`, A.VALIDATION_ERROR, k);
this.name = "ValidationError";
}
}
class K extends z {
constructor(j, k) {
super(j, A.ROLL_ERROR, k);
this.name = "RollError";
}
}
// ../games/dist/shared/chunk-ncvrq0cn.js
class E extends z {
code;
constructor(e, r) {
super(e, r);
this.name = "SchemaError", this.code = r;
}
}
// ../roller/dist/shared/chunk-c998prkd.js
function q(r) {
if (!r.length)
return "";
if (r.length === 1)
return `${r[0]}`;
let e = r.map((u) => `${u}`), t = e.pop();
return `${e.join(" ")} and ${t}`;
}
function O(r) {
let t = r.replace(/[{}]/g, "").split(",").map((f) => f.trim()).filter(Boolean), u = {}, m = [];
for (let f of t)
if (f.startsWith(">=")) {
let n = Number(f.slice(2));
if (!isNaN(n))
u.greaterThanOrEqual = n;
} else if (f.startsWith("<=")) {
let n = Number(f.slice(2));
if (!isNaN(n))
u.lessThanOrEqual = n;
} else if (f.startsWith(">")) {
let n = Number(f.slice(1));
if (!isNaN(n))
u.greaterThan = n;
} else if (f.startsWith("<")) {
let n = Number(f.slice(1));
if (!isNaN(n))
u.lessThan = n;
} else if (f.startsWith("=")) {
let n = Number(f.slice(1));
if (!isNaN(n))
m.push(n);
} else {
let n = Number(f);
if (!isNaN(n))
m.push(n);
}
if (m.length > 0)
u.exact = m;
return u;
}
function a(r) {
return r.greaterThan !== undefined || r.greaterThanOrEqual !== undefined || r.lessThan !== undefined || r.lessThanOrEqual !== undefined || r.exact !== undefined && r.exact.length > 0;
}
function K2({ greaterThan: r, greaterThanOrEqual: e, lessThan: t, lessThanOrEqual: u, exact: m }) {
let f = [];
if (m?.length)
f.push(q(m));
if (e !== undefined)
f.push(`greater than or equal to ${e}`);
if (r !== undefined)
f.push(`greater than ${r}`);
if (u !== undefined)
f.push(`less than or equal to ${u}`);
if (t !== undefined)
f.push(`less than ${t}`);
return f;
}
function C({ greaterThan: r, greaterThanOrEqual: e, lessThan: t, lessThanOrEqual: u, exact: m }) {
let f = [];
if (m?.length)
f.push(...m.map(String));
if (e !== undefined)
f.push(`>=${e}`);
if (r !== undefined)
f.push(`>${r}`);
if (u !== undefined)
f.push(`<=${u}`);
if (t !== undefined)
f.push(`<${t}`);
return f;
}
function h(r) {
return r;
}
var I2 = /[Cc]\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\}/;
var w = h({ name: "cap", priority: 10, pattern: I2, parse: (r) => {
let e = I2.exec(r);
if (!e?.[1])
return {};
let t = O(e[1]), u = {};
if (t.greaterThan !== undefined)
u.greaterThan = t.greaterThan;
if (t.greaterThanOrEqual !== undefined)
u.greaterThanOrEqual = t.greaterThanOrEqual;
if (t.lessThan !== undefined)
u.lessThan = t.lessThan;
if (t.lessThanOrEqual !== undefined)
u.lessThanOrEqual = t.lessThanOrEqual;
if (t.exact?.length)
u.exact = t.exact;
return Object.keys(u).length > 0 ? { cap: u } : {};
}, toNotation: (r) => {
let e = C(r);
return e.length ? `C{${e.join(",")}}` : undefined;
}, toDescription: (r) => {
let { exact: e, ...t } = r, u = [];
if (e?.length)
u.push(...e.map((f) => `No Rolls Greater Than ${f}`));
let m = K2(t);
return u.push(...m.map((f) => `No Rolls ${f}`)), u;
} });
var T = /!!(\d+)?(\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\})?/;
var W = h({ name: "compound", priority: 51, pattern: T, parse: (r) => {
let e = T.exec(r);
if (!e)
return {};
let t = e[1], u = e[3];
if (u) {
let m = O(u);
if (a(m))
return { compound: m };
}
if (t !== undefined)
return { compound: Number(t) };
return { compound: true };
}, toNotation: (r) => {
if (r === true)
return "!!";
if (typeof r === "number")
return `!!${r}`;
if (typeof r === "object") {
let e = C(r);
if (!e.length)
return "!!";
return `!!{${e.join(",")}}`;
}
return;
}, toDescription: (r) => {
if (r === true)
return ["Compounding Dice"];
if (r === 0)
return ["Compounding Dice (unlimited)"];
if (typeof r === "number")
return [`Compounding Dice (max ${r} times)`];
if (typeof r === "object") {
let e = K2(r);
if (e.length === 0)
return ["Compounding Dice"];
return [`Compounding Dice on ${e.join(" or ")}`];
}
return [];
} });
var R = /#\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\}/;
var V = h({ name: "count", priority: 80, pattern: R, parse: (r) => {
let e = R.exec(r);
if (!e)
return {};
let t = O(e[1] ?? ""), u = t.greaterThan !== undefined || t.greaterThanOrEqual !== undefined, m = t.lessThan !== undefined || t.lessThanOrEqual !== undefined, f = { ...t };
if (u && m)
f.deduct = true;
return { count: f };
}, toNotation: (r) => {
let e = [];
if (r.exact?.length)
e.push(...r.exact.map((t) => `=${t}`));
if (r.greaterThanOrEqual !== undefined)
e.push(`>=${r.greaterThanOrEqual}`);
if (r.greaterThan !== undefined)
e.push(`>${r.greaterThan}`);
if (r.lessThanOrEqual !== undefined)
e.push(`<=${r.lessThanOrEqual}`);
if (r.lessThan !== undefined)
e.push(`<${r.lessThan}`);
if (e.length === 0)
return;
return `#{${e.join(",")}}`;
}, toDescription: (r) => {
let e = [];
if (r.exact?.length)
e.push(`Count dice equal to ${r.exact.join(", ")}`);
if (r.greaterThanOrEqual !== undefined)
e.push(`Count dice greater than or equal to ${r.greaterThanOrEqual}`);
if (r.greaterThan !== undefined)
e.push(`Count dice greater than ${r.greaterThan}`);
if (r.lessThanOrEqual !== undefined)
if (r.deduct)
e.push(`deduct dice less than or equal to ${r.lessThanOrEqual}`);
else
e.push(`Count dice less than or equal to ${r.lessThanOrEqual}`);
if (r.lessThan !== undefined)
if (r.deduct)
e.push(`deduct dice less than ${r.lessThan}`);
else
e.push(`Count dice less than ${r.lessThan}`);
if (e.length === 0)
return [];
if (r.deduct && e.length > 1)
return [e.join(", ")];
return e;
} });
var Vr = /[Hh](\d+)?/g;
var Br = /(?<![Kk])[Ll](\d+)?/g;
var Jr = /[Dd]\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\}/;
var B = h({ name: "drop", priority: 65, pattern: /([Hh](\d+)?|(?<![Kk])[Ll](\d+)?|[Dd]\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\})/, parse: (r) => {
let e = {}, t = Array.from(r.matchAll(Vr));
if (t.length > 0)
e.highest = t.reduce((f, n) => {
return f + (n[1] ? Number(n[1]) : 1);
}, 0);
let u = Array.from(r.matchAll(Br));
if (u.length > 0)
e.lowest = u.reduce((f, n) => {
return f + (n[1] ? Number(n[1]) : 1);
}, 0);
let m = Jr.exec(r);
if (m?.[1]) {
let f = O(m[1]);
if (f.greaterThan !== undefined)
e.greaterThan = f.greaterThan;
if (f.greaterThanOrEqual !== undefined)
e.greaterThanOrEqual = f.greaterThanOrEqual;
if (f.lessThan !== undefined)
e.lessThan = f.lessThan;
if (f.lessThanOrEqual !== undefined)
e.lessThanOrEqual = f.lessThanOrEqual;
if (f.exact)
e.exact = f.exact;
}
return a(e) || e.highest !== undefined || e.lowest !== undefined ? { drop: e } : {};
}, toNotation: (r) => {
let { highest: e, lowest: t, greaterThan: u, greaterThanOrEqual: m, lessThan: f, lessThanOrEqual: n, exact: N } = r, $ = [];
if (e)
$.push(e === 1 ? "H" : `H${e}`);
if (t)
$.push(t === 1 ? "L" : `L${t}`);
let b = [];
if (m !== undefined)
b.push(`>=${m}`);
if (u !== undefined)
b.push(`>${u}`);
if (n !== undefined)
b.push(`<=${n}`);
if (f !== undefined)
b.push(`<${f}`);
if (N)
N.forEach((g) => b.push(`${g}`));
if (b.length > 0)
$.push(`D{${b.join(",")}}`);
return $.length ? $.join("") : undefined;
}, toDescription: (r) => {
let { highest: e, lowest: t, greaterThan: u, greaterThanOrEqual: m, lessThan: f, lessThanOrEqual: n, exact: N } = r, $ = [];
if (e)
$.push(e > 1 ? `Drop highest ${e}` : "Drop highest");
if (t)
$.push(t > 1 ? `Drop lowest ${t}` : "Drop lowest");
if (N)
$.push(`Drop ${q(N)}`);
if (m !== undefined)
$.push(`Drop greater than or equal to ${m}`);
if (u !== undefined)
$.push(`Drop greater than ${u}`);
if (n !== undefined)
$.push(`Drop less than or equal to ${n}`);
if (f !== undefined)
$.push(`Drop less than ${f}`);
return $;
} });
var Qr = /(?<!!)!(?!!|[pPsSiIrR])(\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\})?/;
var J2 = h({ name: "explode", priority: 50, pattern: /(?<!!)!(?!!|[pPsSiIrR])(\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\})?/, parse: (r) => {
let e = Qr.exec(r);
if (!e)
return {};
let t = e[2];
if (t) {
let u = O(t);
if (a(u))
return { explode: u };
}
return { explode: true };
}, toNotation: (r) => {
if (r === true)
return "!";
if (typeof r === "object") {
let e = C(r);
if (!e.length)
return "!";
return `!{${e.join(",")}}`;
}
return;
}, toDescription: (r) => {
if (!r)
return [];
if (r === true)
return ["Exploding Dice"];
if (typeof r === "object") {
let e = K2(r);
if (e.length === 0)
return ["Exploding Dice"];
return [`Exploding Dice on ${e.join(" or ")}`];
}
return ["Exploding Dice"];
} });
var zr = /![sS]\{[\d,]+\}/;
var Q = h({ name: "explodeSequence", priority: 53, pattern: /![sS]\{[\d,]+\}|![iI]|![rR]/, parse: (r) => {
let e = zr.exec(r);
if (!e)
return {};
return { explodeSequence: e[0].slice(3, -1).split(",").map(Number) };
}, toNotation: (r) => {
if (!Array.isArray(r) || r.length === 0)
return;
return `!s{${r.join(",")}}`;
}, toDescription: (r) => {
if (!Array.isArray(r) || r.length === 0)
return [];
return [`Explode through sequence: ${r.map((t) => `d${t}`).join(", ")}`];
} });
var S = /\/\/(\d+)/;
var z2 = h({ name: "integerDivide", priority: 93, pattern: S, parse: (r) => {
let e = S.exec(r);
if (!e)
return {};
return { integerDivide: Number(e[1]) };
}, toNotation: (r) => {
return `//${r}`;
}, toDescription: (r) => {
return [`Integer divide by ${r}`];
} });
var Ur = /[Kk][Mm](\d+)?/;
var Zr = /[Kk](?![LlMm])(\d+)?/;
var Pr = /[Kk][Ll](\d+)?/i;
var U = h({ name: "keep", priority: 66, pattern: /[Kk]([LlMm])?(\d+)?/, parse: (r) => {
let e = Ur.exec(r);
if (e) {
let f = e[1] ? Number(e[1]) : 1;
return { drop: { lowest: f, highest: f } };
}
let t = {}, u = Pr.exec(r);
if (u)
return t.lowest = u[1] ? Number(u[1]) : 1, { keep: t };
let m = Zr.exec(r);
if (m)
return t.highest = m[1] ? Number(m[1]) : 1, { keep: t };
return {};
}, toNotation: (r) => {
let { highest: e, lowest: t } = r, u = [];
if (e)
u.push(e === 1 ? "K" : `K${e}`);
if (t)
u.push(t === 1 ? "kl" : `kl${t}`);
return u.length ? u.join("") : undefined;
}, toDescription: (r) => {
let { highest: e, lowest: t } = r, u = [];
if (e)
u.push(e > 1 ? `Keep highest ${e}` : "Keep highest");
if (t)
u.push(t > 1 ? `Keep lowest ${t}` : "Keep lowest");
return u;
} });
function A2(r) {
let { name: e, priority: t, operator: u, verb: m } = r, f = u === "+" ? "\\+" : "-", n = new RegExp(`${f}(\\d+)`), N = new RegExp(`${f}(\\d+)`, "g");
return h({ name: e, priority: t, pattern: n, parse: ($) => {
let b = Array.from($.matchAll(N));
if (b.length === 0)
return {};
let g = b.reduce((p, d) => p + Number(d[1]), 0);
return { [e]: g };
}, toNotation: ($) => {
if (e === "plus" && $ < 0)
return `-${Math.abs($)}`;
return `${u}${$}`;
}, toDescription: ($) => {
return [`${m} ${$}`];
} });
}
var Z = A2({ name: "minus", priority: 91, operator: "-", verb: "Subtract" });
var k = /%(\d+)/;
var P = h({ name: "modulo", priority: 94, pattern: k, parse: (r) => {
let e = k.exec(r);
if (!e)
return {};
return { modulo: Number(e[1]) };
}, toNotation: (r) => {
return `%${r}`;
}, toDescription: (r) => {
return [`Modulo ${r}`];
} });
var _ = /(?<!\*)\*(?!\*)(\d+)/;
var X = h({ name: "multiply", priority: 85, pattern: _, parse: (r) => {
let e = _.exec(r);
if (!e)
return {};
return { multiply: Number(e[1]) };
}, toNotation: (r) => {
return `*${r}`;
}, toDescription: (r) => {
return [`Multiply dice by ${r}`];
} });
var i = /\*\*(\d+)/;
var H2 = h({ name: "multiplyTotal", priority: 100, pattern: i, parse: (r) => {
let e = i.exec(r);
if (!e)
return {};
return { multiplyTotal: Number(e[1]) };
}, toNotation: (r) => {
return `**${r}`;
}, toDescription: (r) => {
return [`Multiply total by ${r}`];
} });
var s = /!p(\d+)?(\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\})?/i;
var Y = h({ name: "penetrate", priority: 52, pattern: s, parse: (r) => {
let e = s.exec(r);
if (!e)
return {};
let t = e[1], u = e[3];
if (u) {
let m = O(u);
if (a(m))
return { penetrate: m };
}
if (t !== undefined)
return { penetrate: Number(t) };
return { penetrate: true };
}, toNotation: (r) => {
if (r === true)
return "!p";
if (typeof r === "number")
return `!p${r}`;
if (typeof r === "object") {
let e = C(r);
if (!e.length)
return "!p";
return `!p{${e.join(",")}}`;
}
return;
}, toDescription: (r) => {
if (r === true)
return ["Penetrating Dice"];
if (r === 0)
return ["Penetrating Dice (unlimited)"];
if (typeof r === "number")
return [`Penetrating Dice (max ${r} times)`];
if (typeof r === "object") {
let e = K2(r);
if (e.length === 0)
return ["Penetrating Dice"];
return [`Penetrating Dice on ${e.join(" or ")}`];
}
return [];
} });
var c = A2({ name: "plus", priority: 90, operator: "+", verb: "Add" });
var rr = /[Vv]\{((?:>=|<=|>|<)?\d+=\d+(?:,(?:>=|<=|>|<)?\d+=\d+)*)\}/;
var G = h({ name: "replace", priority: 30, pattern: rr, parse: (r) => {
let e = rr.exec(r);
if (!e)
return {};
let t = e[1];
if (!t)
return {};
return { replace: t.split(",").map((f) => f.trim()).map((f) => {
let n = /^((?:>=|<=|>|<)?\d+)=(\d+)$/.exec(f);
if (!n?.[1] || !n[2])
return { from: 0, to: 0 };
let [, N, $] = n;
return { from: N.startsWith(">=") ? { greaterThanOrEqual: Number(N.slice(2)) } : N.startsWith("<=") ? { lessThanOrEqual: Number(N.slice(2)) } : N.startsWith(">") ? { greaterThan: Number(N.slice(1)) } : N.startsWith("<") ? { lessThan: Number(N.slice(1)) } : Number(N), to: Number($) };
}) };
}, toNotation: (r) => {
let t = (Array.isArray(r) ? r : [r]).map(({ from: u, to: m }) => {
if (typeof u === "object")
return C(u).map((n) => `${n}=${m}`).join(",");
return `${u}=${m}`;
});
return t.length ? `V{${t.join(",")}}` : undefined;
}, toDescription: (r) => {
return (Array.isArray(r) ? r : [r]).map(({ from: t, to: u }) => {
if (typeof t === "object")
return `Replace ${K2(t).join(" and ")} with ${u}`;
return `Replace ${t} with ${u}`;
});
} });
var er = "((?:>=|<=|>|<|=)?\\d+(?:,(?:>=|<=|>|<|=)?\\d+)*)";
var Xr = new RegExp(`[Rr][Oo]\\{${er}\\}|[Rr]\\{${er}\\}(\\d+)?`, "g");
var L = h({ name: "reroll", priority: 40, pattern: /[Rr]([Oo])?\{((?:>=|<=|>|<|=)?\d+(?:,(?:>=|<=|>|<|=)?\d+)*)\}(\d+)?/, parse: (r) => {
let e = Array.from(r.matchAll(Xr));
if (e.length === 0)
return {};
let t = {};
for (let u of e) {
let m = u[1] !== undefined, f = m ? u[1] : u[2], n = m ? 1 : u[3] ? Number(u[3]) : undefined;
if (n !== undefined)
t.max = n;
if (f) {
let N = O(f);
if (N.greaterThan !== undefined)
t.greaterThan = N.greaterThan;
if (N.greaterThanOrEqual !== undefined)
t.greaterThanOrEqual = N.greaterThanOrEqual;
if (N.lessThan !== undefined)
t.lessThan = N.lessThan;
if (N.lessThanOrEqual !== undefined)
t.lessThanOrEqual = N.lessThanOrEqual;
if (N.exact)
t.exact = [...t.exact ?? [], ...N.exact];
}
}
return a(t) || t.max !== undefined ? { reroll: t } : {};
}, toNotation: (r) => {
let e = C(r);
if (!e.length)
return;
if (r.max === 1)
return `ro{${e.join(",")}}`;
let t = r.max ? `${r.max}` : "";
return `R{${e.join(",")}}${t}`;
}, toDescription: (r) => {
let { exact: e, greaterThan: t, greaterThanOrEqual: u, lessThan: m, lessThanOrEqual: f, max: n } = r, N = [];
if (e)
e.forEach((d) => N.push(`${d}`));
let $ = [];
if (u !== undefined)
$.push(`greater than or equal to ${u}`);
if (t !== undefined)
$.push(`greater than ${t}`);
if (f !== undefined)
$.push(`less than or equal to ${f}`);
if (m !== undefined)
$.push(`less than ${m}`);
let b = q(N.map(Number)), g = $.join(" and "), j = [b, g].filter(Boolean).join(", ");
if (!j)
return [];
if (n === 1)
return [`Reroll once ${j}`];
let p = n !== undefined ? ` (up to ${n} times)` : "";
return [`Reroll ${j}${p}`];
} });
var tr = /[Ss]([Aa]|[Dd])(?![{\d])/;
var v = h({ name: "sort", priority: 95, pattern: tr, parse: (r) => {
let e = tr.exec(r);
if (!e)
return {};
let t = e[1];
if (t === "d" || t === "D")
return { sort: "desc" };
return { sort: "asc" };
}, toNotation: (r) => {
return r === "desc" ? "sd" : "sa";
}, toDescription: (r) => {
return [r === "desc" ? "Sort descending" : "Sort ascending"];
} });
var ur = /[Uu](?:\{([^}]{1,50})\})?/;
var F = h({ name: "unique", priority: 60, pattern: ur, parse: (r) => {
let e = ur.exec(r);
if (!e)
return {};
if (!e[1])
return { unique: true };
return { unique: { notUnique: e[1].split(",").map((u) => Number(u.trim())).filter((u) => !isNaN(u)) } };
}, toNotation: (r) => {
if (r === true)
return "U";
if (typeof r === "object")
return `U{${r.notUnique.join(",")}}`;
return;
}, toDescription: (r) => {
if (r === true)
return ["No Duplicate Rolls"];
if (typeof r === "object")
return [`No Duplicates (except ${q(r.notUnique)})`];
return [];
} });
var fr = /[Ww](?![{])/;
var M = h({ name: "wildDie", priority: 55, pattern: fr, parse: (r) => {
if (!fr.exec(r))
return {};
return { wildDie: true };
}, toNotation: (r) => {
if (r)
return "W";
return;
}, toDescription: (r) => {
if (r)
return ["Wild Die (compound on max, penalty on 1)"];
return [];
} });
var mr = [w, B, U, G, L, J2, W, Y, Q, F, M, X, c, Z, v, z2, P, V, H2];
function Jt(r) {
if (!r)
return "";
return mr.map((e) => {
let t = r[e.name];
if (t === undefined)
return;
return e.toNotation(t);
}).filter((e) => typeof e === "string").join("");
}
function nr(r) {
if (!r)
return [];
return mr.flatMap((e) => {
let t = r[e.name];
if (t === undefined)
return [];
return e.toDescription(t);
}).filter((e) => typeof e === "string" && e.length > 0);
}
function Nr({ sides: r }) {
if (Array.isArray(r))
return { sides: r.length, faces: r };
return { sides: r };
}
function Hr(r, e, t) {
switch (t.dieType) {
case "fate":
return `Roll ${r}dF${t.fateVariant === 2 ? ".2" : ""}`;
case "zeroBias":
return `Roll ${r}z${e}`;
case "custom":
return `Roll ${r}d{${(t.customFaces ?? []).join(",")}}`;
case "draw":
return `Draw ${r} from d${e}`;
case "geometric":
return `Roll g${e} (geometric: roll d${e} until 1)`;
default:
return null;
}
}
function Pt(r) {
let { modifiers: e, quantity: t = 1, arithmetic: u } = r, { sides: m, faces: f = [] } = Nr(r), n = Hr(t, m, r);
if (n !== null)
return [n];
let $ = `Roll ${t} ${m}-sided ${t === 1 ? "die" : "dice"}`, b = `Roll ${t} Dice with the following sides: ${f.join(", ")}`, g = nr(e), j = u === "subtract" ? "and Subtract the result" : "";
return [f.length ? b : $, ...g, j].filter(Boolean);
}
var D = Object.freeze([4, 6, 8, 10, 12, 20, 100]);
var $r = "[Dd]%";
var hr = "[Dd][Ff](?:\\.[12])?";
var br = "[Dd]\\{[^}]+\\}";
var gr = "[Dd][Dd]\\d+";
var yr = "[Gg]\\d+";
var jr = "[Zz]\\d+";
var Or = /[Ff]\{(\d+)\}/;
var l = h({ name: "count", priority: 80, pattern: Or, parse: (r) => {
let e = Or.exec(r);
if (!e)
return {};
return { count: { lessThanOrEqual: Number(e[1]) } };
}, toNotation: (r) => {
if (r.lessThanOrEqual === undefined)
return;
return `F{${r.lessThanOrEqual}}`;
}, toDescription: (r) => {
if (r.lessThanOrEqual === undefined)
return [];
return [`Count failures at or below ${r.lessThanOrEqual}`];
} });
var pr = /(?<!!)[Ss]\{(\d+)(?:,(\d+))?\}/;
var o = h({ name: "count", priority: 80, pattern: pr, parse: (r) => {
let e = pr.exec(r);
if (!e)
return {};
let t = Number(e[1]), u = e[2] ? Number(e[2]) : undefined;
if (u !== undefined)
return { count: { greaterThanOrEqual: t, lessThanOrEqual: u, deduct: true } };
return { count: { greaterThanOrEqual: t } };
}, toNotation: (r) => {
if (r.greaterThanOrEqual === undefined)
return;
if (r.deduct && r.lessThanOrEqual !== undefined)
return `S{${r.greaterThanOrEqual},${r.lessThanOrEqual}}`;
return `S{${r.greaterThanOrEqual}}`;
}, toDescription: (r) => {
if (r.greaterThanOrEqual === undefined)
return [];
if (r.deduct && r.lessThanOrEqual !== undefined)
return [`Count successes >= ${r.greaterThanOrEqual}, botches <= ${r.lessThanOrEqual}`];
return [`Count successes >= ${r.greaterThanOrEqual}`];
} });
function y(r) {
let e = r.flags.replace(/[gy]/g, "");
return new RegExp(r.source, `${e.includes("i") ? e : `${e}i`}y`);
}
var Yr = String.raw`[Mm][Ss]\{\d+\}`;
var Cr = [{ key: "C{..}", category: "Clamp", matcher: y(w.pattern) }, { key: "V{..}", category: "Map", matcher: y(G.pattern) }, { key: "R{..}", category: "Substitute", matcher: y(L.pattern) }, { key: "!", category: "Generate", matcher: y(J2.pattern) }, { key: "!!", category: "Accumulate", matcher: y(W.pattern) }, { key: "!p", category: "Accumulate", matcher: y(Y.pattern) }, { key: "!s", category: "Generate", matcher: y(Q.pattern) }, { key: "W", category: "Dispatch", matcher: y(M.pattern) }, { key: "U", category: "Substitute", matcher: y(F.pattern) }, { key: "drop", category: "Filter", matcher: y(B.pattern) }, { key: "K", category: "Filter", matcher: y(U.pattern) }, { key: "#{..}", category: "Reinterpret", matcher: y(V.pattern) }, { key: "S{..}", category: "Reinterpret", matcher: y(o.pattern) }, { key: "F{..}", category: "Reinterpret", matcher: y(l.pattern) }, { key: "ms{..}", category: "Scale", matcher: new RegExp(Yr, "iy") }, { key: "*", category: "Scale", matcher: y(X.pattern) }, { key: "+", category: "Scale", matcher: y(c.pattern) }, { key: "-", category: "Scale", matcher: y(Z.pattern) }, { key: "//", category: "Scale", matcher: y(z2.pattern) }, { key: "%", category: "Scale", matcher: y(P.pattern) }, { key: "sort", category: "Order", matcher: y(v.pattern) }, { key: "**", category: "Scale", matcher: y(H2.pattern) }];
var ar = [{ key: "DDN", kind: "draw", matcher: new RegExp(`(\\d*)${gr}`, "iy") }, { key: "d%", kind: "percentile", matcher: new RegExp(`(\\d*)${$r}`, "iy") }, { key: "dF", kind: "fate", matcher: new RegExp(`(\\d*)${hr}`, "iy") }, { key: "d{...}", kind: "custom", matcher: new RegExp(`(\\d*)${br}`, "iy") }, { key: "gN", kind: "geometric", matcher: new RegExp(`(\\d*)${yr}`, "iy") }, { key: "zN", kind: "zeroBias", matcher: new RegExp(`(\\d*)${jr}`, "iy") }, { key: "xDN", kind: "standard", matcher: /(\d*)[Dd](\d+)/y }];
function cr(r, e, t) {
let u = r[e], m = u === "+" || u === "-";
if (!m && !t)
return null;
let f = m ? u : "", n = m ? e + 1 : e;
for (let N of ar)
if (N.matcher.lastIndex = n, N.matcher.exec(r)?.index === n) {
let b = N.matcher.lastIndex;
return { text: r.slice(e, b), key: N.key, kind: N.kind, sign: f, end: b };
}
return null;
}
function Gr(r, e) {
for (let t of Cr) {
t.matcher.lastIndex = e;
let u = t.matcher.exec(r);
if (u?.index === e)
return { text: u[0], key: t.key, category: t.category, end: t.matcher.lastIndex };
}
return null;
}
var Lr = /[Xx][1-9]\d*/y;
function vr(r, e, t) {
if (r.charCodeAt(e) !== 91)
return null;
if (e >= t.noCloseBracketFrom)
return null;
let u = r.indexOf("]", e + 1);
if (u === -1)
return t.noCloseBracketFrom = e, null;
if (u === e + 1)
return null;
return r.slice(e, u + 1);
}
function Fr(r, e, t) {
r.lastIndex = t;
let u = r.exec(e);
return u?.index === t ? u[0] : null;
}
function Mr(r, e, t) {
let u = r[r.length - 1];
if (u?.role === "unknown")
r[r.length - 1] = { ...u, text: u.text + e, end: t + 1 };
else
r.push({ text: e, key: "unknown", category: "unknown", start: t, end: t + 1, role: "unknown" });
}
function dr(r, e, t, u) {
let m = e === 0, f = r[e] === "+" || r[e] === "-";
if (m || f) {
let b = cr(r, e, m);
if (b)
return t.push({ text: b.text, key: b.kind === "standard" ? "xDN" : b.key, category: b.kind === "standard" ? "Core" : "Special", start: e, end: b.end, role: "pool", poolKind: b.kind, sign: b.sign }), b.end;
}
let n = Gr(r, e);
if (n)
return t.push({ text: n.text, key: n.key, category: n.category, start: e, end: n.end, role: "modifier" }), n.end;
let N = Fr(Lr, r, e);
if (N)
return t.push({ text: N, key: "xN", category: "Special", start: e, end: e + N.length, role: "repeat" }), e + N.length;
let $ = vr(r, e, u);
if ($)
return t.push({ text: $, key: "label", category: "Special", start: e, end: e + $.length, role: "annotation" }), e + $.length;
return Mr(t, r[e] ?? "", e), e + 1;
}
function Kr(r) {
if (r.length === 0)
return [];
let e = [], t = { pos: 0 }, u = { noCloseBracketFrom: Number.POSITIVE_INFINITY };
while (t.pos < r.length)
t.pos = dr(r, t.pos, e, u);
return e;
}
var E2 = 1000;
var lr = new Set(["#{..}", "S{..}", "F{..}"]);
var or = /^\d+/;
var Rr = /^\d*[Dd]([1-9]\d*)$/;
function Ar(r, e) {
let t = or.exec(e)?.[0];
if (t !== undefined && !/^[1-9]/.test(t))
return false;
if (r === "standard")
return Rr.test(e);
return true;
}
function x(r, e) {
return { valid: false, pools: [], error: { message: r, position: e } };
}
function Er(r, e) {
let t = e.filter((m) => m.role === "modifier"), u = e.find((m) => m.role === "annotation")?.text.slice(1, -1);
return { kind: r.poolKind ?? "standard", sign: r.sign ?? "", text: r.text, body: r.text.replace(/^[+-]/, ""), modifiersText: t.map((m) => m.text).join(""), hasModifiers: t.length > 0, ...u !== undefined ? { label: u } : {} };
}
function bu(r) {
let e = r.length - r.trimStart().length, t = r.trim();
if (t.length === 0)
return x("Empty notation", 0);
if (t.length > E2)
return x(`Notation exceeds ${E2} characters`, E2 + e);
let u = Kr(t), m = u.find((g) => g.role === "unknown");
if (m)
return x(`Unexpected "${m.text}"`, m.start + e);
let f = u[0];
if (!f)
return x("No die expression found", 0);
if (f.role !== "pool")
return x(`Expected a die before "${f.text}"`, f.start + e);
let n = u.find((g, j) => g.role === "repeat" && u.slice(j + 1).some((p) => p.role !== "repeat"));
if (n)
return x(`Repeat "${n.text}" must be at the end of the notation`, n.start + e);
let N = u.filter((g) => g.role === "modifier" && lr.has(g.key));
if (N.length > 1)
return x("Only one Count-family modifier (#{}, S{}, F{}) is permitted", (N[1]?.start ?? 0) + e);
let $ = u.find((g) => g.role === "pool" && !Ar(g.poolKind ?? "standard", g.text.replace(/^[+-]/, "")));
if ($)
return x(`Invalid die "${$.text}"`, $.start + e);
return { valid: true, pools: u.flatMap((g, j) => {
if (g.role !== "pool")
return [];
let p = u.slice(j + 1).findIndex((Wr) => Wr.role === "pool"), d = p === -1 ? u.length : j + 1 + p;
return [Er(g, u.slice(j + 1, d))];
}) };
}
var Dr = /[+-]?[1-9]\d*[Dd][1-9]\d*|[+-][Dd][1-9]\d*|(?<![\s\S])[Dd][1-9]\d*/;
var Ir = [w, B, U, G, L, J2, W, Y, Q, F, M, X, c, Z, v, z2, P, V, H2];
var Tr = [o, l];
var Sr = /[Mm][Ss]\{(\d+)\}/g;
function kr(r) {
return r.replace(Sr, (e, t) => `-${t}`);
}
var _r = [...Ir, ...Tr];
var ir = [R, o.pattern, l.pattern];
function sr(r) {
return ir.flatMap((e) => {
let t = e.flags.includes("g") ? e.flags : `${e.flags}g`, u = new RegExp(e.source, t);
return [...r.matchAll(u)].map((m) => m.index);
}).sort((e, t) => e - t);
}
function xr(r) {
let e = {}, t = kr(r), u = sr(t);
if (u.length > 1) {
let m = u[1];
throw new I("count", "Multiple Count modifiers are not permitted: only one of #{...}, S{...}, or F{...} may appear per notation string. Combine them into a single #{...} or S{n,b}.", { notation: r, ...m !== undefined ? { position: m } : {} });
}
for (let m of _r)
if (m.pattern.test(t))
m.pattern.lastIndex = 0, Object.assign(e, m.parse(t));
return e;
}
var wr = /\[([^\]]+)\]/;
function re(r) {
let e = wr.exec(r);
if (!e)
return { cleaned: r };
let t = r.replace(wr, ""), u = e[1];
if (u === undefined)
return { cleaned: t };
return { cleaned: t, label: u };
}
var ee = /![iI]/;
var te = /![rR]/;
function ue(r) {
let e = D.indexOf(r);
if (e !== -1)
return D.slice(e + 1);
let t = D.findIndex((u) => u >= r);
if (t === -1)
return [];
return D.slice(t);
}
function fe(r) {
let e = D.indexOf(r);
if (e !== -1) {
if (e === 0)
return [];
return [...D.slice(0, e)].reverse();
}
let t = me(D, (m) => m <= r);
if (t === -1)
return [];
return [...D.slice(0, t + 1)].reverse();
}
function me(r, e) {
for (let t of Array.from({ length: r.length }, (u, m) => r.length - 1 - m)) {
let u = r[t];
if (u !== undefined && e(u))
return t;
}
return -1;
}
function Fu(r) {
let e = r.trim(), { cleaned: t, label: u } = re(e), m = t.match(Dr)?.at(0) ?? "", f = t.replace(m, ""), [n = "", N = ""] = m.split(/[Dd]/), $ = n.startsWith("-"), b = n.replace(/^[+-]/, ""), j = { quantity: b === "" ? N === "" ? 0 : 1 : Number(b), arithmetic: $ ? "subtract" : "add", sides: Number(N) };
if (u !== undefined)
j.label = u;
if (f.length === 0)
return j;
let p = xr(f);
if (ee.test(f))
p.explodeSequence = ue(j.sides);
else if (te.test(f))
p.explodeSequence = fe(j.sides);
return { ...j, modifiers: p };
}
// ../roller/dist/shared/chunk-a20vbn0c.js
var _2 = /^([+-]?)(\d*)[Dd]%$/;
var P2 = /^([+-]?)(\d*)[Gg](\d+)$/;
var f = /^([+-]?)(\d*)[Dd][Dd](\d+)$/;
var N = /^([+-]?)(\d*)[Dd][Ff](?:\.([12]))?$/;
var E3 = /^([+-]?)(\d*)[Dd]\{([^}]+)\}$/;
var M2 = /^([+-]?)(\d*)[Zz](\d+)$/;
function B2(j) {
return j === "-" ? "subtract" : "add";
}
function G2(j) {
return j !== undefined && j.length > 0 ? Number(j) : 1;
}
function b(j) {
let J3 = j.trim(), K3 = _2.exec(J3);
if (K3)
return { quantity: G2(K3[2]), sides: 100, arithmetic: B2(K3[1]), kind: "percentile" };
let $ = f.exec(J3);
if ($)
return { quantity: G2($[2]), sides: Number($[3]), arithmetic: B2($[1]), kind: "draw" };
let W2 = P2.exec(J3);
if (W2)
return { quantity: G2(W2[2]), sides: Number(W2[3]), arithmetic: B2(W2[1]), kind: "geometric" };
let z3 = M2.exec(J3);
if (z3)
return { quantity: G2(z3[2]), sides: Number(z3[3]), arithmetic: B2(z3[1]), kind: "zeroBias" };
let Z2 = N.exec(J3);
if (Z2) {
let F2 = Z2[3] === "2" ? 2 : 1;
return { quantity: G2(Z2[2]), sides: F2 === 2 ? 5 : 3, arithmetic: B2(Z2[1]), kind: "fate", fateVariant: F2 };
}
let q2 = E3.exec(J3);
if (q2) {
let F2 = q2[3];
if (F2 === undefined)
return null;
let V2 = F2.split(",").map((O2) => O2.trim());
return { quantity: G2(q2[2]), sides: V2.length, arithmetic: B2(q2[1]), kind: "custom", customFaces: V2 };
}
return null;
}
var L2 = 1000;
var Q2 = 10;
var S2 = /[Xx]([1-9]\d*)$/;
function v2(j) {
let J3 = S2.exec(j);
if (!J3)
return null;
return { base: j.slice(0, J3.index), count: Number(J3[1]), position: J3.index };
}
function X2(j) {
return `${j.body}${j.modifiersText}${j.label !== undefined ? `[${j.label}]` : ""}`;
}
function T2(j) {
let J3 = b(j.text);
if (J3 === null)
return Fu(X2(j));
let K3 = J3.kind, $ = { quantity: J3.quantity, arithmetic: J3.arithmetic, sides: J3.sides, dieType: K3 };
if (J3.fateVariant !== undefined)
$.fateVariant = J3.fateVariant;
if (J3.customFaces !== undefined)
$.customFaces = J3.customFaces;
if (j.label !== undefined)
$.label = j.label;
return $;
}
function h2(j) {
if (j.kind === "percentile" && !j.hasModifiers) {
let K3 = b(j.text);
if (K3 !== null) {
let $ = { quantity: K3.quantity, arithmetic: K3.arithmetic, sides: 100, dieType: "percentile" };
if (j.label !== undefined)
$.label = j.label;
return $;
}
}
if (j.kind !== "standard" && j.kind !== "percentile" && !j.hasModifiers)
return T2(j);
let J3 = Fu(X2(j));
if (j.sign === "-")
J3.arithmetic = "subtract";
return J3;
}
function w2(j, J3) {
if (j.length > E2)
throw new H(j, `notation exceeds maximum length of ${E2} characters`, undefined, { position: E2 });
let K3 = v2(j);
if (K3) {
if (J3 >= Q2)
throw new H(j, `repeat nesting depth exceeds maximum of ${Q2}`, undefined, { position: K3.position });
if (K3.count > L2)
throw new H(j, `repeat count ${K3.count} exceeds maximum of ${L2}`, undefined, { position: K3.position, value: K3.count });
let W2 = w2(K3.base, J3 + 1);
return Array.from({ length: K3.count }, () => W2).flat();
}
let $ = bu(j);
if (!$.valid)
return [Fu(j)];
return $.pools.map(h2);
}
function r(j) {
return w2(j, 0);
}
function g(j) {
let J3 = /^(\d+)(\d+)/.exec(j);
if (J3?.[1] && J3[2]) {
let K3 = J3[1], $ = J3[2];
if (Number.parseInt(K3, 10) <= 100 && Number.parseInt($, 10) >= 2 && Number.parseInt($, 10) <= 1000)
return `${K3}d${$}`;
}
return;
}
function u(j) {
if (/^[dD]\d+/.test(j))
return j.replace(/^[dD]/, "1d");
return;
}
function l2(j) {
let J3 = j.replace(/\s+/g, "");
if (J3 !== j && /^\d+[dD]\d+/.test(J3))
return J3;
return;
}
function I3(j) {
let J3 = j.trim(), K3 = u(J3);
if (K3)
return K3;
let $ = l2(J3);
if ($)
return $;
let W2 = g(J3);
if (W2)
return W2;
let Z2 = /^(\d+)d(\d+)/i.exec(J3);
if (Z2?.[0])
return Z2[0];
if (/^\d+/.test(J3) && !J3.includes("d") && !J3.includes("D")) {
let q2 = /^(\d+)(\d+)/.exec(J3);
if (q2?.[1] && q2[2])
return `${q2[1]}d${q2[2]}`;
}
return;
}
function y2(j) {
if (typeof j !== "string")
return false;
return bu(j).valid;
}
function Wj(j) {
let { modifiers: J3, quantity: K3 = 1, arithmetic: $ } = j, { sides: W2 } = Nr(j), z3 = $ === "subtract" ? "-" : "", Z2 = Jt(J3), q2 = `${z3}${K3}d${W2}${Z2}`;
if (!y2(q2))
throw new H(q2, "Generated notation is invalid", undefined, { value: j });
return q2;
}
var x2 = 1e4;
var A3 = 1e6;
function Yj(j, J3) {
if (!Number.isInteger(j))
throw new J(`${J3} must be an integer, received: ${j}`, { path: J3, value: j });
}
function zj(j) {
if (j > x2)
throw new J(`quantity ${j} exceeds maximum of ${x2}`, { path: "quantity", value: j });
}
function Bj(j) {
if (j > A3)
throw new J(`sides ${j} exceeds maximum of ${A3}`, { path: "sides", value: j });
}
function Gj(j, J3, K3, $) {
if (j < J3 || j > K3)
throw new J(`${$} must be between ${J3} and ${K3}, received: ${j}`, { path: $, value: j });
}
function Hj(j, J3) {
if (!Number.isFinite(j))
throw new J(`${J3} must be a finite number, received: ${j}`, { path: J3, value: j });
}
function Cj(j, J3, K3) {
if (j <= J3)
throw new J(`${K3} must be greater than ${J3}, received: ${j}`, { path: K3, value: j });
}
// ../roller/dist/shared/chunk-44dqqc75.js
var d = { ...w, apply: ($, K3) => {
let { greaterThan: J3, greaterThanOrEqual: Y2, lessThan: Z2, lessThanOrEqual: Q3, exact: G3 } = K3;
return { rolls: $.map((H3) => {
let W2 = J3 !== undefined && H3 > J3 ? J3 : Y2 !== undefined && H3 >= Y2 ? Y2 : H3, j = (G3 ?? []).reduce((B3, k2) => B3 > k2 ? k2 : B3, W2);
return Z2 !== undefined && j < Z2 ? Z2 : Q3 !== undefined && j <= Q3 ? Q3 : j;
}) };
}, validate: ($) => {} };
var F2 = 99;
var P3 = 1000;
function p($) {
if ($.rollOne === undefined)
throw Error("Internal error: rollOne function required but not provided");
return $;
}
function r2($) {
if ($.parameters === undefined)
throw Error("Internal error: parameters required but not provided");
return $;
}
function N2($) {
if ($.rollOne === undefined)
throw Error("Internal error: rollOne function required but not provided");
if ($.parameters === undefined)
throw Error("Internal error: parameters required but not provided");
return $;
}
function U2($, { greaterThan: K3, greaterThanOrEqual: J3, lessThan: Y2, lessThanOrEqual: Z2, exact: Q3 }) {
if (Q3?.includes($))
return true;
if (K3 !== undefined && $ > K3)
return true;
if (J3 !== undefined && $ >= J3)
return true;
if (Y2 !== undefined && $ < Y2)
return true;
if (Z2 !== undefined && $ <= Z2)
return true;
return false;
}
function w3($) {
if ($ === true)
return (K3, J3) => K3 === J3;
if ($ === false)
return () => false;
return (K3, J3) => U2(K3, $);
}
var D2 = { compound: { accumulate: ($, K3) => $ + K3 }, penetrate: { accumulate: ($, K3) => $ + Math.max(1, K3 - 1) } };
function m$($, K3 = 1) {
if (typeof $ === "object")
return K3;
if ($ === true)
return K3;
if ($ === false)
return 0;
if ($ === 0)
return P3;
return $;
}
function T3($, K3, J3, Y2, Z2, Q3) {
let G3 = Q3 ?? Z2.shouldContinue ?? ((H3, W2) => H3 === W2), z3 = (H3, W2) => {
if (W2 >= Y2)
return H3;
let j = J3(), X3 = Z2.accumulate(H3, j, W2);
if (!G3(j, K3))
return X3;
return z3(X3, W2 + 1);
};
return z3($, 0);
}
function O2($) {
return (K3, J3, Y2) => {
let { rollOne: Z2, parameters: Q3 } = N2(Y2), { sides: G3 } = Q3, z3 = m$(J3), H3 = w3(typeof J3 === "number" ? true : J3);
return { rolls: K3.map((j) => H3(j, G3) ? T3(j, G3, Z2, z3, $, H3) : j) };
};
}
var n = { ...W, requiresRollFn: true, requiresParameters: true, apply: O2(D2.compound) };
var s2 = { ...V, mutatesRolls: false, validate: ($) => {
if ($.deduct && $.lessThanOrEqual !== undefined && $.greaterThanOrEqual !== undefined && $.lessThanOrEqual >= $.greaterThanOrEqual)
throw new I("count", `botchThreshold (${$.lessThanOrEqual}) must be less than threshold (${$.greaterThanOrEqual})`, { path: "modifiers.count", value: $ });
}, apply: ($, K3) => {
return { rolls: $, transformTotal: (J3, Y2) => {
if (K3.deduct) {
let Z2 = { ...K3.greaterThan !== undefined ? { greaterThan: K3.greaterThan } : {}, ...K3.greaterThanOrEqual !== undefined ? { greaterThanOrEqual: K3.greaterThanOrEqual } : {}, ...K3.exact !== undefined ? { exact: K3.exact } : {} }, Q3 = { ...K3.lessThan !== undefined ? { lessThan: K3.lessThan } : {}, ...K3.lessThanOrEqual !== undefined ? { lessThanOrEqual: K3.lessThanOrEqual } : {} }, G3 = Y2.filter((H3) => U2(H3, Z2)).length, z3 = Y2.filter((H3) => U2(H3, Q3)).length;
return G3 - z3;
}
return Y2.filter((Z2) => U2(Z2, K3)).length;
} };
} };
var t = { ...B, apply: ($, K3) => {
let { highest: J3, lowest: Y2 } = K3, Z2 = $.filter((j) => !U2(j, K3));
if (J3 === undefined && Y2 === undefined)
return { rolls: Z2 };
let Q3 = Z2.map((j, X3) => ({ roll: j, index: X3 }));
Q3.sort((j, X3) => j.roll - X3.roll);
let G3 = Y2 !== undefined ? new Set(Q3.slice(0, Math.min(Y2, Q3.length)).map((j) => j.index)) : new Set, z3 = J3 !== undefined ? new Set(Q3.slice(Math.max(0, Q3.length - J3)).map((j) => j.index)) : new Set, H3 = new Set([...G3, ...z3]), W2 = Z2.filter((j, X3) => !H3.has(X3));
if (Y2 !== undefined && J3 === undefined)
return { rolls: [...W2].sort((j, X3) => j - X3) };
return { rolls: W2 };
}, validate: ($, { quantity: K3 }) => {
let J3 = ($.lowest ?? 0) + ($.highest ?? 0);
if (J3 >= K3)
throw new I("drop", `Cannot drop ${J3} dice from a pool of ${K3}`, { path: "modifiers.drop", value: $ });
} };
var o2 = { ...J2, requiresRollFn: true, requiresParameters: true, apply: ($, K3, J3) => {
let { rollOne: Y2, parameters: Z2 } = N2(J3), Q3 = w3(K3), G3 = $.filter((z3) => Q3(z3, Z2.sides)).map(() => Y2());
return { rolls: [...$, ...G3] };
} };
function L3($, K3 = Math.random) {
return Math.floor(K3() * $);
}
function q2($, K3, J3) {
if ($ <= 0)
return [];
return Array.from({ length: $ }, () => L3(K3, J3) + 1);
}
function c$($, K3) {
let J3 = [], Y2 = $[$.length - 1];
if (Y2 === undefined)
return J3;
let Z2 = $.length + P3, Q3 = [...$];
for (let G3 of Array.from({ length: Z2 })) {
let z3 = Q3.shift() ?? Y2, H3 = K3(z3);
if (J3.push(H3), H3 !== z3)
break;
}
return J3;
}
var K$ = { ...Q, requiresParameters: true, requiresRandomFn: true, apply: ($, K3, J3) => {
let { parameters: Y2 } = r2(J3);
if (!Array.isArray(K3) || K3.length === 0)
return { rolls: $ };
let { sides: Z2 } = Y2, Q3 = J3.randomFn;
if (Q3 === undefined)
throw new I("explodeSequence", "randomFn function required for explodeSequence modifier");
let G3 = (H3) => L3(H3, Q3) + 1, z3 = [];
for (let H3 of $) {
if (H3 !== Z2)
continue;
let W2 = c$(K3, G3);
z3.push(...W2);
}
return { rolls: [...$, ...z3] };
} };
function _3($) {
return { mutatesRolls: false, apply: (K3, J3) => ({ rolls: K3, transformTotal: (Y2) => $(Y2, J3) }) };
}
var Y$ = { ...z2, ..._3(($, K3) => Math.trunc($ / K3)) };
function v3($, K3, J3) {
let Y2 = $.map((Z2, Q3) => ({ value: Z2, index: Q3 }));
if (J3 === "lowest")
Y2.sort((Z2, Q3) => Z2.value - Q3.value);
else
Y2.sort((Z2, Q3) => Q3.value - Z2.value);
return new Set(Y2.slice(0, K3).map((Z2) => Z2.index));
}
var G$ = { ...U, apply: ($, K3) => {
let { highest: J3, lowest: Y2 } = K3, Z2 = $.length;
if (J3 !== undefined) {
let Q3 = Z2 - J3;
if (Q3 <= 0)
return { rolls: $ };
let G3 = v3($, Q3, "lowest");
return { rolls: $.filter((z3, H3) => !G3.has(H3)) };
}
if (Y2 !== undefined) {
let Q3 = Z2 - Y2;
if (Q3 <= 0)
return { rolls: $ };
let G3 = v3($, Q3, "highest");
return { rolls: $.filter((z3, H3) => !G3.has(H3)) };
}
return { rolls: $ };
}, validate: ($, { quantity: K3 }) => {
if ($.highest !== undefined) {
if ($.highest > K3 || $.highest < 1)
throw new I("keep", `Cannot keep ${$.highest} highest dice from a pool of ${K3}`, { path: "modifiers.keep.highest", value: $.highest });
}
if ($.lowest !== undefined) {
if ($.lowest > K3 || $.lowest < 1)
throw new I("keep", `Cannot keep ${$.lowest} lowest dice from a pool of ${K3}`, { path: "modifiers.keep.lowest", value: $.lowest });
}
} };
var j$ = { ...Z, ..._3(($, K3) => $ - K3) };
var z$ = { ...P, ..._3(($, K3) => $ % K3) };
var X$ = { ...X, ..._3(($, K3) => $ * K3) };
var k$ = { ...H2, ..._3(($, K3) => $ * K3) };
var U$ = { ...Y, requiresRollFn: true, requiresParameters: true, apply: O2(D2.penetrate) };
var L$ = { ...c, ..._3(($, K3) => $ + K3) };
function C2($, K3) {
let { greaterThan: J3, greaterThanOrEqual: Y2, lessThan: Z2, lessThanOrEqual: Q3 } = K3, G3 = u$(Y2, J3), z3 = d$(Q3, Z2);
if (G3 !== undefined && z3 !== undefined && G3 > z3)
throw new I($, `Impossible comparison: condition requires value >= ${G3} AND <= ${z3}`, { path: `modifiers.${$}`, value: K3 });
}
function u$($, K3) {
if ($ !== undefined)
return $;
if (K3 !== undefined)
return K3 + 1;
return;
}
function d$($, K3) {
if ($ !== undefined)
return $;
if (K3 !== undefined)
return K3 - 1;
return;
}
var P$ = { ...G, apply: ($, K3) => {
let J3 = Array.isArray(K3) ? K3 : [K3], Y2 = [], Z2 = (G3, z3) => {
let { from: H3, to: W2 } = z3;
return G3.map((j) => {
if ((typeof H3 === "object" ? U2(j, H3) : j === H3) && j !== W2)
return Y2.push({ from: j, to: W2 }), W2;
return j;
});
};
return { rolls: J3.reduce((G3, z3) => Z2(G3, z3), $), replacements: Y2 };
}, validate: ($) => {
let K3 = Array.isArray($) ? $ : [$];
for (let { from: J3 } of K3)
if (typeof J3 === "object")
C2("replace", J3);
} };
function I$($, K3, J3, Y2 = 0) {
if (Y2 >= F2)
return $;
if (U2($, K3))
return I$(J3(), K3, J3, Y2 + 1);
return $;
}
var F$ = { ...L, requiresRollFn: true, apply: ($, K3, J3) => {
let { rollOne: Y2 } = p(J3), { max: Z2 } = K3, Q3 = [], G3 = [];
for (let z3 of $) {
if (Z2 !== undefined && G3.length >= Z2) {
Q3.push(z3);
continue;
}
let H3 = I$(z3, K3, Y2);
if (H3 !== z3)
G3.push({ from: z3, to: H3 });
Q3.push(H3);
}
return { rolls: Q3, replacements: G3 };
}, validate: ($, { sides: K3 }) => {
if ($.exact) {
for (let J3 of $.exact)
if (J3 < 1 || J3 > K3)
throw new I("reroll", `Reroll value ${J3} is outside valid range [1, ${K3}]`, { path: "modifiers.reroll.exact", value: J3 });
}
C2("reroll", $);
} };
var A$ = { ...v, apply: ($, K3) => {
return { rolls: [...$].sort((Y2, Z2) => K3 === "desc" ? Z2 - Y2 : Y2 - Z2) };
} };
var S$ = { ...F, requiresRollFn: true, requiresParameters: true, apply: ($, K3, J3) => {
let { rollOne: Y2, parameters: Z2 } = N2(J3), { sides: Q3, quantity: G3 } = Z2;
if (G3 > Q3)
throw new I("unique", "Cannot have more rolls than sides when unique is enabled", { path: "modifiers.unique", value: { quantity: G3, sides: Q3 } });
let z3 = new Set(typeof K3 === "object" ? K3.notUnique : []), H3 = (B3, k2) => {
let b2 = (E4, c2) => {
if (c2 >= F2)
throw new I("unique", `Could not find a unique value after ${F2} attempts`);
if (!k2.has(E4) && !z3.has(E4))
return E4;
return b2(Y2(), c2 + 1);
};
return b2(B3, 0);
}, W2 = [], j = new Set, X3 = [];
for (let B3 of $) {
if (z3.has(B3)) {
W2.push(B3);
continue;
}
if (j.has(B3)) {
let k2 = H3(B3, j);
j.add(k2), W2.push(k2), X3.push({ from: B3, to: k2 });
continue;
}
j.add(B3), W2.push(B3);
}
return { rolls: W2, replacements: X3 };
}, validate: ($, { sides: K3, quantity: J3 }) => {
let Y2 = typeof $ === "object" ? $.notUnique.length : 0, Z2 = J3 - Y2;
if (Z2 > K3)
throw new I("unique", `Cannot have ${Z2} unique values with only ${K3} sides`, { path: "modifiers.unique", value: $ });
} };
var w$ = { ...M, requiresRollFn: true, requiresParameters: true, apply: ($, K3, J3) => {
let { rollOne: Y2, parameters: Z2 } = N2(J3), { sides: Q3 } = Z2;
if ($.length === 0)
return { rolls: [] };
let G3 = $.length - 1, z3 = $[G3];
if (z3 === undefined)
return { rolls: $ };
if (z3 === Q3) {
let H3 = [...$], W2 = T3(z3, Q3, Y2, P3, D2.compound);
return H3[G3] = W2, { rolls: H3 };
}
if (z3 === 1) {
let H3 = $.slice(0, G3);
if (H3.length === 0)
return { rolls: [] };
let W2 = Math.max(...H3), j = H3.indexOf(W2);
return { rolls: H3.filter((B3, k2) => k2 !== j) };
}
return { rolls: [...$] };
} };
var A4 = Object.freeze([d, P$, F$, o2, n, U$, K$, w$, S$, t, G$, s2, X$, L$, j$, Y$, z$, A$, k$]);
function O$($, K3) {
return { modifier: $, options: K3, added: [], removed: [] };
}
function f$($, K3, J3, Y2, Z2) {
let Q3 = { modifier: $, options: K3 };
if (J3 === Y2)
return { ...Q3, added: [], removed: [] };
if (J3.length === 0)
return { ...Q3, added: [...Y2], removed: [] };
if (Y2.length === 0)
return { ...Q3, added: [], removed: [...J3] };
let G3 = [...J3].sort((B3, k2) => B3 - k2), z3 = [...Y2].sort((B3, k2) => B3 - k2), H3 = [], W2 = [], j = { i: 0, j: 0 };
while (j.i < G3.length || j.j < z3.length) {
let B3 = G3[j.i], k2 = z3[j.j];
if (B3 === undefined && k2 !== undefined)
H3.push(k2), j.j++;
else if (k2 === undefined && B3 !== undefined)
W2.push(B3), j.i++;
else if (B3 !== undefined && k2 !== undefined)
if (B3 === k2)
j.i++, j.j++;
else if (B3 < k2)
W2.push(B3), j.i++;
else
H3.push(k2), j.j++;
}
let X3 = { ...Q3, added: H3, removed: W2 };
if (Z2 !== undefined && Z2.length > 0)
X3.replacements = Z2;
return X3;
}
var p$ = new Map(A4.map(($) => [$.name, $]));
var M3 = Object.freeze(A4.map(($) => $.name));
function r$($, K3, J3, Y2) {
if (K3 === undefined)
return { rolls: J3, log: null };
let Z2 = p$.get($);
if (!Z2)
throw new I($, `Unknown modifier type: ${$}`, { path: `modifiers.${$}`, value: K3 });
if (Z2.requiresRollFn && Y2.rollOne === undefined)
throw new I($, `rollOne function required for ${$} modifier`);
if (Z2.requiresParameters && Y2.parameters === undefined)
throw new I($, `roll parameters required for ${$} modifier`);
if (Z2.requiresRandomFn && Y2.randomFn === undefined)
throw new I($, `randomFn function required for ${$} modifier`);
let Q3 = [...J3];
try {
let G3 = Z2.apply(J3, K3, Y2), z3 = Z2.mutatesRolls === false ? O$($, K3) : f$($, K3, Q3, G3.rolls, G3.replacements);
if (G3.transformTotal)
return { rolls: G3.rolls, log: z3, transformTotal: G3.transformTotal };
return { rolls: G3.rolls, log: z3 };
} catch (G3) {
if (G3 instanceof Error)
t