dsh-codex-subscription 3.0.0-beta.7 → 3.0.0-beta.8

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/lib/client.js CHANGED
@@ -1075,6 +1075,7 @@ window.__ModuleLoader__.load({
1075
1075
  "account/select",
1076
1076
  "account/remove",
1077
1077
  "usage",
1078
+ "usage/accounts",
1078
1079
  "usage/history",
1079
1080
  "usage/profile",
1080
1081
  "diagnostics",
@@ -5477,6 +5478,8 @@ window.__ModuleLoader__.load({
5477
5478
  const IconChevronDownOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular;
5478
5479
  const IconChevronRightOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular;
5479
5480
  const Menu = _deepseek_ai_dsh_client_ui_primitives.Menu;
5481
+ const MenuSurface = _deepseek_ai_dsh_client_ui_primitives.MenuSurface;
5482
+ const MenuGroup = _deepseek_ai_dsh_client_ui_primitives.MenuGroup;
5480
5483
  const Tooltip = _deepseek_ai_dsh_client_ui_primitives.Tooltip;
5481
5484
  const IconChevronLeftOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutlineRegular;
5482
5485
  const IconCloseOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconCloseOutlineRegular;
@@ -6108,7 +6111,13 @@ window.__ModuleLoader__.load({
6108
6111
  resetNoCredit: "没有可用的额度重置。",
6109
6112
  resetAlready: "这次重置请求已处理。",
6110
6113
  resetFailed: "无法使用额度重置。",
6114
+ accountQuotaLeft: "{label}剩余 {value}%",
6115
+ accountQuotaResets: "{value} 重置",
6116
+ accountQuotaLoading: "正在读取额度…",
6117
+ accountQuotaError: "暂时读不到这个账号的额度",
6118
+ accountQuotaNone: "没有额度窗口信息",
6111
6119
  resetRenewLogin: "登录状态已失效,请重新登录。",
6120
+ resetBlocked: "ChatGPT 的网络防护拦截了这次请求(HTTP 403),登录状态没有问题。请稍后再试,或检查网络、代理或 VPN。",
6112
6121
  resetExpired: "本次确认已失效,请重新开始。",
6113
6122
  resetInProgress: "额度重置正在处理中。",
6114
6123
  resetTooEarly: "请等待冷静期结束后再确认。",
@@ -6781,7 +6790,13 @@ window.__ModuleLoader__.load({
6781
6790
  resetNoCredit: "No quota reset is available.",
6782
6791
  resetAlready: "This reset request was already processed.",
6783
6792
  resetFailed: "Could not use the quota reset.",
6793
+ accountQuotaLeft: "{label} {value}% left",
6794
+ accountQuotaResets: "resets {value}",
6795
+ accountQuotaLoading: "Reading quota…",
6796
+ accountQuotaError: "The quota of this account could not be read right now",
6797
+ accountQuotaNone: "No quota window reported",
6784
6798
  resetRenewLogin: "Your sign-in expired. Sign in again.",
6799
+ resetBlocked: "ChatGPT network protection blocked this request (HTTP 403). Your sign-in is fine; try again later or check your network, proxy or VPN.",
6785
6800
  resetExpired: "This confirmation expired. Start again.",
6786
6801
  resetInProgress: "A quota reset is already in progress.",
6787
6802
  resetTooEarly: "Wait for the cooldown before confirming.",
@@ -6987,6 +7002,9 @@ window.__ModuleLoader__.load({
6987
7002
  .codexSubscriptionAccounts{display:flex;flex-direction:column;border-top:1px solid var(--dsw-alias-border-l2)}
6988
7003
  .codexSubscriptionAccount{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:42px;border-bottom:1px solid var(--dsw-alias-border-l2);font-size:13px}
6989
7004
  .codexSubscriptionAccount:last-child{border-bottom:0}
7005
+ .codexSubscriptionAccountMain{display:flex;flex-direction:column;gap:2px;padding:6px 0;min-width:0}
7006
+ .codexSubscriptionAccountQuota{display:flex;flex-wrap:wrap;gap:2px 12px;font-size:12px;color:var(--dsw-alias-text-l2)}
7007
+ .codexSubscriptionAccountQuota[data-state=error]{color:var(--dsw-alias-text-danger,#c0392b)}
6990
7008
  .codexSubscriptionAccount[data-active=true] .codexSubscriptionEmail,.codexSubscriptionAccount[data-active=true]>span{font-weight:600}
6991
7009
  .codexSubscriptionEmail{max-width:100%;overflow:hidden;padding:2px 4px;border:0;border-radius:5px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}
6992
7010
  .codexSubscriptionEmail:hover{background:var(--dsw-alias-interactive-bg-hover)}
@@ -7129,7 +7147,7 @@ window.__ModuleLoader__.load({
7129
7147
  .codexComposerQuotaBar::-webkit-progress-value{background:var(--dsw-alias-label-secondary);border-radius:999px}
7130
7148
  .codexComposerQuotaBar::-moz-progress-bar{background:var(--dsw-alias-label-secondary);border-radius:999px}
7131
7149
  .codexModelSelect{position:relative;min-width:0}
7132
- .codexModelSelectTrigger{display:flex;align-items:center;gap:4px;min-width:0;max-width:min(360px,45cqw);height:28px;padding:0 4px 0 8px;border:0;border-radius:24px;outline:0;background:transparent;color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:500;line-height:20px;cursor:pointer}
7150
+ .codexModelSelectTrigger{display:flex;align-items:center;gap:4px;min-width:0;max-width:min(360px,45cqw);height:28px;padding:0 4px 0 8px;border:0;border-radius:var(--dsw-radius-sm);outline:0;background:transparent;color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:500;line-height:20px;cursor:pointer}
7133
7151
  .codexModelSelectTrigger:hover:not(:disabled),.codexModelSelectTrigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}
7134
7152
  .codexModelSelectTrigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}
7135
7153
  .codexModelSelectTrigger:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}
@@ -7138,34 +7156,32 @@ window.__ModuleLoader__.load({
7138
7156
  .codexModelSelectEffort{flex:none;color:var(--dsw-alias-label-caption)}
7139
7157
  .codexModelSelectChevron{flex:none;color:var(--dsw-alias-label-caption);transition:transform 120ms}
7140
7158
  .codexModelSelectTrigger[aria-expanded=true] .codexModelSelectChevron{transform:rotate(180deg)}
7141
- .codexModelSelectMenu,.codexModelSelectSubmenu{position:absolute;z-index:30;box-sizing:border-box;width:max-content;min-width:min(240px,calc(100vw - 32px));max-width:min(420px,calc(100vw - 32px));max-height:min(360px,calc(100vh - 96px));padding:4px;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-alias-bg-layer-2,#2c2c2e);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);overflow:hidden}
7142
- .codexModelSelectMenu{right:0;bottom:calc(100% + 8px)}
7143
- .codexModelSelectSubmenu{right:calc(100% + 8px);bottom:0;min-width:min(230px,calc(100vw - 32px))}
7144
- /* Keep search outside the scroll viewport; let the model list fit the bounded menu. */
7145
- .codexModelSelectModelMenu{display:flex;flex-direction:column}
7146
- .codexModelSelectCell{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;height:40px;box-sizing:border-box;padding:0 10px;border:0;border-radius:10px;background:transparent;color:inherit;font-size:14px;line-height:22px;text-align:left;cursor:pointer}
7147
- .codexModelSelectCell:hover,.codexModelSelectCell:focus-visible,.codexModelSelectCell[data-open=true]{background:var(--dsw-alias-interactive-bg-hover);outline:0}
7148
- .codexModelSelectCell:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}
7159
+ /* The menu follows DSH's own model picker: one floating surface above the trigger, rows drill into the same surface. */
7160
+ .codexModelSelectMenu{z-index:1100;--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-sizing:border-box;position:fixed;display:flex;flex-direction:column;width:max-content;min-width:min(240px,100vw - 32px);max-width:min(420px,100vw - 32px);max-height:min(360px,100vh - 96px);padding:4px;border:0;box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);overflow:hidden}
7161
+ .codexModelSelectCell{box-sizing:border-box;display:flex;align-items:center;gap:6px;width:auto;min-width:100%;height:34px;padding:0 8px;border:none;border-radius:var(--dsw-radius-md);outline:none;background:transparent;color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px;text-align:left;cursor:pointer}
7162
+ .codexModelSelectCell:hover,.codexModelSelectCell:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}
7149
7163
  .codexModelSelectCellLabel{flex:none;white-space:nowrap}
7150
7164
  .codexModelSelectCellValue{flex:auto;min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary);text-align:right;text-overflow:ellipsis;white-space:nowrap}
7151
- .codexModelSelectCellChevron{flex:none;color:var(--dsw-alias-label-tertiary)}
7152
- .codexModelSelectSearch{display:block;flex-shrink:0;width:100%;box-sizing:border-box;height:32px;margin:0 0 4px;padding:0 10px;border:1px solid var(--dsw-alias-border-l3);border-radius:8px;outline:0;background:transparent;color:inherit;font:inherit;font-size:13px}
7153
- .codexModelSelectSearch:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}
7165
+ .codexModelSelectCellChevron{flex:none;width:12px;height:12px;color:var(--dsw-alias-menu-icon)}
7166
+ .codexModelSelectSearchRow{flex-shrink:0;position:relative;margin:2px 0 3px}
7167
+ .codexModelSelectSearchRow .codexModelSelectSearch{display:flex;height:auto;padding:5px 7px;border:0 solid transparent;border-radius:var(--dsw-radius-md);background:transparent}
7168
+ .codexModelSelectSearchRow .codexModelSelectSearch:focus-within{border-color:transparent}
7169
+ .codexModelSelectSearchRow .codexModelSelectSearch input{padding:0;font-size:12px;line-height:normal}
7170
+ .codexModelSelectSearchRow .codexModelSelectSearch input::placeholder{color:var(--dsw-alias-label-caption)}
7154
7171
  .codexModelSelectGroups{flex:1 1 auto;min-height:0;overflow-y:auto}
7155
- .codexModelSelectGroup+.codexModelSelectGroup{margin-top:4px}
7156
- .codexModelSelectGroupTitle{position:sticky;top:0;z-index:1;padding:5px 8px 3px;background:var(--dsw-alias-bg-layer-2,#2c2c2e);color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}
7157
- .codexModelSelectOption{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;min-height:38px;box-sizing:border-box;padding:6px 8px;border:0;border-radius:10px;outline:0;background:transparent;color:inherit;text-align:left;cursor:pointer}
7172
+ .codexModelSelectGroupTitle{padding:5px 8px 3px;color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}
7173
+ .codexModelSelectOption{box-sizing:border-box;display:flex;align-items:center;gap:6px;width:auto;min-width:100%;min-height:34px;padding:5px 7px;border:none;border-radius:var(--dsw-radius-md);outline:none;background:transparent;color:inherit;text-align:left;cursor:pointer}
7158
7174
  .codexModelSelectOption:hover:not(:disabled),.codexModelSelectOption:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}
7159
7175
  .codexModelSelectOption:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}
7160
- .codexModelSelectOptionCopy{display:flex;flex:1;min-width:0;flex-direction:column}
7161
- .codexModelSelectOptionName{overflow:hidden;color:inherit;font-size:14px;font-weight:500;line-height:20px;text-overflow:ellipsis;white-space:nowrap}
7162
- .codexModelSelectOptionDescription{overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;text-overflow:ellipsis;white-space:nowrap}
7163
- .codexModelSelectCheck{display:grid;place-items:center;flex:0 0 18px;color:var(--dsw-alias-label-primary)}
7164
- .codexModelSelectStatus,.codexModelSelectEmpty{padding:10px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px}
7165
- .codexModelSelectError,.codexModelSelectWarning{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;margin-bottom:4px;padding:7px 8px;border-radius:8px;background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}
7176
+ .codexModelSelectOptionCopy{display:flex;flex:1;flex-direction:column;min-width:0}
7177
+ .codexModelSelectOptionName{overflow:hidden;color:inherit;font-size:13px;font-weight:400;line-height:18px;text-overflow:ellipsis;white-space:nowrap}
7178
+ .codexModelSelectOptionDescription{overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:16px;text-overflow:ellipsis;white-space:nowrap}
7179
+ .codexModelSelectCheck{display:grid;place-items:center;flex:0 0 14px;color:var(--dsw-alias-label-primary)}
7180
+ .codexModelSelectCheck svg{width:14px;height:14px}
7181
+ .codexModelSelectStatus,.codexModelSelectEmpty{padding:8px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}
7182
+ .codexModelSelectError,.codexModelSelectWarning{display:flex;align-items:flex-start;justify-content:space-between;gap:6px;margin-bottom:3px;padding:6px 7px;border-radius:var(--dsw-radius-md);background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);font-size:11px;line-height:16px}
7166
7183
  .codexModelSelectWarning{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label)}
7167
- .codexModelSelectRetry{flex:none;padding:0;border:0;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
7168
- .codexModelSelectMenu{overflow:visible}
7184
+ .codexModelSelectRetry{flex:none;padding:0;border:none;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
7169
7185
  .codexImageTool{display:flex;flex-direction:column;gap:8px;margin:4px 0;color:var(--dsw-alias-label-primary)}
7170
7186
  .codexImageToolRow{display:flex;align-items:center;min-height:24px;gap:8px;font-size:13px;line-height:20px}
7171
7187
  .codexImageToolIcon{display:block;flex-shrink:0;width:16px;height:16px;color:var(--dsw-alias-label-secondary)}
@@ -9205,7 +9221,9 @@ window.__ModuleLoader__.load({
9205
9221
  return `${local[0]}•••${local.at(-1)}@${domain}`;
9206
9222
  };
9207
9223
  const hours$1 = (seconds) => Math.round(seconds / 3600 * 10) / 10;
9208
- const percent = (value) => Number(value).toLocaleString(void 0, { maximumFractionDigits: 1 });
9224
+ /** The language DSH shows its interface in, so dates and numbers match the text around them rather than the OS. */
9225
+ const uiLocale = () => typeof document === "undefined" ? void 0 : document.documentElement.lang || void 0;
9226
+ const percent = (value) => Number(value).toLocaleString(uiLocale(), { maximumFractionDigits: 1 });
9209
9227
  const isApproximateWindow = (seconds, expected) => seconds >= expected * .95 && seconds <= expected * 1.05;
9210
9228
  const windowLabel = (seconds, t) => {
9211
9229
  if (isApproximateWindow(seconds, 18e3)) return t("windowFiveHours");
@@ -9282,7 +9300,7 @@ window.__ModuleLoader__.load({
9282
9300
  }
9283
9301
  //#endregion
9284
9302
  //#region src/version.js
9285
- const PACKAGE_VERSION = "3.0.0-beta.7";
9303
+ const PACKAGE_VERSION = "3.0.0-beta.8";
9286
9304
  //#endregion
9287
9305
  //#region src/client-recovery.js
9288
9306
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
@@ -9510,7 +9528,7 @@ window.__ModuleLoader__.load({
9510
9528
  }
9511
9529
  function shortReset(quota, t) {
9512
9530
  if (!Number.isSafeInteger(quota.resetsAt)) return t("resetUnknown");
9513
- const value = (/* @__PURE__ */ new Date(quota.resetsAt * 1e3)).toLocaleString(void 0, {
9531
+ const value = (/* @__PURE__ */ new Date(quota.resetsAt * 1e3)).toLocaleString(uiLocale(), {
9514
9532
  month: "numeric",
9515
9533
  day: "numeric",
9516
9534
  hour: "2-digit",
@@ -9553,6 +9571,11 @@ window.__ModuleLoader__.load({
9553
9571
  const ForwardRef = /*#__PURE__*/ react.forwardRef(BoltIcon);
9554
9572
  //#endregion
9555
9573
  //#region src/client-model-select.jsx
9574
+ const MEASURE_STYLE = {
9575
+ visibility: "hidden",
9576
+ left: 0,
9577
+ top: 0
9578
+ };
9556
9579
  function CodexModelSelect({ locked, available, directory, load, select, preference, t }) {
9557
9580
  const state = (0, react.useSyncExternalStore)(directory.subscribe, directory.getSnapshot);
9558
9581
  const preferenceSnapshot = usePreferenceSnapshot(preference);
@@ -9560,6 +9583,8 @@ window.__ModuleLoader__.load({
9560
9583
  const [pane, setPane] = (0, react.useState)("root");
9561
9584
  const [query, setQuery] = (0, react.useState)("");
9562
9585
  const rootRef = (0, react.useRef)(null);
9586
+ const menuRef = (0, react.useRef)(null);
9587
+ const [menuPos, setMenuPos] = (0, react.useState)(null);
9563
9588
  const triggerRef = (0, react.useRef)(null);
9564
9589
  const id = (0, react.useId)();
9565
9590
  const choices = (0, react.useMemo)(() => state.groups.flatMap((group) => group.models.map((model) => ({
@@ -9643,7 +9668,7 @@ window.__ModuleLoader__.load({
9643
9668
  (0, react.useEffect)(() => {
9644
9669
  if (!open) return void 0;
9645
9670
  const closeOutside = (event) => {
9646
- if (!rootRef.current?.contains(event.target)) {
9671
+ if (!rootRef.current?.contains(event.target) && !menuRef.current?.contains(event.target)) {
9647
9672
  setOpen(false);
9648
9673
  setPane("root");
9649
9674
  setQuery("");
@@ -9652,6 +9677,39 @@ window.__ModuleLoader__.load({
9652
9677
  document.addEventListener("mousedown", closeOutside);
9653
9678
  return () => document.removeEventListener("mousedown", closeOutside);
9654
9679
  }, [open]);
9680
+ (0, react.useLayoutEffect)(() => {
9681
+ if (!open) {
9682
+ setMenuPos(null);
9683
+ return;
9684
+ }
9685
+ const place = () => {
9686
+ const rect = triggerRef.current?.getBoundingClientRect();
9687
+ if (rect === void 0) return;
9688
+ const margin = 12;
9689
+ const width = menuRef.current?.offsetWidth ?? 0;
9690
+ const height = menuRef.current?.offsetHeight ?? 0;
9691
+ let left = rect.right - width;
9692
+ let top = rect.top - 8 - height;
9693
+ if (width > 0) left = Math.min(Math.max(left, margin), window.innerWidth - width - margin);
9694
+ if (height > 0) top = Math.min(Math.max(top, margin), window.innerHeight - height - margin);
9695
+ setMenuPos({
9696
+ left,
9697
+ top
9698
+ });
9699
+ };
9700
+ place();
9701
+ window.addEventListener("scroll", place, true);
9702
+ window.addEventListener("resize", place);
9703
+ return () => {
9704
+ window.removeEventListener("scroll", place, true);
9705
+ window.removeEventListener("resize", place);
9706
+ };
9707
+ }, [
9708
+ open,
9709
+ pane,
9710
+ state,
9711
+ query
9712
+ ]);
9655
9713
  (0, react.useEffect)(() => {
9656
9714
  if (pane !== "model") setQuery("");
9657
9715
  }, [pane]);
@@ -9725,10 +9783,10 @@ window.__ModuleLoader__.load({
9725
9783
  type: "button",
9726
9784
  role: "menuitem",
9727
9785
  className: "codexModelSelectCell",
9728
- "data-open": pane === target,
9729
- "aria-haspopup": "menu",
9730
- "aria-expanded": pane === target,
9731
- onClick: () => setPane((current) => current === target ? "root" : target),
9786
+ onClick: () => {
9787
+ setQuery("");
9788
+ setPane(target);
9789
+ },
9732
9790
  children: [
9733
9791
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9734
9792
  className: "codexModelSelectCellLabel",
@@ -9741,141 +9799,147 @@ window.__ModuleLoader__.load({
9741
9799
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronRightOutline14, { className: "codexModelSelectCellChevron" })
9742
9800
  ]
9743
9801
  });
9744
- let submenu = null;
9745
- if (pane === "model") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9746
- className: "codexModelSelectSubmenu codexModelSelectModelMenu",
9747
- role: "menu",
9748
- "aria-label": t("modelLabel"),
9749
- children: [
9750
- state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9751
- className: "codexModelSelectStatus",
9752
- children: t("modelsLoading")
9753
- }) : null,
9754
- state.error === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9755
- className: "codexModelSelectError",
9756
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: fill(t("modelFailed"), { value: state.error }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9757
- className: "codexModelSelectRetry",
9758
- type: "button",
9759
- onClick: load,
9760
- children: t("modelRetry")
9761
- })]
9762
- }),
9763
- state.failures.map((failure) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9764
- className: "codexModelSelectWarning",
9765
- children: fill(t("groupFailed"), {
9766
- name: failure.name,
9767
- value: failure.message
9768
- })
9769
- }, failure.id)),
9770
- searchable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
9802
+ const group = (key, label, children) => MenuGroup === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
9803
+ role: "group",
9804
+ "aria-label": label,
9805
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9806
+ className: "codexModelSelectGroupTitle",
9807
+ children: label
9808
+ }), children]
9809
+ }, key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuGroup, {
9810
+ label,
9811
+ children
9812
+ }, key);
9813
+ let content = null;
9814
+ if (pane === "root") content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
9815
+ cell("model", t("modelLabel"), modelLabel),
9816
+ reasoning === void 0 ? null : cell("effort", t("effortLabel"), effortLabel),
9817
+ (speedSupported || ultrafastSupported) && cell("speed", t("speedTitle"), t(speedKey)),
9818
+ verbositySupported && cell("verbosity", t("verbosityTitle"), verbosityLabel)
9819
+ ] });
9820
+ else if (pane === "model") content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
9821
+ searchable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9822
+ className: "codexModelSelectSearchRow",
9823
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Input, {
9771
9824
  className: "codexModelSelectSearch",
9772
- type: "search",
9825
+ type: "text",
9826
+ role: "searchbox",
9773
9827
  value: query,
9774
9828
  autoFocus: true,
9775
9829
  placeholder: t("modelSearch"),
9776
9830
  "aria-label": t("modelSearch"),
9777
9831
  onChange: (event) => setQuery(event.target.value)
9778
- }) : null,
9779
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9780
- className: "codexModelSelectGroups scrollable",
9781
- children: shownGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
9782
- className: "codexModelSelectGroup",
9783
- role: "group",
9784
- "aria-labelledby": `${id}-${group.id}`,
9785
- children: [
9786
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9787
- className: "codexModelSelectGroupTitle",
9788
- id: `${id}-${group.id}`,
9789
- children: group.name
9790
- }),
9791
- group.allHidden === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9792
- className: "codexModelSelectEmpty",
9793
- children: t("modelsHidden")
9794
- }) : null,
9795
- group.models.map((model) => option({
9796
- key: model.id,
9797
- label: model.name,
9798
- description: model.description,
9799
- selected: state.current?.provider === group.id && state.current.model === model.id,
9800
- disabled: busy,
9801
- onClick: () => chooseModel({
9802
- provider: group.id,
9803
- model: model.id
9804
- })
9805
- }))
9806
- ]
9807
- }, group.id))
9808
- }),
9809
- state.status === "ready" && visibleGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9810
- className: "codexModelSelectEmpty",
9811
- children: t(choices.length === 0 ? "modelsEmpty" : "modelsHidden")
9812
- }) : null,
9813
- state.status === "ready" && visibleGroups.length > 0 && shownGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9832
+ })
9833
+ }) : null,
9834
+ state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9835
+ className: "codexModelSelectStatus",
9836
+ children: t("modelsLoading")
9837
+ }) : null,
9838
+ state.error === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9839
+ className: "codexModelSelectError",
9840
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: fill(t("modelFailed"), { value: state.error }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9841
+ className: "codexModelSelectRetry",
9842
+ type: "button",
9843
+ onClick: load,
9844
+ children: t("modelRetry")
9845
+ })]
9846
+ }),
9847
+ state.failures.map((failure) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9848
+ className: "codexModelSelectWarning",
9849
+ children: fill(t("groupFailed"), {
9850
+ name: failure.name,
9851
+ value: failure.message
9852
+ })
9853
+ }, failure.id)),
9854
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9855
+ className: "codexModelSelectGroups scrollable",
9856
+ role: "menu",
9857
+ "aria-label": t("modelLabel"),
9858
+ children: shownGroups.map((entry) => group(entry.id, entry.name, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [entry.allHidden === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9814
9859
  className: "codexModelSelectEmpty",
9815
- children: t("modelNoMatch")
9816
- }) : null
9817
- ]
9818
- });
9819
- else if (pane === "effort") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9820
- className: "codexModelSelectSubmenu",
9821
- role: "menu",
9822
- "aria-label": t("effortLabel"),
9823
- children: effortChoices.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9860
+ children: t("modelsHidden")
9861
+ }) : null, entry.models.map((model) => option({
9862
+ key: model.id,
9863
+ label: model.name,
9864
+ selected: state.current?.provider === entry.id && state.current.model === model.id,
9865
+ disabled: busy,
9866
+ onClick: () => chooseModel({
9867
+ provider: entry.id,
9868
+ model: model.id
9869
+ })
9870
+ }))] })))
9871
+ }),
9872
+ state.status === "ready" && visibleGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9824
9873
  className: "codexModelSelectEmpty",
