@kerne/react 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ui/index.cjs CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
 
20
- var _chunkIMZFZ3P5cjs = require('../chunk-IMZFZ3P5.cjs');
20
+ var _chunkTYNZ2WU7cjs = require('../chunk-TYNZ2WU7.cjs');
21
21
 
22
22
  // src/ui/AuthFlow.tsx
23
23
  var _react = require('react');
@@ -903,7 +903,7 @@ function Field({
903
903
  const id = _react.useId.call(void 0, );
904
904
  const errorId = `${id}-error`;
905
905
  const noteId = `${id}-note`;
906
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
906
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
907
907
  const isPassword = type === "password";
908
908
  const [revealed, setRevealed] = _react.useState.call(void 0, false);
909
909
  const [capsLock, setCapsLock] = _react.useState.call(void 0, false);
@@ -1031,11 +1031,11 @@ function PasswordStrength({
1031
1031
  password,
1032
1032
  policy
1033
1033
  }) {
1034
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1034
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1035
1035
  const resolved = _nullishCoalesce(policy, () => ( resolvePolicy(null)));
1036
1036
  if (!meetsPolicy(password, resolved)) {
1037
1037
  const labels2 = {
1038
- min_length: _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.common.passwordHint, { count: resolved.min_length }),
1038
+ min_length: _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.common.passwordHint, { count: resolved.min_length }),
1039
1039
  require_uppercase: l10n.common.passwordRequireUppercase,
1040
1040
  require_number: l10n.common.passwordRequireNumber,
1041
1041
  require_symbol: l10n.common.passwordRequireSymbol
@@ -1231,10 +1231,10 @@ function OAuthButtons({
1231
1231
  disabled,
1232
1232
  onSelect
1233
1233
  }) {
1234
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1234
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1235
1235
  if (providers.length === 0) return null;
1236
1236
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "kerne-oauth-group", children: providers.map((provider) => {
1237
- const label = _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.common.continueWith, {
1237
+ const label = _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.common.continueWith, {
1238
1238
  provider: _nullishCoalesce(OAUTH_LABELS[provider], () => ( provider))
1239
1239
  });
1240
1240
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
@@ -1255,12 +1255,12 @@ function OAuthButtons({
1255
1255
  }) });
1256
1256
  }
1257
1257
  function KerneBranding({ show }) {
1258
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1258
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1259
1259
  if (!show) return null;
1260
1260
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "a", { className: "kerne-branding", href: "https://kerne.io", target: "_blank", rel: "noopener noreferrer", children: l10n.common.securedByKerne });
1261
1261
  }
1262
1262
  function FormSkeleton() {
1263
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1263
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1264
1264
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-form", "aria-busy": "true", "aria-label": l10n.common.loading, children: [
1265
1265
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "kerne-skeleton" }),
1266
1266
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "kerne-skeleton" })
@@ -1285,11 +1285,11 @@ function LoginForm({
1285
1285
  logo,
1286
1286
  className
1287
1287
  }) {
1288
- const client = _chunkIMZFZ3P5cjs.useClient.call(void 0, );
1289
- const { login, startPasswordless } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
1290
- const { config, isLoading: configLoading, error: configError } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
1291
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1292
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
1288
+ const client = _chunkTYNZ2WU7cjs.useClient.call(void 0, );
1289
+ const { login, startPasswordless } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
1290
+ const { config, isLoading: configLoading, error: configError } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
1291
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1292
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
1293
1293
  const [email, setEmail] = _react.useState.call(void 0, "");
1294
1294
  const [password, setPassword] = _react.useState.call(void 0, "");
1295
1295
  const [submitting, setSubmitting] = _react.useState.call(void 0, false);
@@ -1353,7 +1353,7 @@ function LoginForm({
1353
1353
  const signUpLine = canSignUp && (signUpUrl || onSignUpClick) ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1354
1354
  l10n.signIn.signUpPrompt,
1355
1355
  " ",
1356
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TextLink, { href: signUpUrl, onClick: onSignUpClick, children: appName ? _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.signIn.signUpForApp, { app: appName }) : l10n.signIn.signUpLink }),
1356
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TextLink, { href: signUpUrl, onClick: onSignUpClick, children: appName ? _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.signIn.signUpForApp, { app: appName }) : l10n.signIn.signUpLink }),
1357
1357
  "."
1358
1358
  ] }) : void 0;
1359
1359
  const submitLabel = submitting ? usePassword ? l10n.signIn.submitting : l10n.signIn.magicSubmitting : usePassword ? l10n.signIn.submit : l10n.signIn.magicSubmit;
@@ -1362,7 +1362,7 @@ function LoginForm({
1362
1362
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Masthead, { logo, title: heading, subtitle: _nullishCoalesce(subtitle, () => ( signUpLine)) }),
1363
1363
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-stack", children: [
1364
1364
  error ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: error }) : null,
1365
- linkSentTo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { children: _chunkIMZFZ3P5cjs.fillNode.call(void 0, l10n.signIn.linkSent, { email: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: linkSentTo }) }) }) : hasEmailMethod ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { className: "kerne-form", onSubmit: handleSubmit, children: [
1365
+ linkSentTo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { children: _chunkTYNZ2WU7cjs.fillNode.call(void 0, l10n.signIn.linkSent, { email: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: linkSentTo }) }) }) : hasEmailMethod ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { className: "kerne-form", onSubmit: handleSubmit, children: [
1366
1366
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1367
1367
  Field,
1368
1368
  {
@@ -1438,13 +1438,13 @@ function RegisterForm({
1438
1438
  logo,
1439
1439
  className
1440
1440
  }) {
1441
- const client = _chunkIMZFZ3P5cjs.useClient.call(void 0, );
1442
- const { register, startPasswordless } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
1443
- const { config, isLoading: configLoading, error: configError } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
1441
+ const client = _chunkTYNZ2WU7cjs.useClient.call(void 0, );
1442
+ const { register, startPasswordless } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
1443
+ const { config, isLoading: configLoading, error: configError } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
1444
1444
  const policy = resolvePolicy(config);
1445
1445
  const invitationToken = useUrlToken("token", invitationTokenProp) || void 0;
1446
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1447
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
1446
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1447
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
1448
1448
  const [email, setEmail] = _react.useState.call(void 0, "");
1449
1449
  const [password, setPassword] = _react.useState.call(void 0, "");
1450
1450
  const [name, setName] = _react.useState.call(void 0, "");
@@ -1455,7 +1455,7 @@ function RegisterForm({
1455
1455
  const [passwordMode, setPasswordMode] = _react.useState.call(void 0, false);
1456
1456
  const shell = (children) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Shell, { appearance, className, children });
1457
1457
  const appName = _optionalChain([config, 'optionalAccess', _13 => _13.app_name]);
1458
- const heading = _nullishCoalesce(title, () => ( (appName ? _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.signUp.titleWithApp, { app: appName }) : l10n.signUp.title)));
1458
+ const heading = _nullishCoalesce(title, () => ( (appName ? _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.signUp.titleWithApp, { app: appName }) : l10n.signUp.title)));
1459
1459
  const signInLine = signInUrl || onSignInClick ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1460
1460
  l10n.signUp.signInPrompt,
1461
1461
  " ",
@@ -1482,7 +1482,7 @@ function RegisterForm({
1482
1482
  return shell(
1483
1483
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1484
1484
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Masthead, { logo, title: l10n.signUp.closedTitle, subtitle: signInLine }),
1485
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { children: _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.signUp.closedBody, { app: _nullishCoalesce(appName, () => ( l10n.common.thisApp)) }) }),
1485
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { children: _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.signUp.closedBody, { app: _nullishCoalesce(appName, () => ( l10n.common.thisApp)) }) }),
1486
1486
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KerneBranding, { show: config.show_kerne_branding })
1487
1487
  ] })
