@open-slot-ui/core 0.8.3 → 0.9.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/dist/index.cjs +438 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +266 -4
- package/dist/index.d.ts +266 -4
- package/dist/index.js +427 -93
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -503,6 +503,16 @@ declare class ValueDisplay extends Control {
|
|
|
503
503
|
readonly value: Signal<number>;
|
|
504
504
|
readonly currency: Signal<CurrencySpec>;
|
|
505
505
|
readonly label?: string;
|
|
506
|
+
/**
|
|
507
|
+
* Show a value at the precision it ACTUALLY carries (default on): when the value has
|
|
508
|
+
* more fraction digits than the currency's native precision — a sub-unit win like a
|
|
509
|
+
* USD 0.01 bet × a ×0.2 face = 0.002, or the 999.982 balance it leaves behind — the
|
|
510
|
+
* display decimals bump just enough to reveal them ($0.002), and drop back to the
|
|
511
|
+
* native look (5.00) once the value is clean again. Set `false` for hard-fixed decimals.
|
|
512
|
+
*/
|
|
513
|
+
autoPrecision: boolean;
|
|
514
|
+
/** The currency's NATIVE precision — what `autoPrecision` returns to on clean values. */
|
|
515
|
+
private baseDecimals;
|
|
506
516
|
/** Minimum odometer column width (0 = auto: sized tightly to the value, grows as it
|
|
507
517
|
* does). Read by the renderer at build time, so set it before mount (or declaratively
|
|
508
518
|
* via `controls.{id}.digits`). */
|
|
@@ -515,8 +525,13 @@ declare class ValueDisplay extends Control {
|
|
|
515
525
|
* good value — malformed host data never throws into the render loop (P11). */
|
|
516
526
|
set(amount: number): void;
|
|
517
527
|
get(): number;
|
|
518
|
-
/** Keep the prior spec on malformed input; clamp decimals to 0..8 (P11).
|
|
528
|
+
/** Keep the prior spec on malformed input; clamp decimals to 0..8 (P11). The given
|
|
529
|
+
* decimals become the NATIVE precision (`autoPrecision` bumps above it as needed). */
|
|
519
530
|
setCurrency(spec: CurrencySpec): void;
|
|
531
|
+
/** Bump the display decimals to what the current value needs — never below the
|
|
532
|
+
* currency's native precision — and drop back once the value is clean again.
|
|
533
|
+
* No-op (and no signal churn) when the shown precision is already right. */
|
|
534
|
+
private applyPrecision;
|
|
520
535
|
/** Accent emphasis: the renderer tints the value in the theme accent while on.
|
|
521
536
|
* For "this number is modified" moments — e.g. a bet display showing the
|
|
522
537
|
* EFFECTIVE stake while an ante/boost multiplies it. */
|
|
@@ -1198,6 +1213,121 @@ declare class DictionaryTranslator implements Translator {
|
|
|
1198
1213
|
/** Convenience factory for a zero-dep dictionary translator. */
|
|
1199
1214
|
declare function dictionary(messages: Record<string, Record<string, string>>, locale: string, socialMessages?: Record<string, Record<string, string>>): DictionaryTranslator;
|
|
1200
1215
|
|
|
1216
|
+
/**
|
|
1217
|
+
* GAME FACTS + the rules-completeness AUDIT — the "can't forget" layer for the
|
|
1218
|
+
* Info/Rules menu (Charter P11: data, not prose).
|
|
1219
|
+
*
|
|
1220
|
+
* A game declares WHAT IT HAS as structured facts — its math modes (base game, buy
|
|
1221
|
+
* features, bet boosts) with their RTP and max win, its free-spins behavior, its
|
|
1222
|
+
* volatility/cap — via `UISpec.facts` and/or `ui.declareFacts` (the buy-feature modal
|
|
1223
|
+
* declares its configured features automatically). The rules content stays modular
|
|
1224
|
+
* blocks (the "block builder"), and two mechanisms tie the two together:
|
|
1225
|
+
*
|
|
1226
|
+
* 1. The `mode-stats` block AUTO-RENDERS the per-mode RTP / Max-win grid straight
|
|
1227
|
+
* from the facts — declared once, so the table can never drift from the config.
|
|
1228
|
+
* 2. `auditRules(facts, rules)` checks the rules blocks against the facts and
|
|
1229
|
+
* reports every REQUIRED declaration that is missing (a mode's RTP or max win,
|
|
1230
|
+
* an undescribed buy feature) plus the HIGHLY RECOMMENDED ones (free-spins count
|
|
1231
|
+
* + retrigger policy, the legal disclaimer, a controls guide). The info menu
|
|
1232
|
+
* renders these findings as an explicit warning card when the rules open — a
|
|
1233
|
+
* forgotten declaration is stated, never silent.
|
|
1234
|
+
*
|
|
1235
|
+
* Any block may carry `covers: ['rtp:bonus', 'freespins', …]` to mark a topic as
|
|
1236
|
+
* covered by hand-written prose the text heuristics can't see.
|
|
1237
|
+
*/
|
|
1238
|
+
|
|
1239
|
+
/** One math mode / play mode the game exposes (base · buy feature · bet boost · ante). */
|
|
1240
|
+
interface GameModeFact {
|
|
1241
|
+
/** Stable id (matches the buy-feature card / RGS mode id), e.g. `'base'`, `'bonus'`. */
|
|
1242
|
+
id: string;
|
|
1243
|
+
/** Display name, e.g. `'Golden Rush'` — run through `ui.t` (social swaps apply). */
|
|
1244
|
+
name: string;
|
|
1245
|
+
/** What kind of mode this is. `'base'` is the plain game; everything else is a
|
|
1246
|
+
* configured feature that MUST be described in the rules. */
|
|
1247
|
+
kind?: 'base' | 'buy' | 'boost' | 'ante' | 'bonus';
|
|
1248
|
+
/** Cost as a multiple of the base bet (buy price / per-spin surcharge). */
|
|
1249
|
+
cost?: number;
|
|
1250
|
+
/** The mode's RTP in percent (e.g. 95.5). Required in the rules for every mode. */
|
|
1251
|
+
rtp?: number;
|
|
1252
|
+
/** The mode's maximum win as a multiple of the base bet (e.g. 5000). Required. */
|
|
1253
|
+
maxWinX?: number;
|
|
1254
|
+
}
|
|
1255
|
+
/** Free-spins behavior — HIGHLY RECOMMENDED to declare (or `false` = game has none). */
|
|
1256
|
+
interface FreeSpinsFact {
|
|
1257
|
+
/** How many free spins the bonus awards (e.g. exactly 3). */
|
|
1258
|
+
count?: number;
|
|
1259
|
+
/** Whether free spins can be retriggered during the bonus. */
|
|
1260
|
+
retrigger?: boolean;
|
|
1261
|
+
/** Free-form note (not audited). */
|
|
1262
|
+
note?: string;
|
|
1263
|
+
}
|
|
1264
|
+
/** Everything the game HAS, declared as data. Drives `mode-stats` + `auditRules`. */
|
|
1265
|
+
interface GameFacts {
|
|
1266
|
+
modes?: GameModeFact[];
|
|
1267
|
+
/** Free-spins facts, or `false` to state explicitly the game has none. */
|
|
1268
|
+
freeSpins?: FreeSpinsFact | false;
|
|
1269
|
+
/** Volatility label shown by `mode-stats` (e.g. `'Very high'`). */
|
|
1270
|
+
volatility?: string;
|
|
1271
|
+
/** The overall round win cap (× base bet) shown by `mode-stats` (e.g. 5000). */
|
|
1272
|
+
maxWinCapX?: number;
|
|
1273
|
+
}
|
|
1274
|
+
/** Merge two facts declarations: modes merge BY ID (defined incoming fields win);
|
|
1275
|
+
* scalar facts take the incoming value when defined. Pure — never mutates inputs. */
|
|
1276
|
+
declare function mergeFacts(base: GameFacts, add: GameFacts): GameFacts;
|
|
1277
|
+
/** Format an RTP percent the Stake way: always two decimals (95.5 → "95.50%"). */
|
|
1278
|
+
declare function formatRtp(rtp: number): string;
|
|
1279
|
+
/** Format a × multiple with thousands grouping (5000 → "5,000×"). */
|
|
1280
|
+
declare function formatTimes(x: number): string;
|
|
1281
|
+
/**
|
|
1282
|
+
* The auto-generated per-mode stat rows a `mode-stats` block renders: one
|
|
1283
|
+
* `RTP · <mode>` + `Max win · <mode>` pair per declared mode, then Volatility and
|
|
1284
|
+
* the round cap when declared. `tr` localizes the label words + mode names (social
|
|
1285
|
+
* mode swaps "Max win" → "Max prize" via the built-in social dictionary).
|
|
1286
|
+
*/
|
|
1287
|
+
declare function modeStatsItems(facts: GameFacts | undefined, tr?: (s: string) => string): Array<{
|
|
1288
|
+
label: string;
|
|
1289
|
+
value: string;
|
|
1290
|
+
}>;
|
|
1291
|
+
/**
|
|
1292
|
+
* The INTERPOLATION VARIABLES the declared facts expose to rules copy — the
|
|
1293
|
+
* "universal interpolatable rules" contract. Any rules text (inline blocks or a
|
|
1294
|
+
* {@link RulesDoc}) may use i18next-style tokens; the info menu resolves them from
|
|
1295
|
+
* the LIVE facts, so a stated RTP / max win / price can never drift from config:
|
|
1296
|
+
*
|
|
1297
|
+
* `{{rtp.<modeId>}}` → "95.50%" `{{maxWin.<modeId>}}` → "5,000×"
|
|
1298
|
+
* `{{cost.<modeId>}}` → "185×" `{{name.<modeId>}}` → the mode name
|
|
1299
|
+
* `{{freeSpins.count}}` → 3 `{{freeSpins.retrigger}}` → "can"/"cannot"
|
|
1300
|
+
* `{{volatility}}` → "Very high" `{{maxWinCap}}` → "5,000×"
|
|
1301
|
+
*
|
|
1302
|
+
* `extra` merges additional host vars (e.g. `game.name`) on top.
|
|
1303
|
+
*/
|
|
1304
|
+
declare function factsVars(facts: GameFacts | undefined, extra?: Record<string, string | number>): Record<string, string | number>;
|
|
1305
|
+
/** One finding from the rules audit. `required` findings are compliance gaps
|
|
1306
|
+
* (RTP / max win / an undescribed configured feature); `recommended` are the
|
|
1307
|
+
* strongly-advised ones (free-spins details, legal disclaimer, controls guide). */
|
|
1308
|
+
interface RulesAuditIssue {
|
|
1309
|
+
level: 'required' | 'recommended';
|
|
1310
|
+
/** Machine code, e.g. `'rules-missing-rtp'`, `'facts-missing-maxwin'`. */
|
|
1311
|
+
code: string;
|
|
1312
|
+
/** The coverage topic that would satisfy it, e.g. `'rtp:bonus'`, `'freespins'`. */
|
|
1313
|
+
topic: string;
|
|
1314
|
+
/** Human sentence shown in the info menu's warning card. */
|
|
1315
|
+
message: string;
|
|
1316
|
+
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Audit the rules blocks against the declared game facts. Pure + never-throw.
|
|
1319
|
+
* Findings come back most severe first (`required`, then `recommended`); an empty
|
|
1320
|
+
* array means the rules declare everything the game's configuration demands.
|
|
1321
|
+
*
|
|
1322
|
+
* `opts.resolve` maps each collected string BEFORE the text heuristics run — pass
|
|
1323
|
+
* the same translate-and-interpolate the renderer uses (`(s) => ui.t(s, factsVars(...))`)
|
|
1324
|
+
* so localized copy and `{{rtp.base}}`-style tokens are audited AS RENDERED: a rules
|
|
1325
|
+
* text that states its RTP via the token is, by construction, always correct.
|
|
1326
|
+
*/
|
|
1327
|
+
declare function auditRules(facts: GameFacts | undefined, rules: BlockSpec[] | undefined, opts?: {
|
|
1328
|
+
resolve?: (s: string) => string;
|
|
1329
|
+
}): RulesAuditIssue[];
|
|
1330
|
+
|
|
1201
1331
|
interface OpenUIOptions {
|
|
1202
1332
|
theme?: Theme;
|
|
1203
1333
|
layout?: LayoutConfig;
|
|
@@ -1262,6 +1392,11 @@ declare class OpenUI {
|
|
|
1262
1392
|
name?: string;
|
|
1263
1393
|
version?: string;
|
|
1264
1394
|
};
|
|
1395
|
+
/** Declared GAME FACTS (modes + RTP/max win, free spins, volatility, cap) — seeded
|
|
1396
|
+
* from `spec.facts`, extended at runtime via {@link declareFacts} (the buy-feature
|
|
1397
|
+
* modal declares its configured features automatically). Drives the `mode-stats`
|
|
1398
|
+
* rules block + the rules-completeness audit in the info menu. */
|
|
1399
|
+
readonly facts: Signal<GameFacts>;
|
|
1265
1400
|
/** Minimum round duration (ms) from jurisdiction — stored for the GAME to enforce. */
|
|
1266
1401
|
minimumRoundDuration: number;
|
|
1267
1402
|
/** Buy-feature confirm threshold, as a multiple of the base bet. A play (buy or
|
|
@@ -1269,6 +1404,13 @@ declare class OpenUI {
|
|
|
1269
1404
|
* — Stake requires that bet modes above 2× never activate on a single click. `0`
|
|
1270
1405
|
* (the default) = off. Set via `spec.buyFeature.confirmAboveCost` or a jurisdiction. */
|
|
1271
1406
|
confirmBuyAboveCost: number;
|
|
1407
|
+
/** When autoplay stops while the balance can no longer cover the next round —
|
|
1408
|
+
* whether the built-in RG enforcement stopped it, the game's own pre-check did, or
|
|
1409
|
+
* the player pressed Stop already broke — pop the SAME insufficient-funds modal a
|
|
1410
|
+
* manual spin shows (ERR_IPB) instead of ending silently. A normal stop with funds
|
|
1411
|
+
* in hand shows nothing. Default on; `spec.autoplay.insufficientFundsNotice: false`
|
|
1412
|
+
* opts out. */
|
|
1413
|
+
autoplayInsufficientNotice: boolean;
|
|
1272
1414
|
private sessionNet;
|
|
1273
1415
|
private prevVolumes;
|
|
1274
1416
|
/** The frozen UISpec `createUI` built this from, if any — authored = run = tested. */
|
|
@@ -1325,6 +1467,9 @@ declare class OpenUI {
|
|
|
1325
1467
|
* limits. One feed point powers both `displayNetPosition` and the autoplay stops.
|
|
1326
1468
|
*/
|
|
1327
1469
|
reportRound(win: number, bet: number): void;
|
|
1470
|
+
/** Merge more game facts into {@link facts} (modes merge by id; defined incoming
|
|
1471
|
+
* fields win). The info menu re-audits + re-renders its rules automatically. */
|
|
1472
|
+
declareFacts(add: GameFacts): void;
|
|
1328
1473
|
/** Reset the running session net + aggregates + timer (e.g. on a fresh session). */
|
|
1329
1474
|
resetSession(): void;
|
|
1330
1475
|
/** Show the menu-style notice modal: declarative blocks + optional action buttons.
|
|
@@ -1499,8 +1644,15 @@ interface ResponsiveOverride {
|
|
|
1499
1644
|
* A declarative menu/panel content block. Discriminated by `kind` so a "shown but
|
|
1500
1645
|
* no payload" bug is uncompilable (Charter B10): a `select` cannot omit options,
|
|
1501
1646
|
* a `slider` cannot carry them.
|
|
1647
|
+
*
|
|
1648
|
+
* Every block may carry `covers` — rules-audit topic tags (e.g. `'rtp:bonus'`,
|
|
1649
|
+
* `'freespins'`) marking that this block's hand-written prose covers a declaration
|
|
1650
|
+
* the audit's text heuristics can't see. See `auditRules` in `spec/facts`.
|
|
1502
1651
|
*/
|
|
1503
1652
|
type BlockSpec = {
|
|
1653
|
+
/** Rules-audit topics this block covers (see `auditRules`). */
|
|
1654
|
+
covers?: string[];
|
|
1655
|
+
} & ({
|
|
1504
1656
|
kind: 'slider';
|
|
1505
1657
|
id: string;
|
|
1506
1658
|
label?: string;
|
|
@@ -1565,6 +1717,13 @@ type BlockSpec = {
|
|
|
1565
1717
|
label: string;
|
|
1566
1718
|
value: string;
|
|
1567
1719
|
}>;
|
|
1720
|
+
} | {
|
|
1721
|
+
kind: 'mode-stats';
|
|
1722
|
+
id: string;
|
|
1723
|
+
extras?: Array<{
|
|
1724
|
+
label: string;
|
|
1725
|
+
value: string;
|
|
1726
|
+
}>;
|
|
1568
1727
|
} | {
|
|
1569
1728
|
kind: 'steps';
|
|
1570
1729
|
id: string;
|
|
@@ -1621,9 +1780,9 @@ type BlockSpec = {
|
|
|
1621
1780
|
id: string;
|
|
1622
1781
|
title?: string;
|
|
1623
1782
|
children: BlockSpec[];
|
|
1624
|
-
};
|
|
1783
|
+
});
|
|
1625
1784
|
/** All block kinds, for runtime validation of untyped host data. */
|
|
1626
|
-
declare const BLOCK_KINDS: readonly ["slider", "toggle", "button", "select", "stepper", "value", "text", "heading", "subheading", "callout", "stat-grid", "steps", "table", "paytable", "image", "media", "cards", "legal", "divider", "group"];
|
|
1785
|
+
declare const BLOCK_KINDS: readonly ["slider", "toggle", "button", "select", "stepper", "value", "text", "heading", "subheading", "callout", "stat-grid", "mode-stats", "steps", "table", "paytable", "image", "media", "cards", "legal", "divider", "group"];
|
|
1627
1786
|
interface PanelSpec {
|
|
1628
1787
|
id: string;
|
|
1629
1788
|
variant: PanelVariant;
|
|
@@ -1651,12 +1810,16 @@ interface UISpec {
|
|
|
1651
1810
|
* optional responsible-gambling limit choices (multiples of bet; Infinity = none).
|
|
1652
1811
|
* When `lossLimits`/`winLimits` are set, the picker offers them and the host must
|
|
1653
1812
|
* feed each round to `hud.reportRound(win, bet)` so they're enforced.
|
|
1813
|
+
* `insufficientFundsNotice` (default true): when autoplay stops with the balance
|
|
1814
|
+
* unable to cover the next round, show the same insufficient-funds modal a manual
|
|
1815
|
+
* spin shows (ERR_IPB) instead of ending silently.
|
|
1654
1816
|
*/
|
|
1655
1817
|
autoplay?: {
|
|
1656
1818
|
options?: number[];
|
|
1657
1819
|
mode?: AutoplayMode;
|
|
1658
1820
|
lossLimits?: number[];
|
|
1659
1821
|
winLimits?: number[];
|
|
1822
|
+
insufficientFundsNotice?: boolean;
|
|
1660
1823
|
};
|
|
1661
1824
|
/** Turbo switcher: 2-mode (off/on) or 3-mode (off/turbo/super). */
|
|
1662
1825
|
turbo?: TurboSpec;
|
|
@@ -1702,6 +1865,15 @@ interface UISpec {
|
|
|
1702
1865
|
name?: string;
|
|
1703
1866
|
version?: string;
|
|
1704
1867
|
};
|
|
1868
|
+
/**
|
|
1869
|
+
* Structured GAME FACTS — what the game HAS: its math modes (base / buy features /
|
|
1870
|
+
* boosts) with RTP + max win, its free-spins behavior, volatility and cap. Drives
|
|
1871
|
+
* the auto `mode-stats` rules block AND the rules-completeness audit: a configured
|
|
1872
|
+
* mode whose RTP / max win / description is missing from the rules is called out
|
|
1873
|
+
* explicitly in the info menu (see `auditRules`). The buy-feature modal declares
|
|
1874
|
+
* its configured features into this automatically (`ui.declareFacts`).
|
|
1875
|
+
*/
|
|
1876
|
+
facts?: GameFacts;
|
|
1705
1877
|
/** Buy-feature / bet-mode confirmation. `confirmAboveCost` (× base bet) makes any
|
|
1706
1878
|
* play costing MORE than that require a confirm step before it commits — Stake
|
|
1707
1879
|
* requires bet modes above 2× to never activate on a single click, so set `2`.
|
|
@@ -1861,6 +2033,60 @@ type Responsive = Partial<Record<ResponsiveKey, ResponsiveOverride>>;
|
|
|
1861
2033
|
*/
|
|
1862
2034
|
declare function installResponsive(ui: OpenUI, responsive: Responsive): Dispose;
|
|
1863
2035
|
|
|
2036
|
+
/**
|
|
2037
|
+
* The UNIVERSAL RULES DOCUMENT — one portable, editable JSON file that carries a
|
|
2038
|
+
* game's whole rules surface: the ordered block list, its i18next-compatible
|
|
2039
|
+
* per-locale messages (flat keys, `{{token}}` interpolation — use i18next with
|
|
2040
|
+
* `keySeparator: false` if you consume them elsewhere), the social/sweepstakes
|
|
2041
|
+
* overrides, and (optionally) the game facts it was authored against.
|
|
2042
|
+
*
|
|
2043
|
+
* Authoring convention: a block's `text` is an i18n KEY (or literal English —
|
|
2044
|
+
* a string is its own key, the house convention); `messages` supplies per-locale
|
|
2045
|
+
* copy; any string may use the `factsVars` tokens (`{{rtp.base}}`,
|
|
2046
|
+
* `{{maxWin.bonus}}`, `{{freeSpins.count}}`, …) which the info menu resolves from
|
|
2047
|
+
* the LIVE declared facts — so stated numbers can never drift from config.
|
|
2048
|
+
*
|
|
2049
|
+
* A game consumes the file with ONE call:
|
|
2050
|
+
*
|
|
2051
|
+
* import doc from './rules.doc.json';
|
|
2052
|
+
* const hud = mountHud(app, applyRulesDoc(spec, doc as RulesDoc));
|
|
2053
|
+
*
|
|
2054
|
+
* The stakeplate rules editor (`npx` runnable) reads/writes this exact format and
|
|
2055
|
+
* validates it against `validateSpec` + `auditRules` while you edit.
|
|
2056
|
+
*/
|
|
2057
|
+
|
|
2058
|
+
interface RulesDoc {
|
|
2059
|
+
/** Format version — currently 1. */
|
|
2060
|
+
version: 1;
|
|
2061
|
+
/** The ordered rules blocks (the same modular `BlockSpec` palette the menu renders). */
|
|
2062
|
+
blocks: BlockSpec[];
|
|
2063
|
+
/** i18next-compatible flat resources per locale (string keys → copy; `{{token}}` ok). */
|
|
2064
|
+
messages?: Record<string, Record<string, string>>;
|
|
2065
|
+
/** Social / sweepstakes wording overrides, same shape, consulted only in social mode. */
|
|
2066
|
+
socialMessages?: Record<string, Record<string, string>>;
|
|
2067
|
+
/** The facts this document was authored against — merged into `spec.facts` (the
|
|
2068
|
+
* spec's own facts win), and used by editors/CI to run the audit stand-alone. */
|
|
2069
|
+
facts?: GameFacts;
|
|
2070
|
+
}
|
|
2071
|
+
/** Runtime shape check — never throws. A malformed doc reports false and is skipped. */
|
|
2072
|
+
declare function isRulesDoc(doc: unknown): doc is RulesDoc;
|
|
2073
|
+
/**
|
|
2074
|
+
* Fold a rules document into a UISpec (pure — returns a NEW spec): the doc's blocks
|
|
2075
|
+
* become `menu.rules`, its messages/socialMessages merge UNDER the spec's own
|
|
2076
|
+
* dictionaries (host copy wins on conflicts), and its facts merge under `spec.facts`.
|
|
2077
|
+
* A malformed doc returns the spec unchanged (never-reject, Charter P11).
|
|
2078
|
+
*/
|
|
2079
|
+
declare function applyRulesDoc(spec: UISpec, doc: RulesDoc): UISpec;
|
|
2080
|
+
/**
|
|
2081
|
+
* Audit a rules document STAND-ALONE (editor / CI use): resolves each string through
|
|
2082
|
+
* the doc's own `locale` messages (default `'en'`) and interpolates the facts tokens,
|
|
2083
|
+
* exactly like the info menu renders it, then runs {@link auditRules}.
|
|
2084
|
+
*/
|
|
2085
|
+
declare function auditRulesDoc(doc: RulesDoc, opts?: {
|
|
2086
|
+
locale?: string;
|
|
2087
|
+
facts?: GameFacts;
|
|
2088
|
+
}): RulesAuditIssue[];
|
|
2089
|
+
|
|
1864
2090
|
/**
|
|
1865
2091
|
* The reference HUD expressed as data — the knobs `new OpenUI()` ships with.
|
|
1866
2092
|
* `createUI(defaultHudSpec)` is byte-equivalent to zero-arg `createUI()` (a test
|
|
@@ -1950,6 +2176,26 @@ declare function resolveCurrency(code: string, overrides?: Partial<CurrencySpec>
|
|
|
1950
2176
|
* non-negative values (used by the net-position readout). Pure + total: a malformed
|
|
1951
2177
|
* number renders as "0".
|
|
1952
2178
|
*/
|
|
2179
|
+
/**
|
|
2180
|
+
* How many fraction digits a value ACTUALLY uses — never fewer than the currency's
|
|
2181
|
+
* native `base` precision, never more than the 8-decimal ceiling. Snaps float noise
|
|
2182
|
+
* (0.1+0.2) by measuring at 8 dp, then strips trailing zeros back down to `base`.
|
|
2183
|
+
*
|
|
2184
|
+
* Why: Stake requires a currency's FULL bet ladder verbatim from authenticate —
|
|
2185
|
+
* including its true minimum (USD 0.01) — so a win (0.01 bet × a ×0.2 face = 0.002)
|
|
2186
|
+
* or a running balance (999.982) can carry sub-unit precision the currency's fixed
|
|
2187
|
+
* decimals would CROP to "0.00". This tells the display exactly how many digits that
|
|
2188
|
+
* value needs; a clean value keeps the ordinary native look (5.00, 1,000.00).
|
|
2189
|
+
*/
|
|
2190
|
+
declare function neededDecimals(value: number, base: number): number;
|
|
2191
|
+
/**
|
|
2192
|
+
* Format an amount at the precision it actually needs (see {@link neededDecimals}),
|
|
2193
|
+
* so a sub-unit win renders in full ("$0.002") instead of rounding to "$0.00".
|
|
2194
|
+
* Values within the currency's native precision format exactly like {@link formatAmount}.
|
|
2195
|
+
*/
|
|
2196
|
+
declare function formatAmountPrecise(value: number, spec: CurrencySpec, opts?: {
|
|
2197
|
+
signed?: boolean;
|
|
2198
|
+
}): string;
|
|
1953
2199
|
declare function formatAmount(value: number, spec: CurrencySpec, opts?: {
|
|
1954
2200
|
signed?: boolean;
|
|
1955
2201
|
}): string;
|
|
@@ -1978,7 +2224,23 @@ declare function buildBetLadder(cfg: RgsBetConfig, divisor?: number): {
|
|
|
1978
2224
|
levels: number[];
|
|
1979
2225
|
index: number;
|
|
1980
2226
|
};
|
|
2227
|
+
/**
|
|
2228
|
+
* Resolve the shown bet ladder from an authenticate response (MAJOR units): use EVERY
|
|
2229
|
+
* level the RGS offers, VERBATIM, and snap the default bet to the matching level.
|
|
2230
|
+
*
|
|
2231
|
+
* Deliberately does NOT filter out low levels. Stake requires every currency's full
|
|
2232
|
+
* ladder — including its true minimum (e.g. USD 0.01) — to come straight from
|
|
2233
|
+
* authenticate. A consequence is that the smallest win can be below one minimal
|
|
2234
|
+
* currency unit (USD 0.01 bet × a ×0.2 face = 0.002); the money displays render that
|
|
2235
|
+
* true sub-unit amount (see `formatAmountPrecise` / `ValueDisplay.autoPrecision`)
|
|
2236
|
+
* rather than hiding the level. Pure — share it between the UISpec builder and the
|
|
2237
|
+
* game's balance store so both agree on the bet.
|
|
2238
|
+
*/
|
|
2239
|
+
declare function resolveBetLadder(availableBets: number[] | undefined, defaultBet: number, fallback?: number[]): {
|
|
2240
|
+
levels: number[];
|
|
2241
|
+
index: number;
|
|
2242
|
+
};
|
|
1981
2243
|
/** Clamp a stake (major units) to the RGS min/max and snap to `stepBet`. Pure. */
|
|
1982
2244
|
declare function clampBet(amount: number, cfg: RgsBetConfig, divisor?: number): number;
|
|
1983
2245
|
|
|
1984
|
-
export { API_AMOUNT_DIVISOR, type Anchor, AutoplayControl, type AutoplayLimits, type AutoplayMode, type AutoplayOptions, BLOCK_KINDS, type BlockFactory, type BlockSpec, type Breakpoint, type BuiltPanel, ButtonControl, type ButtonOptions, CURRENCY_TABLE, CardControl, type CardOptions, type ComposeMenuOptions, Control, type ControlOptions, type ControlOverride, ControlRegistry, type ControlSnapshot, type CurrencyInfo, type CurrencySpec, DEFAULT_MENU_TITLES, DEFAULT_NOTICE_ACTION, type DeepPartial, DictionaryTranslator, type Dispose, EventBus, EventLog, type EventLogOptions, type EventMap, Fade, type ForbiddenMatch, type HostHooks, type JurisdictionConfig, type KnownControlId, LOCALE_LABELS, type LayoutConfig, type LayoutSpec, type LoggedEvent, type MenuSpec, type NoticeAction, type NoticeOptions, OpenUI, type OpenUIEvents, type OpenUIOptions, type Orientation, PanelControl, type PanelOptions, type PanelSpec, type PanelVariant, Parallel, type Placement, Pulse, RGS_ERROR_KEYS, ReadoutControl, type ReadoutKind, type ReadoutOptions, type RealityCheckOptions, type Rect, type ResponsiveKey, type ResponsiveOverride, type RgsBetConfig, type RgsErrorCode, type RgsErrorOptions, type ScreenState, SelectControl, type SelectControlOptions, type SelectOption, Sequence, Signal, SliderControl, type SliderOptions, type SocialPhraseIssue, type SoundControls, type SpecIssue, SpinControl, type SpinPress, type SpinSpec, Squish, type StageRect, type StateDef, type StateMap, StepperControl, type StepperOptions, type Subscribable, type Theme, type ThemeChoice, type ThemeIssue, type ThemeOverrides, type ThemePreset, ToggleControl, type ToggleOptions, type Transition, type Translator, TurboControl, type TurboOptions, type TurboSpec, Turn, type UISpec, ValueDisplay, type ValueDisplayOptions, type ViewInspect, applyJurisdiction, breakpointFor, buildBetLadder, buildBlocks, buildPanel, buttonBlocks, checkSocialPhrases, clampBet, clampDecimals, clampDigits, clampMinDigits, collectSocialCopy, composeMenu, computeScreen, createUI, defaultHudSpec, defaultLayout, defaultLayoutConfig, defaultTheme, defineUI, dictionary, displayDigits, effect, errorBlocks, extendTheme, findForbiddenPhrases, formatAmount, installResponsive, integerDigits, isSafeColor, isSocialCurrency, landscapeDefaultLayouts, openuiDefaults, openuiSocialDefaults, portraitDefaultLayouts, resolveCurrency, resolvePlacement, resolveTheme, resolveTurboModes, safeAmount, sanitizeThemeOverrides, themePresets, validateSpec, valueFitMaxWidth };
|
|
2246
|
+
export { API_AMOUNT_DIVISOR, type Anchor, AutoplayControl, type AutoplayLimits, type AutoplayMode, type AutoplayOptions, BLOCK_KINDS, type BlockFactory, type BlockSpec, type Breakpoint, type BuiltPanel, ButtonControl, type ButtonOptions, CURRENCY_TABLE, CardControl, type CardOptions, type ComposeMenuOptions, Control, type ControlOptions, type ControlOverride, ControlRegistry, type ControlSnapshot, type CurrencyInfo, type CurrencySpec, DEFAULT_MENU_TITLES, DEFAULT_NOTICE_ACTION, type DeepPartial, DictionaryTranslator, type Dispose, EventBus, EventLog, type EventLogOptions, type EventMap, Fade, type ForbiddenMatch, type FreeSpinsFact, type GameFacts, type GameModeFact, type HostHooks, type JurisdictionConfig, type KnownControlId, LOCALE_LABELS, type LayoutConfig, type LayoutSpec, type LoggedEvent, type MenuSpec, type NoticeAction, type NoticeOptions, OpenUI, type OpenUIEvents, type OpenUIOptions, type Orientation, PanelControl, type PanelOptions, type PanelSpec, type PanelVariant, Parallel, type Placement, Pulse, RGS_ERROR_KEYS, ReadoutControl, type ReadoutKind, type ReadoutOptions, type RealityCheckOptions, type Rect, type ResponsiveKey, type ResponsiveOverride, type RgsBetConfig, type RgsErrorCode, type RgsErrorOptions, type RulesAuditIssue, type RulesDoc, type ScreenState, SelectControl, type SelectControlOptions, type SelectOption, Sequence, Signal, SliderControl, type SliderOptions, type SocialPhraseIssue, type SoundControls, type SpecIssue, SpinControl, type SpinPress, type SpinSpec, Squish, type StageRect, type StateDef, type StateMap, StepperControl, type StepperOptions, type Subscribable, type Theme, type ThemeChoice, type ThemeIssue, type ThemeOverrides, type ThemePreset, ToggleControl, type ToggleOptions, type Transition, type Translator, TurboControl, type TurboOptions, type TurboSpec, Turn, type UISpec, ValueDisplay, type ValueDisplayOptions, type ViewInspect, applyJurisdiction, applyRulesDoc, auditRules, auditRulesDoc, breakpointFor, buildBetLadder, buildBlocks, buildPanel, buttonBlocks, checkSocialPhrases, clampBet, clampDecimals, clampDigits, clampMinDigits, collectSocialCopy, composeMenu, computeScreen, createUI, defaultHudSpec, defaultLayout, defaultLayoutConfig, defaultTheme, defineUI, dictionary, displayDigits, effect, errorBlocks, extendTheme, factsVars, findForbiddenPhrases, formatAmount, formatAmountPrecise, formatRtp, formatTimes, installResponsive, integerDigits, isRulesDoc, isSafeColor, isSocialCurrency, landscapeDefaultLayouts, mergeFacts, modeStatsItems, neededDecimals, openuiDefaults, openuiSocialDefaults, portraitDefaultLayouts, resolveBetLadder, resolveCurrency, resolvePlacement, resolveTheme, resolveTurboModes, safeAmount, sanitizeThemeOverrides, themePresets, validateSpec, valueFitMaxWidth };
|