9825
- children: t("effortsEmpty")
9826
- }) : effortChoices.map((level) => option({
9827
- key: level.key,
9828
- label: level.label,
9829
- description: level.description,
9830
- selected: effectiveEffort === level.effort,
9831
- disabled: busy,
9832
- onClick: () => chooseEffort(level.effort)
9833
- }))
9834
- });
9835
- else if (pane === "speed") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9836
- className: "codexModelSelectSubmenu",
9837
- role: "menu",
9838
- "aria-label": t("speedTitle"),
9839
- children: [
9840
- option({
9841
- key: SPEED_MODE_STANDARD,
9842
- label: t("speedStandard"),
9843
- description: t("speedStandardHint"),
9844
- selected: !fast,
9845
- disabled: !speedWritable,
9846
- onClick: () => chooseSpeed(SPEED_MODE_STANDARD)
9847
- }),
9848
- speedSupported && option({
9849
- key: "fast",
9850
- label: t("speedFast"),
9851
- description: t(state.current?.model === "gpt-6-astra" ? "speedFastAstraHint" : "speedFastHint"),
9852
- selected: fast && !ultrafast,
9853
- disabled: !speedWritable,
9854
- onClick: () => chooseSpeed("fast")
9855
- }),
9856
- ultrafastSupported && option({
9857
- key: "ultrafast",
9858
- label: t("speedUltrafast"),
9859
- description: t("speedUltrafastHint"),
9860
- selected: ultrafast,
9861
- disabled: !speedWritable,
9862
- onClick: () => chooseSpeed("ultrafast")
9863
- })
9864
- ]
9865
- });
9866
- else if (pane === "verbosity") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9867
- className: "codexModelSelectSubmenu",
9868
- role: "menu",
9869
- "aria-label": t("verbosityTitle"),
9870
- children: verbosityItems.map((item) => option({
9871
- key: item.id,
9872
- label: item.label,
9873
- description: item.description,
9874
- selected: preferenceSnapshot.outputVerbosity === item.id,
9875
- disabled: !verbosityWritable,
9876
- onClick: () => chooseVerbosity(item.id)
9877
- }))
9878
- });
9874
+ children: t(choices.length === 0 ? "modelsEmpty" : "modelsHidden")
9875
+ }) : null,
9876
+ state.status === "ready" && visibleGroups.length > 0 && shownGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9877
+ className: "codexModelSelectEmpty",
9878
+ children: t("modelNoMatch")
9879
+ }) : null
9880
+ ] });
9881
+ else if (pane === "effort") content = effortChoices.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9882
+ className: "codexModelSelectEmpty",
9883
+ children: t("effortsEmpty")
9884
+ }) : effortChoices.map((level) => option({
9885
+ key: level.key,
9886
+ label: level.label,
9887
+ description: level.description,
9888
+ selected: effectiveEffort === level.effort,
9889
+ disabled: busy,
9890
+ onClick: () => chooseEffort(level.effort)
9891
+ }));
9892
+ else if (pane === "speed") content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
9893
+ option({
9894
+ key: SPEED_MODE_STANDARD,
9895
+ label: t("speedStandard"),
9896
+ description: t("speedStandardHint"),
9897
+ selected: !fast,
9898
+ disabled: !speedWritable,
9899
+ onClick: () => chooseSpeed(SPEED_MODE_STANDARD)
9900
+ }),
9901
+ speedSupported && option({
9902
+ key: "fast",
9903
+ label: t("speedFast"),
9904
+ description: t(state.current?.model === "gpt-6-astra" ? "speedFastAstraHint" : "speedFastHint"),
9905
+ selected: fast && !ultrafast,
9906
+ disabled: !speedWritable,
9907
+ onClick: () => chooseSpeed("fast")
9908
+ }),
9909
+ ultrafastSupported && option({
9910
+ key: "ultrafast",
9911
+ label: t("speedUltrafast"),
9912
+ description: t("speedUltrafastHint"),
9913
+ selected: ultrafast,
9914
+ disabled: !speedWritable,
9915
+ onClick: () => chooseSpeed("ultrafast")
9916
+ })
9917
+ ] });
9918
+ else if (pane === "verbosity") content = verbosityItems.map((item) => option({
9919
+ key: item.id,
9920
+ label: item.label,
9921
+ description: item.description,
9922
+ selected: preferenceSnapshot.outputVerbosity === item.id,
9923
+ disabled: !verbosityWritable,
9924
+ onClick: () => chooseVerbosity(item.id)
9925
+ }));
9926
+ const menu = open ? (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuSurface ?? "div", {
9927
+ ref: menuRef,
9928
+ id: `${id}-menu`,
9929
+ className: "codexModelSelectMenu",
9930
+ style: menuPos ?? MEASURE_STYLE,
9931
+ role: pane === "model" ? "group" : "menu",
9932
+ "aria-label": t("modelMenuAria"),
9933
+ "aria-busy": state.status === "loading" || busy,
9934
+ onKeyDown: (event) => {
9935
+ if (event.key !== "Escape") return;
9936
+ event.preventDefault();
9937
+ event.stopPropagation();
9938
+ if (pane === "root") close(true);
9939
+ else setPane("root");
9940
+ },
9941
+ children: content
9942
+ }), document.body) : null;
9879
9943
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9880
9944
  className: "codexModelSelect",