1488
1488
  );
@@ -1544,7 +1544,7 @@ function RegisterForm({
1544
1544
  ),
1545
1545
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-stack", children: [
1546
1546
  error ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: error }) : null,
1547
- linkSentTo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { children: _chunkIMZFZ3P5cjs.fillNode.call(void 0, l10n.signUp.linkSent, { email: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: linkSentTo }) }) }) : hasEmailMethod ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { className: "kerne-form", onSubmit: handleSubmit, children: [
1547
+ linkSentTo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { children: _chunkTYNZ2WU7cjs.fillNode.call(void 0, l10n.signUp.linkSent, { email: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: linkSentTo }) }) }) : hasEmailMethod ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { className: "kerne-form", onSubmit: handleSubmit, children: [
1548
1548
  needsCode ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1549
1549
  Field,
1550
1550
  {
@@ -1649,10 +1649,10 @@ function ForgotPasswordForm({
1649
1649
  logo,
1650
1650
  className
1651
1651
  }) {
1652
- const { requestPasswordReset } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
1653
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
1654
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1655
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
1652
+ const { requestPasswordReset } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
1653
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
1654
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1655
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
1656
1656
  const [email, setEmail] = _react.useState.call(void 0, "");
1657
1657
  const [submitting, setSubmitting] = _react.useState.call(void 0, false);
1658
1658
  const [error, setError] = _react.useState.call(void 0, null);
@@ -1688,7 +1688,7 @@ function ForgotPasswordForm({
1688
1688
  ),
1689
1689
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-stack", children: [
1690
1690
  error ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: error }) : null,
1691
- sentTo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { children: _chunkIMZFZ3P5cjs.fillNode.call(void 0, l10n.resetPassword.requestSent, { email: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: sentTo }) }) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { className: "kerne-form", onSubmit: handleSubmit, children: [
1691
+ sentTo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { children: _chunkTYNZ2WU7cjs.fillNode.call(void 0, l10n.resetPassword.requestSent, { email: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: sentTo }) }) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { className: "kerne-form", onSubmit: handleSubmit, children: [
1692
1692
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1693
1693
  Field,
1694
1694
  {
@@ -1725,12 +1725,12 @@ function ResetPasswordForm({
1725
1725
  logo,
1726
1726
  className
1727
1727
  }) {
1728
- const { confirmPasswordReset } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
1729
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
1728
+ const { confirmPasswordReset } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
1729
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
1730
1730
  const policy = resolvePolicy(config);
1731
1731
  const token = useUrlToken("token", tokenProp);
1732
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1733
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
1732
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1733
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
1734
1734
  const [password, setPassword] = _react.useState.call(void 0, "");
1735
1735
  const [confirm, setConfirm] = _react.useState.call(void 0, "");
1736
1736
  const [submitting, setSubmitting] = _react.useState.call(void 0, false);
@@ -1845,12 +1845,12 @@ function MagicLinkCallback({
1845
1845
  logo,
1846
1846
  className
1847
1847
  }) {
1848
- const client = _chunkIMZFZ3P5cjs.useClient.call(void 0, );
1849
- const { loginWithMagicLink } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
1850
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
1848
+ const client = _chunkTYNZ2WU7cjs.useClient.call(void 0, );
1849
+ const { loginWithMagicLink } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
1850
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
1851
1851
  const token = useUrlToken("token", tokenProp);
1852
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1853
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
1852
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1853
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
1854
1854
  const [state, setState] = _react.useState.call(void 0, "pending");
1855
1855
  const [message, setMessage] = _react.useState.call(void 0, null);
1856
1856
  const consumed = _react.useRef.call(void 0, false);
@@ -1904,11 +1904,11 @@ function VerifyEmailForm({
1904
1904
  logo,
1905
1905
  className
1906
1906
  }) {
1907
- const { verifyEmailWithCode, verifyEmailWithLink, sendVerificationEmail, refreshToken } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
1908
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
1907
+ const { verifyEmailWithCode, verifyEmailWithLink, sendVerificationEmail, refreshToken } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
1908
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
1909
1909
  const token = useUrlToken("token", tokenProp);
1910
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
1911
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
1910
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
1911
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
1912
1912
  const [code, setCode] = _react.useState.call(void 0, "");
1913
1913
  const [submitting, setSubmitting] = _react.useState.call(void 0, false);
1914
1914
  const [error, setError] = _react.useState.call(void 0, null);
@@ -2030,13 +2030,13 @@ function ActivateAccountForm({
2030
2030
  logo,
2031
2031
  className
2032
2032
  }) {
2033
- const client = _chunkIMZFZ3P5cjs.useClient.call(void 0, );
2034
- const { getActivationContext, completeActivation } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
2035
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
2033
+ const client = _chunkTYNZ2WU7cjs.useClient.call(void 0, );
2034
+ const { getActivationContext, completeActivation } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
2035
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
2036
2036
  const policy = resolvePolicy(config);
2037
2037
  const token = useUrlToken("token", tokenProp);
2038
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2039
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
2038
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2039
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
2040
2040
  const [context, setContext] = _react.useState.call(void 0, null);
2041
2041
  const [loadError, setLoadError] = _react.useState.call(void 0, null);
2042
2042
  const [password, setPassword] = _react.useState.call(void 0, "");
@@ -2106,7 +2106,7 @@ function ActivateAccountForm({
2106
2106
  {
2107
2107
  logo,
2108
2108
  title: heading,
2109
- subtitle: _chunkIMZFZ3P5cjs.fillNode.call(void 0,
2109
+ subtitle: _chunkTYNZ2WU7cjs.fillNode.call(void 0,
2110
2110
  credentialsMode ? l10n.activate.credentialsSubtitle : l10n.activate.magicSubtitle,
2111
2111
  { email: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: context.email }) }
2112
2112
  )
@@ -2178,7 +2178,7 @@ function AuthFlow({
2178
2178
  logo,
2179
2179
  className
2180
2180
  }) {
2181
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
2181
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
2182
2182
  const token = useUrlToken("token");
2183
2183
  const [internalStep, setInternalStep] = _react.useState.call(void 0, null);
2184
2184
  const go = (next) => {
@@ -2265,11 +2265,11 @@ function ChangePasswordForm({
2265
2265
  appearance,
2266
2266
  className
2267
2267
  }) {
2268
- const { updatePassword } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
2269
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
2268
+ const { updatePassword } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
2269
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
2270
2270
  const policy = resolvePolicy(config);
2271
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2272
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
2271
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2272
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
2273
2273
  const heading = title === null ? null : _nullishCoalesce(title, () => ( l10n.security.submit));
2274
2274
  const [currentPassword, setCurrentPassword] = _react.useState.call(void 0, "");
2275
2275
  const [newPassword, setNewPassword] = _react.useState.call(void 0, "");
@@ -2375,10 +2375,10 @@ function WaitlistForm({
2375
2375
  logo,
2376
2376
  className
2377
2377
  }) {
2378
- const { join } = _chunkIMZFZ3P5cjs.useWaitlist.call(void 0, );
2379
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
2380
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2381
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
2378
+ const { join } = _chunkTYNZ2WU7cjs.useWaitlist.call(void 0, );
2379
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
2380
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2381
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
2382
2382
  const [email, setEmail] = _react.useState.call(void 0, "");
2383
2383
  const [name, setName] = _react.useState.call(void 0, "");
2384
2384
  const [submitting, setSubmitting] = _react.useState.call(void 0, false);
@@ -2459,8 +2459,8 @@ function SignOutButton({
2459
2459
  appearance
2460
2460
  }) {
2461
2461
  ensureStylesInjected();
2462
- const { logout } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
2463
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2462
+ const { logout } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
2463
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2464
2464
  const handle = () => {
2465
2465
  logout();
2466
2466
  _optionalChain([onSignedOut, 'optionalCall', _36 => _36()]);
@@ -2494,9 +2494,9 @@ function UserButton({
2494
2494
  className
2495
2495
  }) {
2496
2496
  ensureStylesInjected();
2497
- const { logout, isAuthenticated } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
2498
- const { user, fullName, initials, email } = _chunkIMZFZ3P5cjs.useUser.call(void 0, );
2499
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2497
+ const { logout, isAuthenticated } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
2498
+ const { user, fullName, initials, email } = _chunkTYNZ2WU7cjs.useUser.call(void 0, );
2499
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2500
2500
  const [open, setOpen] = _react.useState.call(void 0, false);
2501
2501
  const wrapRef = _react.useRef.call(void 0, null);
2502
2502
  _react.useEffect.call(void 0, () => {
@@ -2587,10 +2587,10 @@ function UserButton({
2587
2587
 
2588
2588
 
2589
2589
  function ProfileSection({ verificationCallbackUrl, onSaved }) {
2590
- const { updateProfile, sendVerificationEmail, getVerificationStatus } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
2591
- const { user, fullName, initials, email } = _chunkIMZFZ3P5cjs.useUser.call(void 0, );
2592
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2593
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
2590
+ const { updateProfile, sendVerificationEmail, getVerificationStatus } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
2591
+ const { user, fullName, initials, email } = _chunkTYNZ2WU7cjs.useUser.call(void 0, );
2592
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2593
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
2594
2594
  const [firstName, setFirstName] = _react.useState.call(void 0, "");
2595
2595
  const [lastName, setLastName] = _react.useState.call(void 0, "");
2596
2596
  const [saving, setSaving] = _react.useState.call(void 0, false);
@@ -2701,10 +2701,10 @@ function ProfileSection({ verificationCallbackUrl, onSaved }) {
2701
2701
 
2702
2702
 
2703
2703
  function SecuritySection({ showDeleteAccount = true, onDeleted }) {
2704
- const { requestAccountDeletion } = _chunkIMZFZ3P5cjs.useAuth.call(void 0, );
2705
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
2706
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2707
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
2704
+ const { requestAccountDeletion } = _chunkTYNZ2WU7cjs.useAuth.call(void 0, );
2705
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
2706
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2707
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
2708
2708
  const [error, setError] = _react.useState.call(void 0, null);
2709
2709
  const [confirmingDelete, setConfirmingDelete] = _react.useState.call(void 0, false);
2710
2710
  const [deleting, setDeleting] = _react.useState.call(void 0, false);
@@ -2822,6 +2822,44 @@ function resolvePriceDisplay(price, displayInterval) {
2822
2822
  displayInterval
2823
2823
  };
2824
2824
  }
2825
+ function collectPriceLabels(plans) {
2826
+ const bySlug = /* @__PURE__ */ new Map();
2827
+ for (const plan of plans) {
2828
+ for (const price of plan.prices) {
2829
+ if (!bySlug.has(price.label.slug)) bySlug.set(price.label.slug, price.label);
2830
+ }
2831
+ }
2832
+ return Array.from(bySlug.values()).sort(
2833
+ (a, b) => a.sort_order - b.sort_order || a.name.localeCompare(b.name)
2834
+ );
2835
+ }
2836
+ function resolveLabelSavings(plans, labels) {
2837
+ if (labels.length < 2) return null;
2838
+ const priceFor = (labelSlug) => {
2839
+ for (const plan of plans) {
2840
+ const price = plan.prices.find((p) => p.label.slug === labelSlug);
2841
+ if (price) return price;
2842
+ }
2843
+ return void 0;
2844
+ };
2845
+ const sorted = [...labels].sort(
2846
+ (a, b) => approxMonths(_nullishCoalesce(_optionalChain([priceFor, 'call', _51 => _51(a.slug), 'optionalAccess', _52 => _52.interval]), () => ( "1M"))) - approxMonths(_nullishCoalesce(_optionalChain([priceFor, 'call', _53 => _53(b.slug), 'optionalAccess', _54 => _54.interval]), () => ( "1M")))
2847
+ );
2848
+ const shortest = sorted[0];
2849
+ const longest = sorted[sorted.length - 1];
2850
+ if (shortest.slug === longest.slug) return null;
2851
+ for (const plan of plans) {
2852
+ const shortPrice = plan.prices.find((p) => p.label.slug === shortest.slug);
2853
+ const longPrice = plan.prices.find((p) => p.label.slug === longest.slug);
2854
+ if (!_optionalChain([shortPrice, 'optionalAccess', _55 => _55.amount]) || !longPrice) continue;
2855
+ const shortMonths = approxMonths(shortPrice.interval);
2856
+ const longMonths = approxMonths(longPrice.interval);
2857
+ if (!shortMonths || !longMonths) continue;
2858
+ const savings = 1 - longPrice.amount / longMonths / (shortPrice.amount / shortMonths);
2859
+ if (savings > 0.01) return { labelSlug: longest.slug, percent: Math.round(savings * 100) };
2860
+ }
2861
+ return null;
2862
+ }
2825
2863
 
2826
2864
  // src/ui/UsageMeters.tsx
2827
2865
 
@@ -2848,13 +2886,13 @@ function UsageMeters({
2848
2886
  appearance,
2849
2887
  className
2850
2888
  }) {
2851
- const { entitlements, isLoading, error } = _chunkIMZFZ3P5cjs.useEntitlements.call(void 0, );
2852
- const { subscription } = _chunkIMZFZ3P5cjs.useSubscription.call(void 0, );
2853
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2889
+ const { entitlements, isLoading, error } = _chunkTYNZ2WU7cjs.useEntitlements.call(void 0, );
2890
+ const { subscription } = _chunkTYNZ2WU7cjs.useSubscription.call(void 0, );
2891
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2854
2892
  const heading = title === null ? null : _nullishCoalesce(title, () => ( l10n.usage.title));
2855
2893
  const nameFor = (key) => {
2856
- if (_optionalChain([labels, 'optionalAccess', _51 => _51[key]])) return labels[key];
2857
- const fromPlan = _optionalChain([subscription, 'optionalAccess', _52 => _52.entitlements, 'access', _53 => _53.find, 'call', _54 => _54((e) => e.feature_key === key), 'optionalAccess', _55 => _55.feature_name]);
2894
+ if (_optionalChain([labels, 'optionalAccess', _56 => _56[key]])) return labels[key];
2895
+ const fromPlan = _optionalChain([subscription, 'optionalAccess', _57 => _57.entitlements, 'access', _58 => _58.find, 'call', _59 => _59((e) => e.feature_key === key), 'optionalAccess', _60 => _60.feature_name]);
2858
2896
  return _nullishCoalesce(fromPlan, () => ( humanizeFeatureKey(key)));
2859
2897
  };
2860
2898
  const shell = (children) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Shell, { appearance, className, children: [
@@ -2896,12 +2934,12 @@ function UsageMeters({
2896
2934
  const ratio = unlimited ? 0 : quotaRatio(e.used, e.limit);
2897
2935
  const level = unlimited ? "normal" : levelFor(ratio, softOverage);
2898
2936
  const over = !unlimited && e.used > e.limit;
2899
- const standing = billed ? _optionalChain([subscription, 'optionalAccess', _56 => _56.entitlements, 'access', _57 => _57.find, 'call', _58 => _58((se) => se.feature_key === e.feature_key)]) : void 0;
2900
- const capReached = billed && (_nullishCoalesce(_optionalChain([standing, 'optionalAccess', _59 => _59.cap_reached]), () => ( false)));
2937
+ const standing = billed ? _optionalChain([subscription, 'optionalAccess', _61 => _61.entitlements, 'access', _62 => _62.find, 'call', _63 => _63((se) => se.feature_key === e.feature_key)]) : void 0;
2938
+ const capReached = billed && (_nullishCoalesce(_optionalChain([standing, 'optionalAccess', _64 => _64.cap_reached]), () => ( false)));
2901
2939
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-meter", "data-level": level, children: [
2902
2940
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-meter-head", children: [
2903
2941
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "kerne-meter-name", children: nameFor(e.feature_key) }),
2904
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "kerne-meter-value", children: unlimited ? _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.usage.used, { count: formatNumber(e.used) }) : `${formatNumber(e.used)} / ${formatNumber(e.limit)}` })
2942
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "kerne-meter-value", children: unlimited ? _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.usage.used, { count: formatNumber(e.used) }) : `${formatNumber(e.used)} / ${formatNumber(e.limit)}` })
2905
2943
  ] }),
2906
2944
  !unlimited ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2907
2945
  "div",
@@ -2916,14 +2954,14 @@ function UsageMeters({
2916
2954
  }
2917
2955
  ) : null,
2918
2956
  over && softOverage ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2919
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "kerne-meter-note", children: _chunkIMZFZ3P5cjs.fill.call(void 0,
2957
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "kerne-meter-note", children: _chunkTYNZ2WU7cjs.fill.call(void 0,
2920
2958
  // capReached inverts overageBilled's meaning (billing stopped,
2921
2959
  // access didn't) - a variant string would say the opposite of
2922
2960
  // the truth for the one plan that just stopped costing money.
2923
2961
  capReached ? l10n.usage.capReached : billed ? l10n.usage.overageBilled : l10n.usage.overage,
2924
2962
  { count: formatNumber(e.used - e.limit) }
2925
2963
  ) }),
2926
- billed && _optionalChain([standing, 'optionalAccess', _60 => _60.billed_amount]) != null && standing.currency ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "kerne-meter-note kerne-meter-cost", children: _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.usage.billedAmount, {
2964
+ billed && _optionalChain([standing, 'optionalAccess', _65 => _65.billed_amount]) != null && standing.currency ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "kerne-meter-note kerne-meter-cost", children: _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.usage.billedAmount, {
2927
2965
  amount: formatMoney(standing.billed_amount, standing.currency)
2928
2966
  }) }) : null
2929
2967
  ] }) : over ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "kerne-meter-note", children: l10n.usage.limitReached }) : null
@@ -2954,11 +2992,11 @@ function SubscriptionCard({
2954
2992
  appearance,
2955
2993
  className
2956
2994
  }) {
2957
- const { subscription, isLoading, error, refetch } = _chunkIMZFZ3P5cjs.useSubscription.call(void 0, productSlug);
2958
- const { openPortal } = _chunkIMZFZ3P5cjs.usePortal.call(void 0, );
2959
- const { cancelSubscription, isCanceling } = _chunkIMZFZ3P5cjs.useCancelSubscription.call(void 0, );
2960
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
2961
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
2995
+ const { subscription, isLoading, error, refetch } = _chunkTYNZ2WU7cjs.useSubscription.call(void 0, productSlug);
2996
+ const { openPortal } = _chunkTYNZ2WU7cjs.usePortal.call(void 0, );
2997
+ const { cancelSubscription, isCanceling } = _chunkTYNZ2WU7cjs.useCancelSubscription.call(void 0, );
2998
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
2999
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
2962
3000
  const heading = title === null ? null : _nullishCoalesce(title, () => ( l10n.billing.plan));
2963
3001
  const statusLabels = {
2964
3002
  ACTIVE: l10n.billing.statusActive,
@@ -3105,31 +3143,37 @@ function BillingSection({
3105
3143
  usageFeatureKeys,
3106
3144
  usageLabels
3107
3145
  }) {
3108
- const { subscription } = _chunkIMZFZ3P5cjs.useSubscription.call(void 0, productSlug);
3109
- const { plans, isLoading: plansLoading } = _chunkIMZFZ3P5cjs.usePlans.call(void 0, pricingProductIdOrSlug);
3110
- const { openCheckout } = _chunkIMZFZ3P5cjs.useCheckout.call(void 0, );
3111
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
3112
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
3113
- const [busy, setBusy] = _react.useState.call(void 0, null);
3114
- const [error, setError] = _react.useState.call(void 0, null);
3146
+ const { subscription, refetch: refetchSubscription } = _chunkTYNZ2WU7cjs.useSubscription.call(void 0, productSlug);
3147
+ const { plans, isLoading: plansLoading } = _chunkTYNZ2WU7cjs.usePlans.call(void 0, pricingProductIdOrSlug);
3148
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
3149
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
3150
+ const {
3151
+ pending: pendingPlan,
3152
+ switching,
3153
+ switchError,
3154
+ checkoutPriceId: busy,
3155
+ checkoutError,
3156
+ selectPlan,
3157
+ confirmSwitch,
3158
+ dismissSwitch
3159
+ } = _chunkTYNZ2WU7cjs.usePlanSwitch.call(void 0, subscription, refetchSubscription, {
3160
+ successUrl: checkoutSuccessUrl,
3161
+ cancelUrl: checkoutCancelUrl
3162
+ });
3163
+ const error = _nullishCoalesce(checkoutError, () => ( switchError));
3115
3164
  const intervals = _react.useMemo.call(void 0, () => intervalsOf(plans), [plans]);
3116
3165
  const [interval, setInterval] = _react.useState.call(void 0, null);
3117
- const activeInterval = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(interval, () => ( _optionalChain([subscription, 'optionalAccess', _61 => _61.plan_price, 'access', _62 => _62.interval]))), () => ( intervals[0])), () => ( null));
3118
- const handleSwitch = async (planPriceId) => {
3119
- setError(null);
3120
- setBusy(planPriceId);
3121
- try {
3122
- await openCheckout(planPriceId, {
3123
- successUrl: checkoutSuccessUrl,
3124
- cancelUrl: checkoutCancelUrl
3125
- });
3126
- } catch (e) {
3127
- setError(showError(e));
3128
- setBusy(null);
3129
- }
3130
- };
3166
+ const activeInterval = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(interval, () => ( _optionalChain([subscription, 'optionalAccess', _66 => _66.plan_price, 'access', _67 => _67.interval]))), () => ( intervals[0])), () => ( null));
3131
3167
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3132
- error ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: error }) : null,
3168
+ error ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: showError(error) }) : null,
3169
+ pendingPlan ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Panel, { children: [
3170
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.billing.switchConfirmTitle, { plan: pendingPlan.plan.name }) }),
3171
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "kerne-subsection-desc", children: l10n.billing.switchConfirmBody }),
3172
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-inline-actions", children: [
3173
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { variant: "outline", type: "button", onClick: dismissSwitch, disabled: switching, children: l10n.billing.switchConfirmDismiss }),
3174
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { type: "button", onClick: confirmSwitch, loading: switching, children: switching ? l10n.billing.switching : l10n.billing.switchConfirmButton })
3175
+ ] })
3176
+ ] }) : null,
3133
3177
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Subsection, { title: l10n.billing.currentPlan, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3134
3178
  SubscriptionCard,
3135
3179
  {
@@ -3168,7 +3212,7 @@ function BillingSection({
3168
3212
  ) : null,
3169
3213
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "kerne-plan-list", children: plans.map((plan) => {
3170
3214
  const price = _nullishCoalesce(plan.prices.find((p) => p.interval === activeInterval), () => ( plan.prices[0]));
3171
- const isCurrent = _optionalChain([subscription, 'optionalAccess', _63 => _63.plan, 'access', _64 => _64.slug]) === plan.slug;
3215
+ const isCurrent = _optionalChain([subscription, 'optionalAccess', _68 => _68.plan, 'access', _69 => _69.slug]) === plan.slug;
3172
3216
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3173
3217
  "div",
3174
3218
  {
@@ -3187,7 +3231,7 @@ function BillingSection({
3187
3231
  {
3188
3232
  variant: "outline",
3189
3233
  type: "button",
3190
- onClick: () => handleSwitch(price.id),
3234
+ onClick: () => selectPlan(plan, price),
3191
3235
  loading: busy === price.id,
3192
3236
  disabled: busy !== null,
3193
3237
  children: busy === price.id ? l10n.billing.opening : l10n.billing.switchTo
@@ -3226,7 +3270,7 @@ function UserProfile({
3226
3270
  appearance,
3227
3271
  className
3228
3272
  }) {
3229
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
3273
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
3230
3274
  const builtins = {
3231
3275
  profile: {
3232
3276
  label: l10n.profile.tabProfile,
@@ -3253,15 +3297,15 @@ function UserProfile({
3253
3297
  description: t.description
3254
3298
  }))
3255
3299
  ];
3256
- const [internalTab, setInternalTab] = _react.useState.call(void 0, _nullishCoalesce(_nullishCoalesce(defaultTab, () => ( _optionalChain([allTabs, 'access', _65 => _65[0], 'optionalAccess', _66 => _66.id]))), () => ( "profile")));
3300
+ const [internalTab, setInternalTab] = _react.useState.call(void 0, _nullishCoalesce(_nullishCoalesce(defaultTab, () => ( _optionalChain([allTabs, 'access', _70 => _70[0], 'optionalAccess', _71 => _71.id]))), () => ( "profile")));
3257
3301
  const current = _nullishCoalesce(controlledTab, () => ( internalTab));
3258
3302
  const select = (id) => {
3259
3303
  if (controlledTab === void 0) setInternalTab(id);
3260
- _optionalChain([onTabChange, 'optionalCall', _67 => _67(id)]);
3304
+ _optionalChain([onTabChange, 'optionalCall', _72 => _72(id)]);
3261
3305
  };
3262
3306
  const active = _nullishCoalesce(allTabs.find((t) => t.id === current), () => ( allTabs[0]));
3263
3307
  const renderPane = () => {
3264
- switch (_optionalChain([active, 'optionalAccess', _68 => _68.id])) {
3308
+ switch (_optionalChain([active, 'optionalAccess', _73 => _73.id])) {
3265
3309
  case "profile":
3266
3310
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ProfileSection, { verificationCallbackUrl, onSaved });
3267
3311
  case "security":
@@ -3282,7 +3326,7 @@ function UserProfile({
3282
3326
  }
3283
3327
  );
3284
3328
  default:
3285
- return _nullishCoalesce(_optionalChain([extraTabs, 'access', _69 => _69.find, 'call', _70 => _70((t) => t.id === _optionalChain([active, 'optionalAccess', _71 => _71.id])), 'optionalAccess', _72 => _72.content]), () => ( null));
3329
+ return _nullishCoalesce(_optionalChain([extraTabs, 'access', _74 => _74.find, 'call', _75 => _75((t) => t.id === _optionalChain([active, 'optionalAccess', _76 => _76.id])), 'optionalAccess', _77 => _77.content]), () => ( null));
3286
3330
  }
3287
3331
  };
3288
3332
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Shell, { appearance, className, size: "wide", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-profile", children: [
@@ -3291,7 +3335,7 @@ function UserProfile({
3291
3335
  {
3292
3336
  type: "button",
3293
3337
  className: "kerne-nav-item",
3294
- "aria-current": tab.id === _optionalChain([active, 'optionalAccess', _73 => _73.id]) ? "page" : void 0,
3338
+ "aria-current": tab.id === _optionalChain([active, 'optionalAccess', _78 => _78.id]) ? "page" : void 0,
3295
3339
  onClick: () => select(tab.id),
3296
3340
  children: tab.label
3297
3341
  },
@@ -3318,50 +3362,6 @@ function formatEntitlement(e, unlimitedLabel) {
3318
3362
  if (e.limit === -1) return `${unlimitedLabel} ${e.feature_name.toLowerCase()}`;
3319
3363
  return `${formatNumber(e.limit)} ${e.feature_name.toLowerCase()}`;
3320
3364
  }
3321
- function collectLabels(plans) {
3322
- const bySlug = /* @__PURE__ */ new Map();
3323
- for (const plan of plans) {
3324
- for (const price of plan.prices) {
3325
- if (!bySlug.has(price.label.slug)) bySlug.set(price.label.slug, price.label);
3326
- }
3327
- }
3328
- return Array.from(bySlug.values()).sort(
3329
- (a, b) => a.sort_order - b.sort_order || a.name.localeCompare(b.name)
3330
- );
3331
- }
3332
- var ENCODED_INTERVAL_MONTHS = { D: 12 / 365, M: 1, Y: 12 };
3333
- function approxMonths2(value) {
3334
- const match = /^([1-9]\d*)([DMY])$/.exec(value);
3335
- if (!match) return 0;
3336
- return parseInt(match[1], 10) * ENCODED_INTERVAL_MONTHS[match[2]];
3337
- }
3338
- function labelSavings(plans, labels) {
3339
- if (labels.length < 2) return null;
3340
- const priceFor = (labelSlug) => {
3341
- for (const plan of plans) {
3342
- const price = plan.prices.find((p) => p.label.slug === labelSlug);
3343
- if (price) return price;
3344
- }
3345
- return void 0;
3346
- };
3347
- const sorted = [...labels].sort(
3348
- (a, b) => approxMonths2(_nullishCoalesce(_optionalChain([priceFor, 'call', _74 => _74(a.slug), 'optionalAccess', _75 => _75.interval]), () => ( "1M"))) - approxMonths2(_nullishCoalesce(_optionalChain([priceFor, 'call', _76 => _76(b.slug), 'optionalAccess', _77 => _77.interval]), () => ( "1M")))
3349
- );
3350
- const shortest = sorted[0];
3351
- const longest = sorted[sorted.length - 1];
3352
- if (shortest.slug === longest.slug) return null;
3353
- for (const plan of plans) {
3354
- const shortPrice = plan.prices.find((p) => p.label.slug === shortest.slug);
3355
- const longPrice = plan.prices.find((p) => p.label.slug === longest.slug);
3356
- if (!_optionalChain([shortPrice, 'optionalAccess', _78 => _78.amount]) || !longPrice) continue;
3357
- const shortMonths = approxMonths2(shortPrice.interval);
3358
- const longMonths = approxMonths2(longPrice.interval);
3359
- if (!shortMonths || !longMonths) continue;
3360
- const savings = 1 - longPrice.amount / longMonths / (shortPrice.amount / shortMonths);
3361
- if (savings > 0.01) return { labelSlug: longest.slug, percent: Math.round(savings * 100) };
3362
- }
3363
- return null;
3364
- }
3365
3365
  var PricingTableContext = _react.createContext.call(void 0, null);
3366
3366
  function usePricingTable() {
3367
3367
  const ctx = _react.useContext.call(void 0, PricingTableContext);
@@ -3380,39 +3380,39 @@ function PricingTable({
3380
3380
  className,
3381
3381
  children
3382
3382
  }) {
3383
- const { plans, isLoading, error } = _chunkIMZFZ3P5cjs.usePlans.call(void 0, product);
3384
- const { subscription } = _chunkIMZFZ3P5cjs.useSubscription.call(void 0, product);
3385
- const { openCheckout } = _chunkIMZFZ3P5cjs.useCheckout.call(void 0, );
3386
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
3387
- const showError = _chunkIMZFZ3P5cjs.useErrorResolver.call(void 0, );
3383
+ const { plans, isLoading, error } = _chunkTYNZ2WU7cjs.usePlans.call(void 0, product);
3384
+ const { subscription, refetch: refetchSubscription } = _chunkTYNZ2WU7cjs.useSubscription.call(void 0, product);
3385
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
3386
+ const showError = _chunkTYNZ2WU7cjs.useErrorResolver.call(void 0, );
3388
3387
  const [selectedLabelSlug, setSelectedLabelSlug] = _react.useState.call(void 0, _nullishCoalesce(defaultLabel, () => ( null)));
3389
- const [busyPriceId, setBusyPriceId] = _react.useState.call(void 0, null);
3390
- const [checkoutError, setCheckoutError] = _react.useState.call(void 0, null);
3391
- const labels = _react.useMemo.call(void 0, () => collectLabels(plans), [plans]);
3392
- const savings = _react.useMemo.call(void 0, () => labelSavings(plans, labels), [plans, labels]);
3388
+ const {
3389
+ pending: pendingSwitch,
3390
+ switching,
3391
+ switchError,
3392
+ checkoutPriceId: busyPriceId,
3393
+ checkoutError,
3394
+ selectPlan,
3395
+ confirmSwitch,
3396
+ dismissSwitch
3397
+ } = _chunkTYNZ2WU7cjs.usePlanSwitch.call(void 0, subscription, refetchSubscription, {
3398
+ successUrl: checkoutSuccessUrl,
3399
+ cancelUrl: checkoutCancelUrl
3400
+ });
3401
+ const labels = _react.useMemo.call(void 0, () => collectPriceLabels(plans), [plans]);
3402
+ const savings = _react.useMemo.call(void 0, () => resolveLabelSavings(plans, labels), [plans, labels]);
3393
3403
  _react.useEffect.call(void 0, () => {
3394
3404
  if (labels.length === 0) return;
3395
3405
  if (selectedLabelSlug && labels.some((l) => l.slug === selectedLabelSlug)) return;
3396
3406
  setSelectedLabelSlug(labels[0].slug);
3397
3407
  }, [labels]);
3398
- const handleSelectPlan = async (plan) => {
3408
+ const handleSelectPlan = (plan) => {
3399
3409
  const price = _nullishCoalesce(plan.prices.find((p) => p.label.slug === selectedLabelSlug), () => ( plan.prices[0]));
3400
3410
  if (!price) return;
3401
3411
  if (onSelectPlan) {
3402
3412
  onSelectPlan(plan, price);
3403
3413
  return;
3404
3414
  }
3405
- setCheckoutError(null);
3406
- setBusyPriceId(price.id);
3407
- try {
3408
- await openCheckout(price.id, {
3409
- successUrl: checkoutSuccessUrl,
3410
- cancelUrl: checkoutCancelUrl
3411
- });
3412
- } catch (e) {
3413
- setCheckoutError(showError(e));
3414
- setBusyPriceId(null);
3415
- }
3415
+ void selectPlan(plan, price);
3416
3416
  };
3417
3417
  const ctx = {
3418
3418
  plans,
@@ -3425,13 +3425,31 @@ function PricingTable({
3425
3425
  onSelectPlan: handleSelectPlan
3426
3426
  };
3427
3427
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Shell, { appearance, className, size: "wide", children: isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "kerne-pricing-skeleton", "aria-busy": "true", "aria-label": l10n.pricing.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "kerne-skeleton", style: { height: 320 } }) }) : error ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: l10n.pricing.loadFailed }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, PricingTableContext.Provider, { value: ctx, children: [
3428
- checkoutError ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: checkoutError }) : null,
3428
+ checkoutError ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: showError(checkoutError) }) : null,
3429
+ pendingSwitch ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Panel, { children: [
3430
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.billing.switchConfirmTitle, { plan: pendingSwitch.plan.name }) }),
3431
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "kerne-subsection-desc", children: l10n.billing.switchConfirmBody }),
3432
+ switchError ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Panel, { variant: "danger", children: showError(switchError) }) : null,
3433
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-inline-actions", children: [
3434
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3435
+ Button,
3436
+ {
3437
+ variant: "outline",
3438
+ type: "button",
3439
+ onClick: dismissSwitch,
3440
+ disabled: switching,
3441
+ children: l10n.billing.switchConfirmDismiss
3442
+ }
3443
+ ),
3444
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { type: "button", onClick: confirmSwitch, loading: switching, children: switching ? l10n.billing.switching : l10n.billing.switchConfirmButton })
3445
+ ] })
3446
+ ] }) : null,
3429
3447
  children
