@dicelette/core 1.25.1 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/index.d.mts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +113 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +109 -73
- package/dist/index.mjs.map +1 -1
- package/package.json +59 -59
package/README.md
CHANGED
|
@@ -152,6 +152,25 @@ Note: when a parameter `engine` is shown it usually defaults to the `NumberGener
|
|
|
152
152
|
#### Function: getEngine(engine: "nativeMath" | "browserCrypto" | "nodeCrypto"): Engine
|
|
153
153
|
- Returns the engine instance (from `NumberGenerator.engines`) matching the provided name.
|
|
154
154
|
|
|
155
|
+
### Similarity (`src/similarity.ts`)
|
|
156
|
+
#### Function: calculateSimilarity(str1: string, str2: string): number
|
|
157
|
+
- Calculate and return a similarity score between two strings using the levenshtein distance (value between 0 and 1).
|
|
158
|
+
|
|
159
|
+
#### Function: levenshteinDistance(str1: string, str2: string): number
|
|
160
|
+
- Calculate and return the Levenshtein distance between two strings.
|
|
161
|
+
- Used internally by `calculateSimilarity`.
|
|
162
|
+
- Returns an integer distance value.
|
|
163
|
+
|
|
164
|
+
#### Function : findBestStatMatch<T>(searchTerm: string, normalizedStat: Map<string, T>, similarityThreshold: number = 0.5, partialSearch: boolean = true): T | undefined`
|
|
165
|
+
- Find and return the best matching statistic from `normalizedStat` based on `searchTerm`.
|
|
166
|
+
- Normalized stat is a map of lowercased stat names to their original entries
|
|
167
|
+
- `partialSearch` allow to check if `normalizedStat` have a key that starts, ends or contains the `searchTerm` and return it directly.
|
|
168
|
+
- `similarityThreshold` is the minimum similarity score to consider a match. By default, it's set to 0.5.
|
|
169
|
+
|
|
170
|
+
#### Function: `findBestRecord(snippets: Record<string, string>, searchTerm: string, similarityThreshold: number = 0.5): string | undefined`
|
|
171
|
+
- Find and return the best matching string from `snippets` based on `searchTerm`.
|
|
172
|
+
- Just an alias for `findBestStatMatch` specialized for `Record<string, string>` and without partial search.
|
|
173
|
+
|
|
155
174
|
### Dice functions (`src/dice.ts`)
|
|
156
175
|
|
|
157
176
|
#### Function: roll(dice: string, engine?: Engine | null, pity?: boolean): Resultat | undefined
|
package/dist/index.d.mts
CHANGED
|
@@ -307,6 +307,26 @@ declare function replaceInFormula(element: string, diceResult: Resultat, compare
|
|
|
307
307
|
compare: Compare | undefined;
|
|
308
308
|
}, res: boolean, engine?: Engine | null, pity?: boolean): string;
|
|
309
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Utility functions for string similarity and distance calculations.
|
|
312
|
+
*/
|
|
313
|
+
/**
|
|
314
|
+
* Calculates the similarity between two strings as a value between 0 and 1.
|
|
315
|
+
*/
|
|
316
|
+
declare function calculateSimilarity(str1: string, str2: string): number;
|
|
317
|
+
/**
|
|
318
|
+
* Calculates the Levenshtein distance between two strings.
|
|
319
|
+
*/
|
|
320
|
+
declare function levenshteinDistance(str1: string, str2: string): number;
|
|
321
|
+
declare function findBestStatMatch<T>(searchTerm: string, normalizedStats: Map<string, T>, similarityThreshold?: number): T | undefined;
|
|
322
|
+
/**
|
|
323
|
+
* Find the snippet name with the highest similarity to `macroName`.
|
|
324
|
+
* Single-pass O(n) algorithm: keeps the best (name, similarity) seen so far.
|
|
325
|
+
* Returns `null` if no snippets or if the best similarity is < `minSimilarity`.
|
|
326
|
+
* Tie-breaker: first encountered best similarity (deterministic).
|
|
327
|
+
*/
|
|
328
|
+
declare function findBestRecord(record: Record<string, string>, searchTerm: string, similarityThreshold?: number): string | null;
|
|
329
|
+
|
|
310
330
|
/**
|
|
311
331
|
* Escape regex string
|
|
312
332
|
* @param string {string}
|
|
@@ -323,9 +343,10 @@ declare function standardizeDice(dice: string): string;
|
|
|
323
343
|
* and after evaluate any formula using `replaceFormulaInDice`
|
|
324
344
|
* @param {string} originalDice
|
|
325
345
|
* @param {Record<string,number>|undefined} stats
|
|
346
|
+
* @param {number} minThreshold Minimum similarity threshold to consider a stat name match
|
|
326
347
|
* @param {string|undefined} dollarValue
|
|
327
348
|
*/
|
|
328
|
-
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, dollarValue?: string): string;
|
|
349
|
+
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, minThreshold?: number, dollarValue?: string): string;
|
|
329
350
|
/**
|
|
330
351
|
* Replace the {{}} in the dice string and evaluate the interior if any
|
|
331
352
|
* @param dice {string}
|
|
@@ -430,4 +451,4 @@ declare function testStatCombinaison(template: StatisticalTemplate, engine?: Eng
|
|
|
430
451
|
*/
|
|
431
452
|
declare function generateRandomStat(total?: number | undefined, max?: number, min?: number, engine?: Engine | null): number;
|
|
432
453
|
|
|
433
|
-
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, type CustomCriticalMap, DETECT_CRITICAL, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, OPTIONAL_COMMENT, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, SortOrder, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, generateRandomStat, generateStatsDice, getEngine, getEngineId, isNumber, randomInt, replaceExpByRandom, replaceFormulaInDice, replaceInFormula, roll, standardizeDice, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
|
454
|
+
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, type CustomCriticalMap, DETECT_CRITICAL, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, OPTIONAL_COMMENT, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, SortOrder, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, calculateSimilarity, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, findBestRecord, findBestStatMatch, generateRandomStat, generateStatsDice, getEngine, getEngineId, isNumber, levenshteinDistance, randomInt, replaceExpByRandom, replaceFormulaInDice, replaceInFormula, roll, standardizeDice, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
package/dist/index.d.ts
CHANGED
|
@@ -307,6 +307,26 @@ declare function replaceInFormula(element: string, diceResult: Resultat, compare
|
|
|
307
307
|
compare: Compare | undefined;
|
|
308
308
|
}, res: boolean, engine?: Engine | null, pity?: boolean): string;
|
|
309
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Utility functions for string similarity and distance calculations.
|
|
312
|
+
*/
|
|
313
|
+
/**
|
|
314
|
+
* Calculates the similarity between two strings as a value between 0 and 1.
|
|
315
|
+
*/
|
|
316
|
+
declare function calculateSimilarity(str1: string, str2: string): number;
|
|
317
|
+
/**
|
|
318
|
+
* Calculates the Levenshtein distance between two strings.
|
|
319
|
+
*/
|
|
320
|
+
declare function levenshteinDistance(str1: string, str2: string): number;
|
|
321
|
+
declare function findBestStatMatch<T>(searchTerm: string, normalizedStats: Map<string, T>, similarityThreshold?: number): T | undefined;
|
|
322
|
+
/**
|
|
323
|
+
* Find the snippet name with the highest similarity to `macroName`.
|
|
324
|
+
* Single-pass O(n) algorithm: keeps the best (name, similarity) seen so far.
|
|
325
|
+
* Returns `null` if no snippets or if the best similarity is < `minSimilarity`.
|
|
326
|
+
* Tie-breaker: first encountered best similarity (deterministic).
|
|
327
|
+
*/
|
|
328
|
+
declare function findBestRecord(record: Record<string, string>, searchTerm: string, similarityThreshold?: number): string | null;
|
|
329
|
+
|
|
310
330
|
/**
|
|
311
331
|
* Escape regex string
|
|
312
332
|
* @param string {string}
|
|
@@ -323,9 +343,10 @@ declare function standardizeDice(dice: string): string;
|
|
|
323
343
|
* and after evaluate any formula using `replaceFormulaInDice`
|
|
324
344
|
* @param {string} originalDice
|
|
325
345
|
* @param {Record<string,number>|undefined} stats
|
|
346
|
+
* @param {number} minThreshold Minimum similarity threshold to consider a stat name match
|
|
326
347
|
* @param {string|undefined} dollarValue
|
|
327
348
|
*/
|
|
328
|
-
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, dollarValue?: string): string;
|
|
349
|
+
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, minThreshold?: number, dollarValue?: string): string;
|
|
329
350
|
/**
|
|
330
351
|
* Replace the {{}} in the dice string and evaluate the interior if any
|
|
331
352
|
* @param dice {string}
|
|
@@ -430,4 +451,4 @@ declare function testStatCombinaison(template: StatisticalTemplate, engine?: Eng
|
|
|
430
451
|
*/
|
|
431
452
|
declare function generateRandomStat(total?: number | undefined, max?: number, min?: number, engine?: Engine | null): number;
|
|
432
453
|
|
|
433
|
-
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, type CustomCriticalMap, DETECT_CRITICAL, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, OPTIONAL_COMMENT, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, SortOrder, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, generateRandomStat, generateStatsDice, getEngine, getEngineId, isNumber, randomInt, replaceExpByRandom, replaceFormulaInDice, replaceInFormula, roll, standardizeDice, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
|
454
|
+
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, type CustomCriticalMap, DETECT_CRITICAL, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, OPTIONAL_COMMENT, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, SortOrder, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, calculateSimilarity, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, findBestRecord, findBestStatMatch, generateRandomStat, generateStatsDice, getEngine, getEngineId, isNumber, levenshteinDistance, randomInt, replaceExpByRandom, replaceFormulaInDice, replaceInFormula, roll, standardizeDice, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ __export(index_exports, {
|
|
|
34
34
|
SortOrder: () => SortOrder,
|
|
35
35
|
TooManyDice: () => TooManyDice,
|
|
36
36
|
TooManyStats: () => TooManyStats,
|
|
37
|
+
calculateSimilarity: () => calculateSimilarity,
|
|
37
38
|
createCriticalCustom: () => createCriticalCustom,
|
|
38
39
|
diceRandomParse: () => diceRandomParse,
|
|
39
40
|
diceTypeRandomParse: () => diceTypeRandomParse,
|
|
@@ -41,11 +42,14 @@ __export(index_exports, {
|
|
|
41
42
|
evalCombinaison: () => evalCombinaison,
|
|
42
43
|
evalOneCombinaison: () => evalOneCombinaison,
|
|
43
44
|
evalStatsDice: () => evalStatsDice,
|
|
45
|
+
findBestRecord: () => findBestRecord,
|
|
46
|
+
findBestStatMatch: () => findBestStatMatch,
|
|
44
47
|
generateRandomStat: () => generateRandomStat,
|
|
45
48
|
generateStatsDice: () => generateStatsDice,
|
|
46
49
|
getEngine: () => getEngine,
|
|
47
50
|
getEngineId: () => getEngineId,
|
|
48
51
|
isNumber: () => isNumber,
|
|
52
|
+
levenshteinDistance: () => levenshteinDistance,
|
|
49
53
|
randomInt: () => randomInt,
|
|
50
54
|
replaceExpByRandom: () => replaceExpByRandom,
|
|
51
55
|
replaceFormulaInDice: () => replaceFormulaInDice,
|
|
@@ -154,11 +158,11 @@ var NoStatisticsError = class extends Error {
|
|
|
154
158
|
};
|
|
155
159
|
|
|
156
160
|
// src/interfaces/index.ts
|
|
157
|
-
var SortOrder = /* @__PURE__ */ ((
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return
|
|
161
|
+
var SortOrder = /* @__PURE__ */ ((SortOrder2) => {
|
|
162
|
+
SortOrder2["Ascending"] = "sa";
|
|
163
|
+
SortOrder2["Descending"] = "sd";
|
|
164
|
+
SortOrder2["None"] = "none";
|
|
165
|
+
return SortOrder2;
|
|
162
166
|
})(SortOrder || {});
|
|
163
167
|
|
|
164
168
|
// src/interfaces/constant.ts
|
|
@@ -242,6 +246,73 @@ var import_mathjs = require("mathjs");
|
|
|
242
246
|
var import_uniformize = require("uniformize");
|
|
243
247
|
var import_rpg_dice_roller2 = require("@dice-roller/rpg-dice-roller");
|
|
244
248
|
var import_random_js = require("random-js");
|
|
249
|
+
|
|
250
|
+
// src/similarity.ts
|
|
251
|
+
var MIN_THRESHOLD_MATCH = 0.5;
|
|
252
|
+
function calculateSimilarity(str1, str2) {
|
|
253
|
+
const longer = str1.length > str2.length ? str1 : str2;
|
|
254
|
+
const shorter = str1.length > str2.length ? str2 : str1;
|
|
255
|
+
if (longer.length === 0) return 1;
|
|
256
|
+
const distance = levenshteinDistance(longer, shorter);
|
|
257
|
+
return (longer.length - distance) / longer.length;
|
|
258
|
+
}
|
|
259
|
+
function levenshteinDistance(str1, str2) {
|
|
260
|
+
const matrix = Array(str2.length + 1).fill(null).map(() => Array(str1.length + 1).fill(null));
|
|
261
|
+
for (let i = 0; i <= str1.length; i++) matrix[0][i] = i;
|
|
262
|
+
for (let j = 0; j <= str2.length; j++) matrix[j][0] = j;
|
|
263
|
+
for (let j = 1; j <= str2.length; j++) {
|
|
264
|
+
for (let i = 1; i <= str1.length; i++) {
|
|
265
|
+
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
|
|
266
|
+
matrix[j][i] = Math.min(
|
|
267
|
+
matrix[j][i - 1] + 1,
|
|
268
|
+
// insertion
|
|
269
|
+
matrix[j - 1][i] + 1,
|
|
270
|
+
// deletion
|
|
271
|
+
matrix[j - 1][i - 1] + cost
|
|
272
|
+
// substitution
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return matrix[str2.length][str1.length];
|
|
277
|
+
}
|
|
278
|
+
function findBestStatMatch(searchTerm, normalizedStats, similarityThreshold = MIN_THRESHOLD_MATCH) {
|
|
279
|
+
const exact = normalizedStats.get(searchTerm);
|
|
280
|
+
if (exact) return exact;
|
|
281
|
+
const candidates = [];
|
|
282
|
+
for (const [normalizedKey, original] of normalizedStats) {
|
|
283
|
+
if (normalizedKey.startsWith(searchTerm))
|
|
284
|
+
candidates.push([original, calculateSimilarity(searchTerm, normalizedKey)]);
|
|
285
|
+
}
|
|
286
|
+
if (candidates.length === 1) return candidates[0][0];
|
|
287
|
+
if (candidates.length > 0) {
|
|
288
|
+
candidates.sort((a, b) => b[1] - a[1]);
|
|
289
|
+
if (candidates[0][1] >= similarityThreshold) return candidates[0][0];
|
|
290
|
+
}
|
|
291
|
+
let bestMatch;
|
|
292
|
+
let bestSimilarity = 0;
|
|
293
|
+
for (const [normalizedKey, original] of normalizedStats) {
|
|
294
|
+
const similarity = calculateSimilarity(searchTerm, normalizedKey);
|
|
295
|
+
if (similarity === 1) return original;
|
|
296
|
+
if (similarity > bestSimilarity && similarity >= similarityThreshold) {
|
|
297
|
+
bestSimilarity = similarity;
|
|
298
|
+
bestMatch = original;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return bestMatch;
|
|
302
|
+
}
|
|
303
|
+
function findBestRecord(record, searchTerm, similarityThreshold = MIN_THRESHOLD_MATCH) {
|
|
304
|
+
const normalizeRecord = /* @__PURE__ */ new Map();
|
|
305
|
+
for (const key of Object.keys(record)) {
|
|
306
|
+
normalizeRecord.set(key.standardize(), key);
|
|
307
|
+
}
|
|
308
|
+
return findBestStatMatch(
|
|
309
|
+
searchTerm.standardize(),
|
|
310
|
+
normalizeRecord,
|
|
311
|
+
similarityThreshold
|
|
312
|
+
) || null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/utils.ts
|
|
245
316
|
function escapeRegex(string) {
|
|
246
317
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
247
318
|
}
|
|
@@ -251,10 +322,34 @@ function standardizeDice(dice) {
|
|
|
251
322
|
(_match, insideBrackets, outsideText) => insideBrackets ? insideBrackets : outsideText.standardize().replaceAll("df", "dF")
|
|
252
323
|
);
|
|
253
324
|
}
|
|
254
|
-
function
|
|
325
|
+
function handleDiceAfterD(tokenStd, normalizedStats) {
|
|
326
|
+
const diceMatch = /^(\d*)d(.+)$/i.exec(tokenStd);
|
|
327
|
+
if (!diceMatch) return null;
|
|
328
|
+
const diceCount = diceMatch[1] || "";
|
|
329
|
+
const afterD = diceMatch[2];
|
|
330
|
+
const bestMatch = findBestStatMatch(afterD, normalizedStats, 1);
|
|
331
|
+
if (bestMatch) {
|
|
332
|
+
const [, value] = bestMatch;
|
|
333
|
+
return `${diceCount}d${value.toString()}`;
|
|
334
|
+
}
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
function handleSimpleToken(tokenStd, token, normalizedStats, minThreshold) {
|
|
338
|
+
const bestMatch = findBestStatMatch(tokenStd, normalizedStats, minThreshold);
|
|
339
|
+
if (bestMatch) {
|
|
340
|
+
const [, value] = bestMatch;
|
|
341
|
+
return value.toString();
|
|
342
|
+
}
|
|
343
|
+
return token;
|
|
344
|
+
}
|
|
345
|
+
function generateStatsDice(originalDice, stats, minThreshold = 0.6, dollarValue) {
|
|
255
346
|
let dice = originalDice.standardize();
|
|
256
347
|
if (stats && Object.keys(stats).length > 0) {
|
|
257
|
-
const
|
|
348
|
+
const normalizedStats = /* @__PURE__ */ new Map();
|
|
349
|
+
for (const [key, value] of Object.entries(stats)) {
|
|
350
|
+
const normalized = key.standardize();
|
|
351
|
+
normalizedStats.set(normalized, [key, value]);
|
|
352
|
+
}
|
|
258
353
|
const partsRegex = /(\[[^\]]+])|([^[]+)/g;
|
|
259
354
|
let result = "";
|
|
260
355
|
let match;
|
|
@@ -268,7 +363,7 @@ function generateStatsDice(originalDice, stats, dollarValue) {
|
|
|
268
363
|
if (!outsideText) {
|
|
269
364
|
continue;
|
|
270
365
|
}
|
|
271
|
-
const tokenRegex = /(\$?[\p{L}\p{N}_]+)/gu;
|
|
366
|
+
const tokenRegex = /(\$?[\p{L}\p{N}_.]+)/gu;
|
|
272
367
|
let lastIndex = 0;
|
|
273
368
|
let tokenMatch;
|
|
274
369
|
while ((tokenMatch = tokenRegex.exec(outsideText)) !== null) {
|
|
@@ -277,45 +372,13 @@ function generateStatsDice(originalDice, stats, dollarValue) {
|
|
|
277
372
|
const tokenHasDollar = token.startsWith("$");
|
|
278
373
|
const tokenForCompare = tokenHasDollar ? token.slice(1) : token;
|
|
279
374
|
const tokenStd = tokenForCompare.standardize();
|
|
280
|
-
const
|
|
281
|
-
if (
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
for (const key of statKeys) {
|
|
286
|
-
const keyStd = key.standardize();
|
|
287
|
-
if (afterD === keyStd) {
|
|
288
|
-
result += `${diceCount}d${stats[key].toString()}`;
|
|
289
|
-
foundStatAfterD = true;
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
if (foundStatAfterD) {
|
|
294
|
-
lastIndex = tokenRegex.lastIndex;
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
let bestKey = null;
|
|
299
|
-
let bestScore = 0;
|
|
300
|
-
for (const key of statKeys) {
|
|
301
|
-
const keyStd = key.standardize();
|
|
302
|
-
if (tokenStd === keyStd) {
|
|
303
|
-
bestKey = key;
|
|
304
|
-
bestScore = 1;
|
|
305
|
-
break;
|
|
306
|
-
}
|
|
307
|
-
const score = similarityScore(tokenStd, keyStd);
|
|
308
|
-
if (score > bestScore) {
|
|
309
|
-
bestScore = score;
|
|
310
|
-
bestKey = key;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
if (bestKey && bestScore >= 0.6) {
|
|
314
|
-
const statValue = stats[bestKey];
|
|
315
|
-
result += statValue.toString();
|
|
316
|
-
} else {
|
|
317
|
-
result += token;
|
|
375
|
+
const diceReplacement = handleDiceAfterD(tokenStd, normalizedStats);
|
|
376
|
+
if (diceReplacement) {
|
|
377
|
+
result += diceReplacement;
|
|
378
|
+
lastIndex = tokenRegex.lastIndex;
|
|
379
|
+
continue;
|
|
318
380
|
}
|
|
381
|
+
result += handleSimpleToken(tokenStd, token, normalizedStats, minThreshold);
|
|
319
382
|
lastIndex = tokenRegex.lastIndex;
|
|
320
383
|
}
|
|
321
384
|
result += outsideText.slice(lastIndex);
|
|
@@ -359,33 +422,6 @@ function randomInt(min, max, engine = import_rpg_dice_roller2.NumberGenerator.en
|
|
|
359
422
|
if (!rng) rng = new import_random_js.Random(engine || void 0);
|
|
360
423
|
return rng.integer(min, max);
|
|
361
424
|
}
|
|
362
|
-
function levenshteinDistance(a, b) {
|
|
363
|
-
if (a === b) return 0;
|
|
364
|
-
const al = a.length;
|
|
365
|
-
const bl = b.length;
|
|
366
|
-
if (al === 0) return bl;
|
|
367
|
-
if (bl === 0) return al;
|
|
368
|
-
const v0 = new Array(bl + 1);
|
|
369
|
-
const v1 = new Array(bl + 1);
|
|
370
|
-
for (let i = 0; i <= bl; i++) v0[i] = i;
|
|
371
|
-
for (let i = 0; i < al; i++) {
|
|
372
|
-
v1[0] = i + 1;
|
|
373
|
-
for (let j = 0; j < bl; j++) {
|
|
374
|
-
const cost = a[i] === b[j] ? 0 : 1;
|
|
375
|
-
v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);
|
|
376
|
-
}
|
|
377
|
-
for (let j = 0; j <= bl; j++) v0[j] = v1[j];
|
|
378
|
-
}
|
|
379
|
-
return v1[bl];
|
|
380
|
-
}
|
|
381
|
-
function similarityScore(a, b) {
|
|
382
|
-
const la = a.length;
|
|
383
|
-
const lb = b.length;
|
|
384
|
-
if (la === 0 && lb === 0) return 1;
|
|
385
|
-
const dist = levenshteinDistance(a, b);
|
|
386
|
-
const max = Math.max(la, lb);
|
|
387
|
-
return 1 - dist / max;
|
|
388
|
-
}
|
|
389
425
|
function createCriticalCustom(dice, customCritical, template, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) {
|
|
390
426
|
const compareRegex = dice.match(SIGN_REGEX_SPACE);
|
|
391
427
|
let customDice = dice;
|
|
@@ -1505,6 +1541,7 @@ function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roll
|
|
|
1505
1541
|
SortOrder,
|
|
1506
1542
|
TooManyDice,
|
|
1507
1543
|
TooManyStats,
|
|
1544
|
+
calculateSimilarity,
|
|
1508
1545
|
createCriticalCustom,
|
|
1509
1546
|
diceRandomParse,
|
|
1510
1547
|
diceTypeRandomParse,
|
|
@@ -1512,11 +1549,14 @@ function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roll
|
|
|
1512
1549
|
evalCombinaison,
|
|
1513
1550
|
evalOneCombinaison,
|
|
1514
1551
|
evalStatsDice,
|
|
1552
|
+
findBestRecord,
|
|
1553
|
+
findBestStatMatch,
|
|
1515
1554
|
generateRandomStat,
|
|
1516
1555
|
generateStatsDice,
|
|
1517
1556
|
getEngine,
|
|
1518
1557
|
getEngineId,
|
|
1519
1558
|
isNumber,
|
|
1559
|
+
levenshteinDistance,
|
|
1520
1560
|
randomInt,
|
|
1521
1561
|
replaceExpByRandom,
|
|
1522
1562
|
replaceFormulaInDice,
|