9881
9945
  ref: rootRef,
@@ -9911,20 +9975,7 @@ window.__ModuleLoader__.load({
9911
9975
  }),
9912
9976
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDownOutline14, { className: "codexModelSelectChevron" })
9913
9977
  ]
9914
- }), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9915
- className: "codexModelSelectMenu",
9916
- id: `${id}-menu`,
9917
- role: "menu",
9918
- "aria-label": t("modelMenuAria"),
9919
- "aria-busy": state.status === "loading" || busy,
9920
- children: [
9921
- cell("model", t("modelLabel"), modelLabel),
9922
- reasoning === void 0 ? null : cell("effort", t("effortLabel"), effortLabel),
9923
- (speedSupported || ultrafastSupported) && cell("speed", t("speedTitle"), t(speedKey)),
9924
- verbositySupported && cell("verbosity", t("verbosityTitle"), verbosityLabel),
9925
- submenu
9926
- ]
9927
- }) : null]
9978
+ }), menu]
9928
9979
  });
9929
9980
  }
9930
9981
  //#endregion
@@ -12875,7 +12926,7 @@ window.__ModuleLoader__.load({
12875
12926
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: [
12876
12927
  client.name ?? t("remotePhoneUnknown"),
12877
12928
  client.platform,
12878
- client.lastSeenAt ? t("remoteLastSeen").replace("{date}", new Date(client.lastSeenAt).toLocaleString()) : null
12929
+ client.lastSeenAt ? t("remoteLastSeen").replace("{date}", new Date(client.lastSeenAt).toLocaleString(uiLocale())) : null
12879
12930
  ].filter(Boolean).join(" · ") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
12880
12931
  type: "button",
12881
12932
  variant: "outline",
@@ -13768,6 +13819,73 @@ window.__ModuleLoader__.load({
13768
13819
  }
13769
13820
  }
13770
13821
  //#endregion
13822
+ //#region src/client-account-quota.jsx
13823
+ const when = (seconds) => (/* @__PURE__ */ new Date(seconds * 1e3)).toLocaleString(uiLocale(), {
13824
+ month: "numeric",
13825
+ day: "numeric",
13826
+ hour: "2-digit",
13827
+ minute: "2-digit"
13828
+ });
13829
+ /** Quota of every signed-in account (read-only; the active account does not change). */
13830
+ function useAccountQuotas(rpc, ids) {
13831
+ const [entries, setEntries] = (0, react.useState)({});
13832
+ const [busy, setBusy] = (0, react.useState)(false);
13833
+ const request = (0, react.useRef)(0);
13834
+ const key = ids.join(",");
13835
+ const load = (force) => {
13836
+ if (ids.length < 2) {
13837
+ setEntries({});
13838
+ return;
13839
+ }
13840
+ const id = ++request.current;
13841
+ setBusy(true);
13842
+ recoveryCall(rpc, "usage/accounts", { force }).then((value) => {
13843
+ if (request.current === id) setEntries(Object.fromEntries((value?.accounts ?? []).map((entry) => [entry.id, entry])));
13844
+ }).catch(() => {
13845
+ if (request.current === id) setEntries(Object.fromEntries(ids.map((account) => [account, {
13846
+ id: account,
13847
+ error: "Could not read ChatGPT usage"
13848
+ }])));
13849
+ }).finally(() => {
13850
+ if (request.current === id) setBusy(false);
13851
+ });
13852
+ };
13853
+ (0, react.useEffect)(() => {
13854
+ load(false);
13855
+ return () => {
13856
+ request.current += 1;
13857
+ };
13858
+ }, [key]);
13859
+ return {
13860
+ entries,
13861
+ busy,
13862
+ refresh: () => load(true)
13863
+ };
13864
+ }
13865
+ function AccountQuota({ entry, loading, t }) {
13866
+ if (entry === void 0) return loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
13867
+ className: "codexSubscriptionAccountQuota",
13868
+ children: t("accountQuotaLoading")
13869
+ }) : null;
13870
+ if (entry.error !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
13871
+ className: "codexSubscriptionAccountQuota",
13872
+ "data-state": "error",
13873
+ children: entry.error === "ChatGPT sign-in needs to be renewed" ? t("resetRenewLogin") : t("accountQuotaError")
13874
+ });
13875
+ const windows = entry.usage?.rateLimits?.find((limit) => limit.id === "codex")?.windows ?? [];
13876
+ if (windows.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
13877
+ className: "codexSubscriptionAccountQuota",
13878
+ children: t("accountQuotaNone")
13879
+ });
13880
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
13881
+ className: "codexSubscriptionAccountQuota",
13882
+ children: windows.map((window) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [fill(t("accountQuotaLeft"), {
13883
+ label: windowLabel(window.windowSeconds, t),
13884
+ value: percent(window.remainingPercent)
13885
+ }), window.resetsAt === void 0 ? "" : ` · ${fill(t("accountQuotaResets"), { value: when(window.resetsAt) })}`] }, window.windowSeconds))
13886
+ });
13887
+ }
13888
+ //#endregion
13771
13889
  //#region src/client-account.jsx