3430
3448
  ] }) });
3431
3449
  }
3432
3450
  function LabelSwitch() {
3433
3451
  const { labels, selectedLabelSlug, setSelectedLabelSlug, savings } = usePricingTable();
3434
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
3452
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
3435
3453
  const containerRef = _react.useRef.call(void 0, null);
3436
3454
  const buttonRefs = _react.useRef.call(void 0, /* @__PURE__ */ new Map());
3437
3455
  const [thumb, setThumb] = _react.useState.call(void 0, null);
@@ -3478,7 +3496,7 @@ function LabelSwitch() {
3478
3496
  onClick: () => setSelectedLabelSlug(label.slug),
3479
3497
  children: [
3480
3498
  label.name,
3481
- savings && savings.labelSlug === label.slug ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "kerne-pricing-switch-save", children: _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.pricing.save, { percent: savings.percent }) }) : null
3499
+ savings && savings.labelSlug === label.slug ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "kerne-pricing-switch-save", children: _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.pricing.save, { percent: savings.percent }) }) : null
3482
3500
  ]
3483
3501
  },
3484
3502
  label.slug
@@ -3518,7 +3536,7 @@ function useAnimatedAmount(target, durationMs = 420) {
3518
3536
  }
3519
3537
  function Plan({ slug, featured, badge, maxFeatures }) {
3520
3538
  const { plans, selectedLabelSlug, currentPlanId, busyPriceId, onSelectPlan } = usePricingTable();
3521
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
3539
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
3522
3540
  const plan = plans.find((p) => p.slug === slug);
3523
3541
  _react.useEffect.call(void 0, () => {
3524
3542
  if (!plan && process.env.NODE_ENV === "development") {
@@ -3535,7 +3553,7 @@ function Plan({ slug, featured, badge, maxFeatures }) {
3535
3553
  const isBusy = !!price && busyPriceId === price.id;
3536
3554
  const shownEntitlements = maxFeatures ? plan.entitlements.slice(0, maxFeatures) : plan.entitlements;
3537
3555
  const remaining = plan.entitlements.length - shownEntitlements.length;
3538
- const billedCaption = resolved && resolved.displayInterval !== resolved.billedInterval ? _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.pricing.billedAt, {
3556
+ const billedCaption = resolved && resolved.displayInterval !== resolved.billedInterval ? _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.pricing.billedAt, {
3539
3557
  amount: formatMoney(resolved.billedAmount, price.currency),
3540
3558
  interval: formatInterval(resolved.billedInterval, l10n.billing)
3541
3559
  }) : null;
@@ -3566,7 +3584,7 @@ function Plan({ slug, featured, badge, maxFeatures }) {
3566
3584
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CheckIcon2, {}),
3567
3585
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: formatEntitlement(e, l10n.pricing.unlimited) })
3568
3586
  ] }, e.feature_key)),
