@open-slot-ui/pixi 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/art.js +1 -1
- package/dist/{chunk-PYXZIGXG.js → chunk-Z7X5JH7H.js} +7 -4
- package/dist/chunk-Z7X5JH7H.js.map +1 -0
- package/dist/index.cjs +85 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +84 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-PYXZIGXG.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ControlView, ButtonView, SliderView, buildBlockColumn, OpenUIPixi } from './chunk-
|
|
2
|
-
export { AutoplayDrawerView, AutoplayView, ButtonView, ControlView, DialogView, MenuView, OpenUIPixi, ReadoutView, SelectView, SliderView, SpinView, StepperView, TextCellRenderer, ToggleView, TurboView, Tweener, ValueDisplayView, buildBlockColumn, defaultSpinSkin, drawSpin, isDesktop, svgSpinSkin } from './chunk-
|
|
1
|
+
import { ControlView, ButtonView, SliderView, buildBlockColumn, OpenUIPixi } from './chunk-Z7X5JH7H.js';
|
|
2
|
+
export { AutoplayDrawerView, AutoplayView, ButtonView, ControlView, DialogView, MenuView, OpenUIPixi, ReadoutView, SelectView, SliderView, SpinView, StepperView, TextCellRenderer, ToggleView, TurboView, Tweener, ValueDisplayView, buildBlockColumn, defaultSpinSkin, drawSpin, isDesktop, svgSpinSkin } from './chunk-Z7X5JH7H.js';
|
|
3
3
|
import { Text, Graphics, Container, Rectangle } from 'pixi.js';
|
|
4
|
-
import { LOCALE_LABELS, createUI, composeMenu, buildPanel,
|
|
4
|
+
import { LOCALE_LABELS, createUI, composeMenu, buildPanel, modeStatsItems, formatAmountPrecise, factsVars, auditRules } from '@open-slot-ui/core';
|
|
5
5
|
|
|
6
6
|
var RISE = 26;
|
|
7
7
|
var STAGGER = 38;
|
|
@@ -280,7 +280,11 @@ var PanelBodyView = class extends ControlView {
|
|
|
280
280
|
};
|
|
281
281
|
var esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
282
282
|
var rich = (s) => esc(s).replace(/\*\*(.+?)\*\*/g, "<b>$1</b>");
|
|
283
|
-
function
|
|
283
|
+
function statGridHtml(items, tr) {
|
|
284
|
+
const rows = items.map((it) => `<div><dt>${esc(tr(it.label))}</dt><dd>${esc(tr(it.value))}</dd></div>`).join("");
|
|
285
|
+
return `<dl class="ohm-stats">${rows}</dl>`;
|
|
286
|
+
}
|
|
287
|
+
function renderBlocks(blocks, tr, facts) {
|
|
284
288
|
const out = [];
|
|
285
289
|
for (const b of blocks) {
|
|
286
290
|
switch (b.kind) {
|
|
@@ -322,9 +326,16 @@ function renderBlocks(blocks, tr) {
|
|
|
322
326
|
out.push(`<table class="ohm-table">${head}<tbody>${body}</tbody></table>`);
|
|
323
327
|
break;
|
|
324
328
|
}
|
|
325
|
-
case "stat-grid":
|
|
326
|
-
|
|
327
|
-
|
|
329
|
+
case "stat-grid":
|
|
330
|
+
out.push(statGridHtml(b.items, tr));
|
|
331
|
+
break;
|
|
332
|
+
// The AUTO per-mode RTP / Max-win grid — rendered straight from the declared
|
|
333
|
+
// game facts (+ any host extras), so the table can never drift from the config.
|
|
334
|
+
// `modeStatsItems` localizes the label PARTS itself ("Max win" · the mode name),
|
|
335
|
+
// so the grid renderer gets identity-tr — no double translation.
|
|
336
|
+
case "mode-stats": {
|
|
337
|
+
const extras = (b.extras ?? []).map((e) => ({ label: tr(e.label), value: tr(e.value) }));
|
|
338
|
+
out.push(statGridHtml([...modeStatsItems(facts, tr), ...extras], (s) => s));
|
|
328
339
|
break;
|
|
329
340
|
}
|
|
330
341
|
case "steps": {
|
|
@@ -394,8 +405,30 @@ function mountInfoMenu(app, ui) {
|
|
|
394
405
|
const soundMode = menu.sound ?? "sliders";
|
|
395
406
|
const volRow = (id, label, hint, val) => `<div class="ohm-setting"><label class="ohm-row"><span>${esc(tr(label))}</span><input class="ohm-slider" data-vol="${id}" type="range" min="0" max="1" step="0.01" value="${val}"></label><div class="ohm-hint">${esc(tr(hint))}</div></div>`;
|
|
396
407
|
const soundSliders = soundMode === "master" ? volRow("master", "Volume", "Adjust the overall game volume.", ui.sfxSlider.value.get()) : soundMode === "sliders" ? volRow("music", "Music", "Adjust the background music volume.", ui.musicSlider.value.get()) + volRow("sfx", "Effects", "Adjust the sound-effects volume.", ui.sfxSlider.value.get()) : "";
|
|
397
|
-
const
|
|
398
|
-
|
|
408
|
+
const rulesTr = () => {
|
|
409
|
+
const vars2 = factsVars(ui.facts.get(), { "game.name": ui.gameInfo.name ?? "", "game.version": ui.gameInfo.version ?? "" });
|
|
410
|
+
return (s) => ui.t(s, vars2);
|
|
411
|
+
};
|
|
412
|
+
const auditCardHtml = (trr) => {
|
|
413
|
+
if (!menu.rules?.length) return "";
|
|
414
|
+
const issues = auditRules(ui.facts.get(), menu.rules, { resolve: trr });
|
|
415
|
+
if (!issues.length) return "";
|
|
416
|
+
const req = issues.filter((i) => i.level === "required");
|
|
417
|
+
const rec = issues.filter((i) => i.level === "recommended");
|
|
418
|
+
const list = (items) => `<ul>${items.map((i) => `<li>${esc(tr(i.message))}</li>`).join("")}</ul>`;
|
|
419
|
+
return `<div class="ohm-audit" role="alert">
|
|
420
|
+
<div class="ohm-audit-title">\u26A0 ${esc(tr("openui.rulesAudit.title"))}</div>
|
|
421
|
+
${req.length ? `<div class="ohm-audit-sub">${esc(tr("openui.rulesAudit.required"))}</div>${list(req)}` : ""}
|
|
422
|
+
${rec.length ? `<div class="ohm-audit-sub ohm-audit-sub--rec">${esc(tr("openui.rulesAudit.recommended"))}</div><div class="ohm-audit-rec">${list(rec)}</div>` : ""}
|
|
423
|
+
</div>`;
|
|
424
|
+
};
|
|
425
|
+
const rulesInnerHtml = () => {
|
|
426
|
+
if (!menu.rules) return "";
|
|
427
|
+
const trr = rulesTr();
|
|
428
|
+
return auditCardHtml(trr) + renderBlocks(menu.rules, trr, ui.facts.get());
|
|
429
|
+
};
|
|
430
|
+
const paytableHtml = menu.paytable ? renderBlocks(menu.paytable, tr, ui.facts.get()) : "";
|
|
431
|
+
const rulesHtml = rulesInnerHtml();
|
|
399
432
|
const banner = menu.banner ? `<img class="ohm-logo" alt="" src="${menu.banner.src}"${menu.banner.width ? ` width="${menu.banner.width}"` : ""}${menu.banner.height ? ` height="${menu.banner.height}"` : ""}>` : ui.gameInfo.name ? `<h1 class="ohm-logo-text">${esc(ui.gameInfo.name)}</h1>` : "";
|
|
400
433
|
host2.innerHTML = `
|
|
401
434
|
<div class="ohm-backdrop" data-close></div>
|
|
@@ -467,19 +500,40 @@ function mountInfoMenu(app, ui) {
|
|
|
467
500
|
else if (el instanceof HTMLSelectElement) el.addEventListener("change", () => ui.bus.emit("optionSelected", { id, value: el.value, index: el.selectedIndex }));
|
|
468
501
|
});
|
|
469
502
|
host2.querySelectorAll("[data-close]").forEach((b) => b.addEventListener("click", () => ui.settingsPanel.closePanel()));
|
|
503
|
+
const refreshRules = () => {
|
|
504
|
+
const rulesEl = host2.querySelector("#ohm-rules");
|
|
505
|
+
if (rulesEl && menu.rules) rulesEl.innerHTML = rulesInnerHtml();
|
|
506
|
+
};
|
|
470
507
|
disposers.push(
|
|
471
508
|
ui.locale.subscribe(() => {
|
|
472
509
|
const body = host2.querySelector(".ohm-body");
|
|
473
510
|
if (body) {
|
|
474
|
-
|
|
475
|
-
if (rulesEl && menu.rules) rulesEl.innerHTML = renderBlocks(menu.rules, tr);
|
|
511
|
+
refreshRules();
|
|
476
512
|
if (lang) lang.value = ui.locale.get();
|
|
477
513
|
}
|
|
514
|
+
}),
|
|
515
|
+
ui.facts.subscribe(refreshRules)
|
|
516
|
+
);
|
|
517
|
+
let menuLocked = false;
|
|
518
|
+
disposers.push(
|
|
519
|
+
ui.settingsPanel.state.subscribe(() => {
|
|
520
|
+
const isOpen = ui.settingsPanel.isOpen;
|
|
521
|
+
host2.classList.toggle("open", isOpen);
|
|
522
|
+
if (isOpen && !menuLocked) {
|
|
523
|
+
ui.lock();
|
|
524
|
+
menuLocked = true;
|
|
525
|
+
} else if (!isOpen && menuLocked) {
|
|
526
|
+
ui.unlock();
|
|
527
|
+
menuLocked = false;
|
|
528
|
+
}
|
|
478
529
|
})
|
|
479
530
|
);
|
|
480
|
-
disposers.push(ui.settingsPanel.state.subscribe(() => host2.classList.toggle("open", ui.settingsPanel.isOpen)));
|
|
481
531
|
return () => {
|
|
482
532
|
for (const d of disposers.splice(0)) d();
|
|
533
|
+
if (menuLocked) {
|
|
534
|
+
ui.unlock();
|
|
535
|
+
menuLocked = false;
|
|
536
|
+
}
|
|
483
537
|
host2.remove();
|
|
484
538
|
};
|
|
485
539
|
}
|
|
@@ -533,6 +587,13 @@ var OHM_CSS = `
|
|
|
533
587
|
.ohm-stats { margin: 12px 0; display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; }
|
|
534
588
|
.ohm-stats > div { display: flex; justify-content: space-between; padding: 9px 0; border-bottom: 1px solid color-mix(in srgb, var(--text-dim) 20%, transparent); }
|
|
535
589
|
.ohm-stats dt { color: var(--text-dim); margin: 0; } .ohm-stats dd { margin: 0; font-weight: 700; }
|
|
590
|
+
.ohm-audit { margin: 12px 0 18px; padding: 14px 16px; border-radius: 12px; border: 2px solid #d03131; background: color-mix(in srgb, #d03131 8%, transparent); }
|
|
591
|
+
.ohm-audit-title { font-weight: 900; letter-spacing: .5px; color: #b31d1d; }
|
|
592
|
+
.ohm-audit-sub { margin-top: 8px; font-size: 13px; font-weight: 800; color: #b31d1d; }
|
|
593
|
+
.ohm-audit-sub--rec { color: #b07d09; }
|
|
594
|
+
.ohm-audit ul { margin: 6px 0 0; padding-left: 20px; color: var(--text); font-size: 13.5px; line-height: 1.55; }
|
|
595
|
+
.ohm-audit li { margin: 3px 0; }
|
|
596
|
+
.ohm-audit-rec ul { color: var(--text-dim); }
|
|
536
597
|
.ohm-callout { margin: 16px 0 4px; padding: 14px 16px; border-radius: 12px; border-left: 4px solid var(--accent); background: color-mix(in srgb, var(--accent) 9%, transparent); }
|
|
537
598
|
.ohm-callout b { color: var(--accent); } .ohm-callout p { margin: 4px 0 0; color: var(--text); }
|
|
538
599
|
.ohm-callout--warning { border-left-color: #e0a106; background: color-mix(in srgb, #e0a106 10%, transparent); }
|
|
@@ -622,7 +683,7 @@ var CONFIRM_CSS = `
|
|
|
622
683
|
// src/mountHud.ts
|
|
623
684
|
function showReplayModal(ui, info, buttonKey, onSelect) {
|
|
624
685
|
const cur = info.currency ?? ui.balance.currency.get();
|
|
625
|
-
const money2 = (n) =>
|
|
686
|
+
const money2 = (n) => formatAmountPrecise(n, cur);
|
|
626
687
|
ui.showNotice(
|
|
627
688
|
[
|
|
628
689
|
{ kind: "heading", id: "openui-replay-h", text: "openui.replay.title" },
|
|
@@ -760,13 +821,14 @@ function mountHud(app, spec = {}, opts = {}) {
|
|
|
760
821
|
};
|
|
761
822
|
}
|
|
762
823
|
function money(amount, cur) {
|
|
763
|
-
return
|
|
824
|
+
return formatAmountPrecise(amount, cur);
|
|
764
825
|
}
|
|
765
826
|
var esc3 = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
766
827
|
function mountBuyFeatureModal(_app, hud, features, opts = {}) {
|
|
767
828
|
const ui = hud.ui;
|
|
768
829
|
const tr = (k) => ui.t(k);
|
|
769
830
|
const list = features.slice(0, 4);
|
|
831
|
+
ui.declareFacts({ modes: list.map((f) => ({ id: f.id, name: f.name, kind: f.variant, cost: f.cost })) });
|
|
770
832
|
const boosts = /* @__PURE__ */ new Set();
|
|
771
833
|
const activation = opts.activation ?? "multi";
|
|
772
834
|
const blocksBuy = opts.activationBlocksBuy ?? false;
|
|
@@ -889,10 +951,16 @@ function mountBuyFeatureModal(_app, hud, features, opts = {}) {
|
|
|
889
951
|
$("#bfm-plus").addEventListener("click", () => ui.betStepper.inc());
|
|
890
952
|
disposers.push(ui.bet.value.subscribe(() => renderCards()));
|
|
891
953
|
const open = () => {
|
|
954
|
+
if (host2.classList.contains("open")) return;
|
|
892
955
|
renderCards();
|
|
893
956
|
host2.classList.add("open");
|
|
957
|
+
ui.lock();
|
|
958
|
+
};
|
|
959
|
+
const close = () => {
|
|
960
|
+
if (!host2.classList.contains("open")) return;
|
|
961
|
+
host2.classList.remove("open");
|
|
962
|
+
ui.unlock();
|
|
894
963
|
};
|
|
895
|
-
const close = () => host2.classList.remove("open");
|
|
896
964
|
host2.querySelectorAll("[data-close]").forEach((b) => b.addEventListener("click", close));
|
|
897
965
|
disposers.push(ui.on("buttonActivated", ({ id }) => {
|
|
898
966
|
if (id === "bonus") open();
|
|
@@ -910,6 +978,7 @@ function mountBuyFeatureModal(_app, hud, features, opts = {}) {
|
|
|
910
978
|
renderCards();
|
|
911
979
|
return () => {
|
|
912
980
|
window.removeEventListener("resize", onResize);
|
|
981
|
+
if (host2.classList.contains("open")) ui.unlock();
|
|
913
982
|
for (const d of disposers.splice(0)) d();
|
|
914
983
|
host2.remove();
|
|
915
984
|
};
|