13772
13890
  const LOGIN_FAILURES = [
13773
13891
  "account-claim",
@@ -13789,6 +13907,7 @@ window.__ModuleLoader__.load({
13789
13907
  children: emailVisible ? candidate.email : maskEmail(candidate.email)
13790
13908
  });
13791
13909
  }
13910
+ const signedInIds = (account) => account?.authenticated === true ? (account.accounts ?? []).map((candidate) => candidate.id).filter((id) => typeof id === "string") : [];
13792
13911
  function AccountCard({ rpc, t, account, setAccount, onSignedOut }) {
13793
13912
  const [flow, setFlow] = (0, react.useState)();
13794
13913
  const flowGeneration = (0, react.useRef)(0);
@@ -13801,6 +13920,7 @@ window.__ModuleLoader__.load({
13801
13920
  const [emailVisibilityKey, setEmailVisibilityKey] = (0, react.useState)(accountVisibilityKey);
13802
13921
  const [busy, setBusy] = (0, react.useState)(false);
13803
13922
  const [error, setError] = (0, react.useState)();
13923
+ const quotas = useAccountQuotas(rpc, signedInIds(account));
13804
13924
  const call = (endpoint, payload = {}) => recoveryCall(rpc, endpoint, payload);
13805
13925
  (0, react.useEffect)(() => {
13806
13926
  if (emailVisibilityKey === accountVisibilityKey) return;
@@ -13996,12 +14116,19 @@ window.__ModuleLoader__.load({
13996
14116
  children: accounts.map((candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13997
14117
  className: "codexSubscriptionAccount",
13998
14118
  "data-active": candidate.active,
13999
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountEmail, {
14000
- candidate,
14001
- fallback: candidate.label,
14002
- t,
14003
- emailVisible: emailVisibleForAccount,
14004
- onClick: toggleEmail
14119
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14120
+ className: "codexSubscriptionAccountMain",
14121
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountEmail, {
14122
+ candidate,
14123
+ fallback: candidate.label,
14124
+ t,
14125
+ emailVisible: emailVisibleForAccount,
14126
+ onClick: toggleEmail
14127
+ }), accounts.length > 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountQuota, {
14128
+ entry: quotas.entries[candidate.id],
14129
+ loading: quotas.busy,
14130
+ t
14131
+ }) : null]
14005
14132
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14006
14133
  className: "codexSubscriptionActions",
14007
14134
  children: [
@@ -14405,7 +14532,7 @@ window.__ModuleLoader__.load({
14405
14532
  children: [
14406
14533
  t("diagnosticsSnapshotTime"),
14407
14534
  " ",
14408
- new Date(report.generatedAt).toLocaleString()
14535
+ new Date(report.generatedAt).toLocaleString(uiLocale())
14409
14536
  ]
14410
14537
  }) : null,
14411
14538
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -14423,7 +14550,7 @@ window.__ModuleLoader__.load({
14423
14550
  " · ",
14424
14551
  t(`diagnosticSource_${event.source}`),
14425
14552
  " · ",
14426
- new Date(event.observedAt).toLocaleTimeString()
14553
+ new Date(event.observedAt).toLocaleTimeString(uiLocale())
14427
14554
  ] }, `${event.source}:${event.action}`)) }) : null
14428
14555
  ] }, item.code)) }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("diagnosticsNoRecordedFailure") })