3569
- remaining > 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "kerne-pricing-feature-more", children: _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.pricing.moreFeatures, { count: remaining }) }) : null
3587
+ remaining > 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "kerne-pricing-feature-more", children: _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.pricing.moreFeatures, { count: remaining }) }) : null
3570
3588
  ] }) : null,
3571
3589
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "kerne-pricing-cta", children: isCurrent ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { variant: "outline", type: "button", disabled: true, children: l10n.billing.current }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3572
3590
  Button,
@@ -3632,9 +3650,9 @@ function CheckoutResult({
3632
3650
  logo,
3633
3651
  className
3634
3652
  }) {
3635
- const client = _chunkIMZFZ3P5cjs.useClient.call(void 0, );
3636
- const { config } = _chunkIMZFZ3P5cjs.useAuthConfig.call(void 0, );
3637
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
3653
+ const client = _chunkTYNZ2WU7cjs.useClient.call(void 0, );
3654
+ const { config } = _chunkTYNZ2WU7cjs.useAuthConfig.call(void 0, );
3655
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
3638
3656
  const [state, setState] = _react.useState.call(void 0, "checking");
3639
3657
  const confirmed = _react.useRef.call(void 0, false);
3640
3658
  _react.useEffect.call(void 0, () => {
@@ -3718,8 +3736,8 @@ function UpgradePrompt({
3718
3736
  appearance,
3719
3737
  className
3720
3738
  }) {
3721
- const { details, allowed, isLoading } = _chunkIMZFZ3P5cjs.useAccess.call(void 0, featureKey, requested);
3722
- const l10n = _chunkIMZFZ3P5cjs.useLocalization.call(void 0, );
3739
+ const { details, allowed, isLoading } = _chunkTYNZ2WU7cjs.useAccess.call(void 0, featureKey, requested);
3740
+ const l10n = _chunkTYNZ2WU7cjs.useLocalization.call(void 0, );
3723
3741
  if (isLoading) {
3724
3742
  if (hideWhileLoading) return null;
3725
3743
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Shell, { appearance, className, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "kerne-skeleton", style: { height: 80 }, "aria-label": l10n.upgrade.checking }) });
@@ -3727,14 +3745,14 @@ function UpgradePrompt({
3727
3745
  if (allowed) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
3728
3746
  const name = _nullishCoalesce(featureName, () => ( humanizeFeatureKey(featureKey).toLowerCase()));
3729
3747
  const quotaExhausted = _optionalChain([details, 'optionalAccess', _92 => _92.feature_type]) === "QUOTA" && typeof details.limit === "number" && typeof details.used === "number";
3730
- const heading = _nullishCoalesce(title, () => ( _chunkIMZFZ3P5cjs.fill.call(void 0, quotaExhausted ? l10n.upgrade.quotaTitle : l10n.upgrade.featureTitle, { feature: name })));
3731
- const body = _nullishCoalesce(description, () => ( (quotaExhausted ? _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.upgrade.quotaBody, {
3748
+ const heading = _nullishCoalesce(title, () => ( _chunkTYNZ2WU7cjs.fill.call(void 0, quotaExhausted ? l10n.upgrade.quotaTitle : l10n.upgrade.featureTitle, { feature: name })));
3749
+ const body = _nullishCoalesce(description, () => ( (quotaExhausted ? _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.upgrade.quotaBody, {
3732
3750
  used: formatNumber(details.used),
3733
3751
  // `access_limit` is where access actually stops; `limit` is only the
3734
3752
  // included allocation and can understate it past an overage ceiling.
3735
3753
  // Falls back to `limit` defensively - should never be needed here.
3736
3754
  limit: formatNumber(_nullishCoalesce(details.access_limit, () => ( details.limit)))
3737
- }) : _chunkIMZFZ3P5cjs.fill.call(void 0, l10n.upgrade.featureBody, { feature: name }))));
3755
+ }) : _chunkTYNZ2WU7cjs.fill.call(void 0, l10n.upgrade.featureBody, { feature: name }))));
3738
3756
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Shell, { appearance, className, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-status", children: [
3739
3757
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-heading", children: [
3740
3758
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "kerne-section-title", style: { fontSize: 17 }, children: heading }),
@@ -3777,4 +3795,12 @@ function UpgradePrompt({
3777
3795
 
3778
3796
 
3779
3797
 
3780
- exports.ActivateAccountForm = ActivateAccountForm; exports.AuthFlow = AuthFlow; exports.BillingSection = BillingSection; exports.ChangePasswordForm = ChangePasswordForm; exports.CheckoutResult = CheckoutResult; exports.ForgotPasswordForm = ForgotPasswordForm; exports.LoginForm = LoginForm; exports.MagicLinkCallback = MagicLinkCallback; exports.PricingTable = PricingTable; exports.ProfileSection = ProfileSection; exports.RegisterForm = RegisterForm; exports.ResetPasswordForm = ResetPasswordForm; exports.SecuritySection = SecuritySection; exports.SignOutButton = SignOutButton; exports.SubscriptionCard = SubscriptionCard; exports.UpgradePrompt = UpgradePrompt; exports.UsageMeters = UsageMeters; exports.UserButton = UserButton; exports.UserProfile = UserProfile; exports.VerifyEmailForm = VerifyEmailForm; exports.WaitlistForm = WaitlistForm; exports.defaultLocalization = _chunkIMZFZ3P5cjs.defaultLocalization; exports.useLocalization = _chunkIMZFZ3P5cjs.useLocalization; exports.usePricingTable = usePricingTable;
3798
+
3799
+
3800
+
3801
+
3802
+
3803
+
3804
+
3805
+
3806
+ exports.ActivateAccountForm = ActivateAccountForm; exports.AuthFlow = AuthFlow; exports.BillingSection = BillingSection; exports.ChangePasswordForm = ChangePasswordForm; exports.CheckoutResult = CheckoutResult; exports.ForgotPasswordForm = ForgotPasswordForm; exports.LoginForm = LoginForm; exports.MagicLinkCallback = MagicLinkCallback; exports.PricingTable = PricingTable; exports.ProfileSection = ProfileSection; exports.RegisterForm = RegisterForm; exports.ResetPasswordForm = ResetPasswordForm; exports.SecuritySection = SecuritySection; exports.SignOutButton = SignOutButton; exports.SubscriptionCard = SubscriptionCard; exports.UpgradePrompt = UpgradePrompt; exports.UsageMeters = UsageMeters; exports.UserButton = UserButton; exports.UserProfile = UserProfile; exports.VerifyEmailForm = VerifyEmailForm; exports.WaitlistForm = WaitlistForm; exports.collectPriceLabels = collectPriceLabels; exports.defaultLocalization = _chunkTYNZ2WU7cjs.defaultLocalization; exports.formatDate = formatDate; exports.formatInterval = formatInterval; exports.formatMoney = formatMoney; exports.formatNumber = formatNumber; exports.humanizeFeatureKey = humanizeFeatureKey; exports.resolveLabelSavings = resolveLabelSavings; exports.resolvePriceDisplay = resolvePriceDisplay; exports.useLocalization = _chunkTYNZ2WU7cjs.useLocalization; exports.usePricingTable = usePricingTable;