tokentracker-cli 0.49.3 → 0.50.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/dashboard/dist/assets/{ActivityHeatmap-DByCSENs.js → ActivityHeatmap-x4ohgosH.js} +1 -1
- package/dashboard/dist/assets/{Card-B71GwGxO.js → Card-tlCRSq-e.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-BjOx4W82.js → DashboardPage-BlFLk2ee.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-Cfj34qew.js → DevicePage-CIMvm9Vy.js} +1 -1
- package/dashboard/dist/assets/{DialogTitle-BdNBXNZX.js → DialogTitle-BI0HlgVk.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-BuCfpXMc.js → FadeIn-SA17xTew.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-DpZhDW9t.js → HeaderGithubStar-DBFhlCLz.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-DJtvaczo.js → IpCheckPage-I9fj2-3q.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-DVR_EDlv.js → LandingPage-m8NEfaOu.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardAvatar-C6KucnuS.js → LeaderboardAvatar-Cd1fppi4.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-DKHvUmGb.js → LeaderboardPage-DvefmvLn.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfileModal-sb4nmMCj.js → LeaderboardProfileModal-_di-rfgB.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfilePage-BK-1QWfg.js → LeaderboardProfilePage-bmVuH12k.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-D7m20XVf.js → LimitsPage-CqGsi8ko.js} +1 -1
- package/dashboard/dist/assets/{LocalOnlyNotice-DZslFoj5.js → LocalOnlyNotice-DI_6H-8g.js} +1 -1
- package/dashboard/dist/assets/LoginPage-BctYGcS4.js +1 -0
- package/dashboard/dist/assets/{PopoverPopup-BjP_x_N0.js → PopoverPopup-DVVdIiBy.js} +1 -1
- package/dashboard/dist/assets/ResetPasswordPage-C8czjNkQ.js +1 -0
- package/dashboard/dist/assets/{Select-B5C3SgjS.js → Select-L2fWCCVd.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-XBZTRfTk.js → SelectItemText-BWr2sP70.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-C3pgKsph.js → SettingsPage-Cf5iyHdz.js} +1 -1
- package/dashboard/dist/assets/{SkillsPage-C884cEOL.js → SkillsPage-B7S4Dlug.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-Wsg4rX9h.js → WidgetsPage-BpNdlHGe.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-BSWIQwdE.js → WrappedPage-FUt_dPFJ.js} +1 -1
- package/dashboard/dist/assets/{agent-logos-umK0ojkk.js → agent-logos-C7snoB9g.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-BGMGSKrn.js → arrow-up-right-BdUd8Qy3.js} +1 -1
- package/dashboard/dist/assets/{download-DBdm8vu1.js → download-BXgc7vy9.js} +1 -1
- package/dashboard/dist/assets/{info-Dc1md1UE.js → info-CbKvss5U.js} +1 -1
- package/dashboard/dist/assets/{main-Br5SsufY.css → main-B1lf1bLt.css} +1 -1
- package/dashboard/dist/assets/main-BsNBj90S.js +1013 -0
- package/dashboard/dist/assets/{use-limits-display-prefs-yZId6XkL.js → use-limits-display-prefs-DY6YXcXP.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-CquG9vh_.js → use-native-settings-BWUsC6-N.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-BvhFrG8a.js → use-usage-limits-CNYuXTxe.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-DCzLyxzN.js → useCurrency-mUI-Iuk0.js} +1 -1
- package/dashboard/dist/assets/{useScrollLock-C5gi8Y07.js → useScrollLock-DMN_zEMe.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/share.html +2 -2
- package/package.json +1 -1
- package/src/lib/cloud-account.js +58 -7
- package/src/lib/local-api.js +6 -1
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +11 -3
- package/src/lib/usage-limits.js +35 -6
- package/dashboard/dist/assets/LoginPage-HQ8ks6KL.js +0 -1
- package/dashboard/dist/assets/main-BTU7nBLK.js +0 -999
package/src/lib/rollout.js
CHANGED
|
@@ -7590,15 +7590,23 @@ async function parseCopilotIncremental({ otelPaths, cursors, queuePath, onProgre
|
|
|
7590
7590
|
|
|
7591
7591
|
const inputRaw = toNonNegativeInt(attrs["gen_ai.usage.input_tokens"]);
|
|
7592
7592
|
const output = toNonNegativeInt(attrs["gen_ai.usage.output_tokens"]);
|
|
7593
|
-
const cacheRead = toNonNegativeInt(
|
|
7593
|
+
const cacheRead = toNonNegativeInt(
|
|
7594
|
+
attrs["gen_ai.usage.cache_read.input_tokens"] ??
|
|
7595
|
+
attrs["gen_ai.usage.cache_read_input_tokens"] ??
|
|
7596
|
+
attrs["gen_ai.usage.cached_input_tokens"],
|
|
7597
|
+
);
|
|
7594
7598
|
// Copilot CLI: cache_write.input_tokens; Copilot Chat extension: cache_creation.input_tokens
|
|
7595
7599
|
const cacheWrite = toNonNegativeInt(
|
|
7596
7600
|
attrs["gen_ai.usage.cache_write.input_tokens"] ??
|
|
7597
|
-
attrs["gen_ai.usage.cache_creation.input_tokens"]
|
|
7601
|
+
attrs["gen_ai.usage.cache_creation.input_tokens"] ??
|
|
7602
|
+
attrs["gen_ai.usage.cache_write_input_tokens"] ??
|
|
7603
|
+
attrs["gen_ai.usage.cache_creation_input_tokens"],
|
|
7598
7604
|
);
|
|
7599
7605
|
// Copilot CLI: reasoning.output_tokens; Copilot Chat extension: reasoning_tokens
|
|
7600
7606
|
const reasoning = toNonNegativeInt(
|
|
7601
|
-
attrs["gen_ai.usage.reasoning.output_tokens"] ??
|
|
7607
|
+
attrs["gen_ai.usage.reasoning.output_tokens"] ??
|
|
7608
|
+
attrs["gen_ai.usage.reasoning_tokens"] ??
|
|
7609
|
+
attrs["gen_ai.usage.reasoning_output_tokens"],
|
|
7602
7610
|
);
|
|
7603
7611
|
// OTEL input_tokens INCLUDES cache_read — subtract per project convention
|
|
7604
7612
|
const cacheReadClamped = Math.min(cacheRead, inputRaw);
|
package/src/lib/usage-limits.js
CHANGED
|
@@ -36,6 +36,7 @@ const ANTIGRAVITY_LIMITS_CACHE_UNKNOWN_RESET_TTL_MS = 12 * 60 * 60 * 1000;
|
|
|
36
36
|
// file with only its own key, so a shared file would clobber).
|
|
37
37
|
const CLAUDE_LIMITS_CACHE_FILE = "claude-usage-limits-cache.json";
|
|
38
38
|
const CLAUDE_LIMITS_CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
39
|
+
const CLAUDE_LIMITS_CACHE_FRESH_TTL_MS = 10 * 60 * 1000;
|
|
39
40
|
// A 429 from the usage endpoint carries a long `retry-after` (often 20+ minutes). Persist
|
|
40
41
|
// the cooldown so every surface — this process, the menu bar app's embedded server, a later
|
|
41
42
|
// restart — stops calling until it expires. Hammering during the cooldown just renews the
|
|
@@ -1484,11 +1485,18 @@ function hasClaudeWindow(limits) {
|
|
|
1484
1485
|
return Boolean(limits?.five_hour || limits?.seven_day || limits?.seven_day_opus);
|
|
1485
1486
|
}
|
|
1486
1487
|
|
|
1487
|
-
function normalizeClaudeCachedLimits(
|
|
1488
|
+
function normalizeClaudeCachedLimits(
|
|
1489
|
+
raw,
|
|
1490
|
+
{
|
|
1491
|
+
nowMs = Date.now(),
|
|
1492
|
+
maxAgeMs = CLAUDE_LIMITS_CACHE_MAX_AGE_MS,
|
|
1493
|
+
stale = true,
|
|
1494
|
+
} = {},
|
|
1495
|
+
) {
|
|
1488
1496
|
const cachedAtMs = parseTimeMs(raw?.cached_at);
|
|
1489
1497
|
if (!Number.isFinite(cachedAtMs)) return null;
|
|
1490
1498
|
if (cachedAtMs > nowMs + 60_000) return null;
|
|
1491
|
-
if (nowMs - cachedAtMs >
|
|
1499
|
+
if (nowMs - cachedAtMs > maxAgeMs) return null;
|
|
1492
1500
|
|
|
1493
1501
|
const cached = {
|
|
1494
1502
|
configured: true,
|
|
@@ -1497,22 +1505,36 @@ function normalizeClaudeCachedLimits(raw, { nowMs = Date.now() } = {}) {
|
|
|
1497
1505
|
seven_day: isClaudeCacheWindowUsable(raw?.seven_day, { nowMs }) ? raw.seven_day : null,
|
|
1498
1506
|
seven_day_opus: isClaudeCacheWindowUsable(raw?.seven_day_opus, { nowMs }) ? raw.seven_day_opus : null,
|
|
1499
1507
|
extra_usage: raw?.extra_usage ?? null,
|
|
1500
|
-
stale
|
|
1508
|
+
stale,
|
|
1501
1509
|
cached_at: raw.cached_at,
|
|
1502
1510
|
};
|
|
1503
1511
|
return hasClaudeWindow(cached) ? cached : null;
|
|
1504
1512
|
}
|
|
1505
1513
|
|
|
1506
|
-
function readClaudeLimitsCache({
|
|
1514
|
+
function readClaudeLimitsCache({
|
|
1515
|
+
home,
|
|
1516
|
+
nowMs = Date.now(),
|
|
1517
|
+
maxAgeMs = CLAUDE_LIMITS_CACHE_MAX_AGE_MS,
|
|
1518
|
+
stale = true,
|
|
1519
|
+
} = {}) {
|
|
1507
1520
|
const cachePath = resolveClaudeLimitsCachePath({ home });
|
|
1508
1521
|
try {
|
|
1509
1522
|
const parsed = JSON.parse(fs.readFileSync(cachePath, "utf8"));
|
|
1510
|
-
return normalizeClaudeCachedLimits(parsed?.claude, { nowMs });
|
|
1523
|
+
return normalizeClaudeCachedLimits(parsed?.claude, { nowMs, maxAgeMs, stale });
|
|
1511
1524
|
} catch (_error) {
|
|
1512
1525
|
return null;
|
|
1513
1526
|
}
|
|
1514
1527
|
}
|
|
1515
1528
|
|
|
1529
|
+
function readFreshClaudeLimitsCache({ home, nowMs = Date.now() } = {}) {
|
|
1530
|
+
return readClaudeLimitsCache({
|
|
1531
|
+
home,
|
|
1532
|
+
nowMs,
|
|
1533
|
+
maxAgeMs: CLAUDE_LIMITS_CACHE_FRESH_TTL_MS,
|
|
1534
|
+
stale: false,
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1516
1538
|
function writeClaudeLimitsCache(limits, { home, nowMs = Date.now() } = {}) {
|
|
1517
1539
|
if (!limits?.configured || limits.error || !hasClaudeWindow(limits)) return;
|
|
1518
1540
|
const cachePath = resolveClaudeLimitsCachePath({ home });
|
|
@@ -2016,10 +2038,15 @@ async function fetchUsageLimitsUncached({
|
|
|
2016
2038
|
// Skip the upstream Claude call entirely while a 429 cooldown is active — calling again
|
|
2017
2039
|
// just renews the penalty. The result handling below serves cache or a cooldown message.
|
|
2018
2040
|
const claudeRetryAtMs = claudeToken ? readClaudeRateLimitRetryAtMs({ home, nowMs }) : null;
|
|
2041
|
+
// Also avoid cross-process hammering after a recent successful read. The macOS app can
|
|
2042
|
+
// restart its embedded Node server or force-refresh the limits page, both of which clear
|
|
2043
|
+
// the in-memory cache; the disk cache keeps those paths from immediately spending
|
|
2044
|
+
// another Claude OAuth usage request.
|
|
2045
|
+
const freshClaudeCache = claudeToken ? readFreshClaudeLimitsCache({ home, nowMs }) : null;
|
|
2019
2046
|
|
|
2020
2047
|
const providerFetch = withFetchTimeout(fetchImpl, providerTimeoutMs);
|
|
2021
2048
|
const [claudeResult, codexResult, cursor, kimi, gemini, kiro, antigravity, copilot, grok] = await Promise.all([
|
|
2022
|
-
claudeToken && !claudeRetryAtMs
|
|
2049
|
+
claudeToken && !freshClaudeCache && !claudeRetryAtMs
|
|
2023
2050
|
? withProviderTimeout(fetchClaudeUsageLimits(claudeToken, { fetchImpl: providerFetch, maxAttempts: 1 }), "Claude", providerTimeoutMs).then(
|
|
2024
2051
|
(value) => ({ status: "fulfilled", value }),
|
|
2025
2052
|
(reason) => ({ status: "rejected", reason }),
|
|
@@ -2052,6 +2079,8 @@ async function fetchUsageLimitsUncached({
|
|
|
2052
2079
|
let claude;
|
|
2053
2080
|
if (!claudeToken) {
|
|
2054
2081
|
claude = { configured: false };
|
|
2082
|
+
} else if (freshClaudeCache) {
|
|
2083
|
+
claude = freshClaudeCache;
|
|
2055
2084
|
} else if (claudeResult && claudeResult.status === "fulfilled") {
|
|
2056
2085
|
claude = {
|
|
2057
2086
|
configured: true,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{at as K,aJ as Z,Y as ee,r,G as s,j as e,L as V,V as v}from"./main-BTU7nBLK.js";function te(n){const a=new URLSearchParams(n).get("next");return typeof a!="string"||a.length===0||!a.startsWith("/")||a.startsWith("//")?"/dashboard":a}const D={google:"Google",github:"GitHub",microsoft:"Microsoft",discord:"Discord",linkedin:"LinkedIn",facebook:"Facebook",instagram:"Instagram",tiktok:"TikTok",apple:"Apple",x:"X",spotify:"Spotify"};function $(n){const a=String(n||"").trim();return D[a]?D[a]:a.replace(/-/g," ")}function ie(){const n=K(),[a,A]=Z(),{enabled:o,loading:g,signedIn:f,refreshUser:C,signInWithPassword:E,signUp:M,signInWithOAuth:I,getPublicAuthConfig:F}=ee(),m=r.useMemo(()=>te(a.toString()),[a]),[l,j]=r.useState("signin"),[x,H]=r.useState(""),[h,J]=r.useState(""),[N,Q]=r.useState(""),[k,p]=r.useState(!1),[O,c]=r.useState(null),[U,b]=r.useState(null),[S,B]=r.useState(!0),[_,R]=r.useState([]),[P,T]=r.useState([]),[W,X]=r.useState(8);r.useEffect(()=>{const t=a.get("insforge_status"),i=a.get("insforge_type"),u=a.get("insforge_error");t==="success"&&i==="verify_email"?b(s("login.verify_email_success")):t==="error"&&i==="verify_email"&&u&&b(s("shared.error.prefix",{error:u}))},[a]),r.useEffect(()=>{if(!o){B(!1);return}let t=!0;return(async()=>{const{data:i,error:u}=await F();t&&(u||!i?(R(["google","github"]),T([])):(R(Array.isArray(i.oAuthProviders)?i.oAuthProviders:[]),T(Array.isArray(i.customOAuthProviders)?i.customOAuthProviders:[]),typeof i.passwordMinLength=="number"&&i.passwordMinLength>0&&X(i.passwordMinLength)),B(!1))})(),()=>{t=!1}},[o,F]);const d=r.useMemo(()=>a.get("native")==="1",[a]),y=r.useMemo(()=>a.get("provider")||null,[a]);r.useEffect(()=>{if(!(!o||g)&&f){if(d){window.location.href="/auth/native-callback";return}n(m,{replace:!0})}},[o,g,f,n,m,d]),r.useEffect(()=>{o&&C()},[o,C]);const q=r.useMemo(()=>typeof window>"u"||d?"":`${window.location.origin}/`,[d]),G=r.useMemo(()=>typeof window>"u"?"":`${window.location.origin}/`,[]),Y=r.useCallback(async t=>{t.preventDefault(),c(null),p(!0);try{if(l==="signup"){const{data:u,error:L}=await M({email:x.trim(),password:h,name:N.trim()||void 0,redirectTo:G});if(L){c(L.message||String(L));return}if(u?.requireEmailVerification){b(s("login.verify_email_pending")),j("signin");return}n(m,{replace:!0});return}const{error:i}=await E({email:x.trim(),password:h});if(i){c(i.message||String(i));return}n(m,{replace:!0})}finally{p(!1)}},[l,x,h,N,M,E,n,m,G]),w=r.useCallback(async t=>{c(null),p(!0);try{const{error:i}=await I(t,q);i&&c(i.message||String(i))}finally{p(!1)}},[I,q]);r.useEffect(()=>{if(d&&typeof window<"u")try{window.sessionStorage.setItem("tokentracker_native_login","1")}catch{}},[d]),r.useEffect(()=>{if(!o||g||f||S||!d||!y)return;[..._,...P].includes(y)&&w(y)},[o,g,f,S,d,y,_,P,w]);const z=r.useCallback(()=>{A(t=>{const i=new URLSearchParams(t);return i.delete("insforge_status"),i.delete("insforge_type"),i.delete("insforge_error"),i},{replace:!0}),b(null)},[A]);return o?e.jsxs("div",{className:"min-h-screen bg-oai-gray-950 text-oai-white font-oai antialiased dark flex flex-col",children:[e.jsx("header",{className:"border-b border-oai-gray-900 px-4 sm:px-6 h-16 flex items-center justify-between",children:e.jsx(V,{to:"/",className:"text-sm font-medium text-oai-gray-400 hover:text-white no-underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand-500 rounded",children:s("login.back_home")})}),e.jsx("main",{className:"flex-1 flex items-center justify-center px-4 py-12",children:e.jsxs("div",{className:"w-full max-w-md space-y-8",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("h1",{className:"text-2xl font-semibold text-white tracking-tight",children:s("login.title")}),e.jsx("p",{className:"mt-2 text-sm text-oai-gray-500",children:s("login.subtitle")})]}),U?e.jsxs("div",{className:"rounded-lg border border-oai-gray-800 bg-oai-gray-900/50 px-4 py-3 text-sm text-oai-gray-300 flex justify-between gap-3 items-start",role:"status",children:[e.jsx("span",{children:U}),e.jsx("button",{type:"button",onClick:z,className:"shrink-0 text-oai-gray-500 hover:text-white text-xs",children:s("login.dismiss")})]}):null,O?e.jsx("p",{className:"text-sm text-red-400",role:"alert",children:s("shared.error.prefix",{error:O})}):null,e.jsx("div",{className:"space-y-3",children:S?e.jsx("div",{className:"h-11 rounded-lg bg-oai-gray-900 animate-pulse","aria-hidden":!0}):e.jsxs(e.Fragment,{children:[_.map(t=>e.jsx("button",{type:"button",disabled:k,onClick:()=>w(t),className:v("w-full h-11 rounded-lg border border-oai-gray-700 bg-oai-gray-900 text-sm font-medium text-white","hover:bg-oai-gray-800 transition-colors disabled:opacity-50"),children:s("login.oauth.continue",{provider:$(t)})},t)),P.map(t=>e.jsx("button",{type:"button",disabled:k,onClick:()=>w(t),className:v("w-full h-11 rounded-lg border border-oai-gray-700 bg-oai-gray-900 text-sm font-medium text-white","hover:bg-oai-gray-800 transition-colors disabled:opacity-50"),children:s("login.oauth.continue",{provider:$(t)})},t))]})}),e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute inset-0 flex items-center","aria-hidden":!0,children:e.jsx("span",{className:"w-full border-t border-oai-gray-800"})}),e.jsx("div",{className:"relative flex justify-center text-xs uppercase tracking-wider",children:e.jsx("span",{className:"bg-oai-gray-950 px-3 text-oai-gray-600",children:s("login.divider")})})]}),e.jsxs("div",{className:"flex rounded-lg border border-oai-gray-800 p-0.5 bg-oai-gray-900/50",children:[e.jsx("button",{type:"button",className:v("flex-1 py-2 text-sm font-medium rounded-md transition-colors",l==="signin"?"bg-oai-gray-800 text-white":"text-oai-gray-500 hover:text-oai-gray-300"),onClick:()=>{j("signin"),c(null)},children:s("login.tab.sign_in")}),e.jsx("button",{type:"button",className:v("flex-1 py-2 text-sm font-medium rounded-md transition-colors",l==="signup"?"bg-oai-gray-800 text-white":"text-oai-gray-500 hover:text-oai-gray-300"),onClick:()=>{j("signup"),c(null)},children:s("login.tab.sign_up")})]}),e.jsxs("form",{onSubmit:Y,className:"space-y-4",children:[l==="signup"?e.jsxs("div",{children:[e.jsx("label",{htmlFor:"login-name",className:"block text-xs font-medium text-oai-gray-500 mb-1",children:s("login.field.name")}),e.jsx("input",{id:"login-name",type:"text",autoComplete:"name",value:N,onChange:t=>Q(t.target.value),className:"w-full h-11 rounded-lg border border-oai-gray-800 bg-oai-gray-900 px-3 text-sm text-white placeholder-oai-gray-600 focus:outline-none focus:ring-2 focus:ring-oai-brand-500",placeholder:s("login.field.name_placeholder")})]}):null,e.jsxs("div",{children:[e.jsx("label",{htmlFor:"login-email",className:"block text-xs font-medium text-oai-gray-500 mb-1",children:s("login.field.email")}),e.jsx("input",{id:"login-email",type:"email",autoComplete:"email",required:!0,value:x,onChange:t=>H(t.target.value),className:"w-full h-11 rounded-lg border border-oai-gray-800 bg-oai-gray-900 px-3 text-sm text-white placeholder-oai-gray-600 focus:outline-none focus:ring-2 focus:ring-oai-brand-500"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"login-password",className:"block text-xs font-medium text-oai-gray-500 mb-1",children:s("login.field.password")}),e.jsx("input",{id:"login-password",type:"password",autoComplete:l==="signup"?"new-password":"current-password",required:!0,minLength:l==="signup"?W:void 0,value:h,onChange:t=>J(t.target.value),className:"w-full h-11 rounded-lg border border-oai-gray-800 bg-oai-gray-900 px-3 text-sm text-white placeholder-oai-gray-600 focus:outline-none focus:ring-2 focus:ring-oai-brand-500"}),l==="signup"?e.jsx("p",{className:"mt-1 text-xs text-oai-gray-600",children:s("login.password_hint",{min:String(W)})}):null]}),e.jsx("button",{type:"submit",disabled:k||g,className:"w-full h-11 rounded-lg bg-white text-oai-gray-950 text-sm font-semibold hover:bg-oai-gray-100 transition-colors disabled:opacity-50",children:l==="signup"?s("login.submit.sign_up"):s("login.submit.sign_in")})]})]})})]}):e.jsxs("div",{className:"min-h-screen bg-oai-gray-950 text-oai-white font-oai antialiased dark flex flex-col",children:[e.jsx("header",{className:"border-b border-oai-gray-900 px-4 sm:px-6 py-4",children:e.jsx(V,{to:"/",className:"text-sm font-medium text-oai-gray-400 hover:text-white no-underline",children:s("login.back_home")})}),e.jsx("main",{className:"flex-1 flex items-center justify-center px-4",children:e.jsx("p",{className:"text-oai-gray-400 text-center max-w-md",children:s("login.cloud_only")})})]})}export{ie as LoginPage};
|