hbengine 0.2.3
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 +20 -0
- package/engine-cli/connect.mjs +73 -0
- package/engine-cli/hbengine.mjs +565 -0
- package/engine-cli/package.json +1 -0
- package/engine-cli/templates.mjs +14 -0
- package/engine-conformance/analyse-worker.mjs +12 -0
- package/engine-conformance/analyse.mjs +4458 -0
- package/engine-conformance/bundle.mjs +208 -0
- package/engine-conformance/clock.mjs +294 -0
- package/engine-conformance/csp.go +56 -0
- package/engine-conformance/csp.json +6 -0
- package/engine-conformance/csp.mjs +20 -0
- package/engine-conformance/gzip-sizes.mjs +9 -0
- package/engine-conformance/package.json +1 -0
- package/engine-conformance/picture.mjs +55 -0
- package/engine-conformance/report.go +349 -0
- package/engine-conformance/run.mjs +1217 -0
- package/engine-conformance/scan.mjs +476 -0
- package/engine-conformance/testdata/clock-overlay/bundle/assets.json +1 -0
- package/engine-conformance/testdata/clock-overlay/bundle/game.css +17 -0
- package/engine-conformance/testdata/clock-overlay/bundle/game.js +83 -0
- package/engine-conformance/testdata/clock-overlay/bundle/hbtest.json +4 -0
- package/engine-conformance/testdata/clock-overlay/bundle/index.html +34 -0
- package/engine-conformance/testdata/clock-probe/bundle/assets.json +1 -0
- package/engine-conformance/testdata/clock-probe/bundle/game.css +17 -0
- package/engine-conformance/testdata/clock-probe/bundle/game.js +65 -0
- package/engine-conformance/testdata/clock-probe/bundle/hbtest.json +4 -0
- package/engine-conformance/testdata/clock-probe/bundle/index.html +35 -0
- package/engine-conformance/testdata/clock-probe/bundle/probe-worker.js +46 -0
- package/engine-conformance/testdata/clock-probe/bundle/probe.js +210 -0
- package/engine-conformance/testdata/clock-probe/math/dice.tsv +100 -0
- package/engine-conformance/testdata/clock-probe/math/manifest.json +2925 -0
- package/engine-conformance/testdata/clock-worker/bundle/assets.json +1 -0
- package/engine-conformance/testdata/clock-worker/bundle/clock-worker.js +14 -0
- package/engine-conformance/testdata/clock-worker/bundle/game.css +17 -0
- package/engine-conformance/testdata/clock-worker/bundle/game.js +61 -0
- package/engine-conformance/testdata/clock-worker/bundle/hbtest.json +4 -0
- package/engine-conformance/testdata/clock-worker/bundle/index.html +35 -0
- package/engine-conformance/testdata/clock-worker/math/dice.tsv +100 -0
- package/engine-conformance/testdata/clock-worker/math/manifest.json +2925 -0
- package/engine-conformance/travel.mjs +1209 -0
- package/engine-conformance/vendor/acorn/LICENSE +21 -0
- package/engine-conformance/vendor/acorn/acorn.mjs +6266 -0
- package/engine-conformance/wasm-releases.json +168 -0
- package/engine-examples/README.md +23 -0
- package/engine-examples/coin/AGENTS.md +3 -0
- package/engine-examples/coin/README.md +7 -0
- package/engine-examples/coin/bundle/assets.json +1 -0
- package/engine-examples/coin/bundle/game.css +5 -0
- package/engine-examples/coin/bundle/game.js +19 -0
- package/engine-examples/coin/bundle/hbtest.json +5 -0
- package/engine-examples/coin/bundle/index.html +16 -0
- package/engine-examples/coin/math/coin.tsv +2 -0
- package/engine-examples/coin/math/manifest.json +17 -0
- package/engine-examples/crash/AGENTS.md +3 -0
- package/engine-examples/crash/README.md +14 -0
- package/engine-examples/crash/bundle/assets.json +1 -0
- package/engine-examples/crash/bundle/game.css +8 -0
- package/engine-examples/crash/bundle/game.js +90 -0
- package/engine-examples/crash/bundle/hbtest.json +5 -0
- package/engine-examples/crash/bundle/index.html +20 -0
- package/engine-examples/crash/math/crash-01.tsv +2 -0
- package/engine-examples/crash/math/crash-02.tsv +2 -0
- package/engine-examples/crash/math/crash-03.tsv +2 -0
- package/engine-examples/crash/math/crash-04.tsv +2 -0
- package/engine-examples/crash/math/crash-05.tsv +2 -0
- package/engine-examples/crash/math/crash-06.tsv +2 -0
- package/engine-examples/crash/math/crash-07.tsv +2 -0
- package/engine-examples/crash/math/crash-08.tsv +2 -0
- package/engine-examples/crash/math/crash-09.tsv +2 -0
- package/engine-examples/crash/math/crash-10.tsv +2 -0
- package/engine-examples/crash/math/crash-11.tsv +2 -0
- package/engine-examples/crash/math/crash-12.tsv +2 -0
- package/engine-examples/crash/math/crash-13.tsv +2 -0
- package/engine-examples/crash/math/crash-14.tsv +2 -0
- package/engine-examples/crash/math/crash-15.tsv +2 -0
- package/engine-examples/crash/math/crash-16.tsv +2 -0
- package/engine-examples/crash/math/crash-17.tsv +2 -0
- package/engine-examples/crash/math/crash-18.tsv +2 -0
- package/engine-examples/crash/math/crash-19.tsv +2 -0
- package/engine-examples/crash/math/crash-20.tsv +2 -0
- package/engine-examples/crash/math/crash-21.tsv +2 -0
- package/engine-examples/crash/math/crash-22.tsv +2 -0
- package/engine-examples/crash/math/crash-23.tsv +2 -0
- package/engine-examples/crash/math/crash-24.tsv +2 -0
- package/engine-examples/crash/math/crash-25.tsv +2 -0
- package/engine-examples/crash/math/crash-26.tsv +2 -0
- package/engine-examples/crash/math/crash-27.tsv +2 -0
- package/engine-examples/crash/math/crash-28.tsv +2 -0
- package/engine-examples/crash/math/crash-29.tsv +2 -0
- package/engine-examples/crash/math/crash-30.tsv +2 -0
- package/engine-examples/crash/math/crash-31.tsv +2 -0
- package/engine-examples/crash/math/crash-32.tsv +2 -0
- package/engine-examples/crash/math/crash-33.tsv +2 -0
- package/engine-examples/crash/math/crash-34.tsv +2 -0
- package/engine-examples/crash/math/crash-35.tsv +2 -0
- package/engine-examples/crash/math/crash-36.tsv +2 -0
- package/engine-examples/crash/math/crash-37.tsv +2 -0
- package/engine-examples/crash/math/crash-38.tsv +2 -0
- package/engine-examples/crash/math/crash-39.tsv +2 -0
- package/engine-examples/crash/math/crash-40.tsv +2 -0
- package/engine-examples/crash/math/crash-41.tsv +2 -0
- package/engine-examples/crash/math/crash-42.tsv +2 -0
- package/engine-examples/crash/math/crash-43.tsv +2 -0
- package/engine-examples/crash/math/crash-44.tsv +2 -0
- package/engine-examples/crash/math/crash-45.tsv +2 -0
- package/engine-examples/crash/math/crash-46.tsv +2 -0
- package/engine-examples/crash/math/crash-47.tsv +2 -0
- package/engine-examples/crash/math/crash-48.tsv +2 -0
- package/engine-examples/crash/math/crash-49.tsv +2 -0
- package/engine-examples/crash/math/crash-50.tsv +2 -0
- package/engine-examples/crash/math/crash-51.tsv +2 -0
- package/engine-examples/crash/math/crash-52.tsv +2 -0
- package/engine-examples/crash/math/crash-53.tsv +2 -0
- package/engine-examples/crash/math/crash-54.tsv +2 -0
- package/engine-examples/crash/math/crash-55.tsv +2 -0
- package/engine-examples/crash/math/crash-56.tsv +2 -0
- package/engine-examples/crash/math/crash-57.tsv +2 -0
- package/engine-examples/crash/math/crash-58.tsv +2 -0
- package/engine-examples/crash/math/crash-59.tsv +2 -0
- package/engine-examples/crash/math/crash-60.tsv +2 -0
- package/engine-examples/crash/math/crash-61.tsv +2 -0
- package/engine-examples/crash/math/crash-62.tsv +2 -0
- package/engine-examples/crash/math/crash-63.tsv +2 -0
- package/engine-examples/crash/math/crash-64.tsv +2 -0
- package/engine-examples/crash/math/gen.mjs +31 -0
- package/engine-examples/crash/math/manifest.json +1 -0
- package/engine-examples/dice/AGENTS.md +3 -0
- package/engine-examples/dice/README.md +25 -0
- package/engine-examples/dice/bundle/assets.json +1 -0
- package/engine-examples/dice/bundle/game.css +17 -0
- package/engine-examples/dice/bundle/game.js +61 -0
- package/engine-examples/dice/bundle/hbtest.json +4 -0
- package/engine-examples/dice/bundle/index.html +34 -0
- package/engine-examples/dice/math/dice.tsv +100 -0
- package/engine-examples/dice/math/manifest.json +2925 -0
- package/engine-examples/keno/AGENTS.md +3 -0
- package/engine-examples/keno/README.md +11 -0
- package/engine-examples/keno/bundle/assets.json +1 -0
- package/engine-examples/keno/bundle/game.css +14 -0
- package/engine-examples/keno/bundle/game.js +86 -0
- package/engine-examples/keno/bundle/hbtest.json +4 -0
- package/engine-examples/keno/bundle/i18n.json +342 -0
- package/engine-examples/keno/bundle/index.html +20 -0
- package/engine-examples/keno/bundle/model.json +1 -0
- package/engine-examples/keno/math/gen.mjs +35 -0
- package/engine-examples/keno/math/keno-picks-1.tsv +2 -0
- package/engine-examples/keno/math/keno-picks-10.tsv +11 -0
- package/engine-examples/keno/math/keno-picks-2.tsv +3 -0
- package/engine-examples/keno/math/keno-picks-3.tsv +4 -0
- package/engine-examples/keno/math/keno-picks-4.tsv +5 -0
- package/engine-examples/keno/math/keno-picks-5.tsv +6 -0
- package/engine-examples/keno/math/keno-picks-6.tsv +7 -0
- package/engine-examples/keno/math/keno-picks-7.tsv +8 -0
- package/engine-examples/keno/math/keno-picks-8.tsv +9 -0
- package/engine-examples/keno/math/keno-picks-9.tsv +10 -0
- package/engine-examples/keno/math/manifest.json +1 -0
- package/engine-examples/keno/math-kit/pack.mjs +165 -0
- package/engine-examples/keno/math-kit/package.json +8 -0
- package/engine-examples/keno/math-kit/slot.mjs +94 -0
- package/engine-examples/keno/math-kit/tumble.mjs +94 -0
- package/engine-examples/lines/AGENTS.md +3 -0
- package/engine-examples/lines/README.md +20 -0
- package/engine-examples/lines/bundle/assets.json +1 -0
- package/engine-examples/lines/bundle/game.css +16 -0
- package/engine-examples/lines/bundle/game.js +125 -0
- package/engine-examples/lines/bundle/hbtest.json +4 -0
- package/engine-examples/lines/bundle/i18n.json +242 -0
- package/engine-examples/lines/bundle/index.html +23 -0
- package/engine-examples/lines/bundle/model.json +1 -0
- package/engine-examples/lines/math/gen.mjs +54 -0
- package/engine-examples/lines/math-kit/pack.mjs +165 -0
- package/engine-examples/lines/math-kit/package.json +8 -0
- package/engine-examples/lines/math-kit/slot.mjs +94 -0
- package/engine-examples/lines/math-kit/tumble.mjs +94 -0
- package/engine-examples/mines/AGENTS.md +3 -0
- package/engine-examples/mines/README.md +13 -0
- package/engine-examples/mines/bundle/assets.json +1 -0
- package/engine-examples/mines/bundle/game.css +12 -0
- package/engine-examples/mines/bundle/game.js +58 -0
- package/engine-examples/mines/bundle/hbtest.json +8 -0
- package/engine-examples/mines/bundle/index.html +16 -0
- package/engine-examples/mines/math/gen.mjs +40 -0
- package/engine-examples/mines/math/manifest.json +1 -0
- package/engine-examples/mines/math/mines-1-1.tsv +2 -0
- package/engine-examples/mines/math/mines-1-2.tsv +2 -0
- package/engine-examples/mines/math/mines-1-22.tsv +2 -0
- package/engine-examples/mines/math/mines-1-23.tsv +2 -0
- package/engine-examples/mines/math/mines-1-24.tsv +2 -0
- package/engine-examples/mines/math/mines-1-3.tsv +2 -0
- package/engine-examples/mines/math/mines-10-1.tsv +2 -0
- package/engine-examples/mines/math/mines-10-10.tsv +2 -0
- package/engine-examples/mines/math/mines-10-11.tsv +2 -0
- package/engine-examples/mines/math/mines-10-12.tsv +2 -0
- package/engine-examples/mines/math/mines-10-13.tsv +2 -0
- package/engine-examples/mines/math/mines-10-14.tsv +2 -0
- package/engine-examples/mines/math/mines-10-15.tsv +2 -0
- package/engine-examples/mines/math/mines-10-2.tsv +2 -0
- package/engine-examples/mines/math/mines-10-3.tsv +2 -0
- package/engine-examples/mines/math/mines-10-4.tsv +2 -0
- package/engine-examples/mines/math/mines-10-5.tsv +2 -0
- package/engine-examples/mines/math/mines-10-6.tsv +2 -0
- package/engine-examples/mines/math/mines-10-7.tsv +2 -0
- package/engine-examples/mines/math/mines-10-8.tsv +2 -0
- package/engine-examples/mines/math/mines-10-9.tsv +2 -0
- package/engine-examples/mines/math/mines-11-1.tsv +2 -0
- package/engine-examples/mines/math/mines-11-10.tsv +2 -0
- package/engine-examples/mines/math/mines-11-11.tsv +2 -0
- package/engine-examples/mines/math/mines-11-12.tsv +2 -0
- package/engine-examples/mines/math/mines-11-13.tsv +2 -0
- package/engine-examples/mines/math/mines-11-14.tsv +2 -0
- package/engine-examples/mines/math/mines-11-2.tsv +2 -0
- package/engine-examples/mines/math/mines-11-3.tsv +2 -0
- package/engine-examples/mines/math/mines-11-4.tsv +2 -0
- package/engine-examples/mines/math/mines-11-5.tsv +2 -0
- package/engine-examples/mines/math/mines-11-6.tsv +2 -0
- package/engine-examples/mines/math/mines-11-7.tsv +2 -0
- package/engine-examples/mines/math/mines-11-8.tsv +2 -0
- package/engine-examples/mines/math/mines-11-9.tsv +2 -0
- package/engine-examples/mines/math/mines-12-1.tsv +2 -0
- package/engine-examples/mines/math/mines-12-10.tsv +2 -0
- package/engine-examples/mines/math/mines-12-11.tsv +2 -0
- package/engine-examples/mines/math/mines-12-12.tsv +2 -0
- package/engine-examples/mines/math/mines-12-13.tsv +2 -0
- package/engine-examples/mines/math/mines-12-2.tsv +2 -0
- package/engine-examples/mines/math/mines-12-3.tsv +2 -0
- package/engine-examples/mines/math/mines-12-4.tsv +2 -0
- package/engine-examples/mines/math/mines-12-5.tsv +2 -0
- package/engine-examples/mines/math/mines-12-6.tsv +2 -0
- package/engine-examples/mines/math/mines-12-7.tsv +2 -0
- package/engine-examples/mines/math/mines-12-8.tsv +2 -0
- package/engine-examples/mines/math/mines-12-9.tsv +2 -0
- package/engine-examples/mines/math/mines-13-1.tsv +2 -0
- package/engine-examples/mines/math/mines-13-10.tsv +2 -0
- package/engine-examples/mines/math/mines-13-11.tsv +2 -0
- package/engine-examples/mines/math/mines-13-12.tsv +2 -0
- package/engine-examples/mines/math/mines-13-2.tsv +2 -0
- package/engine-examples/mines/math/mines-13-3.tsv +2 -0
- package/engine-examples/mines/math/mines-13-4.tsv +2 -0
- package/engine-examples/mines/math/mines-13-5.tsv +2 -0
- package/engine-examples/mines/math/mines-13-6.tsv +2 -0
- package/engine-examples/mines/math/mines-13-7.tsv +2 -0
- package/engine-examples/mines/math/mines-13-8.tsv +2 -0
- package/engine-examples/mines/math/mines-13-9.tsv +2 -0
- package/engine-examples/mines/math/mines-14-1.tsv +2 -0
- package/engine-examples/mines/math/mines-14-10.tsv +2 -0
- package/engine-examples/mines/math/mines-14-11.tsv +2 -0
- package/engine-examples/mines/math/mines-14-2.tsv +2 -0
- package/engine-examples/mines/math/mines-14-3.tsv +2 -0
- package/engine-examples/mines/math/mines-14-4.tsv +2 -0
- package/engine-examples/mines/math/mines-14-5.tsv +2 -0
- package/engine-examples/mines/math/mines-14-6.tsv +2 -0
- package/engine-examples/mines/math/mines-14-7.tsv +2 -0
- package/engine-examples/mines/math/mines-14-8.tsv +2 -0
- package/engine-examples/mines/math/mines-14-9.tsv +2 -0
- package/engine-examples/mines/math/mines-15-1.tsv +2 -0
- package/engine-examples/mines/math/mines-15-10.tsv +2 -0
- package/engine-examples/mines/math/mines-15-2.tsv +2 -0
- package/engine-examples/mines/math/mines-15-3.tsv +2 -0
- package/engine-examples/mines/math/mines-15-4.tsv +2 -0
- package/engine-examples/mines/math/mines-15-5.tsv +2 -0
- package/engine-examples/mines/math/mines-15-6.tsv +2 -0
- package/engine-examples/mines/math/mines-15-7.tsv +2 -0
- package/engine-examples/mines/math/mines-15-8.tsv +2 -0
- package/engine-examples/mines/math/mines-15-9.tsv +2 -0
- package/engine-examples/mines/math/mines-16-1.tsv +2 -0
- package/engine-examples/mines/math/mines-16-2.tsv +2 -0
- package/engine-examples/mines/math/mines-16-3.tsv +2 -0
- package/engine-examples/mines/math/mines-16-4.tsv +2 -0
- package/engine-examples/mines/math/mines-16-5.tsv +2 -0
- package/engine-examples/mines/math/mines-16-6.tsv +2 -0
- package/engine-examples/mines/math/mines-16-7.tsv +2 -0
- package/engine-examples/mines/math/mines-16-8.tsv +2 -0
- package/engine-examples/mines/math/mines-16-9.tsv +2 -0
- package/engine-examples/mines/math/mines-17-1.tsv +2 -0
- package/engine-examples/mines/math/mines-17-2.tsv +2 -0
- package/engine-examples/mines/math/mines-17-3.tsv +2 -0
- package/engine-examples/mines/math/mines-17-4.tsv +2 -0
- package/engine-examples/mines/math/mines-17-5.tsv +2 -0
- package/engine-examples/mines/math/mines-17-6.tsv +2 -0
- package/engine-examples/mines/math/mines-17-7.tsv +2 -0
- package/engine-examples/mines/math/mines-17-8.tsv +2 -0
- package/engine-examples/mines/math/mines-18-1.tsv +2 -0
- package/engine-examples/mines/math/mines-18-2.tsv +2 -0
- package/engine-examples/mines/math/mines-18-3.tsv +2 -0
- package/engine-examples/mines/math/mines-18-4.tsv +2 -0
- package/engine-examples/mines/math/mines-18-5.tsv +2 -0
- package/engine-examples/mines/math/mines-18-6.tsv +2 -0
- package/engine-examples/mines/math/mines-18-7.tsv +2 -0
- package/engine-examples/mines/math/mines-19-1.tsv +2 -0
- package/engine-examples/mines/math/mines-19-2.tsv +2 -0
- package/engine-examples/mines/math/mines-19-3.tsv +2 -0
- package/engine-examples/mines/math/mines-19-4.tsv +2 -0
- package/engine-examples/mines/math/mines-19-5.tsv +2 -0
- package/engine-examples/mines/math/mines-19-6.tsv +2 -0
- package/engine-examples/mines/math/mines-2-1.tsv +2 -0
- package/engine-examples/mines/math/mines-2-19.tsv +2 -0
- package/engine-examples/mines/math/mines-2-2.tsv +2 -0
- package/engine-examples/mines/math/mines-2-20.tsv +2 -0
- package/engine-examples/mines/math/mines-2-21.tsv +2 -0
- package/engine-examples/mines/math/mines-2-22.tsv +2 -0
- package/engine-examples/mines/math/mines-2-23.tsv +2 -0
- package/engine-examples/mines/math/mines-2-3.tsv +2 -0
- package/engine-examples/mines/math/mines-2-4.tsv +2 -0
- package/engine-examples/mines/math/mines-2-5.tsv +2 -0
- package/engine-examples/mines/math/mines-20-1.tsv +2 -0
- package/engine-examples/mines/math/mines-20-2.tsv +2 -0
- package/engine-examples/mines/math/mines-20-3.tsv +2 -0
- package/engine-examples/mines/math/mines-20-4.tsv +2 -0
- package/engine-examples/mines/math/mines-20-5.tsv +2 -0
- package/engine-examples/mines/math/mines-21-1.tsv +2 -0
- package/engine-examples/mines/math/mines-21-2.tsv +2 -0
- package/engine-examples/mines/math/mines-21-3.tsv +2 -0
- package/engine-examples/mines/math/mines-21-4.tsv +2 -0
- package/engine-examples/mines/math/mines-22-1.tsv +2 -0
- package/engine-examples/mines/math/mines-22-2.tsv +2 -0
- package/engine-examples/mines/math/mines-22-3.tsv +2 -0
- package/engine-examples/mines/math/mines-23-1.tsv +2 -0
- package/engine-examples/mines/math/mines-23-2.tsv +2 -0
- package/engine-examples/mines/math/mines-24-1.tsv +2 -0
- package/engine-examples/mines/math/mines-3-1.tsv +2 -0
- package/engine-examples/mines/math/mines-3-17.tsv +2 -0
- package/engine-examples/mines/math/mines-3-18.tsv +2 -0
- package/engine-examples/mines/math/mines-3-19.tsv +2 -0
- package/engine-examples/mines/math/mines-3-2.tsv +2 -0
- package/engine-examples/mines/math/mines-3-20.tsv +2 -0
- package/engine-examples/mines/math/mines-3-21.tsv +2 -0
- package/engine-examples/mines/math/mines-3-22.tsv +2 -0
- package/engine-examples/mines/math/mines-3-3.tsv +2 -0
- package/engine-examples/mines/math/mines-3-4.tsv +2 -0
- package/engine-examples/mines/math/mines-3-5.tsv +2 -0
- package/engine-examples/mines/math/mines-3-6.tsv +2 -0
- package/engine-examples/mines/math/mines-4-1.tsv +2 -0
- package/engine-examples/mines/math/mines-4-13.tsv +2 -0
- package/engine-examples/mines/math/mines-4-14.tsv +2 -0
- package/engine-examples/mines/math/mines-4-15.tsv +2 -0
- package/engine-examples/mines/math/mines-4-16.tsv +2 -0
- package/engine-examples/mines/math/mines-4-17.tsv +2 -0
- package/engine-examples/mines/math/mines-4-18.tsv +2 -0
- package/engine-examples/mines/math/mines-4-19.tsv +2 -0
- package/engine-examples/mines/math/mines-4-2.tsv +2 -0
- package/engine-examples/mines/math/mines-4-20.tsv +2 -0
- package/engine-examples/mines/math/mines-4-21.tsv +2 -0
- package/engine-examples/mines/math/mines-4-3.tsv +2 -0
- package/engine-examples/mines/math/mines-4-4.tsv +2 -0
- package/engine-examples/mines/math/mines-4-5.tsv +2 -0
- package/engine-examples/mines/math/mines-4-6.tsv +2 -0
- package/engine-examples/mines/math/mines-4-7.tsv +2 -0
- package/engine-examples/mines/math/mines-4-8.tsv +2 -0
- package/engine-examples/mines/math/mines-4-9.tsv +2 -0
- package/engine-examples/mines/math/mines-5-1.tsv +2 -0
- package/engine-examples/mines/math/mines-5-10.tsv +2 -0
- package/engine-examples/mines/math/mines-5-11.tsv +2 -0
- package/engine-examples/mines/math/mines-5-12.tsv +2 -0
- package/engine-examples/mines/math/mines-5-13.tsv +2 -0
- package/engine-examples/mines/math/mines-5-14.tsv +2 -0
- package/engine-examples/mines/math/mines-5-15.tsv +2 -0
- package/engine-examples/mines/math/mines-5-16.tsv +2 -0
- package/engine-examples/mines/math/mines-5-17.tsv +2 -0
- package/engine-examples/mines/math/mines-5-18.tsv +2 -0
- package/engine-examples/mines/math/mines-5-19.tsv +2 -0
- package/engine-examples/mines/math/mines-5-2.tsv +2 -0
- package/engine-examples/mines/math/mines-5-20.tsv +2 -0
- package/engine-examples/mines/math/mines-5-3.tsv +2 -0
- package/engine-examples/mines/math/mines-5-4.tsv +2 -0
- package/engine-examples/mines/math/mines-5-5.tsv +2 -0
- package/engine-examples/mines/math/mines-5-6.tsv +2 -0
- package/engine-examples/mines/math/mines-5-7.tsv +2 -0
- package/engine-examples/mines/math/mines-5-8.tsv +2 -0
- package/engine-examples/mines/math/mines-5-9.tsv +2 -0
- package/engine-examples/mines/math/mines-6-1.tsv +2 -0
- package/engine-examples/mines/math/mines-6-10.tsv +2 -0
- package/engine-examples/mines/math/mines-6-11.tsv +2 -0
- package/engine-examples/mines/math/mines-6-12.tsv +2 -0
- package/engine-examples/mines/math/mines-6-13.tsv +2 -0
- package/engine-examples/mines/math/mines-6-14.tsv +2 -0
- package/engine-examples/mines/math/mines-6-15.tsv +2 -0
- package/engine-examples/mines/math/mines-6-16.tsv +2 -0
- package/engine-examples/mines/math/mines-6-17.tsv +2 -0
- package/engine-examples/mines/math/mines-6-18.tsv +2 -0
- package/engine-examples/mines/math/mines-6-19.tsv +2 -0
- package/engine-examples/mines/math/mines-6-2.tsv +2 -0
- package/engine-examples/mines/math/mines-6-3.tsv +2 -0
- package/engine-examples/mines/math/mines-6-4.tsv +2 -0
- package/engine-examples/mines/math/mines-6-5.tsv +2 -0
- package/engine-examples/mines/math/mines-6-6.tsv +2 -0
- package/engine-examples/mines/math/mines-6-7.tsv +2 -0
- package/engine-examples/mines/math/mines-6-8.tsv +2 -0
- package/engine-examples/mines/math/mines-6-9.tsv +2 -0
- package/engine-examples/mines/math/mines-7-1.tsv +2 -0
- package/engine-examples/mines/math/mines-7-10.tsv +2 -0
- package/engine-examples/mines/math/mines-7-11.tsv +2 -0
- package/engine-examples/mines/math/mines-7-12.tsv +2 -0
- package/engine-examples/mines/math/mines-7-13.tsv +2 -0
- package/engine-examples/mines/math/mines-7-14.tsv +2 -0
- package/engine-examples/mines/math/mines-7-15.tsv +2 -0
- package/engine-examples/mines/math/mines-7-16.tsv +2 -0
- package/engine-examples/mines/math/mines-7-17.tsv +2 -0
- package/engine-examples/mines/math/mines-7-18.tsv +2 -0
- package/engine-examples/mines/math/mines-7-2.tsv +2 -0
- package/engine-examples/mines/math/mines-7-3.tsv +2 -0
- package/engine-examples/mines/math/mines-7-4.tsv +2 -0
- package/engine-examples/mines/math/mines-7-5.tsv +2 -0
- package/engine-examples/mines/math/mines-7-6.tsv +2 -0
- package/engine-examples/mines/math/mines-7-7.tsv +2 -0
- package/engine-examples/mines/math/mines-7-8.tsv +2 -0
- package/engine-examples/mines/math/mines-7-9.tsv +2 -0
- package/engine-examples/mines/math/mines-8-1.tsv +2 -0
- package/engine-examples/mines/math/mines-8-10.tsv +2 -0
- package/engine-examples/mines/math/mines-8-11.tsv +2 -0
- package/engine-examples/mines/math/mines-8-12.tsv +2 -0
- package/engine-examples/mines/math/mines-8-13.tsv +2 -0
- package/engine-examples/mines/math/mines-8-14.tsv +2 -0
- package/engine-examples/mines/math/mines-8-15.tsv +2 -0
- package/engine-examples/mines/math/mines-8-16.tsv +2 -0
- package/engine-examples/mines/math/mines-8-17.tsv +2 -0
- package/engine-examples/mines/math/mines-8-2.tsv +2 -0
- package/engine-examples/mines/math/mines-8-3.tsv +2 -0
- package/engine-examples/mines/math/mines-8-4.tsv +2 -0
- package/engine-examples/mines/math/mines-8-5.tsv +2 -0
- package/engine-examples/mines/math/mines-8-6.tsv +2 -0
- package/engine-examples/mines/math/mines-8-7.tsv +2 -0
- package/engine-examples/mines/math/mines-8-8.tsv +2 -0
- package/engine-examples/mines/math/mines-8-9.tsv +2 -0
- package/engine-examples/mines/math/mines-9-1.tsv +2 -0
- package/engine-examples/mines/math/mines-9-10.tsv +2 -0
- package/engine-examples/mines/math/mines-9-11.tsv +2 -0
- package/engine-examples/mines/math/mines-9-12.tsv +2 -0
- package/engine-examples/mines/math/mines-9-13.tsv +2 -0
- package/engine-examples/mines/math/mines-9-14.tsv +2 -0
- package/engine-examples/mines/math/mines-9-15.tsv +2 -0
- package/engine-examples/mines/math/mines-9-16.tsv +2 -0
- package/engine-examples/mines/math/mines-9-2.tsv +2 -0
- package/engine-examples/mines/math/mines-9-3.tsv +2 -0
- package/engine-examples/mines/math/mines-9-4.tsv +2 -0
- package/engine-examples/mines/math/mines-9-5.tsv +2 -0
- package/engine-examples/mines/math/mines-9-6.tsv +2 -0
- package/engine-examples/mines/math/mines-9-7.tsv +2 -0
- package/engine-examples/mines/math/mines-9-8.tsv +2 -0
- package/engine-examples/mines/math/mines-9-9.tsv +2 -0
- package/engine-examples/plinko/AGENTS.md +3 -0
- package/engine-examples/plinko/README.md +9 -0
- package/engine-examples/plinko/bundle/assets.json +1 -0
- package/engine-examples/plinko/bundle/game.css +5 -0
- package/engine-examples/plinko/bundle/game.js +92 -0
- package/engine-examples/plinko/bundle/hbtest.json +4 -0
- package/engine-examples/plinko/bundle/index.html +16 -0
- package/engine-examples/plinko/bundle/model.json +1 -0
- package/engine-examples/plinko/math/gen.mjs +40 -0
- package/engine-examples/plinko/math/manifest.json +1 -0
- package/engine-examples/plinko/math/plinko-12-high.tsv +13 -0
- package/engine-examples/plinko/math/plinko-12-low.tsv +13 -0
- package/engine-examples/plinko/math/plinko-12-medium.tsv +13 -0
- package/engine-examples/plinko/math/plinko-16-high.tsv +17 -0
- package/engine-examples/plinko/math/plinko-16-low.tsv +17 -0
- package/engine-examples/plinko/math/plinko-16-medium.tsv +17 -0
- package/engine-examples/plinko/math/plinko-8-high.tsv +9 -0
- package/engine-examples/plinko/math/plinko-8-low.tsv +9 -0
- package/engine-examples/plinko/math/plinko-8-medium.tsv +9 -0
- package/engine-examples/plinko/math-kit/pack.mjs +165 -0
- package/engine-examples/plinko/math-kit/package.json +8 -0
- package/engine-examples/plinko/math-kit/slot.mjs +94 -0
- package/engine-examples/plinko/math-kit/tumble.mjs +94 -0
- package/engine-examples/slot/AGENTS.md +3 -0
- package/engine-examples/slot/README.md +26 -0
- package/engine-examples/slot/bundle/assets.json +1 -0
- package/engine-examples/slot/bundle/game.css +19 -0
- package/engine-examples/slot/bundle/game.js +42 -0
- package/engine-examples/slot/bundle/hbtest.json +4 -0
- package/engine-examples/slot/bundle/index.html +23 -0
- package/engine-examples/slot/math/gen.mjs +79 -0
- package/engine-examples/slot/math/manifest.json +1 -0
- package/engine-examples/slot/math/slot.tsv +110592 -0
- package/engine-examples/tower/AGENTS.md +3 -0
- package/engine-examples/tower/README.md +21 -0
- package/engine-examples/tower/bundle/assets.json +1 -0
- package/engine-examples/tower/bundle/game.css +8 -0
- package/engine-examples/tower/bundle/game.js +37 -0
- package/engine-examples/tower/bundle/hbtest.json +5 -0
- package/engine-examples/tower/bundle/index.html +16 -0
- package/engine-examples/tower/math/floor.tsv +4 -0
- package/engine-examples/tower/math/manifest.json +61 -0
- package/engine-examples/tumble/AGENTS.md +3 -0
- package/engine-examples/tumble/README.md +18 -0
- package/engine-examples/tumble/bundle/assets.json +1 -0
- package/engine-examples/tumble/bundle/game.css +13 -0
- package/engine-examples/tumble/bundle/game.js +119 -0
- package/engine-examples/tumble/bundle/hbtest.json +4 -0
- package/engine-examples/tumble/bundle/i18n.json +122 -0
- package/engine-examples/tumble/bundle/index.html +20 -0
- package/engine-examples/tumble/bundle/model.json +1 -0
- package/engine-examples/tumble/math/gen.mjs +38 -0
- package/engine-examples/tumble/math-kit/pack.mjs +165 -0
- package/engine-examples/tumble/math-kit/package.json +8 -0
- package/engine-examples/tumble/math-kit/slot.mjs +94 -0
- package/engine-examples/tumble/math-kit/tumble.mjs +94 -0
- package/engine-examples/wheel/README.md +14 -0
- package/engine-examples/wheel/bundle/assets.json +1 -0
- package/engine-examples/wheel/bundle/game.css +7 -0
- package/engine-examples/wheel/bundle/game.js +51 -0
- package/engine-examples/wheel/bundle/hbtest.json +4 -0
- package/engine-examples/wheel/bundle/index.html +19 -0
- package/engine-examples/wheel/math/high.tsv +24 -0
- package/engine-examples/wheel/math/low.tsv +24 -0
- package/engine-examples/wheel/math/manifest.json +48 -0
- package/engine-examples/wheel/math/medium.tsv +24 -0
- package/engine-math/pack.mjs +165 -0
- package/engine-math/package.json +1 -0
- package/engine-math/slot.mjs +94 -0
- package/engine-math/tumble.mjs +94 -0
- package/engine-mcp/package.json +1 -0
- package/engine-mcp/server.mjs +151 -0
- package/engine-sdk/GUIDE.md +855 -0
- package/engine-sdk/assets.js +92 -0
- package/engine-sdk/autoplay.js +82 -0
- package/engine-sdk/bet-field.js +391 -0
- package/engine-sdk/kit/fiat-coins.js +51 -0
- package/engine-sdk/kit/numeric-input.js +116 -0
- package/engine-sdk/kit/wallet-format.js +423 -0
- package/engine-sdk/marks.js +22 -0
- package/engine-sdk/messages.js +289 -0
- package/engine-sdk/money.js +89 -0
- package/engine-sdk/package.json +1 -0
- package/engine-sdk/protocol.js +263 -0
- package/engine-sdk/sdk.d.ts +138 -0
- package/engine-sdk/sdk.js +330 -0
- package/engine-sdk/stake.js +68 -0
- package/engine-sdk/ui.d.ts +36 -0
- package/engine-sdk/ui.js +340 -0
- package/engine-shell/core/faults.js +127 -0
- package/engine-shell/core/rgs.js +193 -0
- package/engine-shell/core/router.js +917 -0
- package/engine-shell/host/boot.js +408 -0
- package/engine-shell/host/engine-v1.js +438 -0
- package/engine-shell/host/fair.js +285 -0
- package/engine-shell/host/fonts/SOURCE.json +11 -0
- package/engine-shell/host/fonts/figtree-400.woff2 +0 -0
- package/engine-shell/host/fonts/figtree-500.woff2 +0 -0
- package/engine-shell/host/fonts/figtree-600.woff2 +0 -0
- package/engine-shell/host/fonts/red-hat-display-700.woff2 +0 -0
- package/engine-shell/host/index.html +230 -0
- package/engine-shell/host/page.js +809 -0
- package/engine-shell/host/sandbox-panel.js +681 -0
- package/engine-shell/host/sandbox-scenarios.js +554 -0
- package/engine-shell/host/site-bridge.js +87 -0
- package/engine-shell/host/strings.js +916 -0
- package/engine-shell/package.json +1 -0
- package/engine-shell/verifiers/badcat/coin.tsv +2 -0
- package/engine-shell/verifiers/badcat/dice-2.tsv +11 -0
- package/engine-shell/verifiers/badcat/dice-5.tsv +26 -0
- package/engine-shell/verifiers/badcat/dice-9.tsv +46 -0
- package/engine-shell/verifiers/badcat/manifest.json +3344 -0
- package/engine-shell/verifiers/badcat/rps.tsv +3 -0
- package/engine-shell/verifiers/badcat/triple.tsv +66 -0
- package/engine-shell/verifiers/engine-verify.js +358 -0
- package/engine-shell/verifiers/package.json +5 -0
- package/engine-shell/verifiers/parity/manifest.json +27 -0
- package/engine-shell/verifiers/parity/wide.tsv +5 -0
- package/engine-shell/verifiers/parity-vectors.json +244 -0
- package/engine-shell/verifiers/vectors.json +100 -0
- package/package.json +10 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# For agents
|
|
2
|
+
|
|
3
|
+
This is a House Engine game (Housebets). Read the guide first: `engine_guide` (MCP) or `engine-sdk/GUIDE.md`. Then `hbengine verify`, `hbengine dev`, `hbengine upload` (or the `engine_*` tools). The math is `math/`, the frontend `bundle/`; never compute money or outcomes in the frontend.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Keno — exact hypergeometric weights
|
|
2
|
+
|
|
3
|
+
40 numbers, 10 drawn, 1 to 10 picks: ten modes (`picks-1` … `picks-10`),
|
|
4
|
+
one `draw` bet each. With n picks, k hits have weight
|
|
5
|
+
C(n, k) · C(40 − n, 10 − k), exact. From half the picks up each extra hit
|
|
6
|
+
pays four times the last, up to 1,000×; the first is solved for 99% and every
|
|
7
|
+
multiplier is rounded down to 0.01×, so the board shows exactly what pays
|
|
8
|
+
(98.6%–99.0%). The player's picks choose the mode; which numbers show as
|
|
9
|
+
drawn is cosmetic, always exactly the drawn number of hits.
|
|
10
|
+
|
|
11
|
+
node math/gen.mjs && npx hbengine verify .
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"groups": {"boot": {"files": ["index.html", "game.js", "game.css", "model.json", "i18n.json"]}}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
body { margin: 0; background: #08141a; }
|
|
2
|
+
.keno { container-type: inline-size; display: flex; flex-direction: column; align-items: center; gap: 12px; width: 100%; padding: 14px 12px; box-sizing: border-box; font-family: 'Figtree', system-ui, sans-serif; }
|
|
3
|
+
.board { --c: min(58px, (100cqi - 24px - 7 * 6px) / 8); display: grid; grid-template-columns: repeat(8, var(--c)); gap: 6px; }
|
|
4
|
+
.board button { height: var(--c); border: 0; border-radius: 8px; background: #0D2A38; color: #8F96A8; font: 700 calc(var(--c) * .32)/1 'Red Hat Display', system-ui, sans-serif; cursor: pointer; transition: background 120ms; }
|
|
5
|
+
.board button[aria-pressed="true"] { background: #1b4a5c; color: #F9F9FB; box-shadow: inset 0 0 0 2px #5cf6f6; }
|
|
6
|
+
.board button.drawn { background: #26323a; color: #F9F9FB; }
|
|
7
|
+
.board button.hit { background: #7d5410; color: #FDDC73; box-shadow: inset 0 0 0 2px #FDDC73; }
|
|
8
|
+
.board button:disabled { cursor: default; }
|
|
9
|
+
.row { display: flex; gap: 8px; }
|
|
10
|
+
.row button { height: 34px; padding: 0 14px; border: 0; border-radius: 8px; background: rgba(9, 102, 125, .15); color: #8F96A8; font: 600 13px/1 'Figtree', system-ui, sans-serif; cursor: pointer; }
|
|
11
|
+
.row button:hover { color: #F9F9FB; }
|
|
12
|
+
.pays { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; max-width: 100%; }
|
|
13
|
+
.pays span { padding: 4px 8px; border-radius: 6px; background: #0b1f28; color: #8F96A8; font: 600 12px/16px 'Red Hat Display', system-ui, sans-serif; font-variant-numeric: tabular-nums; }
|
|
14
|
+
.pays span.on { background: #7d5410; color: #FDDC73; }
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Keno: 40 numbers, 10 drawn. The panel is the engine's (engine-sdk/ui.js);
|
|
2
|
+
// the player's picks choose the mode (picks-1 … picks-10). The server draws
|
|
3
|
+
// how many hit; which numbers show as drawn is cosmetic (from the round's
|
|
4
|
+
// nonce), always exactly that many of the picks.
|
|
5
|
+
import { mount } from '/engine-sdk/ui.js';
|
|
6
|
+
|
|
7
|
+
const model = await (await fetch('./model.json')).json();
|
|
8
|
+
// The page's own words in the player's language (bundle/i18n.json, English otherwise).
|
|
9
|
+
const I18N = await (await fetch('./i18n.json')).json();
|
|
10
|
+
let W = I18N.en;
|
|
11
|
+
const t = (k, v = {}) => W[k].replace(/\{(\w+)\}/g, (_, x) => v[x]);
|
|
12
|
+
const boardEl = document.getElementById('board'), paysEl = document.getElementById('pays');
|
|
13
|
+
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
14
|
+
let picks = [3, 11, 19, 27, 35]; // five to start with: a bet works at once
|
|
15
|
+
let busy = false, game;
|
|
16
|
+
|
|
17
|
+
const cells = Array.from({ length: model.balls }, (_, i) => {
|
|
18
|
+
const b = document.createElement('button');
|
|
19
|
+
b.type = 'button';
|
|
20
|
+
b.textContent = String(i + 1);
|
|
21
|
+
b.onclick = () => {
|
|
22
|
+
if (busy) return;
|
|
23
|
+
picks = picks.includes(i) ? picks.filter((x) => x !== i) : picks.length < 10 ? [...picks, i] : picks;
|
|
24
|
+
sync();
|
|
25
|
+
};
|
|
26
|
+
boardEl.append(b);
|
|
27
|
+
return b;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function paint(drawn = [], hits = -1) {
|
|
31
|
+
cells.forEach((b, i) => {
|
|
32
|
+
b.setAttribute('aria-pressed', String(picks.includes(i)));
|
|
33
|
+
b.classList.toggle('drawn', drawn.includes(i) && !picks.includes(i));
|
|
34
|
+
b.classList.toggle('hit', drawn.includes(i) && picks.includes(i));
|
|
35
|
+
});
|
|
36
|
+
const pays = model.pays[picks.length] || [];
|
|
37
|
+
paysEl.replaceChildren(...pays.map((bp, k) => Object.assign(document.createElement('span'), { textContent: `${k}: ${bp / 10000}×`, className: k === hits ? 'on' : '' })).filter((_, k) => pays[k] > 0 || k === hits));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The picks are the mode; at least one pick.
|
|
41
|
+
function sync() {
|
|
42
|
+
if (!picks.length) picks = [Math.floor(Math.random() * model.balls)];
|
|
43
|
+
if (game && game.mode !== `picks-${picks.length}`) game.mode = `picks-${picks.length}`;
|
|
44
|
+
paint();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Which numbers show as drawn: k of the picks and the rest from the others, shuffled by the nonce.
|
|
48
|
+
function drawn(k, seed) {
|
|
49
|
+
let s = (seed >>> 0) || 1;
|
|
50
|
+
const rnd = (n) => { s ^= s << 13; s ^= s >>> 17; s ^= s << 5; return (s >>> 0) % n; };
|
|
51
|
+
const shuffle = (a) => { for (let i = a.length - 1; i > 0; i--) { const j = rnd(i + 1); [a[i], a[j]] = [a[j], a[i]]; } return a; };
|
|
52
|
+
const others = shuffle([...Array(model.balls).keys()].filter((i) => !picks.includes(i)));
|
|
53
|
+
return shuffle([...shuffle([...picks]).slice(0, k), ...others.slice(0, model.drawn - k)]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
document.getElementById('random').onclick = () => {
|
|
57
|
+
if (busy) return;
|
|
58
|
+
const n = picks.length || 5, all = [...Array(model.balls).keys()];
|
|
59
|
+
picks = all.sort(() => Math.random() - 0.5).slice(0, n); // visual choice of numbers only
|
|
60
|
+
sync();
|
|
61
|
+
};
|
|
62
|
+
document.getElementById('clear').onclick = () => { if (!busy) { picks = []; sync(); } };
|
|
63
|
+
|
|
64
|
+
game = await mount(document.getElementById('game'), {
|
|
65
|
+
labels: Object.fromEntries(Object.entries(I18N).map(([l, w]) => [l, w.modes])),
|
|
66
|
+
async reveal(round) {
|
|
67
|
+
busy = true;
|
|
68
|
+
const k = round.data[0].k, shown = [];
|
|
69
|
+
for (const i of drawn(k, Number(round.nonce) || 1)) { shown.push(i); paint(shown); await wait(70); }
|
|
70
|
+
paint(shown, k);
|
|
71
|
+
busy = false;
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
document.getElementById('game').addEventListener('select', (e) => {
|
|
75
|
+
// A mode picked in the panel: add or drop picks to match it.
|
|
76
|
+
const n = Number(e.detail.mode.split('-')[1]);
|
|
77
|
+
while (picks.length > n) picks.pop();
|
|
78
|
+
const free = [...Array(model.balls).keys()].filter((i) => !picks.includes(i));
|
|
79
|
+
while (picks.length < n) picks.push(free.splice(Math.floor(Math.random() * free.length), 1)[0]);
|
|
80
|
+
paint();
|
|
81
|
+
});
|
|
82
|
+
sync();
|
|
83
|
+
W = I18N[(game.engine.config.locale || 'en').slice(0, 2)] || I18N.en;
|
|
84
|
+
document.getElementById('random').textContent = t('random');
|
|
85
|
+
document.getElementById('clear').textContent = t('clear');
|
|
86
|
+
boardEl.setAttribute('aria-label', t('pick'));
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
{
|
|
2
|
+
"en": {
|
|
3
|
+
"random": "Random picks",
|
|
4
|
+
"clear": "Clear",
|
|
5
|
+
"pick": "Pick up to 10 numbers",
|
|
6
|
+
"modes": {
|
|
7
|
+
"picks-1": "Picks: 1",
|
|
8
|
+
"picks-2": "Picks: 2",
|
|
9
|
+
"picks-3": "Picks: 3",
|
|
10
|
+
"picks-4": "Picks: 4",
|
|
11
|
+
"picks-5": "Picks: 5",
|
|
12
|
+
"picks-6": "Picks: 6",
|
|
13
|
+
"picks-7": "Picks: 7",
|
|
14
|
+
"picks-8": "Picks: 8",
|
|
15
|
+
"picks-9": "Picks: 9",
|
|
16
|
+
"picks-10": "Picks: 10"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"ar": {
|
|
20
|
+
"random": "اختيار عشوائي",
|
|
21
|
+
"clear": "مسح",
|
|
22
|
+
"pick": "اختر حتى 10 أرقام",
|
|
23
|
+
"modes": {
|
|
24
|
+
"picks-1": "1 أرقام",
|
|
25
|
+
"picks-2": "2 أرقام",
|
|
26
|
+
"picks-3": "3 أرقام",
|
|
27
|
+
"picks-4": "4 أرقام",
|
|
28
|
+
"picks-5": "5 أرقام",
|
|
29
|
+
"picks-6": "6 أرقام",
|
|
30
|
+
"picks-7": "7 أرقام",
|
|
31
|
+
"picks-8": "8 أرقام",
|
|
32
|
+
"picks-9": "9 أرقام",
|
|
33
|
+
"picks-10": "10 أرقام"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"da": {
|
|
37
|
+
"random": "Tilfældige valg",
|
|
38
|
+
"clear": "Ryd",
|
|
39
|
+
"pick": "Vælg op til 10 tal",
|
|
40
|
+
"modes": {
|
|
41
|
+
"picks-1": "1 tal",
|
|
42
|
+
"picks-2": "2 tal",
|
|
43
|
+
"picks-3": "3 tal",
|
|
44
|
+
"picks-4": "4 tal",
|
|
45
|
+
"picks-5": "5 tal",
|
|
46
|
+
"picks-6": "6 tal",
|
|
47
|
+
"picks-7": "7 tal",
|
|
48
|
+
"picks-8": "8 tal",
|
|
49
|
+
"picks-9": "9 tal",
|
|
50
|
+
"picks-10": "10 tal"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"de": {
|
|
54
|
+
"random": "Zufallsauswahl",
|
|
55
|
+
"clear": "Leeren",
|
|
56
|
+
"pick": "Wähle bis zu 10 Zahlen",
|
|
57
|
+
"modes": {
|
|
58
|
+
"picks-1": "1 Zahlen",
|
|
59
|
+
"picks-2": "2 Zahlen",
|
|
60
|
+
"picks-3": "3 Zahlen",
|
|
61
|
+
"picks-4": "4 Zahlen",
|
|
62
|
+
"picks-5": "5 Zahlen",
|
|
63
|
+
"picks-6": "6 Zahlen",
|
|
64
|
+
"picks-7": "7 Zahlen",
|
|
65
|
+
"picks-8": "8 Zahlen",
|
|
66
|
+
"picks-9": "9 Zahlen",
|
|
67
|
+
"picks-10": "10 Zahlen"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"es": {
|
|
71
|
+
"random": "Selección al azar",
|
|
72
|
+
"clear": "Borrar",
|
|
73
|
+
"pick": "Elige hasta 10 números",
|
|
74
|
+
"modes": {
|
|
75
|
+
"picks-1": "1 números",
|
|
76
|
+
"picks-2": "2 números",
|
|
77
|
+
"picks-3": "3 números",
|
|
78
|
+
"picks-4": "4 números",
|
|
79
|
+
"picks-5": "5 números",
|
|
80
|
+
"picks-6": "6 números",
|
|
81
|
+
"picks-7": "7 números",
|
|
82
|
+
"picks-8": "8 números",
|
|
83
|
+
"picks-9": "9 números",
|
|
84
|
+
"picks-10": "10 números"
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"fi": {
|
|
88
|
+
"random": "Satunnaiset valinnat",
|
|
89
|
+
"clear": "Tyhjennä",
|
|
90
|
+
"pick": "Valitse enintään 10 numeroa",
|
|
91
|
+
"modes": {
|
|
92
|
+
"picks-1": "1 numeroa",
|
|
93
|
+
"picks-2": "2 numeroa",
|
|
94
|
+
"picks-3": "3 numeroa",
|
|
95
|
+
"picks-4": "4 numeroa",
|
|
96
|
+
"picks-5": "5 numeroa",
|
|
97
|
+
"picks-6": "6 numeroa",
|
|
98
|
+
"picks-7": "7 numeroa",
|
|
99
|
+
"picks-8": "8 numeroa",
|
|
100
|
+
"picks-9": "9 numeroa",
|
|
101
|
+
"picks-10": "10 numeroa"
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"fr": {
|
|
105
|
+
"random": "Choix au hasard",
|
|
106
|
+
"clear": "Effacer",
|
|
107
|
+
"pick": "Choisissez jusqu'à 10 numéros",
|
|
108
|
+
"modes": {
|
|
109
|
+
"picks-1": "1 numéros",
|
|
110
|
+
"picks-2": "2 numéros",
|
|
111
|
+
"picks-3": "3 numéros",
|
|
112
|
+
"picks-4": "4 numéros",
|
|
113
|
+
"picks-5": "5 numéros",
|
|
114
|
+
"picks-6": "6 numéros",
|
|
115
|
+
"picks-7": "7 numéros",
|
|
116
|
+
"picks-8": "8 numéros",
|
|
117
|
+
"picks-9": "9 numéros",
|
|
118
|
+
"picks-10": "10 numéros"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"hi": {
|
|
122
|
+
"random": "रैंडम चुनाव",
|
|
123
|
+
"clear": "साफ़ करें",
|
|
124
|
+
"pick": "10 तक नंबर चुनें",
|
|
125
|
+
"modes": {
|
|
126
|
+
"picks-1": "1 नंबर",
|
|
127
|
+
"picks-2": "2 नंबर",
|
|
128
|
+
"picks-3": "3 नंबर",
|
|
129
|
+
"picks-4": "4 नंबर",
|
|
130
|
+
"picks-5": "5 नंबर",
|
|
131
|
+
"picks-6": "6 नंबर",
|
|
132
|
+
"picks-7": "7 नंबर",
|
|
133
|
+
"picks-8": "8 नंबर",
|
|
134
|
+
"picks-9": "9 नंबर",
|
|
135
|
+
"picks-10": "10 नंबर"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
"hu": {
|
|
139
|
+
"random": "Véletlen választás",
|
|
140
|
+
"clear": "Törlés",
|
|
141
|
+
"pick": "Válassz legfeljebb 10 számot",
|
|
142
|
+
"modes": {
|
|
143
|
+
"picks-1": "1 szám",
|
|
144
|
+
"picks-2": "2 szám",
|
|
145
|
+
"picks-3": "3 szám",
|
|
146
|
+
"picks-4": "4 szám",
|
|
147
|
+
"picks-5": "5 szám",
|
|
148
|
+
"picks-6": "6 szám",
|
|
149
|
+
"picks-7": "7 szám",
|
|
150
|
+
"picks-8": "8 szám",
|
|
151
|
+
"picks-9": "9 szám",
|
|
152
|
+
"picks-10": "10 szám"
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"id": {
|
|
156
|
+
"random": "Pilih acak",
|
|
157
|
+
"clear": "Hapus",
|
|
158
|
+
"pick": "Pilih hingga 10 angka",
|
|
159
|
+
"modes": {
|
|
160
|
+
"picks-1": "1 angka",
|
|
161
|
+
"picks-2": "2 angka",
|
|
162
|
+
"picks-3": "3 angka",
|
|
163
|
+
"picks-4": "4 angka",
|
|
164
|
+
"picks-5": "5 angka",
|
|
165
|
+
"picks-6": "6 angka",
|
|
166
|
+
"picks-7": "7 angka",
|
|
167
|
+
"picks-8": "8 angka",
|
|
168
|
+
"picks-9": "9 angka",
|
|
169
|
+
"picks-10": "10 angka"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"it": {
|
|
173
|
+
"random": "Scelta casuale",
|
|
174
|
+
"clear": "Cancella",
|
|
175
|
+
"pick": "Scegli fino a 10 numeri",
|
|
176
|
+
"modes": {
|
|
177
|
+
"picks-1": "1 numeri",
|
|
178
|
+
"picks-2": "2 numeri",
|
|
179
|
+
"picks-3": "3 numeri",
|
|
180
|
+
"picks-4": "4 numeri",
|
|
181
|
+
"picks-5": "5 numeri",
|
|
182
|
+
"picks-6": "6 numeri",
|
|
183
|
+
"picks-7": "7 numeri",
|
|
184
|
+
"picks-8": "8 numeri",
|
|
185
|
+
"picks-9": "9 numeri",
|
|
186
|
+
"picks-10": "10 numeri"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"ja": {
|
|
190
|
+
"random": "ランダム選択",
|
|
191
|
+
"clear": "クリア",
|
|
192
|
+
"pick": "数字を最大10個選択",
|
|
193
|
+
"modes": {
|
|
194
|
+
"picks-1": "1個",
|
|
195
|
+
"picks-2": "2個",
|
|
196
|
+
"picks-3": "3個",
|
|
197
|
+
"picks-4": "4個",
|
|
198
|
+
"picks-5": "5個",
|
|
199
|
+
"picks-6": "6個",
|
|
200
|
+
"picks-7": "7個",
|
|
201
|
+
"picks-8": "8個",
|
|
202
|
+
"picks-9": "9個",
|
|
203
|
+
"picks-10": "10個"
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
"ko": {
|
|
207
|
+
"random": "무작위 선택",
|
|
208
|
+
"clear": "지우기",
|
|
209
|
+
"pick": "숫자를 최대 10개 선택",
|
|
210
|
+
"modes": {
|
|
211
|
+
"picks-1": "1개",
|
|
212
|
+
"picks-2": "2개",
|
|
213
|
+
"picks-3": "3개",
|
|
214
|
+
"picks-4": "4개",
|
|
215
|
+
"picks-5": "5개",
|
|
216
|
+
"picks-6": "6개",
|
|
217
|
+
"picks-7": "7개",
|
|
218
|
+
"picks-8": "8개",
|
|
219
|
+
"picks-9": "9개",
|
|
220
|
+
"picks-10": "10개"
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
"pl": {
|
|
224
|
+
"random": "Losowy wybór",
|
|
225
|
+
"clear": "Wyczyść",
|
|
226
|
+
"pick": "Wybierz do 10 liczb",
|
|
227
|
+
"modes": {
|
|
228
|
+
"picks-1": "Liczby: 1",
|
|
229
|
+
"picks-2": "Liczby: 2",
|
|
230
|
+
"picks-3": "Liczby: 3",
|
|
231
|
+
"picks-4": "Liczby: 4",
|
|
232
|
+
"picks-5": "Liczby: 5",
|
|
233
|
+
"picks-6": "Liczby: 6",
|
|
234
|
+
"picks-7": "Liczby: 7",
|
|
235
|
+
"picks-8": "Liczby: 8",
|
|
236
|
+
"picks-9": "Liczby: 9",
|
|
237
|
+
"picks-10": "Liczby: 10"
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
"pt": {
|
|
241
|
+
"random": "Escolha aleatória",
|
|
242
|
+
"clear": "Limpar",
|
|
243
|
+
"pick": "Escolha até 10 números",
|
|
244
|
+
"modes": {
|
|
245
|
+
"picks-1": "1 números",
|
|
246
|
+
"picks-2": "2 números",
|
|
247
|
+
"picks-3": "3 números",
|
|
248
|
+
"picks-4": "4 números",
|
|
249
|
+
"picks-5": "5 números",
|
|
250
|
+
"picks-6": "6 números",
|
|
251
|
+
"picks-7": "7 números",
|
|
252
|
+
"picks-8": "8 números",
|
|
253
|
+
"picks-9": "9 números",
|
|
254
|
+
"picks-10": "10 números"
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"ru": {
|
|
258
|
+
"random": "Случайный выбор",
|
|
259
|
+
"clear": "Очистить",
|
|
260
|
+
"pick": "Выберите до 10 чисел",
|
|
261
|
+
"modes": {
|
|
262
|
+
"picks-1": "Чисел: 1",
|
|
263
|
+
"picks-2": "Чисел: 2",
|
|
264
|
+
"picks-3": "Чисел: 3",
|
|
265
|
+
"picks-4": "Чисел: 4",
|
|
266
|
+
"picks-5": "Чисел: 5",
|
|
267
|
+
"picks-6": "Чисел: 6",
|
|
268
|
+
"picks-7": "Чисел: 7",
|
|
269
|
+
"picks-8": "Чисел: 8",
|
|
270
|
+
"picks-9": "Чисел: 9",
|
|
271
|
+
"picks-10": "Чисел: 10"
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
"th": {
|
|
275
|
+
"random": "สุ่มเลือก",
|
|
276
|
+
"clear": "ล้าง",
|
|
277
|
+
"pick": "เลือกได้สูงสุด 10 ตัวเลข",
|
|
278
|
+
"modes": {
|
|
279
|
+
"picks-1": "1 ตัวเลข",
|
|
280
|
+
"picks-2": "2 ตัวเลข",
|
|
281
|
+
"picks-3": "3 ตัวเลข",
|
|
282
|
+
"picks-4": "4 ตัวเลข",
|
|
283
|
+
"picks-5": "5 ตัวเลข",
|
|
284
|
+
"picks-6": "6 ตัวเลข",
|
|
285
|
+
"picks-7": "7 ตัวเลข",
|
|
286
|
+
"picks-8": "8 ตัวเลข",
|
|
287
|
+
"picks-9": "9 ตัวเลข",
|
|
288
|
+
"picks-10": "10 ตัวเลข"
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"tr": {
|
|
292
|
+
"random": "Rastgele seçim",
|
|
293
|
+
"clear": "Temizle",
|
|
294
|
+
"pick": "En fazla 10 sayı seç",
|
|
295
|
+
"modes": {
|
|
296
|
+
"picks-1": "1 sayı",
|
|
297
|
+
"picks-2": "2 sayı",
|
|
298
|
+
"picks-3": "3 sayı",
|
|
299
|
+
"picks-4": "4 sayı",
|
|
300
|
+
"picks-5": "5 sayı",
|
|
301
|
+
"picks-6": "6 sayı",
|
|
302
|
+
"picks-7": "7 sayı",
|
|
303
|
+
"picks-8": "8 sayı",
|
|
304
|
+
"picks-9": "9 sayı",
|
|
305
|
+
"picks-10": "10 sayı"
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
"vi": {
|
|
309
|
+
"random": "Chọn ngẫu nhiên",
|
|
310
|
+
"clear": "Xóa",
|
|
311
|
+
"pick": "Chọn tối đa 10 số",
|
|
312
|
+
"modes": {
|
|
313
|
+
"picks-1": "1 số",
|
|
314
|
+
"picks-2": "2 số",
|
|
315
|
+
"picks-3": "3 số",
|
|
316
|
+
"picks-4": "4 số",
|
|
317
|
+
"picks-5": "5 số",
|
|
318
|
+
"picks-6": "6 số",
|
|
319
|
+
"picks-7": "7 số",
|
|
320
|
+
"picks-8": "8 số",
|
|
321
|
+
"picks-9": "9 số",
|
|
322
|
+
"picks-10": "10 số"
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
"zh": {
|
|
326
|
+
"random": "随机选择",
|
|
327
|
+
"clear": "清除",
|
|
328
|
+
"pick": "最多选择 10 个号码",
|
|
329
|
+
"modes": {
|
|
330
|
+
"picks-1": "1 个号码",
|
|
331
|
+
"picks-2": "2 个号码",
|
|
332
|
+
"picks-3": "3 个号码",
|
|
333
|
+
"picks-4": "4 个号码",
|
|
334
|
+
"picks-5": "5 个号码",
|
|
335
|
+
"picks-6": "6 个号码",
|
|
336
|
+
"picks-7": "7 个号码",
|
|
337
|
+
"picks-8": "8 个号码",
|
|
338
|
+
"picks-9": "9 个号码",
|
|
339
|
+
"picks-10": "10 个号码"
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
6
|
+
<title>Keno</title>
|
|
7
|
+
<link rel="stylesheet" href="./game.css">
|
|
8
|
+
<script type="module" src="/engine-sdk/bet-field.js"></script>
|
|
9
|
+
<script type="module" src="./game.js"></script>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<hb-game id="game">
|
|
13
|
+
<div slot="zone" class="keno">
|
|
14
|
+
<div class="board" id="board" role="group" aria-label="Pick up to 10 numbers"></div>
|
|
15
|
+
<div class="row"><button type="button" id="random">Random picks</button><button type="button" id="clear">Clear</button></div>
|
|
16
|
+
<div class="pays" id="pays" aria-live="polite"></div>
|
|
17
|
+
</div>
|
|
18
|
+
</hb-game>
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"balls":40,"drawn":10,"pays":{"1":[0,39500],"2":[0,16000,64300],"3":[0,0,53400,213700],"4":[0,0,24200,96900,387700],"5":[0,0,0,79900,319900,1279900],"6":[0,0,0,38500,154000,616000,2464000],"7":[0,0,0,0,131800,527500,2110000,8440100],"8":[0,0,0,0,65900,263700,1055000,4220100,10000000],"9":[0,0,0,0,0,241500,966100,3864400,10000000,10000000],"10":[0,0,0,0,0,123400,493600,1974400,7897700,10000000,10000000]}}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Keno's maths: 40 numbers, 10 drawn, the player picks 1 to 10. With n
|
|
3
|
+
// picks, k hits have weight C(n, k) · C(40 − n, 10 − k) — exact, no
|
|
4
|
+
// simulation. From half the picks up, each extra hit pays GROWTH times the
|
|
5
|
+
// one before, up to CAP; the first multiplier is solved for 99% and every
|
|
6
|
+
// multiplier rounded down to 0.01× so the board shows exactly what pays.
|
|
7
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { dirname, join } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
import { binomial, writePack } from '../math-kit/pack.mjs';
|
|
11
|
+
|
|
12
|
+
const DIR = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const project = join(DIR, '..', 'hbengine.json');
|
|
14
|
+
const GAME = process.argv[2] || (existsSync(project) ? JSON.parse(readFileSync(project, 'utf8')).slug : 'keno');
|
|
15
|
+
const BALLS = 40, DRAWN = 10, RTP = 9900, GROWTH = 4, CAP = 1000;
|
|
16
|
+
|
|
17
|
+
const modes = [], board = {};
|
|
18
|
+
for (let n = 1; n <= 10; n++) {
|
|
19
|
+
const weight = (k) => binomial(n, k) * binomial(BALLS - n, DRAWN - k);
|
|
20
|
+
const total = binomial(BALLS, DRAWN);
|
|
21
|
+
// Hits that pay: from half the picks up (rounded up), at least one.
|
|
22
|
+
const paying = [];
|
|
23
|
+
for (let k = Math.max(1, Math.ceil(n / 2)); k <= n; k++) paying.push(k);
|
|
24
|
+
const p = (k) => Number(weight(k)) / Number(total);
|
|
25
|
+
const shape = (c) => paying.map((k, i) => Math.min(CAP, c * GROWTH ** i));
|
|
26
|
+
let lo = 0, hi = CAP;
|
|
27
|
+
for (let i = 0; i < 200; i++) { const c = (lo + hi) / 2; (shape(c).reduce((s, m, j) => s + m * p(paying[j]), 0) < RTP / 10000 ? (lo = c) : (hi = c)); }
|
|
28
|
+
const pays = Array(n + 1).fill(0);
|
|
29
|
+
shape(lo).forEach((m, j) => { pays[paying[j]] = Math.floor(m * 100) * 100; }); // bp, down to 0.01×
|
|
30
|
+
board[n] = pays;
|
|
31
|
+
modes.push({ id: `picks-${n}`, label: `${n} pick${n > 1 ? 's' : ''}`, bets: [{ id: 'draw', label: 'Draw' }],
|
|
32
|
+
rows: pays.map((m, k) => ({ weight: weight(k), data: { k }, pay: { draw: m } })) });
|
|
33
|
+
}
|
|
34
|
+
writePack(DIR, { game: GAME, rtpBp: RTP, modes });
|
|
35
|
+
writeFileSync(join(DIR, '..', 'bundle', 'model.json'), JSON.stringify({ balls: BALLS, drawn: DRAWN, pays: board }) + '\n');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"format":"house-engine-math/1","game":"keno","rtpBp":9900,"modes":[{"id":"picks-1","label":"1 pick","kind":"table","table":"keno-picks-1.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[1,1]],"multBp":39500}]}]},{"id":"picks-2","label":"2 picks","kind":"table","table":"keno-picks-2.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[1,1]],"multBp":16000},{"outcomes":[[2,2]],"multBp":64300}]}]},{"id":"picks-3","label":"3 picks","kind":"table","table":"keno-picks-3.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[2,2]],"multBp":53400},{"outcomes":[[3,3]],"multBp":213700}]}]},{"id":"picks-4","label":"4 picks","kind":"table","table":"keno-picks-4.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[2,2]],"multBp":24200},{"outcomes":[[3,3]],"multBp":96900},{"outcomes":[[4,4]],"multBp":387700}]}]},{"id":"picks-5","label":"5 picks","kind":"table","table":"keno-picks-5.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[3,3]],"multBp":79900},{"outcomes":[[4,4]],"multBp":319900},{"outcomes":[[5,5]],"multBp":1279900}]}]},{"id":"picks-6","label":"6 picks","kind":"table","table":"keno-picks-6.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[3,3]],"multBp":38500},{"outcomes":[[4,4]],"multBp":154000},{"outcomes":[[5,5]],"multBp":616000},{"outcomes":[[6,6]],"multBp":2464000}]}]},{"id":"picks-7","label":"7 picks","kind":"table","table":"keno-picks-7.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[4,4]],"multBp":131800},{"outcomes":[[5,5]],"multBp":527500},{"outcomes":[[6,6]],"multBp":2110000},{"outcomes":[[7,7]],"multBp":8440100}]}]},{"id":"picks-8","label":"8 picks","kind":"table","table":"keno-picks-8.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[4,4]],"multBp":65900},{"outcomes":[[5,5]],"multBp":263700},{"outcomes":[[6,6]],"multBp":1055000},{"outcomes":[[7,7]],"multBp":4220100},{"outcomes":[[8,8]],"multBp":10000000}]}]},{"id":"picks-9","label":"9 picks","kind":"table","table":"keno-picks-9.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[5,5]],"multBp":241500},{"outcomes":[[6,6]],"multBp":966100},{"outcomes":[[7,7]],"multBp":3864400},{"outcomes":[[8,9]],"multBp":10000000}]}]},{"id":"picks-10","label":"10 picks","kind":"table","table":"keno-picks-10.tsv","bets":[{"id":"draw","label":"Draw","tiers":[{"outcomes":[[5,5]],"multBp":123400},{"outcomes":[[6,6]],"multBp":493600},{"outcomes":[[7,7]],"multBp":1974400},{"outcomes":[[8,8]],"multBp":7897700},{"outcomes":[[9,10]],"multBp":10000000}]}]}]}
|