14429
14556
  }),
@@ -14441,7 +14568,7 @@ window.__ModuleLoader__.load({
14441
14568
  ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: (report.inspection?.capabilities ?? []).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
14442
14569
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: t(`diagnosticCapability_${item.id}`) }),
14443
14570
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", { children: [t(`diagnosticReason_${item.reason}`), item.blockedBy ? ` · ${t(`diagnosticCapability_${item.blockedBy}`)}` : ""] }),
14444
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", { children: [item.latest ? `${item.latest.action} · ${t(`diagnosticSource_${item.latest.source}`)} · ${t(`diagnosticOutcome_${item.latest.status}`)} · ${new Date(item.latest.observedAt).toLocaleTimeString()}` : t("diagnosticsUnverified"), item.unresolved?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("diagnosticsUnresolved") }) : null] })
14571
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", { children: [item.latest ? `${item.latest.action} · ${t(`diagnosticSource_${item.latest.source}`)} · ${t(`diagnosticOutcome_${item.latest.status}`)} · ${new Date(item.latest.observedAt).toLocaleTimeString(uiLocale())}` : t("diagnosticsUnverified"), item.unresolved?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("diagnosticsUnresolved") }) : null] })
14445
14572
  ] }, item.id)) })]
14446
14573
  }),
14447
14574
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -14588,7 +14715,6 @@ window.__ModuleLoader__.load({
14588
14715
  }
14589
14716
  //#endregion
14590
14717
  //#region src/client-usage-overview.jsx
14591
- const uiLocale = () => typeof document === "undefined" ? void 0 : document.documentElement.lang || void 0;
14592
14718
  const WEEKS = 26;
14593
14719
  const compact = (value) => new Intl.NumberFormat(uiLocale(), {
14594
14720
  notation: "compact",
@@ -14858,8 +14984,8 @@ window.__ModuleLoader__.load({
14858
14984
  }
14859
14985
  //#endregion
14860
14986
  //#region src/client-usage.jsx
14861
- const count = (value) => Number(value).toLocaleString();
14862
- const creditAmount = (value) => Number.isFinite(Number(value)) && String(value).trim() !== "" ? Number(value).toLocaleString(void 0, { maximumFractionDigits: 2 }) : value;
14987
+ const count = (value) => Number(value).toLocaleString(uiLocale());
14988
+ const creditAmount = (value) => Number.isFinite(Number(value)) && String(value).trim() !== "" ? Number(value).toLocaleString(uiLocale(), { maximumFractionDigits: 2 }) : value;
14863
14989
  function CreditExpiry({ credits, t }) {
14864
14990
  const date = validDate(credits.expiresAt);
14865
14991
  if (date === void 0 || credits.unlimited) return null;
@@ -14870,7 +14996,7 @@ window.__ModuleLoader__.load({
14870
14996
  "data-soon": status.soon,
14871
14997
  role: "status",
14872
14998
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { children: [fill(t(status.daysLeft === 0 ? "creditsExpiredToday" : "creditsExpires"), {
14873
- date: date.toLocaleDateString(),
14999
+ date: date.toLocaleDateString(uiLocale()),
14874
15000
  days: status.daysLeft
14875
15001
  }), estimate ? ` ${t("creditsExpiryEstimate")}` : ""] })
14876
15002
  });
@@ -14878,7 +15004,7 @@ window.__ModuleLoader__.load({
14878
15004
  function ResetTime({ resetsAt, t }) {
14879
15005
  const date = Number.isSafeInteger(resetsAt) ? validDate(resetsAt * 1e3) : void 0;
14880
15006
  if (date === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("resetUnknown") });
14881
- const value = date.toLocaleString(void 0, {
15007
+ const value = date.toLocaleString(uiLocale(), {
14882
15008
  month: "numeric",
14883
15009
  day: "numeric",
14884
15010
  hour: "2-digit",
@@ -14886,7 +15012,7 @@ window.__ModuleLoader__.load({
14886
15012
  });
14887
15013
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
14888
15014
  dateTime: date.toISOString(),
14889
- title: date.toLocaleString(),
15015
+ title: date.toLocaleString(uiLocale()),
14890
15016
  children: fill(t("resets"), { value })
14891
15017
  });
14892
15018
  }
@@ -14896,8 +15022,8 @@ window.__ModuleLoader__.load({
14896
15022
  className: "codexSubscriptionResetExpiry",
14897
15023
  children: date === void 0 ? t("resetCreditExpiryUnknown") : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
14898
15024
  dateTime: date.toISOString(),
14899
- title: date.toLocaleString(),
14900
- children: fill(t("resetCreditExpires"), { value: date.toLocaleDateString(void 0, {
15025
+ title: date.toLocaleString(uiLocale()),
15026
+ children: fill(t("resetCreditExpires"), { value: date.toLocaleDateString(uiLocale(), {
14901
15027
  month: "long",
14902
15028
  day: "numeric"
14903
15029
  }) })
@@ -15089,6 +15215,7 @@ window.__ModuleLoader__.load({
15089
15215
  return t((/* @__PURE__ */ new Map([
15090
15216
  ["ChatGPT subscription is not signed in", "resetRenewLogin"],
15091
15217
  ["ChatGPT sign-in needs to be renewed", "resetRenewLogin"],
15218
+ ["ChatGPT blocked this request before it reached your account (HTTP 403); your sign-in is fine, try again later or check your network, proxy or VPN", "resetBlocked"],
15092
15219
  ["No quota reset is available", "resetNoCredit"],
15093
15220
  ["No usable quota reset is available", "resetNoCredit"],
15094
15221
  ["The available quota reset expires too soon", "resetExpired"],
@@ -15151,7 +15278,7 @@ window.__ModuleLoader__.load({
15151
15278
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("usage") }), fetchedAt === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
15152
15279
  className: "codexSubscriptionFreshness",
15153
15280
  dateTime: fetchedAt.toISOString(),
15154
- children: fill(t("usageUpdated"), { value: fetchedAt.toLocaleString() })
15281
+ children: fill(t("usageUpdated"), { value: fetchedAt.toLocaleString(uiLocale()) })
15155
15282
  })]
15156
15283
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
15157
15284
  className: "codexSubscriptionRefresh",