dsh-blackjack 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -26
- package/blackjack.cordis.yml +10 -0
- package/dist/api.d.ts +27 -3
- package/dist/api.js +43 -3
- package/dist/client/Table.d.ts +10 -2
- package/dist/client/Table.js +39 -36
- package/dist/client/index.d.ts +20 -0
- package/dist/client/index.js +91 -9
- package/dist/client.js +12 -2
- package/dist/commands.d.ts +4 -1
- package/dist/commands.js +165 -80
- package/dist/config.d.ts +2 -0
- package/dist/config.js +5 -0
- package/dist/copy.d.ts +16 -2
- package/dist/copy.js +14 -19
- package/dist/i18n/en.d.ts +110 -0
- package/dist/i18n/en.js +170 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.js +6 -0
- package/dist/i18n/messages.d.ts +412 -0
- package/dist/i18n/messages.js +33 -0
- package/dist/i18n/zh.d.ts +110 -0
- package/dist/i18n/zh.js +168 -0
- package/dist/index.js +9 -2
- package/dist/render.d.ts +3 -3
- package/dist/render.js +19 -31
- package/dist/router.d.ts +16 -3
- package/dist/router.js +12 -11
- package/package.json +2 -1
package/dist/client/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useState, useSyncExternalStore } from 'react';
|
|
3
3
|
import { BlackjackTable, Linkified } from './Table.js';
|
|
4
4
|
import { reduce, rowPlan } from './state.js';
|
|
5
|
+
import { resolveMessages } from '../i18n/index.js';
|
|
5
6
|
/**
|
|
6
7
|
* Client module entry: registers the graphical table into the KEYED
|
|
7
8
|
* `conversation.chat.commandview` slot under `key: 'blackjack'`, so every
|
|
@@ -22,21 +23,94 @@ async function getJson(path, init) {
|
|
|
22
23
|
}
|
|
23
24
|
return body;
|
|
24
25
|
}
|
|
25
|
-
/**
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* 浏览器端解析出当前语言。优先跟 dsh 的客户端 locale 服务走——有它就意味着
|
|
28
|
+
* 图形界面用户完全不用为这个插件单独配置语言,宿主切一次语言,牌桌跟着变。
|
|
29
|
+
*
|
|
30
|
+
* `runtime` 必须是可选的:`ctx.locale` 只在 profile 装了 `dsh-client-locale`
|
|
31
|
+
* 时才存在(见 task-5-locale-api-notes.md 的坑)。这不只是"值可能是
|
|
32
|
+
* undefined"——cordis 的服务读取默认按 inject 语义走:没在这个模块的
|
|
33
|
+
* `inject` 数组里声明、又在整棵 fiber 树里都找不到 provider 的属性,直接
|
|
34
|
+
* 读 `ctx.locale` 会**抛错**,不是安全返回 undefined(读过 cordis 的
|
|
35
|
+
* `reflect.ts` 才确认这点)。所以 `apply()` 里用的是 cordis 公开文档过的
|
|
36
|
+
* `ctx.get('locale')`——"Read a service from the store without the inject
|
|
37
|
+
* requirement...returns the service value, or undefined when not (yet)
|
|
38
|
+
* provided",dsh 生态里读可选服务的标准写法(dsh-credentials、dsh-llm 等
|
|
39
|
+
* 到处都是 `ctx.get(...)`)。这里只是消费 apply() 传下来的结果,退到
|
|
40
|
+
* `navigator.language`。两条路径的默认语言都固定是 `en`——和
|
|
41
|
+
* `i18n/index.ts` 的 fallback 保持一致,不能在这里另开一个"没配置就是中文"
|
|
42
|
+
* 的分支,否则两处 fallback 语义就分裂了。
|
|
43
|
+
*
|
|
44
|
+
* `navigator` 读取要判空:这个函数在 `useSyncExternalStore` 的 `getSnapshot`
|
|
45
|
+
* 里被调用,React 在渲染期间执行它——正常生产环境这段代码只跑在浏览器
|
|
46
|
+
* client bundle 里(`build.client.mjs` 的 `platform: 'browser'`),但
|
|
47
|
+
* `@deepseek-ai/dsh-client-locale` 自己的产物(`lib/client.js`)留了一段
|
|
48
|
+
* 注释,说他们的 node e2e 在启动 client tree 时,Node 全局的 `navigator`
|
|
49
|
+
* 会存在、但报的是跑测试那台机器自己的语言,不是要测的浏览器语言——他们判的
|
|
50
|
+
* 是 `window`,不是 `navigator`。这里没有 `window` 可判(这段代码不依赖它),
|
|
51
|
+
* 但同一个教训适用:只要有任何一条路径可能在没有真实浏览器 `navigator` 的
|
|
52
|
+
* 环境里执行到这一行(该包自己的例子已经证明这种环境真实存在),不判空就是
|
|
53
|
+
* 渲染期间硬崩溃,比"语言猜错"严重得多。
|
|
54
|
+
*/
|
|
55
|
+
function browserFallbackLocale() {
|
|
56
|
+
const lang = typeof navigator === 'object' && navigator !== null ? navigator.language : undefined;
|
|
57
|
+
return typeof lang === 'string' && lang.toLowerCase().startsWith('zh') ? 'zh' : 'en';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* `useSyncExternalStore` 服务端/无 DOM 渲染时的快照。**不摸 `navigator`、
|
|
61
|
+
* 也不摸 `runtime`**——SSR/无浏览器环境里两者都不可信,这里只回退到项目
|
|
62
|
+
* 统一的默认语言 `en`,等真正的客户端渲染接管后 `getSnapshot` 会立刻用
|
|
63
|
+
* 真实值覆盖它,玩家看不到这个占位值。生产环境(`platform: 'browser'`
|
|
64
|
+
* 的 client bundle)永远不会真的调用到这个函数——补它纯粹是为了不让
|
|
65
|
+
* `useSyncExternalStore` 在任何非浏览器渲染路径上因为缺这个参数而报错
|
|
66
|
+
* /退化成不稳定行为。
|
|
67
|
+
*/
|
|
68
|
+
function getServerSnapshot() {
|
|
69
|
+
return 'en';
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* `getSnapshot`:单独导出成一个不依赖 hook 的纯函数,好让"每次调用都重新读
|
|
73
|
+
* `runtime.getSnapshot().active`,而不是只在挂载时读一次就缓存住"这条能被
|
|
74
|
+
* 直接断言——`useSyncExternalStore` 本身的"收到 subscribe 通知后重新渲染"
|
|
75
|
+
* 这条契约是 React 自己保证、经过充分测试的机制,这个包真正可能回归的地方
|
|
76
|
+
* 是这条:`getSnapshot` 有没有老老实实转发到 `runtime`。
|
|
77
|
+
*/
|
|
78
|
+
export function resolveLocaleId(runtime) {
|
|
79
|
+
return runtime ? runtime.getSnapshot().active : browserFallbackLocale();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* `subscribe`:同样单独导出成纯函数,好让"传给 `useSyncExternalStore` 的
|
|
83
|
+
* `subscribe` 真的把 onChange 转发给了 `runtime.subscribe`,而不是悄悄变成
|
|
84
|
+
* 一个什么都不做的空函数"这条能被直接断言——这正是"自动跟随退化成挂载时
|
|
85
|
+
* 生效一次"这个回归的另一半:`getSnapshot` 就算读得对,`subscribe` 不转发的
|
|
86
|
+
* 话 React 永远不会知道要重新调用它。
|
|
87
|
+
*/
|
|
88
|
+
export function subscribeToLocale(runtime, onChange) {
|
|
89
|
+
return runtime ? runtime.subscribe(onChange) : () => { };
|
|
90
|
+
}
|
|
91
|
+
export function useLocaleId(runtime) {
|
|
92
|
+
const subscribe = useCallback((onChange) => subscribeToLocale(runtime, onChange), [runtime]);
|
|
93
|
+
const getSnapshot = useCallback(() => resolveLocaleId(runtime), [runtime]);
|
|
94
|
+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
95
|
+
}
|
|
27
96
|
/**
|
|
28
97
|
* Container: owns data fetching. 牌局以发牌/动作的**返回值**为准,只有玩家点
|
|
29
98
|
* "收起"才清空;余额刷新单独走,绝不碰牌局。0.1.2 之前这里把动作返回值整个
|
|
30
99
|
* 丢掉、再拉一次 /api/state,而那个端点只报进行中的牌局——于是玩家一爆牌,
|
|
31
100
|
* 画面就跳回"当前没有进行中的牌局",从头到尾看不见自己怎么输的。
|
|
32
101
|
*/
|
|
33
|
-
function BlackjackTableContainer({ node }) {
|
|
102
|
+
function BlackjackTableContainer({ node, locale: localeRuntime }) {
|
|
34
103
|
// 这一行渲染什么由子命令决定。keyed 槽按命令名分发,注册 `blackjack` 会顶掉
|
|
35
104
|
// 宿主负责渲染文字的 GenericCommandCard —— 不自己把文字渲染回来,
|
|
36
105
|
// /blackjack exchange 的配对码和 /blackjack agree 的须知就会凭空消失。
|
|
37
106
|
const plan = rowPlan(node);
|
|
107
|
+
const locale = useLocaleId(localeRuntime);
|
|
108
|
+
const m = resolveMessages(locale);
|
|
38
109
|
const [state, setState] = useState(null);
|
|
39
|
-
|
|
110
|
+
// 只存"上一次操作失败了"这个布尔状态,文案在渲染时按当前 m 现算——存字符串
|
|
111
|
+
// 的话,操作失败后紧接着切了语言,错误提示会停在旧语言上,牌桌其它地方都
|
|
112
|
+
// 跟着变了就它不变。
|
|
113
|
+
const [hasActionError, setHasActionError] = useState(false);
|
|
40
114
|
/** 整份同步:挂载时,以及动作失败后状态存疑时。 */
|
|
41
115
|
const sync = useCallback(() => {
|
|
42
116
|
getJson('/blackjack/api/state')
|
|
@@ -60,14 +134,14 @@ function BlackjackTableContainer({ node }) {
|
|
|
60
134
|
body: JSON.stringify(body),
|
|
61
135
|
})
|
|
62
136
|
.then((round) => {
|
|
63
|
-
|
|
137
|
+
setHasActionError(false);
|
|
64
138
|
setState((s) => (s ? reduce(s, { type: 'round', round }) : s));
|
|
65
139
|
refreshMe();
|
|
66
140
|
})
|
|
67
141
|
.catch(() => {
|
|
68
142
|
// 失败(含 404 "no active round")后牌局状态存疑,整份重同步,
|
|
69
143
|
// 免得动作栏停在一个已经不存在的牌局上。
|
|
70
|
-
|
|
144
|
+
setHasActionError(true);
|
|
71
145
|
sync();
|
|
72
146
|
});
|
|
73
147
|
}, [refreshMe, sync]);
|
|
@@ -81,12 +155,20 @@ function BlackjackTableContainer({ node }) {
|
|
|
81
155
|
return notice;
|
|
82
156
|
if (state === null)
|
|
83
157
|
return notice;
|
|
84
|
-
return (_jsxs("div", { children: [notice, _jsx(BlackjackTable, { state: state, onAction: onAction, onDeal: onDeal, onDismiss: onDismiss, error:
|
|
158
|
+
return (_jsxs("div", { children: [notice, _jsx(BlackjackTable, { state: state, m: m, onAction: onAction, onDeal: onDeal, onDismiss: onDismiss, error: hasActionError ? m.actionFailedNotice() : undefined })] }));
|
|
85
159
|
}
|
|
86
160
|
export function apply(ctx) {
|
|
87
161
|
ctx.slots.inject('conversation.chat.commandview', () => ctx.slots.register({
|
|
88
162
|
name: 'conversation.chat.commandview',
|
|
89
163
|
key: 'blackjack',
|
|
90
164
|
inject: () => ({}),
|
|
91
|
-
},
|
|
165
|
+
}, (props) => (
|
|
166
|
+
// `ctx.get('locale', false)` 而不是 `ctx.locale`:见上面 useLocaleId 的
|
|
167
|
+
// 注释——'locale' 没进这个模块的 inject 数组,直接属性读在没装
|
|
168
|
+
// dsh-client-locale 的 profile 里会抛错而不是给 undefined。`strict: false`
|
|
169
|
+
// 是因为这里只是"有就用、没有就退到浏览器语言",不需要 provider 必须处于
|
|
170
|
+
// active 状态这条更严格的默认语义。放在这个包装组件里逐次读(而不是在
|
|
171
|
+
// `apply()` 里读一次存起来),是为了不去赌 dsh-client-locale 一定比这个
|
|
172
|
+
// 插件先激活——晚激活的话,下一次这一行渲染时就能读到它。
|
|
173
|
+
_jsx(BlackjackTableContainer, { ...props, locale: ctx.get('locale', false) }))));
|
|
92
174
|
}
|
package/dist/client.js
CHANGED
|
@@ -3,7 +3,7 @@ window.__ModuleLoader__.load({
|
|
|
3
3
|
factory: (require) => {
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
|
-
"use strict";var
|
|
6
|
+
"use strict";var v=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var X=(e,n)=>{for(var t in n)v(e,t,{get:n[t],enumerable:!0})},W=(e,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of J(n))!U.call(e,o)&&o!==t&&v(e,o,{get:()=>n[o],enumerable:!(i=q(n,o))||i.enumerable});return e};var z=e=>W(v({},"__esModule",{value:!0}),e);var pe={};X(pe,{apply:()=>ge,inject:()=>de,resolveLocaleId:()=>A,subscribeToLocale:()=>R,useLocaleId:()=>M});module.exports=z(pe);var u=require("react");var H=require("react");function w(e,n){return e.mode==="free"?n.freeStakeLine(e.betChips):n.raiseStakeLine(e.betChips)}function P(e,n){let t=e.payoutChips??0,i=e.betChips;return e.hands.length>0&&e.hands.every(o=>o.outcome==="push")?e.mode==="free"?n.freePush():n.raisePush(i):t>0?e.mode==="free"?n.freeWin(t):n.raiseWin(t,i):e.mode==="free"?n.freeLose():n.raiseLose(i)}var a=require("react/jsx-runtime"),Y={S:"\u2660",H:"\u2665",D:"\u2666",C:"\u2663"},O=new Set(["H","D"]),S=e=>e.toLocaleString("en-US"),Q=`
|
|
7
7
|
.bj-table { --bj-felt: #0f3d2e; --bj-line: rgba(255,255,255,.18); font-size: 14px; }
|
|
8
8
|
.bj-hand { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin: 4px 0; }
|
|
9
9
|
.bj-card {
|
|
@@ -38,7 +38,17 @@ window.__ModuleLoader__.load({
|
|
|
38
38
|
color: #c0392b; border: 1px solid rgba(192,57,43,.4); border-radius: 6px;
|
|
39
39
|
padding: 4px 8px; margin-bottom: 8px;
|
|
40
40
|
}
|
|
41
|
-
`;function
|
|
41
|
+
`;function L({text:e}){let n=e.split(/(https?:\/\/[^\s,。))]+)/g);return(0,a.jsx)(a.Fragment,{children:n.map((t,i)=>/^https?:\/\//.test(t)?(0,a.jsx)("a",{href:t,target:"_blank",rel:"noreferrer noopener",children:t},i):t)})}function I({card:e,m:n}){if("hidden"in e)return(0,a.jsx)("div",{className:"bj-card bj-card-back","aria-label":n.hiddenCardLabel()});let t=Y[e.suit]??e.suit,i=O.has(e.suit)?"bj-card-red":"bj-card-black";return(0,a.jsx)("div",{className:`bj-card ${i}`,children:`${e.rank}${t}`})}function _({hand:e,label:n,m:t}){return(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"bj-meta",children:[n,t.totalInParens(e.total,e.soft),e.doubled?t.doubled():""]}),(0,a.jsx)("div",{className:"bj-hand",children:e.cards.map((i,o)=>(0,a.jsx)(I,{card:i,m:t},o))})]})}function K({dealer:e,m:n}){return(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"bj-meta",children:[n.tableDealerLabel(),e.total!==void 0?n.totalInParens(e.total,!1):""]}),(0,a.jsx)("div",{className:"bj-hand",children:e.cards.map((t,i)=>(0,a.jsx)(I,{card:t,m:n},i))})]})}function Z({m:e}){return(0,a.jsx)("div",{className:"bj-table",children:(0,a.jsx)("div",{style:{whiteSpace:"pre-wrap"},children:e.consentText()})})}function ee({me:e,m:n}){let t=e.exchangeThresholdChips-e.chips;return(0,a.jsxs)("div",{className:"bj-meta",children:[n.tableBalanceHeader(e.chips,e.freeHandsRemaining),e.points>0?n.tablePointsSuffix(e.points):"",e.exchangedChips>0?n.tableExchangedSuffix(e.exchangedChips):"",(0,a.jsx)("div",{className:"bj-note",children:t<=0?n.tableExchangeThresholdReached(e.exchangeThresholdChips):n.tableExchangeThresholdShort(t,e.exchangeThresholdChips)}),e.exchangedChips>0?(0,a.jsx)("div",{className:"bj-note",children:n.tableExchangedQuotaNote(e.exchangedChips)}):null,e.poolEmpty?(0,a.jsx)("div",{children:n.tablePoolEmptyNotice()}):null,e.sponsorText?(0,a.jsx)("div",{children:e.sponsorText}):null]})}function ne({round:e,m:n}){return(0,a.jsxs)("div",{className:"bj-meta",children:[e.phase==="settled"?P(e,n):w(e,n),e.pointsGranted?(0,a.jsx)("div",{children:n.pointsGrantedNotice(e.pointsGranted)}):null]})}function te(e,n){return e==="double"||e==="split"?n:e==="insure"?Math.ceil(n/2):0}function ae({round:e,me:n,onAction:t,m:i}){if(e.actions.length===0)return null;let o=n?.chips??0,d=i.tableActionLabels;return(0,a.jsx)("div",{className:"bj-actions",children:e.actions.map(c=>{let l=te(c,e.betChips),h=l>o;return(0,a.jsxs)("button",{type:"button",disabled:h,title:h?i.actionShortfallHint(l):void 0,onClick:()=>t(c),children:[d[c]??c,l>0?i.tableCostSuffix(l):""]},c)})})}function ie(e,n,t){return!Number.isInteger(e)||e<1?t.invalidBetAmount():e>n.maxChips?t.betAmountExceedsCap(n.maxChips):e>n.balanceChips?t.betAmountExceedsBalance():null}function oe({me:e,onDeal:n,freeLabel:t,m:i}){let o=e?.freeHandsRemaining??0,d=e?[e.baseBetChips,e.baseBetChips*2]:[];return(0,a.jsxs)("div",{className:"bj-actions",children:[(0,a.jsxs)("button",{type:"button",disabled:o<=0,onClick:()=>n(),children:[t,e?i.dealButtonFreeHandsSuffix(o):""]}),d.map(c=>(0,a.jsxs)("button",{type:"button",disabled:(e?.chips??0)<c,onClick:()=>n(c),children:[S(c)," CHIP"]},c))]})}function se({me:e,onDeal:n,m:t}){let i=e.maxRaiseBetChips,[o,d]=(0,H.useState)(!1),[c,l]=(0,H.useState)("");if(i===void 0)return null;let h=Number(c),g=c.trim()===""?t.betAmountMissing():ie(h,{balanceChips:e.chips,maxChips:i},t);return(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"bj-actions",children:(0,a.jsx)("button",{type:"button",onClick:()=>d(!o),children:t.customBetToggle()})}),o?(0,a.jsxs)("div",{className:"bj-custom",children:[(0,a.jsx)("input",{type:"number",min:1,max:i,value:c,onChange:x=>l(x.target.value),"aria-label":t.customBetToggle()}),(0,a.jsx)("button",{type:"button",disabled:g!==null,onClick:()=>n(h),children:t.customBetSubmit()}),(0,a.jsx)("span",{className:"bj-hint",children:g??t.customBetRange(i)})]}):null]})}function re({me:e,onDeal:n,m:t}){let i=e?.freeHandsRemaining??0,o=e?.baseBetChips??0,d=e?[o,o*2]:[],c=e?d.some(l=>e.chips>=l):!1;return(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"bj-meta",children:t.noActiveRoundNotice()}),(0,a.jsxs)("div",{className:"bj-group",children:[(0,a.jsxs)("div",{className:"bj-group-title",children:[t.freeHandsGroupTitle(),i>0?t.freeHandsRemainingToday(i):t.freeHandsExhaustedToday()]}),e?(0,a.jsx)("div",{className:"bj-note",children:t.freeHandExplainer(o,Math.floor(o*1.5))}):null,(0,a.jsx)("div",{className:"bj-actions",children:(0,a.jsx)("button",{type:"button",disabled:i<=0,onClick:()=>n(),children:t.startFreeHandButton()})})]}),e?(0,a.jsxs)("div",{className:"bj-group",children:[(0,a.jsxs)("div",{className:"bj-group-title",children:[t.raiseGroupTitle(),c?"":t.insufficientBalanceSuffix()]}),(0,a.jsx)("div",{className:"bj-note",children:t.raiseExplainer()}),(0,a.jsx)("div",{className:"bj-actions",children:d.map(l=>(0,a.jsxs)("button",{type:"button",disabled:e.chips<l,onClick:()=>n(l),children:[S(l)," CHIP"]},l))}),(0,a.jsx)(se,{me:e,onDeal:n,m:t})]}):null]})}function ce({me:e,onDeal:n,onDismiss:t,m:i}){return(0,a.jsxs)("div",{children:[(0,a.jsx)(oe,{me:e,onDeal:n,freeLabel:i.rematchFreeLabel(),m:i}),(0,a.jsx)("div",{className:"bj-actions",children:(0,a.jsx)("button",{type:"button",onClick:t,children:i.dismissButton()})})]})}function $({state:e,m:n,onAction:t,onDeal:i,onDismiss:o,error:d}){if(!e.consented)return(0,a.jsx)(Z,{m:n});let{me:c,round:l}=e;return(0,a.jsxs)("div",{className:"bj-table",children:[(0,a.jsx)("style",{children:Q}),d?(0,a.jsx)("div",{className:"bj-error",children:d}):null,c?(0,a.jsx)(ee,{me:c,m:n}):null,l?(0,a.jsxs)("div",{children:[l.hands.map((h,g)=>(0,a.jsx)(_,{hand:h,m:n,label:l.hands.length>1?n.tableSplitHandLabel(g+1):n.tableHandLabel()},g)),(0,a.jsx)(K,{dealer:l.dealer,m:n}),(0,a.jsx)(ne,{round:l,m:n}),(0,a.jsx)(ae,{round:l,me:c,onAction:t,m:n}),l.phase==="settled"?(0,a.jsx)(ce,{me:c,onDeal:i,onDismiss:o,m:n}):null]}):(0,a.jsx)(re,{me:c,onDeal:i,m:n})]})}function f(e,n){switch(n.type){case"synced":return{consented:n.payload.consented,me:n.payload.me,round:n.payload.round};case"round":return{...e,round:n.round};case"meRefreshed":return{...e,me:n.me};case"dismissed":return{...e,round:void 0}}}var le=new Set(["","deal"]);function T(e){let n=(e.args??"").trim().split(/\s+/)[0]??"",t=le.has(n),i=e.outcome,o=i?.kind==="error";return t?{table:!0,isError:o,...o&&i?.text?{text:i.text}:{}}:{table:!1,isError:o,...i?.text!==void 0?{text:i.text}:{}}}var s=e=>e.toLocaleString("en-US"),E={freeStakeLine:e=>`\u8FD9\u662F\u514D\u8D39\u7684\u4E00\u5C40\uFF1A\u8D62\u4E86\u62FF ${s(e)} CHIP\uFF0C\u8F93\u4E86\u4E0D\u635F\u5931\u4EFB\u4F55\u4E1C\u897F\u3002`,raiseStakeLine:e=>`\u672C\u5C40\u5DF2\u52A0\u6CE8 ${s(e)} CHIP\uFF0C\u4ECE\u4F60\u7684\u4F59\u989D\u91CC\u51FA\u3002`,freeWin:e=>`\u8D62\u4E86\uFF0C\u62FF\u5230 ${s(e)} CHIP\u3002`,freeLose:()=>"\u8FD9\u624B\u8F93\u4E86\u3002\u514D\u8D39\u624B\u4E0D\u635F\u5931\u4EFB\u4F55\u4E1C\u897F\u3002",freePush:()=>"\u5E73\u5C40\u3002\u8FD9\u624B\u4E0D\u635F\u5931\u4E5F\u4E0D\u83B7\u5F97\u3002",raiseWin:(e,n)=>`\u8D62\u4E86\uFF0C\u62FF\u56DE ${s(e)} CHIP\uFF08\u52A0\u6CE8 ${s(n)}\uFF09\u3002`,raiseLose:e=>`\u8FD9\u624B\u8F93\u4E86\uFF0C\u52A0\u6CE8\u7684 ${s(e)} CHIP \u6536\u4E0D\u56DE\u3002`,raisePush:e=>`\u5E73\u5C40\u3002\u52A0\u6CE8\u7684 ${s(e)} CHIP \u539F\u6837\u9000\u56DE\u3002`,handLabel:()=>"\u4F60\u7684\u724C\uFF1A",splitHandLabel:e=>`\u4F60\u7684\u7B2C ${e} \u624B\uFF1A`,dealerLabel:()=>"\u5E84\u5BB6\uFF1A",totalInParens:(e,n)=>`\uFF08${n?"\u8F6F":""}${e}\uFF09`,doubled:()=>" [\u53CC\u500D]",actionsPrefix:()=>"\u53EF\u9009\uFF1A",actionLabels:{hit:"/bj-hit \u8981\u724C",stand:"/bj-stand \u505C\u724C",double:"/bj-double \u53CC\u500D",split:"/bj-split \u5206\u724C",insure:"/bj-insure \u4E70\u4FDD\u9669",decline:"/bj-decline \u4E0D\u4E70\u4FDD\u9669"},actionsSeparator:()=>"\u3000",balanceLine:(e,n)=>`\u4F59\u989D\uFF1A${s(e)} CHIP\u3000\u5DF2\u5151\u6362\u989D\u5EA6\uFF1A${s(n)} CHIP`,freeHandsLine:(e,n)=>`\u4ECA\u65E5\u5269\u4F59\u514D\u8D39\u624B\uFF1A${e}\u3000\u8D5B\u5B63\uFF1A${n}`,thresholdLine:e=>`\u5151\u6362\u95E8\u69DB\uFF1A${s(e)} CHIP\uFF08\u8FBE\u6807\u540E\u53EF\u7528 /blackjack exchange \u5151\u6362\uFF09`,pointsLine:e=>`\u79EF\u5206\uFF1A${s(e)}`,poolEmptyNotice:()=>"\u63D0\u793A\uFF1A\u672C\u671F\u5956\u6C60\u5DF2\u53D1\u5B8C\uFF0C\u73B0\u5728\u8D62\u724C\u5C06\u53D1\u653E\u79EF\u5206\u3002",pointsGrantedNotice:e=>`\u672C\u671F\u5956\u6C60\u5DF2\u53D1\u5B8C\uFF0C\u6539\u4E3A\u53D1\u653E ${s(e)} \u79EF\u5206\u3002`,chipValidityNotice:()=>"\uFF08\u8D5B\u5B63\u7ED3\u675F\u65F6\uFF0C\u672A\u8FBE\u5151\u6362\u95E8\u69DB\u7684 CHIP \u4F1A\u6298\u7B97\u4E3A\u79EF\u5206\u5E76\u56DE\u6536\uFF1B\u8FBE\u6807\u7684\u7ED3\u8F6C\uFF09",consentText:()=>["\u3010\u9996\u6B21\u4F7F\u7528\u8BF7\u5148\u9605\u8BFB\u3011","\xB7 \u8FD9\u662F\u793E\u533A\u5F00\u53D1\u8005\u53D1\u5E03\u7684\u7B2C\u4E09\u65B9\u5C0F\u6E38\u620F\uFF0C\u4E0E\u4EFB\u4F55\u6A21\u578B\u5382\u5546\u5747\u65E0\u5173\u8054\uFF0C\u4E0D\u4EE3\u8868\u5176\u7ACB\u573A\u3002","\xB7 \u53C2\u4E0E\u514D\u8D39\uFF1A\u6BCF\u65E5\u6709\u9650\u6B21\u514D\u8D39\u624B\uFF0C\u8F93\u4E86\u4E0D\u6263\u4EFB\u4F55\u4E1C\u897F\uFF0C\u4F60\u81EA\u5DF1\u7684\u5BC6\u94A5\u4E0E\u4F59\u989D\u4E0D\u53D7\u5F71\u54CD\u3002","\xB7 \u8D62\u5F97\u7684 CHIP \u53EA\u80FD\u5728\u672C\u63D2\u4EF6\u5185\u5151\u6362\u4E3A\u6A21\u578B\u989D\u5EA6\u6D88\u8D39\uFF1A\u4E0D\u53EF\u63D0\u73B0\u3001\u4E0D\u53EF\u8F6C\u8BA9\u3001\u4E0D\u53EF\u8F6C\u5165\u4EFB\u4F55\u5382\u5546\u8D26\u6237\u3002","\xB7 \u5956\u52B1\u6709\u8D5B\u5B63\u6709\u6548\u671F\uFF0C\u8D5B\u5B63\u7ED3\u675F\u540E\u3001\u6216\u957F\u671F\u4E0D\u6D3B\u8DC3\u65F6\uFF0C\u672A\u4F7F\u7528\u7684\u90E8\u5206\u6309\u89C4\u5219\u56DE\u6536\u3002","","\u9605\u8BFB\u5E76\u540C\u610F\u4EE5\u4E0A\u5185\u5BB9\u540E\uFF0C\u6267\u884C /blackjack agree confirm \u5F00\u59CB\u3002"].join(`
|
|
42
|
+
`),agreeHint:()=>"\u8BF7\u5148\u9605\u8BFB\u987B\u77E5\u5E76\u6267\u884C /blackjack agree \u540E\u518D\u4F7F\u7528\u3002",noRoundHint:()=>"\u5F53\u524D\u6CA1\u6709\u8FDB\u884C\u4E2D\u7684\u724C\u5C40\uFF0C\u5148\u7528 /blackjack deal \u5F00\u4E00\u5C40\u3002",commandUsage:()=>"agree | deal [\u6CE8\u989D] | exchange [\u6570\u91CF] | reset",actionDescriptions:{hit:"21 \u70B9\uFF1A\u5411\u724C\u684C\u8981\u4E00\u5F20\u724C",stand:"21 \u70B9\uFF1A\u505C\u724C\uFF0C\u8FDB\u5165\u7ED3\u7B97",double:"21 \u70B9\uFF1A\u52A0\u500D\u6CE8\u989D\u5E76\u518D\u8981\u4E00\u5F20\u724C",split:"21 \u70B9\uFF1A\u628A\u4E00\u5BF9\u76F8\u540C\u70B9\u6570\u7684\u724C\u5206\u6210\u4E24\u624B",insure:"21 \u70B9\uFF1A\u5E84\u5BB6\u660E\u724C\u4E3A A \u65F6\u8D2D\u4E70\u4FDD\u9669",decline:"21 \u70B9\uFF1A\u4E0D\u8D2D\u4E70\u4FDD\u9669"},blackjackCommandDescription:()=>"21 \u70B9\u724C\u684C\uFF08\u9700\u5148\u8FDB\u5165\u4F1A\u8BDD\uFF09\uFF1A\u67E5\u770B\u72B6\u6001\u3001\u5F00\u5C40\u3001\u5151\u6362\u989D\u5EA6\u3001\u91CD\u7F6E\u51ED\u8BC1",genericFailure:()=>"\u64CD\u4F5C\u6CA1\u6709\u6210\u529F\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",serviceUnreachable:()=>"\u6682\u65F6\u8FDE\u4E0D\u4E0A\u724C\u684C\u670D\u52A1\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",dailyFreeHandsExhausted:()=>"\u4ECA\u5929\u7684\u514D\u8D39\u624B\u7528\u5B8C\u4E86\uFF0C\u660E\u5929\u518D\u6765\u3002",belowExchangeThreshold:e=>`\u4F59\u989D\u8FD8\u6CA1\u5230\u5151\u6362\u95E8\u69DB\uFF08\u9700\u8981 ${s(e)} CHIP\uFF09\u3002`,insufficientBalance:()=>"\u4F59\u989D\u4E0D\u8DB3\u4EE5\u5B8C\u6210\u8FD9\u4E2A\u52A8\u4F5C\u3002",roundAlreadyInProgress:()=>"\u5DF2\u7ECF\u6709\u4E00\u5C40\u5728\u8FDB\u884C\u4E2D\u3002",githubBindingRequired:()=>"\u8FD9\u4E2A\u94B1\u5305\u7684 GitHub \u7ED1\u5B9A\u72B6\u6001\u6709\u95EE\u9898\uFF0C\u6682\u65F6\u65E0\u6CD5\u76F4\u63A5\u5151\u6362\u3002\u8BF7\u7A0D\u540E\u518D\u8BD5\uFF1B\u5982\u679C\u4E00\u76F4\u8FD9\u6837\uFF0C\u8BF7\u8054\u7CFB\u8FD0\u8425\u8005\u5904\u7406\u3002",seasonCapReached:(e,n)=>`\u8FD9\u7B14\u4F1A\u8D85\u8FC7\u672C\u8D5B\u5B63\u5151\u6362\u603B\u989D\u4E0A\u9650\uFF08\u4E0A\u9650 ${s(e)} CHIP\uFF0C\u672C\u8D5B\u5B63\u5DF2\u5151\u6362 ${s(n)} CHIP\uFF09\u3002`,exchangeUnavailable:()=>"\u5151\u6362\u529F\u80FD\u6682\u65F6\u4E0D\u53EF\u7528\uFF08\u8FD0\u8425\u8005\u90E8\u7F72\u672A\u914D\u7F6E\u5B8C\u6574\uFF09\uFF0C\u724C\u5C40\u672C\u8EAB\u4E0D\u53D7\u5F71\u54CD\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",betAmountAboveLimit:e=>`\u6CE8\u989D\u8D85\u8FC7\u4E0A\u9650\uFF0C\u6700\u591A\u53EF\u4E0B\u6CE8 ${s(e)} CHIP\u3002`,illegalAction:()=>"\u8FD9\u4E2A\u52A8\u4F5C\u73B0\u5728\u4E0D\u53EF\u7528\u4E86\uFF0C\u724C\u5C40\u72B6\u6001\u53EF\u80FD\u5DF2\u7ECF\u53D8\u5316\uFF0C\u8BF7\u7528 /blackjack \u67E5\u770B\u6700\u65B0\u72B6\u6001\u3002",registerRateLimited:()=>"\u5F53\u524D\u7F51\u7EDC\u6CE8\u518C\u6B21\u6570\u8FC7\u591A\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",unknownPlayerToken:()=>"\u8FD9\u53F0\u673A\u5668\u4E0A\u7684\u724C\u684C\u51ED\u8BC1\uFF0C\u670D\u52A1\u7AEF\u5DF2\u7ECF\u4E0D\u8BA4\u8BC6\u4E86\uFF08\u670D\u52A1\u7AEF\u91CD\u7F6E\u8FC7\uFF0C\u6216\u8005 serverUrl \u6539\u6307\u5230\u4E86\u53E6\u4E00\u4E2A\u90E8\u7F72\uFF09\u3002\u8BF7\u5148\u6267\u884C /blackjack reset confirm \u6E05\u6389\u5B83\uFF0C\u518D\u6267\u884C /blackjack agree \u91CD\u65B0\u5F00\u59CB\u3002",agreeWelcome:()=>["\u5DF2\u786E\u8BA4\u987B\u77E5\uFF0C\u6B22\u8FCE\u4E0A\u684C\u3002","/blackjack deal \u5F00\u59CB\u4ECA\u5929\u7684\u514D\u8D39\u624B\uFF0C\u6216 /blackjack deal <\u6CE8\u989D> \u7528\u4F59\u989D\u52A0\u6CE8\u3002"].join(`
|
|
43
|
+
`),invalidBetAmount:()=>"\u6CE8\u989D\u5FC5\u987B\u662F\u6B63\u6574\u6570\u3002",pairingInstructions:(e,n)=>["\u9996\u6B21\u5151\u6362\u8981\u5148\u7ED1\u5B9A GitHub\uFF0C\u53EA\u9700\u505A\u8FD9\u4E00\u6B21\u3002","","\u8BF7\u5728\u6D4F\u89C8\u5668\u91CC\u6253\u5F00\u8FD9\u4E2A\u94FE\u63A5\uFF1A",e,"","\u6253\u5F00\u540E\u70B9\u300C\u7528 GitHub \u7EE7\u7EED\u300D\u6388\u6743\uFF0C\u7136\u540E\u5728\u540C\u4E00\u4E2A\u9875\u9762\u586B\u5199\u8981\u5151\u6362\u7684\u6570\u91CF\u5E76\u63D0\u4EA4\u3002",`\u94FE\u63A5\u7EA6 ${n} \u5206\u949F\u5185\u6709\u6548\uFF1B\u8FC7\u671F\u4E86\u5C31\u518D\u6267\u884C\u4E00\u6B21 /blackjack exchange \u62FF\u4E00\u4E2A\u65B0\u7684\u3002`,"\u7ED1\u5B9A\u5B8C\u6210\u540E\uFF0C\u4EE5\u540E\u76F4\u63A5\u7528 /blackjack exchange <\u6570\u91CF> \u5151\u6362\uFF0C\u4E0D\u7528\u518D\u5F00\u6D4F\u89C8\u5668\u3002"].join(`
|
|
44
|
+
`),exchangeAmountPrompt:(e,n,t)=>[`\u5DF2\u7ED1\u5B9A GitHub \u8D26\u53F7\uFF1A${e}`,`\u5F53\u524D\u4F59\u989D\uFF1A${s(n)} CHIP\u3000\u5151\u6362\u95E8\u69DB\uFF1A${s(t)} CHIP`,"\u8BF7\u7528 /blackjack exchange <\u6570\u91CF> \u6307\u5B9A\u8981\u5151\u6362\u7684 CHIP \u6570\u91CF\u3002"].join(`
|
|
45
|
+
`),invalidExchangeAmount:()=>"\u5151\u6362\u6570\u91CF\u5FC5\u987B\u662F\u6B63\u6574\u6570\u3002",exchangeSuccess:(e,n)=>[`\u5DF2\u5151\u6362 ${s(e)} CHIP\u3002`,`\u7D2F\u8BA1\u5DF2\u5151\u6362\u989D\u5EA6\uFF1A${s(n)} CHIP`,"\u8FD9\u4EFD\u989D\u5EA6\u4F1A\u5728\u4F60\u81EA\u5DF1\u7684\u6A21\u578B\u989D\u5EA6\u8017\u5C3D\u65F6\uFF0C\u81EA\u52A8\u63A5\u7BA1\u90A3\u4E00\u6B21\u5931\u8D25\u7684\u8BF7\u6C42\uFF1B\u5E73\u65F6\u4E0D\u4F1A\u52A8\u7528\uFF0C\u4F60\u4E0D\u9700\u8981\u505A\u4EFB\u4F55\u4E8B\u3002"].join(`
|
|
46
|
+
`),exchangedQuotaNote:(e,n)=>n?`\u5DF2\u5151\u6362\u989D\u5EA6\u4EC5\u9650\u672C\u63D2\u4EF6\u5185\u6D88\u8D39\uFF0C\u4E0D\u53EF\u63D0\u73B0\u3001\u4E0D\u53EF\u8F6C\u8BA9\u3002\u8FDE\u7EED ${e} \u5929\u65E0\u6E38\u620F\u4E14\u65E0\u6D88\u8D39\u7684\u8D26\u6237\uFF0C\u4F59\u989D\u4F1A\u88AB\u56DE\u6536\u8FDB\u5956\u6C60\u3002`:`\u5DF2\u5151\u6362\u989D\u5EA6\u4EC5\u9650\u672C\u63D2\u4EF6\u5185\u6D88\u8D39\uFF0C\u4E0D\u53EF\u63D0\u73B0\u3001\u4E0D\u53EF\u8F6C\u8BA9\u3002\u5B83\u4E0D\u4F1A\u56E0\u8D5B\u5B63\u7ED3\u675F\u800C\u6E05\u96F6\uFF1B\u4F46\u8FDE\u7EED ${e} \u5929\u65E0\u6E38\u620F\u4E14\u65E0\u6D88\u8D39\u7684\u8D26\u6237\uFF0C\u4F59\u989D\u4F1A\u88AB\u56DE\u6536\u8FDB\u5956\u6C60\u3002`,resetConfirmPrompt:()=>"\u8FD9\u4F1A\u6E05\u9664\u672C\u673A\u4FDD\u5B58\u7684\u724C\u684C\u51ED\u8BC1\uFF08\u4E0D\u5F71\u54CD\u670D\u52A1\u7AEF\u8BB0\u5F55\uFF0C\u91CD\u65B0\u914D\u5BF9\u5373\u53EF\u627E\u56DE\uFF09\u3002\u786E\u8BA4\u8BF7\u6267\u884C /blackjack reset confirm",resetDone:()=>"\u5DF2\u6E05\u9664\u672C\u673A\u51ED\u8BC1\uFF0C\u53EF\u7528 /blackjack agree \u91CD\u65B0\u5F00\u59CB\u3002",unknownSubcommand:(e,n)=>`\u672A\u77E5\u5B50\u547D\u4EE4\u300C${e}\u300D\u3002\u53EF\u7528\uFF1A${n}`,poolSwitchNotice:()=>"\u5DF2\u5207\u6362\u81F3\u5956\u6C60\u4F59\u989D\u7EE7\u7EED\u672C\u6B21\u8BF7\u6C42\u3002",noCredentialHint:()=>"\u7EED\u547D\u53EA\u5728\u4F60\u81EA\u5DF1\u7684\u6A21\u578B\u989D\u5EA6\u8017\u5C3D\u65F6\u63A5\u7BA1\uFF1B\u5F53\u524D\u662F\u6CA1\u6709\u914D\u7F6E key\uFF0C\u6240\u4EE5\u7528\u4E0D\u5230\u4F60\u5DF2\u5151\u6362\u7684\u989D\u5EA6\u3002",hiddenCardLabel:()=>"\u6697\u724C",tableHandLabel:()=>"\u4F60\u7684\u724C",tableSplitHandLabel:e=>`\u4F60\u7684\u7B2C ${e} \u624B`,tableDealerLabel:()=>"\u5E84\u5BB6",tableActionLabels:{hit:"\u8981\u724C",stand:"\u505C\u724C",double:"\u53CC\u500D",split:"\u5206\u724C",insure:"\u4E70\u4FDD\u9669",decline:"\u4E0D\u4E70\u4FDD\u9669"},tableBalanceHeader:(e,n)=>`\u4F59\u989D\uFF1A${s(e)} CHIP\u3000\u4ECA\u65E5\u5269\u4F59\u514D\u8D39\u624B\uFF1A${n}`,tablePointsSuffix:e=>`\u3000\u79EF\u5206\uFF1A${s(e)}`,tableExchangedSuffix:e=>`\u3000\u5DF2\u5151\u6362\u989D\u5EA6\uFF1A${s(e)} CHIP`,tableExchangeThresholdReached:e=>`\u5DF2\u8FBE\u5151\u6362\u95E8\u69DB\uFF08${s(e)} CHIP\uFF09\xB7 \u7528 /blackjack exchange \u628A CHIP \u6362\u6210\u6A21\u578B\u989D\u5EA6`,tableExchangeThresholdShort:(e,n)=>`\u8FD8\u5DEE ${s(e)} CHIP \u5230\u5151\u6362\u95E8\u69DB\uFF08${s(n)}\uFF09\xB7 \u8FC7\u7EBF\u540E\u53EF\u7528 /blackjack exchange \u6362\u6210\u6A21\u578B\u989D\u5EA6`,tableExchangedQuotaNote:e=>`\u5DF2\u5151\u6362\u7684 ${s(e)} CHIP \u4F1A\u5728\u4F60\u81EA\u5DF1\u7684\u6A21\u578B\u989D\u5EA6\u8017\u5C3D\u65F6\u81EA\u52A8\u63A5\u7BA1\u90A3\u4E00\u6B21\u8BF7\u6C42\uFF0C\u5E73\u65F6\u4E0D\u4F1A\u52A8\u7528\u3002`,tablePoolEmptyNotice:()=>"\uFF08\u672C\u671F\u5956\u6C60\u5DF2\u53D1\u5B8C\uFF0C\u73B0\u5728\u8D62\u724C\u5C06\u53D1\u653E\u79EF\u5206\uFF09",actionShortfallHint:e=>`\u8FD8\u8981\u518D\u51FA ${s(e)} CHIP\uFF0C\u4F59\u989D\u4E0D\u8DB3`,tableCostSuffix:e=>`\uFF08${s(e)}\uFF09`,betAmountMissing:()=>"\u8BF7\u8F93\u5165\u6CE8\u989D\u3002",betAmountExceedsCap:e=>`\u5355\u5C40\u6700\u591A ${s(e)} CHIP\u3002`,betAmountExceedsBalance:()=>"\u4F59\u989D\u4E0D\u8DB3\u4EE5\u4E0B\u8FD9\u4E2A\u6CE8\u3002",customBetToggle:()=>"\u81EA\u5B9A\u4E49\u6CE8\u989D",customBetSubmit:()=>"\u5F00\u59CB",customBetRange:e=>`1 \uFF5E ${s(e)} CHIP`,noActiveRoundNotice:()=>"\u5F53\u524D\u6CA1\u6709\u8FDB\u884C\u4E2D\u7684\u724C\u5C40\u3002",freeHandsGroupTitle:()=>"\u514D\u8D39\u624B",freeHandsRemainingToday:e=>` \xB7 \u4ECA\u65E5\u5269 ${e} \u624B`,freeHandsExhaustedToday:()=>" \xB7 \u4ECA\u65E5\u5DF2\u7528\u5B8C\uFF0C\u660E\u5929\u518D\u6765",freeHandExplainer:(e,n)=>`\u4E0D\u7528\u51FA CHIP\u3002\u8D62\u4E86\u62FF ${s(e)} CHIP\uFF1B\u5934\u4E24\u5F20\u724C\u5C31\u51D1\u6210 21 \u70B9\uFF08A \u914D 10/J/Q/K\uFF09\u62FF ${s(n)}\u3002\u8F93\u4E86\u6216\u5E73\u5C40\u90FD\u4E0D\u635F\u5931\u4EFB\u4F55\u4E1C\u897F\u3002`,startFreeHandButton:()=>"\u5F00\u59CB\u514D\u8D39\u7684\u4E00\u5C40",raiseGroupTitle:()=>"\u7528\u4F59\u989D\u52A0\u6CE8",insufficientBalanceSuffix:()=>" \xB7 \u4F59\u989D\u4E0D\u8DB3",raiseExplainer:()=>"\u52A0\u6CE8\u7684 CHIP \u4ECE\u4F60\u7684\u4F59\u989D\u91CC\u51FA\uFF0C\u8D62\u4E86\u7FFB\u500D\uFF0C\u8F93\u4E86\u6536\u4E0D\u56DE\u3002",rematchFreeLabel:()=>"\u518D\u6765\u4E00\u5C40\uFF08\u514D\u8D39\uFF09",dealButtonFreeHandsSuffix:e=>`\xB7\u5269 ${e} \u624B`,dismissButton:()=>"\u6536\u8D77",actionFailedNotice:()=>"\u4E0A\u4E00\u6B21\u64CD\u4F5C\u6CA1\u6709\u6210\u529F\uFF0C\u5DF2\u4E3A\u4F60\u5237\u65B0\u5230\u6700\u65B0\u72B6\u6001\u3002"};var r=e=>e.toLocaleString("en-US"),N={freeStakeLine:e=>`This hand is free: win and you take ${r(e)} CHIP; lose and you are out nothing.`,raiseStakeLine:e=>`${r(e)} CHIP is committed from your balance for this hand.`,freeWin:e=>`You won ${r(e)} CHIP.`,freeLose:()=>"This hand did not win. A free hand costs you nothing.",freePush:()=>"A tie. Nothing gained, nothing lost.",raiseWin:(e,n)=>`You won \u2014 ${r(e)} CHIP back (${r(n)} committed).`,raiseLose:e=>`This hand lost; the ${r(e)} CHIP you committed is gone.`,raisePush:e=>`A tie. Your ${r(e)} CHIP comes back.`,handLabel:()=>"Your hand: ",splitHandLabel:e=>`Hand ${e}: `,dealerLabel:()=>"Dealer: ",totalInParens:(e,n)=>` (${n?"soft ":""}${e})`,doubled:()=>" [doubled]",actionsPrefix:()=>"Available: ",actionLabels:{hit:"/bj-hit hit",stand:"/bj-stand stand",double:"/bj-double double down",split:"/bj-split split",insure:"/bj-insure buy insurance",decline:"/bj-decline decline insurance"},actionsSeparator:()=>" ",balanceLine:(e,n)=>`Balance: ${r(e)} CHIP Exchanged so far: ${r(n)} CHIP`,freeHandsLine:(e,n)=>`Free hands left today: ${e} Season: ${n}`,thresholdLine:e=>`Exchange threshold: ${r(e)} CHIP (once reached, use /blackjack exchange)`,pointsLine:e=>`Points: ${r(e)}`,poolEmptyNotice:()=>"Note: this season's pool is spent; wins now grant points instead.",pointsGrantedNotice:e=>`This season's pool is spent, so you were granted ${r(e)} points instead.`,chipValidityNotice:()=>"(At season end, CHIP below the exchange threshold converts to points and is reclaimed; CHIP past the threshold carries over.)",consentText:()=>["[Please read before first use]","\xB7 This is a third-party mini-game published by a community developer; it is not affiliated with any model vendor and does not represent any vendor's position.","\xB7 Taking part is free: you get a limited number of free hands each day, losing costs you nothing, and your own API key and balance are unaffected.","\xB7 CHIP you win can only be exchanged, within this plugin, for model API quota to spend: it cannot be withdrawn, cannot be transferred to anyone else, and cannot be moved into any vendor account.","\xB7 Rewards carry a season-limited validity period; whatever is left unused is reclaimed under the rules after the season ends, or after a long stretch of inactivity.","","Once you have read and agree to the above, run /blackjack agree confirm to start."].join(`
|
|
47
|
+
`),agreeHint:()=>"Please read the notice and run /blackjack agree before using this.",noRoundHint:()=>"No hand is in progress right now \u2014 run /blackjack deal to start one.",commandUsage:()=>"agree | deal [amount] | exchange [amount] | reset",actionDescriptions:{hit:"Blackjack: draw one card from the shoe",stand:"Blackjack: stand, ending your turn and moving to settlement",double:"Blackjack: double down \u2014 double your committed CHIP and draw exactly one more card",split:"Blackjack: split a pair of equal-rank cards into two hands",insure:"Blackjack: buy insurance when the dealer shows an Ace",decline:"Blackjack: decline insurance"},blackjackCommandDescription:()=>"Blackjack table (needs an open conversation): status, deal, exchange quota, reset",genericFailure:()=>"That didn't go through \u2014 please try again in a moment.",serviceUnreachable:()=>"Can't reach the table service right now \u2014 please try again shortly.",dailyFreeHandsExhausted:()=>"You're out of free hands for today \u2014 come back tomorrow.",belowExchangeThreshold:e=>`Your balance hasn't reached the exchange threshold yet (needs ${r(e)} CHIP).`,insufficientBalance:()=>"Your balance isn't enough to complete this action.",roundAlreadyInProgress:()=>"A hand is already in progress.",githubBindingRequired:()=>"This wallet's GitHub link looks inconsistent, so a direct exchange isn't possible right now. Please try again later; if it keeps happening, contact the operator.",seasonCapReached:(e,n)=>`This would go over this season's exchange cap (cap ${r(e)} CHIP, already exchanged ${r(n)} CHIP this season).`,exchangeUnavailable:()=>"Exchanging isn't available right now (an operator deployment setting is missing) \u2014 the table itself is unaffected, please try again later.",betAmountAboveLimit:e=>`That amount is over the limit \u2014 the most you can raise is ${r(e)} CHIP.`,illegalAction:()=>"That move isn't available anymore \u2014 the hand's state may have changed. Run /blackjack to see the current state.",registerRateLimited:()=>"Too many registrations from this network right now \u2014 please try again later.",unknownPlayerToken:()=>"The table service no longer recognizes the credential stored on this machine (the server was reset, or serverUrl now points at a different deployment). Run /blackjack reset confirm to clear it, then /blackjack agree to start over.",agreeWelcome:()=>["You have confirmed the notice \u2014 welcome to the table.","Run /blackjack deal to start today's free hand, or /blackjack deal <amount> to raise from your balance."].join(`
|
|
48
|
+
`),invalidBetAmount:()=>"The amount must be a positive integer.",pairingInstructions:(e,n)=>["Linking a GitHub account is required for your first exchange \u2014 this is a one-time step.","","Open this link in your browser:",e,"",'After opening it, click "Continue with GitHub" to authorize, then enter the amount to exchange on the same page and submit.',`The link stays valid for about ${n} ${n===1?"minute":"minutes"}; if it expires, just run /blackjack exchange again for a new one.`,"Once linked, use /blackjack exchange <amount> directly from now on \u2014 no more browser trips needed."].join(`
|
|
49
|
+
`),exchangeAmountPrompt:(e,n,t)=>[`GitHub account linked: ${e}`,`Current balance: ${r(n)} CHIP Exchange threshold: ${r(t)} CHIP`,"Use /blackjack exchange <amount> to specify how much CHIP to exchange."].join(`
|
|
50
|
+
`),invalidExchangeAmount:()=>"The exchange amount must be a positive integer.",exchangeSuccess:(e,n)=>[`You exchanged ${r(e)} CHIP.`,`Total exchanged so far: ${r(n)} CHIP`,"This quota automatically takes over the one request that fails once your own model quota runs out; it isn't touched otherwise, and there's nothing you need to do."].join(`
|
|
51
|
+
`),exchangedQuotaNote:(e,n)=>n?`Exchanged quota is spendable only inside this plugin \u2014 it can't be withdrawn or transferred. An account with ${e} consecutive days of no play and no spending has its balance recycled into the pool.`:`Exchanged quota is spendable only inside this plugin \u2014 it can't be withdrawn or transferred. It doesn't expire at the end of a season; but an account with ${e} consecutive days of no play and no spending has its balance recycled into the pool.`,resetConfirmPrompt:()=>"This clears the table credential saved on this machine (server-side records are unaffected; pairing again will recover it). Confirm with /blackjack reset confirm",resetDone:()=>"Local credential cleared. Run /blackjack agree to start over.",unknownSubcommand:(e,n)=>`Unknown subcommand "${e}". Available: ${n}`,poolSwitchNotice:()=>"Switched to the pool balance to continue this request.",noCredentialHint:()=>"The fallback route only takes over once your own model quota is exhausted; right now no API key is configured, so your exchanged quota can't be used yet.",hiddenCardLabel:()=>"Hidden card",tableHandLabel:()=>"Your hand",tableSplitHandLabel:e=>`Hand ${e}`,tableDealerLabel:()=>"Dealer",tableActionLabels:{hit:"Hit",stand:"Stand",double:"Double down",split:"Split",insure:"Buy insurance",decline:"Decline insurance"},tableBalanceHeader:(e,n)=>`Balance: ${r(e)} CHIP \xB7 Free hands left today: ${n}`,tablePointsSuffix:e=>` \xB7 Points: ${r(e)}`,tableExchangedSuffix:e=>` \xB7 Exchanged so far: ${r(e)} CHIP`,tableExchangeThresholdReached:e=>`You've reached the exchange threshold (${r(e)} CHIP) \u2014 use /blackjack exchange to turn CHIP into model quota`,tableExchangeThresholdShort:(e,n)=>`${r(e)} CHIP short of the exchange threshold (${r(n)}) \u2014 once you cross it, use /blackjack exchange to turn CHIP into model quota`,tableExchangedQuotaNote:e=>`The ${r(e)} CHIP you've exchanged automatically takes over the one request that fails once your own model quota runs out; it isn't touched otherwise.`,tablePoolEmptyNotice:()=>"(This season's pool is spent \u2014 wins now grant points instead)",actionShortfallHint:e=>`${r(e)} more CHIP needed \u2014 balance too low`,tableCostSuffix:e=>` (${r(e)})`,betAmountMissing:()=>"Enter an amount.",betAmountExceedsCap:e=>`The cap for a single hand is ${r(e)} CHIP.`,betAmountExceedsBalance:()=>"Your balance isn't enough for this amount.",customBetToggle:()=>"Custom amount",customBetSubmit:()=>"Start",customBetRange:e=>`1 to ${r(e)} CHIP`,noActiveRoundNotice:()=>"No hand is in progress right now.",freeHandsGroupTitle:()=>"Free hands",freeHandsRemainingToday:e=>` \xB7 ${e} left today`,freeHandsExhaustedToday:()=>" \xB7 used up for today \u2014 come back tomorrow",freeHandExplainer:(e,n)=>`No CHIP required. Win and you take ${r(e)} CHIP; a natural blackjack in the first two cards (an Ace with a 10/J/Q/K) pays ${r(n)}. Lose or tie and you are out nothing.`,startFreeHandButton:()=>"Start a free hand",raiseGroupTitle:()=>"Raise from your balance",insufficientBalanceSuffix:()=>" \xB7 balance too low",raiseExplainer:()=>"The CHIP you raise comes from your balance: win and it doubles, lose and it is gone.",rematchFreeLabel:()=>"Play again (free)",dealButtonFreeHandsSuffix:e=>` \u2014 ${e} left`,dismissButton:()=>"Dismiss",actionFailedNotice:()=>"That didn't go through \u2014 you've been refreshed to the latest state."};function B(e){return e==="zh"?E:N}var m=require("react/jsx-runtime"),de=["slots"];async function j(e,n){let t=await fetch(e,n),i=await t.text(),o=i.length>0?JSON.parse(i):{};if(!t.ok){let d=typeof o?.error=="string"?o.error:`${t.status}`;throw new Error(d)}return o}function ue(){let e=typeof navigator=="object"&&navigator!==null?navigator.language:void 0;return typeof e=="string"&&e.toLowerCase().startsWith("zh")?"zh":"en"}function be(){return"en"}function A(e){return e?e.getSnapshot().active:ue()}function R(e,n){return e?e.subscribe(n):()=>{}}function M(e){let n=(0,u.useCallback)(i=>R(e,i),[e]),t=(0,u.useCallback)(()=>A(e),[e]);return(0,u.useSyncExternalStore)(n,t,be)}function he({node:e,locale:n}){let t=T(e),i=M(n),o=B(i),[d,c]=(0,u.useState)(null),[l,h]=(0,u.useState)(!1),g=(0,u.useCallback)(()=>{j("/blackjack/api/state").then(b=>c(p=>f(p??{consented:!1},{type:"synced",payload:b}))).catch(()=>c({consented:!1}))},[]),x=(0,u.useCallback)(()=>{j("/blackjack/api/state").then(b=>c(p=>p&&f(p,{type:"meRefreshed",me:b.me}))).catch(()=>{})},[]);(0,u.useEffect)(()=>{t.table&&g()},[g,t.table]);let k=(0,u.useCallback)((b,p)=>{j(b,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(p)}).then(G=>{h(!1),c(C=>C&&f(C,{type:"round",round:G})),x()}).catch(()=>{h(!0),g()})},[x,g]),D=(0,u.useCallback)(b=>k("/blackjack/api/deal",b===void 0?{}:{betChips:b}),[k]),V=(0,u.useCallback)(b=>k("/blackjack/api/action",{action:b}),[k]),F=(0,u.useCallback)(()=>c(b=>b&&f(b,{type:"dismissed"})),[]),y=t.text===void 0?null:(0,m.jsx)("div",{style:{whiteSpace:"pre-wrap",marginBottom:"8px",...t.isError?{color:"#c0392b"}:{}},children:(0,m.jsx)(L,{text:t.text})});return!t.table||d===null?y:(0,m.jsxs)("div",{children:[y,(0,m.jsx)($,{state:d,m:o,onAction:V,onDeal:D,onDismiss:F,error:l?o.actionFailedNotice():void 0})]})}function ge(e){e.slots.inject("conversation.chat.commandview",()=>e.slots.register({name:"conversation.chat.commandview",key:"blackjack",inject:()=>({})},n=>(0,m.jsx)(he,{...n,locale:e.get("locale",!1)})))}
|
|
42
52
|
return module.exports;
|
|
43
53
|
}
|
|
44
54
|
});
|
package/dist/commands.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
2
|
import { type Api } from './api.js';
|
|
3
3
|
import type { Identity } from './identity.js';
|
|
4
|
+
import type { Messages } from './i18n/messages.js';
|
|
4
5
|
/**
|
|
5
6
|
* Register the zero-token blackjack table commands. Every handler here runs
|
|
6
7
|
* through `ctx.commands.register`, so its result never enters model history
|
|
@@ -9,9 +10,11 @@ import type { Identity } from './identity.js';
|
|
|
9
10
|
*
|
|
10
11
|
* Handlers must never throw: an uncaught throw settles as `command/done`
|
|
11
12
|
* with `kind:'error'` and writes internal detail into the session log, so
|
|
12
|
-
* every branch below is wrapped to translate failures into
|
|
13
|
+
* every branch below is wrapped to translate failures into `m`'s
|
|
14
|
+
* plain-language copy (never internal status codes, URLs, or stack traces).
|
|
13
15
|
*/
|
|
14
16
|
export declare function registerCommands(ctx: Context, deps: {
|
|
15
17
|
api: Api;
|
|
16
18
|
identity: Identity;
|
|
19
|
+
m: Messages;
|
|
17
20
|
}): void;
|