@getauthui/core 0.1.2 → 0.1.4

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.
Files changed (41) hide show
  1. package/README.md +25 -5
  2. package/dist/active-team.d.ts +4 -0
  3. package/dist/active-team.d.ts.map +1 -0
  4. package/dist/{authui-user-button-C64OcOdr.js → authui-user-button-CZBp3mFt.js} +1666 -810
  5. package/dist/authui.cdn.js +630 -283
  6. package/dist/authui.cdn.mjs +2609 -1753
  7. package/dist/authui.js +57 -48
  8. package/dist/components/authui-account.d.ts +15 -1
  9. package/dist/components/authui-account.d.ts.map +1 -1
  10. package/dist/components/authui-config.d.ts +1 -1
  11. package/dist/components/authui-config.d.ts.map +1 -1
  12. package/dist/components/authui-modal.d.ts +1 -0
  13. package/dist/components/authui-modal.d.ts.map +1 -1
  14. package/dist/components/authui-show.d.ts +10 -0
  15. package/dist/components/authui-show.d.ts.map +1 -1
  16. package/dist/components/authui-sign-in.d.ts +6 -0
  17. package/dist/components/authui-sign-in.d.ts.map +1 -1
  18. package/dist/components/authui-user-button.d.ts +10 -0
  19. package/dist/components/authui-user-button.d.ts.map +1 -1
  20. package/dist/components/sign-in.styles.d.ts.map +1 -1
  21. package/dist/errors.d.ts +6 -1
  22. package/dist/errors.d.ts.map +1 -1
  23. package/dist/i18n.d.ts.map +1 -1
  24. package/dist/icons.d.ts +3 -0
  25. package/dist/icons.d.ts.map +1 -1
  26. package/dist/index.d.ts +6 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/last-method.d.ts +7 -0
  29. package/dist/last-method.d.ts.map +1 -0
  30. package/dist/password-strength.d.ts +21 -0
  31. package/dist/password-strength.d.ts.map +1 -0
  32. package/dist/preview.d.ts.map +1 -1
  33. package/dist/react/index.d.ts +1 -0
  34. package/dist/react/index.d.ts.map +1 -1
  35. package/dist/react.js +1 -1
  36. package/dist/store.d.ts +23 -0
  37. package/dist/store.d.ts.map +1 -1
  38. package/dist/styles/base.d.ts.map +1 -1
  39. package/dist/types.d.ts +63 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/package.json +2 -2
@@ -1,13 +1,16 @@
1
- import { state as d, property as f, customElement as _, query as rt } from "lit/decorators.js";
2
- import { css as I, LitElement as X, nothing as o, html as s, svg as l } from "lit";
3
- import { Client as ot, Account as ct, ID as V, Avatars as lt } from "appwrite";
4
- const dt = {
1
+ import { state as h, property as g, customElement as O, query as gt } from "lit/decorators.js";
2
+ import { css as F, LitElement as it, nothing as o, html as r, svg as d } from "lit";
3
+ import { Client as at, Account as nt, Teams as bt, ID as j, Avatars as yt } from "appwrite";
4
+ const wt = {
5
5
  signIn: "Sign in",
6
+ dialogSignIn: "Sign in",
6
7
  signUp: "Sign up",
7
8
  signOut: "Sign out",
8
9
  continueAsGuest: "Continue as guest",
9
10
  email: "Email",
10
11
  password: "Password",
12
+ showPassword: "Show password",
13
+ hidePassword: "Hide password",
11
14
  newPassword: "New password",
12
15
  confirmPassword: "Confirm password",
13
16
  name: "Name",
@@ -23,6 +26,9 @@ const dt = {
23
26
  continueWithPhone: "Continue with phone",
24
27
  sendMagicLink: "Send magic link",
25
28
  sendCode: "Send code",
29
+ resendCode: "Resend code",
30
+ useDifferentEmail: "Use a different email",
31
+ useDifferentPhone: "Use a different phone number",
26
32
  verifyCode: "Verify code",
27
33
  magicLinkSent: "We sent a sign-in link to {email}. Open it on this device to continue.",
28
34
  codeSent: "We sent a code to {target}. Enter it below to continue.",
@@ -38,6 +44,7 @@ const dt = {
38
44
  resetLinkSent: "If an account exists for {email}, a reset link is on its way.",
39
45
  passwordUpdated: "Your password was updated. You can sign in now.",
40
46
  sendResetLink: "Send reset link",
47
+ requestNewLink: "Request a new link",
41
48
  agreeTo: "By continuing you agree to our",
42
49
  terms: "Terms of Service",
43
50
  privacy: "Privacy Policy",
@@ -63,21 +70,28 @@ const dt = {
63
70
  verified: "Verified",
64
71
  unverified: "Unverified",
65
72
  verifyEmail: "Verify email",
73
+ verificationResendIn: "Sent. You can resend in {seconds} s",
66
74
  verificationSent: "Verification email sent. Check your inbox.",
67
75
  emailVerified: "Your email is verified.",
68
76
  changePassword: "Change password",
69
77
  currentPassword: "Current password",
70
78
  twoFactor: "Two-factor authentication",
79
+ mfaBadge: "MFA",
71
80
  twoFactorDescription: "Require a second factor when signing in to this account.",
81
+ mfaNoFactorWarning: "Turn on an authenticator, or verify your email or phone, before enabling two-factor authentication. Without a factor, this setting does not protect the account.",
72
82
  enable: "Enable",
73
83
  disable: "Disable",
74
84
  authenticatorApp: "Authenticator app",
75
85
  authenticatorAdd: "Add authenticator",
76
86
  authenticatorScan: "Scan this QR code with your authenticator app, then enter the 6-digit code.",
87
+ qrCodeAlt: "QR code",
77
88
  authenticatorManual: "Or enter this key manually",
89
+ authenticatorCopyKey: "Copy key",
78
90
  authenticatorVerify: "Verify and enable",
79
91
  recoveryCodes: "Recovery codes",
92
+ viewRecoveryCodes: "View recovery codes",
80
93
  recoveryCodesDescription: "Use a recovery code to sign in if you lose access to your other factors.",
94
+ recoveryCodesOnceHint: "Recovery codes can be viewed only once after they are generated. Viewing them again requires a recent second factor.",
81
95
  generateRecoveryCodes: "Generate recovery codes",
82
96
  regenerateRecoveryCodes: "Regenerate",
83
97
  recoveryCodesWarning: "Store these codes somewhere safe. Each code works once.",
@@ -87,16 +101,34 @@ const dt = {
87
101
  signOutAllSessionsDescription: "End every session, including this one.",
88
102
  noConnections: "No connected accounts.",
89
103
  disconnect: "Disconnect",
104
+ connectProvider: "Connect {provider}",
90
105
  noActivity: "No recent activity.",
106
+ noSessions: "No active sessions.",
91
107
  deleteAccount: "Delete account",
92
- deleteAccountDescription: "Your account is disabled and you are signed out. An administrator can restore it.",
108
+ deleteAccountDescription: "Deleting disables your account and signs you out everywhere. An administrator can restore it.",
93
109
  deleteAccountConfirm: "Delete my account",
94
110
  loading: "Loading",
95
111
  copied: "Copied",
112
+ copyFailed: "Could not copy. Select the text and copy it manually.",
96
113
  copy: "Copy",
97
114
  done: "Done",
115
+ nameUpdated: "Name updated.",
116
+ emailUpdated: "Email updated. Verify the new address.",
117
+ phoneUpdated: "Phone number updated.",
118
+ phoneVerified: "Phone verified.",
119
+ authenticatorAdded: "Authenticator added.",
120
+ accountConverted: "Account created.",
121
+ enabled: "Enabled",
122
+ disabled: "Disabled",
123
+ createPassword: "Create a password",
124
+ createPasswordHint: "This becomes your sign-in password.",
125
+ errorCurrentPassword: "Current password is incorrect.",
98
126
  errorGeneric: "Something went wrong. Please try again.",
99
127
  errorInvalidCredentials: "Invalid email or password.",
128
+ errorInvalidEmail: "Enter a valid email address.",
129
+ errorInvalidPassword: "Password must be between 8 and 256 characters.",
130
+ errorInvalidPhone: "Enter a phone number in E.164 format, starting with +.",
131
+ errorInvalidName: "Enter a name.",
100
132
  errorUserExists: "An account with this email already exists.",
101
133
  errorUserBlocked: "This account is blocked. Contact support.",
102
134
  errorRateLimit: "Too many attempts. Wait a moment and try again.",
@@ -113,9 +145,23 @@ const dt = {
113
145
  errorNetwork: "Could not reach the server. Check your connection.",
114
146
  errorMethodDisabled: "This sign-in method is disabled for this project.",
115
147
  errorNotConfigured: "Auth UI is not configured. Call AuthUI.init() or add <authui-config>.",
148
+ errorConfigIncomplete: "Auth UI is missing endpoint or project. Set them on <authui-config> or pass them to AuthUI.init().",
149
+ errorConfig: "Auth UI cannot reach this Appwrite project. Check that endpoint ends with /v1, the project ID is correct, and this hostname is registered as a Web platform.",
150
+ errorConfigEndpoint: "Check that endpoint ends with /v1. Appwrite API URLs look like https://cloud.appwrite.io/v1.",
116
151
  passwordHint: "At least 8 characters.",
152
+ passwordStrengthLabel: "Password strength",
153
+ passwordStrengthTooWeak: "Too weak",
154
+ passwordStrengthWeak: "Weak",
155
+ passwordStrengthFair: "Fair",
156
+ passwordStrengthStrong: "Strong",
157
+ passwordStrengthVeryStrong: "Very strong",
158
+ lastUsed: "Last used",
159
+ teamsLabel: "Teams",
160
+ noTeams: "You are not on any teams yet.",
161
+ activeTeam: "Active",
117
162
  signedInAs: "Signed in as",
118
163
  manageAccount: "Manage account",
164
+ dialogAccount: "Account",
119
165
  continue: "Continue",
120
166
  provider: "Provider",
121
167
  lastActive: "Last active",
@@ -123,13 +169,13 @@ const dt = {
123
169
  guestAccountDescription: "Add an email and password to keep your data.",
124
170
  preview: "Preview"
125
171
  };
126
- function ht(e, t = {}) {
172
+ function $t(e, t = {}) {
127
173
  return e.replace(
128
174
  /\{(\w+)\}/g,
129
- (i, r) => r in t ? String(t[r]) : `{${r}}`
175
+ (i, s) => s in t ? String(t[s]) : `{${s}}`
130
176
  );
131
177
  }
132
- const ut = {
178
+ const xt = {
133
179
  amazon: "Amazon",
134
180
  apple: "Apple",
135
181
  appwrite: "Appwrite",
@@ -180,10 +226,10 @@ const ut = {
180
226
  zoho: "Zoho",
181
227
  zoom: "Zoom"
182
228
  };
183
- function D(e) {
184
- return ut[e] ?? e.charAt(0).toUpperCase() + e.slice(1);
229
+ function q(e) {
230
+ return xt[e] ?? e.charAt(0).toUpperCase() + e.slice(1);
185
231
  }
186
- const q = (e, t, i = 401) => Object.assign(new Error(t), { type: e, code: i }), P = () => (/* @__PURE__ */ new Date()).toISOString(), M = (e) => new Date(Date.now() - e * 6e4).toISOString(), T = [
232
+ const H = (e, t, i = 401) => Object.assign(new Error(t), { type: e, code: i }), P = () => (/* @__PURE__ */ new Date()).toISOString(), U = (e) => new Date(Date.now() - e * 6e4).toISOString(), W = [
187
233
  "amber",
188
234
  "brave",
189
235
  "calm",
@@ -196,13 +242,13 @@ const q = (e, t, i = 401) => Object.assign(new Error(t), { type: e, code: i }),
196
242
  "juniper",
197
243
  "kite",
198
244
  "lumen"
199
- ], Z = () => `${T[Math.floor(Math.random() * T.length)]}-${T[Math.floor(Math.random() * T.length)]}`, F = () => Math.random().toString(36).slice(2, 12), J = () => Array.from({ length: 2 }, () => Math.random().toString(36).slice(2, 7)).join("-"), pt = {
245
+ ], ot = () => `${W[Math.floor(Math.random() * W.length)]}-${W[Math.floor(Math.random() * W.length)]}`, T = () => Math.random().toString(36).slice(2, 12), ct = () => Array.from({ length: 2 }, () => Math.random().toString(36).slice(2, 7)).join("-"), kt = {
200
246
  name: "Ada Lovelace",
201
247
  email: "ada@example.com",
202
248
  phone: "+15550100"
203
249
  };
204
- class ft {
205
- constructor(t = pt) {
250
+ class Ct {
251
+ constructor(t = kt) {
206
252
  this.seed = t, this.user = null, this.mfaPending = !1, this.mfaEnabled = !1, this.totpEnrolled = !1, this.recoveryCodes = [], this.lastChallenge = 0, this.sessions = [], this.identities = [], this.logs = [], this.tokens = /* @__PURE__ */ new Map(), this.pendingAuthenticator = null;
207
253
  }
208
254
  // ───────────────────────── helpers ─────────────────────────
@@ -210,13 +256,13 @@ class ft {
210
256
  const i = t.anonymous ?? !1;
211
257
  return this.user = {
212
258
  $id: "preview-user",
213
- $createdAt: M(1440 * 30),
259
+ $createdAt: U(1440 * 30),
214
260
  $updatedAt: P(),
215
261
  name: i ? "" : t.name ?? this.seed.name,
216
- registration: M(1440 * 30),
262
+ registration: U(1440 * 30),
217
263
  status: !0,
218
264
  labels: [],
219
- passwordUpdate: i ? "" : M(1440 * 7),
265
+ passwordUpdate: i ? "" : U(1440 * 7),
220
266
  email: i ? "" : t.email ?? this.seed.email,
221
267
  phone: i ? "" : t.phone ?? this.seed.phone,
222
268
  emailVerification: !i,
@@ -266,8 +312,8 @@ class ft {
266
312
  },
267
313
  {
268
314
  ...i,
269
- $id: F(),
270
- $createdAt: M(300),
315
+ $id: T(),
316
+ $createdAt: U(300),
271
317
  provider: t,
272
318
  ip: "198.51.100.7",
273
319
  osCode: "IOS",
@@ -283,8 +329,8 @@ class ft {
283
329
  },
284
330
  {
285
331
  ...i,
286
- $id: F(),
287
- $createdAt: M(1440 * 3),
332
+ $id: T(),
333
+ $createdAt: U(1440 * 3),
288
334
  provider: "oauth2",
289
335
  ip: "192.0.2.90",
290
336
  osCode: "WIN",
@@ -299,8 +345,8 @@ class ft {
299
345
  ], this.identities = [
300
346
  {
301
347
  $id: "identity-github",
302
- $createdAt: M(1440 * 20),
303
- $updatedAt: M(1440 * 20),
348
+ $createdAt: U(1440 * 20),
349
+ $updatedAt: U(1440 * 20),
304
350
  userId: "preview-user",
305
351
  provider: "github",
306
352
  providerUid: "8675309",
@@ -320,7 +366,7 @@ class ft {
320
366
  },
321
367
  {
322
368
  event: "user.update.name",
323
- time: M(1440 * 2),
369
+ time: U(1440 * 2),
324
370
  clientName: "Safari",
325
371
  osName: "iOS",
326
372
  countryName: "Germany",
@@ -328,7 +374,7 @@ class ft {
328
374
  },
329
375
  {
330
376
  event: "session.create",
331
- time: M(1440 * 3),
377
+ time: U(1440 * 3),
332
378
  clientName: "Firefox",
333
379
  osName: "Windows",
334
380
  countryName: "United States",
@@ -338,9 +384,9 @@ class ft {
338
384
  }
339
385
  requireUser() {
340
386
  if (!this.user)
341
- throw q("general_unauthorized_scope", "User (role: guests) missing scope (account)");
387
+ throw H("general_unauthorized_scope", "User (role: guests) missing scope (account)");
342
388
  if (this.mfaPending)
343
- throw q(
389
+ throw H(
344
390
  "user_more_factors_required",
345
391
  "More factors are required to complete the sign in process."
346
392
  );
@@ -348,7 +394,7 @@ class ft {
348
394
  }
349
395
  requireRecentChallenge() {
350
396
  if (Date.now() - this.lastChallenge > 30 * 6e4)
351
- throw q(
397
+ throw H(
352
398
  "user_challenge_required",
353
399
  "A recently successful challenge is required to complete this action."
354
400
  );
@@ -358,7 +404,7 @@ class ft {
358
404
  this.mfaPending = !!(this.user?.mfa && t);
359
405
  }
360
406
  async delay(t, i = 150) {
361
- return await new Promise((r) => setTimeout(r, i)), typeof t == "function" ? t() : t;
407
+ return await new Promise((s) => setTimeout(s, i)), typeof t == "function" ? t() : t;
362
408
  }
363
409
  /** Sign the preview user in directly (used by the playground). */
364
410
  signInDirectly() {
@@ -368,7 +414,7 @@ class ft {
368
414
  async get() {
369
415
  return this.delay(() => this.requireUser(), 120);
370
416
  }
371
- async create(t, i, r, a) {
417
+ async create(t, i, s, a) {
372
418
  return this.delay(() => this.makeUser({ email: i, name: a || i.split("@")[0] }));
373
419
  }
374
420
  async createEmailPasswordSession(t) {
@@ -384,26 +430,26 @@ class ft {
384
430
  }
385
431
  async createMagicURLToken(t, i) {
386
432
  return this.tokens.set(t, { email: i }), this.delay({
387
- $id: F(),
433
+ $id: T(),
388
434
  $createdAt: P(),
389
435
  userId: t,
390
436
  secret: "",
391
437
  expire: "",
392
- phrase: Z()
438
+ phrase: ot()
393
439
  });
394
440
  }
395
441
  async createEmailToken(t, i) {
396
442
  return this.tokens.set(t, { email: i }), this.delay({
397
- $id: F(),
443
+ $id: T(),
398
444
  $createdAt: P(),
399
445
  userId: t,
400
446
  secret: "",
401
447
  expire: "",
402
- phrase: Z()
448
+ phrase: ot()
403
449
  });
404
450
  }
405
451
  async createPhoneToken(t, i) {
406
- return this.tokens.set(t, { phone: i }), this.delay({ $id: F(), $createdAt: P(), userId: t, secret: "", expire: "", phrase: "" });
452
+ return this.tokens.set(t, { phone: i }), this.delay({ $id: T(), $createdAt: P(), userId: t, secret: "", expire: "", phrase: "" });
407
453
  }
408
454
  async createSession(t) {
409
455
  return this.delay(() => {
@@ -467,7 +513,10 @@ class ft {
467
513
  return this.delay(() => (this.requireUser(), { total: this.sessions.length, sessions: this.sessions }));
468
514
  }
469
515
  async deleteSession(t = "current") {
470
- return this.delay(() => (t === "current" ? this.reset() : this.sessions = this.sessions.filter((i) => i.$id !== t), {}));
516
+ return this.delay(() => {
517
+ const i = this.sessions.find((s) => s.$id === t);
518
+ return t === "current" || i?.current ? this.reset() : this.sessions = this.sessions.filter((s) => s.$id !== t), {};
519
+ });
471
520
  }
472
521
  async deleteSessions() {
473
522
  return this.delay(() => (this.reset(), {}));
@@ -492,7 +541,7 @@ class ft {
492
541
  });
493
542
  }
494
543
  async createMFAChallenge() {
495
- return this.delay({ $id: F(), $createdAt: P(), userId: "preview-user", expire: "" });
544
+ return this.delay({ $id: T(), $createdAt: P(), userId: "preview-user", expire: "" });
496
545
  }
497
546
  async updateMFAChallenge() {
498
547
  return this.delay(() => (this.mfaPending = !1, this.lastChallenge = Date.now(), this.sessions[0]));
@@ -521,35 +570,35 @@ class ft {
521
570
  async createMFARecoveryCodes() {
522
571
  return this.delay(() => {
523
572
  if (this.recoveryCodes.length > 0)
524
- throw q("user_recovery_codes_already_exists", "Recovery codes already generated.", 409);
525
- return this.recoveryCodes = Array.from({ length: 6 }, J), { recoveryCodes: this.recoveryCodes };
573
+ throw H("user_recovery_codes_already_exists", "Recovery codes already generated.", 409);
574
+ return this.recoveryCodes = Array.from({ length: 6 }, ct), { recoveryCodes: this.recoveryCodes };
526
575
  });
527
576
  }
528
577
  async getMFARecoveryCodes() {
529
578
  return this.delay(() => (this.requireRecentChallenge(), { recoveryCodes: this.recoveryCodes }));
530
579
  }
531
580
  async updateMFARecoveryCodes() {
532
- return this.delay(() => (this.requireRecentChallenge(), this.recoveryCodes = Array.from({ length: 6 }, J), { recoveryCodes: this.recoveryCodes }));
581
+ return this.delay(() => (this.requireRecentChallenge(), this.recoveryCodes = Array.from({ length: 6 }, ct), { recoveryCodes: this.recoveryCodes }));
533
582
  }
534
583
  /** Forget everything, as a sign out would. */
535
584
  reset() {
536
585
  this.user = null, this.mfaPending = !1, this.sessions = [], this.identities = [], this.logs = [], this.tokens.clear();
537
586
  }
538
587
  }
539
- function mt(e) {
588
+ function St(e) {
540
589
  let t = 2166136261;
541
590
  const i = () => (t ^= t << 13, t ^= t >>> 17, t ^= t << 5, (t >>> 0) / 4294967296);
542
591
  for (const x of e) t = (t ^ x.charCodeAt(0)) * 16777619;
543
- const r = 25;
592
+ const s = 25;
544
593
  let a = "";
545
- const h = (x, S) => `<rect x="${x}" y="${S}" width="7" height="7"/><rect x="${x + 1}" y="${S + 1}" width="5" height="5" fill="#fff"/><rect x="${x + 2}" y="${S + 2}" width="3" height="3"/>`;
546
- for (let x = 0; x < r; x++)
547
- for (let S = 0; S < r; S++)
548
- !(S < 8 && x < 8 || S >= r - 8 && x < 8 || S < 8 && x >= r - 8) && i() < 0.45 && (a += `<rect x="${S}" y="${x}" width="1" height="1"/>`);
549
- const u = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${r} ${r}" shape-rendering="crispEdges"><rect width="${r}" height="${r}" fill="#fff"/><g fill="#000">${h(0, 0)}${h(r - 7, 0)}${h(0, r - 7)}${a}</g></svg>`;
594
+ const l = (x, C) => `<rect x="${x}" y="${C}" width="7" height="7"/><rect x="${x + 1}" y="${C + 1}" width="5" height="5" fill="#fff"/><rect x="${x + 2}" y="${C + 2}" width="3" height="3"/>`;
595
+ for (let x = 0; x < s; x++)
596
+ for (let C = 0; C < s; C++)
597
+ !(C < 8 && x < 8 || C >= s - 8 && x < 8 || C < 8 && x >= s - 8) && i() < 0.45 && (a += `<rect x="${C}" y="${x}" width="1" height="1"/>`);
598
+ const u = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${s} ${s}" shape-rendering="crispEdges"><rect width="${s}" height="${s}" fill="#fff"/><g fill="#000">${l(0, 0)}${l(s - 7, 0)}${l(0, s - 7)}${a}</g></svg>`;
550
599
  return `data:image/svg+xml;utf8,${encodeURIComponent(u)}`;
551
600
  }
552
- const v = {
601
+ const f = {
553
602
  moreFactorsRequired: "user_more_factors_required",
554
603
  invalidCredentials: "user_invalid_credentials",
555
604
  userAlreadyExists: "user_already_exists",
@@ -569,6 +618,8 @@ const v = {
569
618
  recoveryCodesNotFound: "user_recovery_codes_not_found",
570
619
  authenticatorNotFound: "user_authenticator_not_found",
571
620
  routeNotFound: "general_route_not_found",
621
+ projectNotFound: "project_not_found",
622
+ unknownOrigin: "general_unknown_origin",
572
623
  emailAlreadyVerified: "user_email_already_verified",
573
624
  sessionNotFound: "user_session_not_found",
574
625
  wafChallenged: "waf_request_challenged",
@@ -579,64 +630,90 @@ const v = {
579
630
  userUnauthorized: "user_unauthorized",
580
631
  authMethodUnsupported: "user_auth_method_unsupported",
581
632
  countMaxExceeded: "user_count_exceeded",
582
- targetAlreadyExists: "user_target_already_exists"
633
+ targetAlreadyExists: "user_target_already_exists",
634
+ argumentInvalid: "general_argument_invalid"
583
635
  };
584
- function N(e) {
636
+ function R(e) {
585
637
  if (e && typeof e == "object") {
586
638
  const t = e;
587
- return {
588
- message: typeof t.message == "string" ? t.message : "Unknown error",
639
+ let i = typeof t.message == "string" ? t.message : "Unknown error";
640
+ return /^\s*<(!doctype|html)/i.test(i) && (i = ""), {
641
+ message: i,
589
642
  type: typeof t.type == "string" ? t.type : "",
590
643
  code: typeof t.code == "number" ? t.code : 0
591
644
  };
592
645
  }
593
646
  return { message: String(e), type: "", code: 0 };
594
647
  }
595
- function B(e, t) {
596
- return N(e).type === t;
648
+ function N(e, t) {
649
+ return R(e).type === t;
597
650
  }
598
- function at(e, t, i = "link") {
599
- const r = N(e);
600
- switch (r.type) {
601
- case v.invalidCredentials:
602
- return t.errorInvalidCredentials;
603
- case v.userAlreadyExists:
604
- case v.emailAlreadyExists:
605
- case v.phoneAlreadyExists:
651
+ function K(e, t, i = "link") {
652
+ const s = R(e);
653
+ switch (s.type) {
654
+ case f.invalidCredentials:
655
+ return i === "password" ? t.errorCurrentPassword : t.errorInvalidCredentials;
656
+ case f.userAlreadyExists:
657
+ case f.emailAlreadyExists:
658
+ case f.phoneAlreadyExists:
606
659
  return t.errorUserExists;
607
- case v.userBlocked:
660
+ case f.userBlocked:
608
661
  return t.errorUserBlocked;
609
- case v.rateLimit:
662
+ case f.rateLimit:
610
663
  return t.errorRateLimit;
611
- case v.invalidToken:
664
+ case f.invalidToken:
612
665
  return i === "code" ? t.errorInvalidCode : t.errorInvalidToken;
613
- case v.invalidCode:
666
+ case f.invalidCode:
614
667
  return t.errorInvalidCode;
615
- case v.passwordMismatch:
668
+ case f.passwordMismatch:
616
669
  return t.errorPasswordMismatch;
617
- case v.passwordRecentlyUsed:
670
+ case f.passwordRecentlyUsed:
618
671
  return t.errorPasswordRecentlyUsed;
619
- case v.passwordPersonalData:
672
+ case f.passwordPersonalData:
620
673
  return t.errorPasswordPersonalData;
621
- case v.passwordWeak:
674
+ case f.passwordWeak:
622
675
  return t.errorPasswordWeak;
623
- case v.passwordPwned:
676
+ case f.passwordPwned:
624
677
  return t.errorPasswordPwned;
625
- case v.challengeRequired:
678
+ case f.challengeRequired:
626
679
  return t.errorChallengeRequired;
627
- case v.sessionAlreadyExists:
680
+ case f.sessionAlreadyExists:
628
681
  return t.errorSessionExists;
629
- case v.oauthUnauthorized:
630
- case v.oauthBadRequest:
682
+ case f.oauthUnauthorized:
683
+ case f.oauthBadRequest:
631
684
  return t.errorOAuth;
632
- case v.authMethodUnsupported:
685
+ case f.authMethodUnsupported:
633
686
  return t.errorMethodDisabled;
634
687
  }
635
- return r.code === 0 && /fetch|network/i.test(r.message) ? t.errorNetwork : r.message || t.errorGeneric;
688
+ if (s.type === f.argumentInvalid || /Invalid `\w+` param/i.test(s.message)) {
689
+ const a = s.message.match(/Invalid `([^`]+)` param/i)?.[1]?.toLowerCase();
690
+ return a === "email" ? t.errorInvalidEmail : a === "password" ? t.errorInvalidPassword : a === "phone" ? t.errorInvalidPhone : a === "name" ? t.errorInvalidName : t.errorGeneric;
691
+ }
692
+ return s.type === f.projectNotFound || s.type === f.unknownOrigin ? t.errorConfig : s.type === f.routeNotFound ? t.errorConfigEndpoint : s.code === 0 && /fetch|network/i.test(s.message) ? t.errorNetwork : /Invalid `\w+` param/i.test(s.message) ? t.errorGeneric : s.message ? s.message || t.errorGeneric : s.code === 404 || s.type === f.routeNotFound ? t.errorConfigEndpoint : t.errorGeneric;
693
+ }
694
+ function Pt(e) {
695
+ const t = R(e);
696
+ return !!(t.type === f.projectNotFound || t.type === f.unknownOrigin || t.type === f.routeNotFound || !t.message && t.code === 404 || t.code === 0 && /fetch|network|load failed|failed to fetch/i.test(t.message));
697
+ }
698
+ const Q = (e) => `authui:active-team:${e}`;
699
+ function lt(e) {
700
+ if (typeof localStorage > "u" || !e) return null;
701
+ try {
702
+ return localStorage.getItem(Q(e));
703
+ } catch {
704
+ return null;
705
+ }
636
706
  }
637
- function k(e, t, i) {
638
- for (const r of t) {
639
- const a = e[r];
707
+ function At(e, t) {
708
+ if (!(typeof localStorage > "u" || !e))
709
+ try {
710
+ t ? localStorage.setItem(Q(e), t) : localStorage.removeItem(Q(e));
711
+ } catch {
712
+ }
713
+ }
714
+ function S(e, t, i) {
715
+ for (const s of t) {
716
+ const a = e[s];
640
717
  if (typeof a == "function")
641
718
  return a.apply(e, i);
642
719
  }
@@ -644,21 +721,41 @@ function k(e, t, i) {
644
721
  new Error(`Appwrite SDK is missing ${t[0]}(). Update the appwrite package.`)
645
722
  );
646
723
  }
647
- const G = "authui", tt = ["userId", "secret", "expire", "project", "error", G], et = () => ({
724
+ const J = "authui", dt = ["userId", "secret", "expire", "project", "error", J], ht = () => ({
648
725
  status: "loading",
649
726
  user: null,
650
727
  mfaFactors: null,
651
728
  pending: null,
652
- configured: !1
729
+ configured: !1,
730
+ configError: null
653
731
  });
654
- class gt {
732
+ class Ut {
655
733
  constructor() {
656
- this.client = null, this.account = null, this.config = null, this.state = et(), this.listeners = /* @__PURE__ */ new Map(), this.refreshPromise = null, this.preview = null;
734
+ this.client = null, this.account = null, this.config = null, this.state = ht(), this.listeners = /* @__PURE__ */ new Map(), this.refreshPromise = null, this.preview = null, this.teams = null, this.activeTeamId = null;
657
735
  }
658
736
  // ───────────────────────────── configuration ─────────────────────────────
659
737
  /** Configure the Appwrite client. Safe to call more than once; the last call wins. */
660
738
  configure(t) {
661
- this.config = t, this.client = new ot().setEndpoint(t.endpoint).setProject(t.project), this.preview = t.preview ? new ft() : null, this.account = this.preview ? this.preview : new ct(this.client), this.setState({ configured: !0, status: "loading" }), this.preview ? this.refresh() : typeof window < "u" && this.handleRedirect().then(() => this.refresh());
739
+ const i = t.endpoint.trim().replace(/\/+$/, "");
740
+ i && !i.endsWith("/v1") && console.warn(
741
+ `[authui] endpoint should end with /v1 (got "${t.endpoint}"). Without it Appwrite returns HTML 404 pages.`
742
+ ), this.config = t, this.client = new at().setEndpoint(t.endpoint).setProject(t.project), this.preview = t.preview ? new Ct() : null, this.account = this.preview ? this.preview : new nt(this.client), this.teams = null, this.activeTeamId = lt(t.project), this.setState({ configured: !0, status: "loading", configError: null }), this.preview ? this.refresh() : typeof window < "u" && this.handleRedirect().then(() => this.refresh());
743
+ }
744
+ /**
745
+ * Called by <authui-config> when it is on the page but missing endpoint or project.
746
+ * Moves status off "loading" so the UI can show a developer-facing message.
747
+ */
748
+ notifyConfigIncomplete() {
749
+ if (this.config) return;
750
+ const t = this.getStrings().errorConfigIncomplete;
751
+ console.warn(`[authui] ${t}`), this.setState({
752
+ status: "signed-out",
753
+ user: null,
754
+ mfaFactors: null,
755
+ configured: !1,
756
+ configError: t,
757
+ pending: { type: "notice", tone: "error", message: t }
758
+ });
662
759
  }
663
760
  get isConfigured() {
664
761
  return this.config !== null;
@@ -685,8 +782,31 @@ class gt {
685
782
  getAccount() {
686
783
  return this.account;
687
784
  }
785
+ /** List teams the signed-in user belongs to. Empty in preview or when signed out. */
786
+ async listTeams() {
787
+ if (this.preview || !this.client || this.state.status !== "signed-in") return [];
788
+ this.teams ??= new bt(this.client);
789
+ try {
790
+ return (await this.teams.list()).teams ?? [];
791
+ } catch (t) {
792
+ this.fail(t);
793
+ }
794
+ }
795
+ getActiveTeamId() {
796
+ if (this.activeTeamId) return this.activeTeamId;
797
+ const t = this.config?.project;
798
+ return t ? (this.activeTeamId = lt(t), this.activeTeamId) : null;
799
+ }
800
+ /**
801
+ * Remember the active team locally and emit `active-team`.
802
+ * Does not call Appwrite; membership is already required to appear in listTeams().
803
+ */
804
+ setActiveTeam(t) {
805
+ const i = this.config?.project;
806
+ i && At(i, t?.$id ?? null), this.activeTeamId = t?.$id ?? null, this.emit("active-team", { teamId: this.activeTeamId, team: t });
807
+ }
688
808
  getStrings() {
689
- return { ...dt, ...this.config?.strings ?? {} };
809
+ return { ...wt, ...this.config?.strings ?? {} };
690
810
  }
691
811
  getState() {
692
812
  return { ...this.state };
@@ -696,13 +816,13 @@ class gt {
696
816
  }
697
817
  // ─────────────────────────────── events ───────────────────────────────
698
818
  on(t, i) {
699
- let r = this.listeners.get(t);
700
- return r || (r = /* @__PURE__ */ new Set(), this.listeners.set(t, r)), r.add(i), () => r.delete(i);
819
+ let s = this.listeners.get(t);
820
+ return s || (s = /* @__PURE__ */ new Set(), this.listeners.set(t, s)), s.add(i), () => s.delete(i);
701
821
  }
702
822
  emit(t, i) {
703
- this.listeners.get(t)?.forEach((r) => {
823
+ this.listeners.get(t)?.forEach((s) => {
704
824
  try {
705
- r(i);
825
+ s(i);
706
826
  } catch (a) {
707
827
  console.error("[authui] listener failed", a);
708
828
  }
@@ -712,7 +832,7 @@ class gt {
712
832
  this.state = { ...this.state, ...t }, this.emit("change", this.getState());
713
833
  }
714
834
  fail(t) {
715
- const i = N(t);
835
+ const i = R(t);
716
836
  throw this.emit("error", i), t;
717
837
  }
718
838
  acct() {
@@ -730,43 +850,94 @@ class gt {
730
850
  const t = this.state.status === "signed-in";
731
851
  try {
732
852
  const i = await this.account.get();
733
- this.setState({ status: "signed-in", user: i, mfaFactors: null }), t || this.emit("signed-in", i);
853
+ this.setState({ status: "signed-in", user: i, mfaFactors: null, configError: null }), t || this.emit("signed-in", i);
734
854
  } catch (i) {
735
- if (B(i, v.moreFactorsRequired)) {
736
- let r = null;
855
+ if (N(i, f.moreFactorsRequired)) {
856
+ let s = null;
737
857
  try {
738
- r = await k(
858
+ s = await S(
739
859
  this.account,
740
860
  ["listMFAFactors", "listMfaFactors"],
741
861
  []
742
862
  );
743
863
  } catch {
744
864
  }
745
- this.setState({ status: "mfa-required", user: null, mfaFactors: r });
865
+ this.setState({ status: "mfa-required", user: null, mfaFactors: s });
866
+ } else if (N(i, f.userBlocked))
867
+ await this.purgeLocalSession(), this.setState({
868
+ status: "signed-out",
869
+ user: null,
870
+ mfaFactors: null,
871
+ pending: {
872
+ type: "notice",
873
+ tone: "error",
874
+ message: this.getStrings().errorUserBlocked
875
+ }
876
+ }), t && this.emit("signed-out", void 0);
877
+ else if (!t && Pt(i)) {
878
+ const a = K(i, this.getStrings()) || this.getStrings().errorConfig;
879
+ console.warn(
880
+ `[authui] ${a} (endpoint=${this.config?.endpoint ?? "?"}, project=${this.config?.project ?? "?"})`
881
+ );
882
+ const l = R(i);
883
+ this.emit("error", { message: a, type: l.type, code: l.code }), this.setState({
884
+ status: "signed-out",
885
+ user: null,
886
+ mfaFactors: null,
887
+ configError: a,
888
+ pending: { type: "notice", tone: "error", message: a }
889
+ });
746
890
  } else
747
- this.setState({ status: "signed-out", user: null, mfaFactors: null }), t && this.emit("signed-out", void 0);
891
+ this.setState({ status: "signed-out", user: null, mfaFactors: null, configError: null }), t && this.emit("signed-out", void 0);
748
892
  }
749
893
  })().finally(() => {
750
894
  this.refreshPromise = null;
751
895
  }), this.refreshPromise);
752
896
  }
753
897
  async afterSignIn() {
754
- await this.refresh();
898
+ if (await this.refresh(), this.state.status !== "signed-in" && this.state.status !== "mfa-required") {
899
+ const i = this.state.pending;
900
+ if (i?.type === "notice" && i.tone === "error")
901
+ throw Object.assign(new Error(i.message), {
902
+ type: f.userBlocked,
903
+ code: 401
904
+ });
905
+ }
755
906
  const t = this.config?.successUrl;
756
907
  t && this.state.status === "signed-in" && typeof window < "u" && window.location.assign(t);
757
908
  }
909
+ /**
910
+ * Drop a poisoned Appwrite session (e.g. after user_blocked). Deletes the
911
+ * current session when possible and clears the SDK fallback without reading it.
912
+ */
913
+ async purgeLocalSession() {
914
+ try {
915
+ await this.account?.deleteSession("current");
916
+ } catch {
917
+ }
918
+ try {
919
+ this.client?.setSession("");
920
+ } catch {
921
+ }
922
+ if (typeof localStorage < "u")
923
+ try {
924
+ localStorage.removeItem("cookieFallback");
925
+ } catch {
926
+ }
927
+ this.config && !this.preview && (this.client = new at().setEndpoint(this.config.endpoint).setProject(this.config.project), this.account = new nt(this.client));
928
+ }
758
929
  // ─────────────────────────────── sign in ───────────────────────────────
759
930
  async signInWithEmailPassword(t, i) {
760
931
  try {
761
932
  await this.acct().createEmailPasswordSession(t.trim(), i);
762
- } catch (r) {
763
- this.fail(r);
933
+ } catch (s) {
934
+ this.fail(s);
764
935
  }
765
936
  await this.afterSignIn();
766
937
  }
767
- async signUp(t, i, r) {
938
+ async signUp(t, i, s) {
768
939
  try {
769
- await this.acct().create(V.unique(), t.trim(), i, r?.trim() || void 0), await this.acct().createEmailPasswordSession(t.trim(), i);
940
+ await this.acct().create(j.unique(), t.trim(), i, s?.trim() || void 0), await this.acct().createEmailPasswordSession(t.trim(), i);
770
941
  } catch (a) {
771
942
  this.fail(a);
772
943
  }
@@ -786,9 +957,9 @@ class gt {
786
957
  */
787
958
  async signInWithOAuth(t) {
788
959
  const i = this.config?.oauthScopes?.[t];
789
- let r;
960
+ let s;
790
961
  try {
791
- r = this.acct().createOAuth2Token(
962
+ s = this.acct().createOAuth2Token(
792
963
  t,
793
964
  this.redirectUrl("oauth"),
794
965
  this.redirectUrl("oauth-failed"),
@@ -797,9 +968,9 @@ class gt {
797
968
  } catch (a) {
798
969
  this.fail(a);
799
970
  }
800
- if (r && typeof r.then == "function") {
971
+ if (s && typeof s.then == "function") {
801
972
  try {
802
- await r;
973
+ await s;
803
974
  } catch (a) {
804
975
  this.fail(a);
805
976
  }
@@ -809,7 +980,7 @@ class gt {
809
980
  async sendMagicUrl(t) {
810
981
  try {
811
982
  return await this.acct().createMagicURLToken(
812
- V.unique(),
983
+ j.unique(),
813
984
  t.trim(),
814
985
  this.redirectUrl("magic-url"),
815
986
  this.config?.securityPhrase ?? !0
@@ -821,7 +992,7 @@ class gt {
821
992
  async sendEmailOtp(t) {
822
993
  try {
823
994
  return await this.acct().createEmailToken(
824
- V.unique(),
995
+ j.unique(),
825
996
  t.trim(),
826
997
  this.config?.securityPhrase ?? !0
827
998
  );
@@ -831,7 +1002,7 @@ class gt {
831
1002
  }
832
1003
  async sendPhoneOtp(t) {
833
1004
  try {
834
- return await this.acct().createPhoneToken(V.unique(), t.replace(/[\s()-]/g, ""));
1005
+ return await this.acct().createPhoneToken(j.unique(), t.replace(/[\s()-]/g, ""));
835
1006
  } catch (i) {
836
1007
  return this.fail(i);
837
1008
  }
@@ -840,15 +1011,15 @@ class gt {
840
1011
  async signInWithToken(t, i) {
841
1012
  try {
842
1013
  await this.acct().createSession(t, i.trim());
843
- } catch (r) {
844
- this.fail(r);
1014
+ } catch (s) {
1015
+ this.fail(s);
845
1016
  }
846
1017
  await this.afterSignIn();
847
1018
  }
848
1019
  // ─────────────────────────────── MFA ───────────────────────────────
849
1020
  async createMfaChallenge(t) {
850
1021
  try {
851
- return await k(
1022
+ return await S(
852
1023
  this.acct(),
853
1024
  ["createMFAChallenge", "createMfaChallenge"],
854
1025
  [t]
@@ -858,9 +1029,9 @@ class gt {
858
1029
  }
859
1030
  }
860
1031
  /** Verify a challenge. Completes a pending sign in, or acts as a step-up for protected actions. */
861
- async completeMfaChallenge(t, i, r = {}) {
1032
+ async completeMfaChallenge(t, i, s = {}) {
862
1033
  try {
863
- await k(
1034
+ await S(
864
1035
  this.acct(),
865
1036
  ["updateMFAChallenge", "updateMfaChallenge"],
866
1037
  [t, i.trim()]
@@ -868,11 +1039,11 @@ class gt {
868
1039
  } catch (a) {
869
1040
  this.fail(a);
870
1041
  }
871
- (r.signIn ?? !0) && await this.afterSignIn();
1042
+ (s.signIn ?? !0) && await this.afterSignIn();
872
1043
  }
873
1044
  async listMfaFactors() {
874
1045
  try {
875
- return await k(this.acct(), ["listMFAFactors", "listMfaFactors"], []);
1046
+ return await S(this.acct(), ["listMFAFactors", "listMfaFactors"], []);
876
1047
  } catch (t) {
877
1048
  return this.fail(t);
878
1049
  }
@@ -887,7 +1058,7 @@ class gt {
887
1058
  }
888
1059
  async addAuthenticator() {
889
1060
  try {
890
- return await k(
1061
+ return await S(
891
1062
  this.acct(),
892
1063
  ["createMFAAuthenticator", "createMfaAuthenticator"],
893
1064
  ["totp"]
@@ -898,7 +1069,7 @@ class gt {
898
1069
  }
899
1070
  async verifyAuthenticator(t) {
900
1071
  try {
901
- await k(
1072
+ await S(
902
1073
  this.acct(),
903
1074
  ["updateMFAAuthenticator", "updateMfaAuthenticator"],
904
1075
  ["totp", t.trim()]
@@ -911,7 +1082,7 @@ class gt {
911
1082
  /** Requires a recent MFA challenge (server rejects with user_challenge_required otherwise). */
912
1083
  async removeAuthenticator() {
913
1084
  try {
914
- await k(this.acct(), ["deleteMFAAuthenticator", "deleteMfaAuthenticator"], ["totp"]);
1085
+ await S(this.acct(), ["deleteMFAAuthenticator", "deleteMfaAuthenticator"], ["totp"]);
915
1086
  } catch (t) {
916
1087
  this.fail(t);
917
1088
  }
@@ -919,7 +1090,7 @@ class gt {
919
1090
  }
920
1091
  async createRecoveryCodes() {
921
1092
  try {
922
- return (await k(
1093
+ return (await S(
923
1094
  this.acct(),
924
1095
  ["createMFARecoveryCodes", "createMfaRecoveryCodes"],
925
1096
  []
@@ -931,7 +1102,7 @@ class gt {
931
1102
  /** Requires a recent MFA challenge. */
932
1103
  async regenerateRecoveryCodes() {
933
1104
  try {
934
- return (await k(
1105
+ return (await S(
935
1106
  this.acct(),
936
1107
  ["updateMFARecoveryCodes", "updateMfaRecoveryCodes"],
937
1108
  []
@@ -943,7 +1114,7 @@ class gt {
943
1114
  /** Requires a recent MFA challenge. */
944
1115
  async getRecoveryCodes() {
945
1116
  try {
946
- return (await k(
1117
+ return (await S(
947
1118
  this.acct(),
948
1119
  ["getMFARecoveryCodes", "getMfaRecoveryCodes"],
949
1120
  []
@@ -960,9 +1131,9 @@ class gt {
960
1131
  this.fail(i);
961
1132
  }
962
1133
  }
963
- async completePasswordRecovery(t, i, r) {
1134
+ async completePasswordRecovery(t, i, s) {
964
1135
  try {
965
- await this.acct().updateRecovery(t, i, r);
1136
+ await this.acct().updateRecovery(t, i, s);
966
1137
  } catch (a) {
967
1138
  this.fail(a);
968
1139
  }
@@ -975,7 +1146,15 @@ class gt {
975
1146
  } catch (i) {
976
1147
  this.fail(i);
977
1148
  }
978
- t === "current" && (this.setState({ status: "signed-out", user: null, mfaFactors: null }), this.emit("signed-out", void 0));
1149
+ if (t === "current") {
1150
+ this.setState({ status: "signed-out", user: null, mfaFactors: null }), this.emit("signed-out", void 0);
1151
+ return;
1152
+ }
1153
+ try {
1154
+ await this.acct().get();
1155
+ } catch {
1156
+ this.setState({ status: "signed-out", user: null, mfaFactors: null }), this.emit("signed-out", void 0);
1157
+ }
979
1158
  }
980
1159
  async signOutEverywhere() {
981
1160
  try {
@@ -1025,31 +1204,31 @@ class gt {
1025
1204
  async updateEmail(t, i) {
1026
1205
  try {
1027
1206
  await this.acct().updateEmail(t.trim(), i);
1028
- } catch (r) {
1029
- this.fail(r);
1207
+ } catch (s) {
1208
+ this.fail(s);
1030
1209
  }
1031
1210
  await this.refresh();
1032
1211
  }
1033
1212
  async updatePhone(t, i) {
1034
1213
  try {
1035
1214
  await this.acct().updatePhone(t.replace(/[\s()-]/g, ""), i);
1036
- } catch (r) {
1037
- this.fail(r);
1215
+ } catch (s) {
1216
+ this.fail(s);
1038
1217
  }
1039
1218
  await this.refresh();
1040
1219
  }
1041
1220
  async updatePassword(t, i) {
1042
1221
  try {
1043
1222
  await this.acct().updatePassword(t, i || void 0);
1044
- } catch (r) {
1045
- this.fail(r);
1223
+ } catch (s) {
1224
+ this.fail(s);
1046
1225
  }
1047
1226
  await this.refresh();
1048
1227
  }
1049
1228
  /** Turn an anonymous session into a full account. */
1050
- async convertGuest(t, i, r) {
1229
+ async convertGuest(t, i, s) {
1051
1230
  try {
1052
- await this.acct().updateEmail(t.trim(), i), r?.trim() && await this.acct().updateName(r.trim());
1231
+ await this.acct().updateEmail(t.trim(), i), s?.trim() && await this.acct().updateName(s.trim());
1053
1232
  } catch (a) {
1054
1233
  this.fail(a);
1055
1234
  }
@@ -1057,7 +1236,7 @@ class gt {
1057
1236
  }
1058
1237
  async sendEmailVerification() {
1059
1238
  try {
1060
- await k(
1239
+ await S(
1061
1240
  this.acct(),
1062
1241
  ["createEmailVerification", "createVerification"],
1063
1242
  [this.redirectUrl("verify-email")]
@@ -1078,8 +1257,8 @@ class gt {
1078
1257
  if (i) {
1079
1258
  try {
1080
1259
  await this.acct().updatePhoneVerification(i, t.trim());
1081
- } catch (r) {
1082
- this.fail(r);
1260
+ } catch (s) {
1261
+ this.fail(s);
1083
1262
  }
1084
1263
  await this.refresh();
1085
1264
  }
@@ -1096,9 +1275,9 @@ class gt {
1096
1275
  // ───────────────────────────── redirects ─────────────────────────────
1097
1276
  /** Build the URL Appwrite should send the user back to for a given flow. */
1098
1277
  redirectUrl(t) {
1099
- const i = this.config?.redirectUrl ?? (typeof window < "u" ? window.location.origin + window.location.pathname : ""), r = new URL(i, typeof window < "u" ? window.location.href : void 0);
1100
- for (const a of tt) r.searchParams.delete(a);
1101
- return r.searchParams.set(G, t), r.toString();
1278
+ const i = this.config?.redirectUrl ?? (typeof window < "u" ? window.location.origin + window.location.pathname : ""), s = new URL(i, typeof window < "u" ? window.location.href : void 0);
1279
+ for (const a of dt) s.searchParams.delete(a);
1280
+ return s.searchParams.set(J, t), s.toString();
1102
1281
  }
1103
1282
  setPending(t) {
1104
1283
  this.setState({ pending: t });
@@ -1109,54 +1288,63 @@ class gt {
1109
1288
  */
1110
1289
  async handleRedirect() {
1111
1290
  if (typeof window > "u") return !1;
1112
- const t = new URLSearchParams(window.location.search), i = t.get(G);
1291
+ const t = new URLSearchParams(window.location.search), i = t.get(J);
1113
1292
  if (!i) return !1;
1114
- const r = t.get("userId") ?? "", a = t.get("secret") ?? "";
1293
+ const s = t.get("userId") ?? "", a = t.get("secret") ?? "";
1115
1294
  this.cleanUrl();
1295
+ const l = () => {
1296
+ this.setState({
1297
+ pending: {
1298
+ type: "notice",
1299
+ message: this.getStrings().errorInvalidToken,
1300
+ tone: "error"
1301
+ }
1302
+ });
1303
+ };
1116
1304
  try {
1117
1305
  switch (i) {
1118
1306
  case "oauth":
1119
1307
  case "magic-url":
1120
- r && a && await this.acct().createSession(r, a);
1308
+ s && a ? await this.acct().createSession(s, a) : l();
1121
1309
  break;
1122
1310
  case "oauth-failed":
1123
1311
  this.setState({ pending: { type: "oauth-failed" } });
1124
1312
  break;
1125
1313
  case "recovery":
1126
- r && a && this.setState({ pending: { type: "reset-password", userId: r, secret: a } });
1314
+ s && a ? this.setState({ pending: { type: "reset-password", userId: s, secret: a } }) : l();
1127
1315
  break;
1128
1316
  case "verify-email":
1129
- r && a && (await k(
1317
+ s && a ? (await S(
1130
1318
  this.acct(),
1131
1319
  ["updateEmailVerification", "updateVerification"],
1132
- [r, a]
1320
+ [s, a]
1133
1321
  ), this.setState({
1134
1322
  pending: {
1135
1323
  type: "notice",
1136
1324
  message: this.getStrings().emailVerified,
1137
1325
  tone: "success"
1138
1326
  }
1139
- }));
1327
+ })) : l();
1140
1328
  break;
1141
1329
  }
1142
- } catch (h) {
1143
- const u = N(h);
1144
- this.emit("error", u), this.setState({ pending: { type: "notice", message: u.message, tone: "error" } });
1330
+ } catch (u) {
1331
+ const x = R(u), C = K(u, this.getStrings(), "link");
1332
+ this.emit("error", x), this.setState({ pending: { type: "notice", message: C, tone: "error" } });
1145
1333
  }
1146
1334
  return !0;
1147
1335
  }
1148
1336
  cleanUrl() {
1149
1337
  const t = new URL(window.location.href);
1150
- for (const i of tt) t.searchParams.delete(i);
1338
+ for (const i of dt) t.searchParams.delete(i);
1151
1339
  window.history.replaceState(window.history.state, "", t.toString());
1152
1340
  }
1153
1341
  /** Test helper. */
1154
1342
  reset() {
1155
- this.client = null, this.account = null, this.preview = null, this.config = null, this.state = et(), this.listeners.clear();
1343
+ this.client = null, this.account = null, this.teams = null, this.activeTeamId = null, this.preview = null, this.config = null, this.state = ht(), this.listeners.clear();
1156
1344
  }
1157
1345
  }
1158
- const n = new gt();
1159
- class vt {
1346
+ const n = new Ut();
1347
+ class It {
1160
1348
  constructor() {
1161
1349
  this.listeners = /* @__PURE__ */ new Set(), this.observer = null, this.media = null, this.notify = () => {
1162
1350
  const t = this.isDark("auto");
@@ -1184,14 +1372,14 @@ class vt {
1184
1372
  this.observer?.disconnect(), this.observer = null, this.media?.removeEventListener?.("change", this.notify), this.media = null;
1185
1373
  }
1186
1374
  }
1187
- const it = new vt(), st = {
1375
+ const ut = new It(), pt = {
1188
1376
  none: "0px",
1189
1377
  sm: "0.25rem",
1190
1378
  md: "0.625rem",
1191
1379
  lg: "0.875rem",
1192
1380
  xl: "1.125rem",
1193
1381
  full: "1.5rem"
1194
- }, bt = I`
1382
+ }, Et = F`
1195
1383
  :host {
1196
1384
  /* Light theme (matches :root in the console) */
1197
1385
  --authui-background: oklch(1 0 0);
@@ -1269,7 +1457,7 @@ const it = new vt(), st = {
1269
1457
  --authui-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.5);
1270
1458
  color-scheme: dark;
1271
1459
  }
1272
- `, yt = I`
1460
+ `, Mt = F`
1273
1461
  *,
1274
1462
  *::before,
1275
1463
  *::after {
@@ -1284,6 +1472,8 @@ const it = new vt(), st = {
1284
1472
  -webkit-font-smoothing: antialiased;
1285
1473
  -moz-osx-font-smoothing: grayscale;
1286
1474
  text-align: start;
1475
+ min-width: 0;
1476
+ max-width: 100%;
1287
1477
  }
1288
1478
 
1289
1479
  [hidden] {
@@ -1532,6 +1722,57 @@ const it = new vt(), st = {
1532
1722
  color: var(--authui-muted-foreground);
1533
1723
  margin: 0;
1534
1724
  }
1725
+ .strength {
1726
+ display: grid;
1727
+ gap: 6px;
1728
+ margin-top: 6px;
1729
+ }
1730
+ .strength-meter {
1731
+ display: grid;
1732
+ grid-template-columns: repeat(4, 1fr);
1733
+ gap: 4px;
1734
+ height: 4px;
1735
+ }
1736
+ .strength-meter span {
1737
+ border-radius: 999px;
1738
+ background: var(--authui-muted);
1739
+ transition: background-color 120ms ease;
1740
+ }
1741
+ .strength-meter[data-level="1"] span:nth-child(-n + 1) {
1742
+ background: var(--authui-destructive);
1743
+ }
1744
+ .strength-meter[data-level="2"] span:nth-child(-n + 2) {
1745
+ background: var(--authui-warning-foreground);
1746
+ }
1747
+ .strength-meter[data-level="3"] span:nth-child(-n + 3) {
1748
+ background: var(--authui-warning-foreground);
1749
+ }
1750
+ .strength-meter[data-level="4"] span {
1751
+ background: var(--authui-success);
1752
+ }
1753
+ .strength-label {
1754
+ font-size: 12px;
1755
+ color: var(--authui-muted-foreground);
1756
+ margin: 0;
1757
+ }
1758
+
1759
+ .btn.last-used {
1760
+ border-color: var(--authui-brand);
1761
+ box-shadow: 0 0 0 1px color-mix(in oklab, var(--authui-brand) 35%, transparent);
1762
+ }
1763
+ .last-used-badge {
1764
+ display: inline-flex;
1765
+ align-items: center;
1766
+ margin-inline-start: auto;
1767
+ padding: 1px 6px;
1768
+ border-radius: 999px;
1769
+ font-size: 10px;
1770
+ font-weight: 600;
1771
+ letter-spacing: 0.02em;
1772
+ text-transform: uppercase;
1773
+ color: var(--authui-brand);
1774
+ background: color-mix(in oklab, var(--authui-brand) 12%, transparent);
1775
+ }
1535
1776
  .form {
1536
1777
  display: flex;
1537
1778
  flex-direction: column;
@@ -1539,6 +1780,9 @@ const it = new vt(), st = {
1539
1780
  }
1540
1781
 
1541
1782
  /* ── Alert ── */
1783
+ .alert:has(.dismiss) {
1784
+ padding-inline-end: 36px;
1785
+ }
1542
1786
  .alert {
1543
1787
  position: relative;
1544
1788
  width: 100%;
@@ -1660,7 +1904,7 @@ const it = new vt(), st = {
1660
1904
  .tabs {
1661
1905
  display: inline-flex;
1662
1906
  align-items: center;
1663
- justify-content: center;
1907
+ justify-content: flex-start;
1664
1908
  height: 36px;
1665
1909
  width: fit-content;
1666
1910
  max-width: 100%;
@@ -1671,6 +1915,7 @@ const it = new vt(), st = {
1671
1915
  padding: 3px;
1672
1916
  gap: 2px;
1673
1917
  scrollbar-width: none;
1918
+ -webkit-overflow-scrolling: touch;
1674
1919
  }
1675
1920
  :host([data-theme="dark"]) .tabs {
1676
1921
  background: color-mix(in oklab, var(--authui-muted) 80%, transparent);
@@ -1681,7 +1926,7 @@ const it = new vt(), st = {
1681
1926
  justify-content: center;
1682
1927
  gap: 6px;
1683
1928
  height: 100%;
1684
- flex: 1;
1929
+ flex: 0 0 auto;
1685
1930
  padding: 4px 10px;
1686
1931
  border-radius: var(--authui-radius-md);
1687
1932
  border: 1px solid transparent;
@@ -1808,6 +2053,8 @@ const it = new vt(), st = {
1808
2053
  align-items: center;
1809
2054
  gap: 8px;
1810
2055
  flex-wrap: wrap;
2056
+ min-width: 0;
2057
+ flex: 1;
1811
2058
  }
1812
2059
  .between {
1813
2060
  display: flex;
@@ -1916,6 +2163,9 @@ const it = new vt(), st = {
1916
2163
  .providers.two {
1917
2164
  grid-template-columns: repeat(2, minmax(0, 1fr));
1918
2165
  }
2166
+ .providers.two > :last-child:nth-child(odd) {
2167
+ grid-column: 1 / -1;
2168
+ }
1919
2169
  .providers .btn svg {
1920
2170
  width: 18px;
1921
2171
  height: 18px;
@@ -2012,25 +2262,25 @@ const it = new vt(), st = {
2012
2262
  }
2013
2263
  }
2014
2264
  `;
2015
- var wt = Object.defineProperty, $t = (e, t, i, r) => {
2016
- for (var a = void 0, h = e.length - 1, u; h >= 0; h--)
2017
- (u = e[h]) && (a = u(t, i, a) || a);
2018
- return a && wt(t, i, a), a;
2019
- }, U;
2020
- const nt = (U = class extends X {
2265
+ var Ft = Object.defineProperty, Ot = (e, t, i, s) => {
2266
+ for (var a = void 0, l = e.length - 1, u; l >= 0; l--)
2267
+ (u = e[l]) && (a = u(t, i, a) || a);
2268
+ return a && Ft(t, i, a), a;
2269
+ }, I;
2270
+ const vt = (I = class extends it {
2021
2271
  constructor() {
2022
2272
  super(...arguments), this.auth = n.getState(), this.unsubscribeStore = null, this.unsubscribeTheme = null, this.stopKeys = (t) => t.stopPropagation();
2023
2273
  }
2024
2274
  connectedCallback() {
2025
2275
  super.connectedCallback();
2026
- for (const t of U.KEY_EVENTS) this.addEventListener(t, this.stopKeys);
2276
+ for (const t of I.KEY_EVENTS) this.addEventListener(t, this.stopKeys);
2027
2277
  this.auth = n.getState(), this.unsubscribeStore = n.on("change", (t) => {
2028
2278
  this.auth = t, this.applyBranding();
2029
- }), this.unsubscribeTheme = it.subscribe(() => this.applyBranding()), this.applyBranding();
2279
+ }), this.unsubscribeTheme = ut.subscribe(() => this.applyBranding()), this.applyBranding();
2030
2280
  }
2031
2281
  disconnectedCallback() {
2032
2282
  super.disconnectedCallback();
2033
- for (const t of U.KEY_EVENTS) this.removeEventListener(t, this.stopKeys);
2283
+ for (const t of I.KEY_EVENTS) this.removeEventListener(t, this.stopKeys);
2034
2284
  this.unsubscribeStore?.(), this.unsubscribeTheme?.(), this.unsubscribeStore = null, this.unsubscribeTheme = null;
2035
2285
  }
2036
2286
  get strings() {
@@ -2038,7 +2288,7 @@ const nt = (U = class extends X {
2038
2288
  }
2039
2289
  /** Translate a string key with optional `{placeholders}`. */
2040
2290
  t(t, i) {
2041
- return ht(this.strings[t], i);
2291
+ return $t(this.strings[t], i);
2042
2292
  }
2043
2293
  get config() {
2044
2294
  return n.getConfig();
@@ -2048,27 +2298,27 @@ const nt = (U = class extends X {
2048
2298
  }
2049
2299
  /** Push theme and branding from config onto the host element. */
2050
2300
  applyBranding() {
2051
- const t = this.config?.branding, i = it.isDark(t?.theme ?? "auto");
2301
+ const t = this.config?.branding, i = ut.isDark(t?.theme ?? "auto");
2052
2302
  this.setAttribute("data-theme", i ? "dark" : "light"), t?.primary && (this.style.setProperty("--authui-primary", t.primary), this.style.setProperty(
2053
2303
  "--authui-primary-foreground",
2054
2304
  t.primaryForeground ?? "#ffffff"
2055
- )), t?.radius && st[t.radius] && this.style.setProperty("--authui-radius", st[t.radius]);
2305
+ )), t?.radius && pt[t.radius] && this.style.setProperty("--authui-radius", pt[t.radius]);
2056
2306
  }
2057
2307
  /** Emit a composed custom event from this element. */
2058
2308
  fire(t, i) {
2059
2309
  this.dispatchEvent(new CustomEvent(t, { detail: i, bubbles: !0, composed: !0 }));
2060
2310
  }
2061
- }, U.styles = [bt, yt], U.KEY_EVENTS = ["keydown", "keyup", "keypress"], U);
2062
- $t([
2063
- d()
2064
- ], nt.prototype, "auth");
2065
- let A = nt;
2066
- var xt = Object.defineProperty, kt = Object.getOwnPropertyDescriptor, y = (e, t, i, r) => {
2067
- for (var a = r > 1 ? void 0 : r ? kt(t, i) : t, h = e.length - 1, u; h >= 0; h--)
2068
- (u = e[h]) && (a = (r ? u(t, i, a) : u(a)) || a);
2069
- return r && a && xt(t, i, a), a;
2311
+ }, I.styles = [Et, Mt], I.KEY_EVENTS = ["keydown", "keyup", "keypress"], I);
2312
+ Ot([
2313
+ h()
2314
+ ], vt.prototype, "auth");
2315
+ let A = vt;
2316
+ var _t = Object.defineProperty, Tt = Object.getOwnPropertyDescriptor, y = (e, t, i, s) => {
2317
+ for (var a = s > 1 ? void 0 : s ? Tt(t, i) : t, l = e.length - 1, u; l >= 0; l--)
2318
+ (u = e[l]) && (a = (s ? u(t, i, a) : u(a)) || a);
2319
+ return s && a && _t(t, i, a), a;
2070
2320
  };
2071
- let b = class extends X {
2321
+ let b = class extends it {
2072
2322
  constructor() {
2073
2323
  super(...arguments), this.endpoint = "", this.project = "", this.redirectUrl = "", this.successUrl = "", this.methods = "email-password", this.signUp = "true", this.requireName = "true", this.mfa = "true", this.securityPhrase = "true", this.name = "", this.logo = "", this.theme = "auto", this.radius = "", this.primary = "", this.primaryForeground = "", this.termsUrl = "", this.privacyUrl = "", this.preview = "";
2074
2324
  }
@@ -2079,15 +2329,20 @@ let b = class extends X {
2079
2329
  this.configure();
2080
2330
  }
2081
2331
  configure() {
2082
- if (!this.endpoint || !this.project) return;
2332
+ if (!this.endpoint || !this.project) {
2333
+ queueMicrotask(() => {
2334
+ (!this.endpoint || !this.project) && n.notifyConfigIncomplete();
2335
+ });
2336
+ return;
2337
+ }
2083
2338
  const e = this.toConfig(), t = n.getConfig();
2084
2339
  t && JSON.stringify(t) === JSON.stringify(e) || n.configure(e);
2085
2340
  }
2086
2341
  toConfig() {
2087
- const e = { oauth: [] };
2088
- for (const t of this.methods.split(/[\s,]+/).filter(Boolean))
2089
- t.startsWith("oauth:") ? e.oauth.push(t.slice(6)) : t === "email-password" ? e.emailPassword = !0 : t === "magic-url" ? e.magicUrl = !0 : t === "email-otp" ? e.emailOtp = !0 : t === "phone" ? e.phone = !0 : (t === "anonymous" || t === "guest") && (e.anonymous = !0);
2090
- return e.emailPassword === void 0 && !this.methods.trim() && (e.emailPassword = !0), {
2342
+ const e = { oauth: [] }, t = this.methods.split(/[\s,]+/).filter(Boolean);
2343
+ for (const i of t)
2344
+ i.startsWith("oauth:") ? e.oauth.push(i.slice(6)) : i === "email-password" ? e.emailPassword = !0 : i === "magic-url" ? e.magicUrl = !0 : i === "email-otp" ? e.emailOtp = !0 : i === "phone" ? e.phone = !0 : (i === "anonymous" || i === "guest") && (e.anonymous = !0);
2345
+ return e.emailPassword = t.length > 0 ? t.includes("email-password") : !0, {
2091
2346
  endpoint: this.endpoint,
2092
2347
  project: this.project,
2093
2348
  redirectUrl: this.redirectUrl || void 0,
@@ -2113,82 +2368,98 @@ let b = class extends X {
2113
2368
  };
2114
2369
  }
2115
2370
  };
2116
- b.styles = I`
2371
+ b.styles = F`
2117
2372
  :host {
2118
2373
  display: none;
2119
2374
  }
2120
2375
  `;
2121
2376
  y([
2122
- f({ type: String })
2377
+ g({ type: String })
2123
2378
  ], b.prototype, "endpoint", 2);
2124
2379
  y([
2125
- f({ type: String })
2380
+ g({ type: String })
2126
2381
  ], b.prototype, "project", 2);
2127
2382
  y([
2128
- f({ type: String, attribute: "redirect-url" })
2383
+ g({ type: String, attribute: "redirect-url" })
2129
2384
  ], b.prototype, "redirectUrl", 2);
2130
2385
  y([
2131
- f({ type: String, attribute: "success-url" })
2386
+ g({ type: String, attribute: "success-url" })
2132
2387
  ], b.prototype, "successUrl", 2);
2133
2388
  y([
2134
- f({ type: String })
2389
+ g({ type: String })
2135
2390
  ], b.prototype, "methods", 2);
2136
2391
  y([
2137
- f({ type: String, attribute: "sign-up" })
2392
+ g({ type: String, attribute: "sign-up" })
2138
2393
  ], b.prototype, "signUp", 2);
2139
2394
  y([
2140
- f({ type: String, attribute: "require-name" })
2395
+ g({ type: String, attribute: "require-name" })
2141
2396
  ], b.prototype, "requireName", 2);
2142
2397
  y([
2143
- f({ type: String })
2398
+ g({ type: String })
2144
2399
  ], b.prototype, "mfa", 2);
2145
2400
  y([
2146
- f({ type: String, attribute: "security-phrase" })
2401
+ g({ type: String, attribute: "security-phrase" })
2147
2402
  ], b.prototype, "securityPhrase", 2);
2148
2403
  y([
2149
- f({ type: String })
2404
+ g({ type: String })
2150
2405
  ], b.prototype, "name", 2);
2151
2406
  y([
2152
- f({ type: String })
2407
+ g({ type: String })
2153
2408
  ], b.prototype, "logo", 2);
2154
2409
  y([
2155
- f({ type: String })
2410
+ g({ type: String })
2156
2411
  ], b.prototype, "theme", 2);
2157
2412
  y([
2158
- f({ type: String })
2413
+ g({ type: String })
2159
2414
  ], b.prototype, "radius", 2);
2160
2415
  y([
2161
- f({ type: String })
2416
+ g({ type: String })
2162
2417
  ], b.prototype, "primary", 2);
2163
2418
  y([
2164
- f({ type: String, attribute: "primary-foreground" })
2419
+ g({ type: String, attribute: "primary-foreground" })
2165
2420
  ], b.prototype, "primaryForeground", 2);
2166
2421
  y([
2167
- f({ type: String, attribute: "terms-url" })
2422
+ g({ type: String, attribute: "terms-url" })
2168
2423
  ], b.prototype, "termsUrl", 2);
2169
2424
  y([
2170
- f({ type: String, attribute: "privacy-url" })
2425
+ g({ type: String, attribute: "privacy-url" })
2171
2426
  ], b.prototype, "privacyUrl", 2);
2172
2427
  y([
2173
- f({ type: String })
2428
+ g({ type: String })
2174
2429
  ], b.prototype, "preview", 2);
2175
2430
  b = y([
2176
- _("authui-config")
2431
+ O("authui-config")
2177
2432
  ], b);
2178
- var Ct = Object.defineProperty, Pt = Object.getOwnPropertyDescriptor, H = (e, t, i, r) => {
2179
- for (var a = r > 1 ? void 0 : r ? Pt(t, i) : t, h = e.length - 1, u; h >= 0; h--)
2180
- (u = e[h]) && (a = (r ? u(t, i, a) : u(a)) || a);
2181
- return r && a && Ct(t, i, a), a;
2433
+ var Dt = Object.defineProperty, Rt = Object.getOwnPropertyDescriptor, Y = (e, t, i, s) => {
2434
+ for (var a = s > 1 ? void 0 : s ? Rt(t, i) : t, l = e.length - 1, u; l >= 0; l--)
2435
+ (u = e[l]) && (a = (s ? u(t, i, a) : u(a)) || a);
2436
+ return s && a && Dt(t, i, a), a;
2182
2437
  };
2183
- if (typeof document < "u" && !document.getElementById("authui-fouc")) {
2184
- const e = document.createElement("style");
2185
- e.id = "authui-fouc", e.textContent = "authui-show:not([ready]){display:none}", document.head.appendChild(e);
2438
+ const mt = "authui-show:not([ready]){display:none}", ie = "authui-show:not([ready]){display:none}authui-button:not(:defined),authui-user-button:not(:defined){visibility:hidden}";
2439
+ let ft = !1;
2440
+ function zt() {
2441
+ if (!(typeof document > "u" || ft)) {
2442
+ ft = !0;
2443
+ try {
2444
+ if (typeof CSSStyleSheet < "u" && "adoptedStyleSheets" in Document.prototype) {
2445
+ const e = new CSSStyleSheet();
2446
+ e.replaceSync(mt), document.adoptedStyleSheets = [...document.adoptedStyleSheets, e];
2447
+ return;
2448
+ }
2449
+ } catch {
2450
+ }
2451
+ if (!document.getElementById("authui-fouc")) {
2452
+ const e = document.createElement("style");
2453
+ e.id = "authui-fouc", e.textContent = mt, document.head.appendChild(e);
2454
+ }
2455
+ }
2186
2456
  }
2187
- const St = ["loading", "signed-out", "signed-in", "mfa-required"];
2188
- function W(e) {
2189
- return e ? e.split(/[\s,]+/).map((t) => t.trim()).filter((t) => St.includes(t)) : [];
2457
+ zt();
2458
+ const Lt = ["loading", "signed-out", "signed-in", "mfa-required"];
2459
+ function X(e) {
2460
+ return e ? e.split(/[\s,]+/).map((t) => t.trim()).filter((t) => Lt.includes(t)) : [];
2190
2461
  }
2191
- let L = class extends X {
2462
+ let B = class extends it {
2192
2463
  constructor() {
2193
2464
  super(...arguments), this.when = "", this.unless = "", this.status = n.getState().status, this.unsubscribe = null;
2194
2465
  }
@@ -2200,35 +2471,38 @@ let L = class extends X {
2200
2471
  }
2201
2472
  /** Whether the current status satisfies `when` and `unless`. */
2202
2473
  get visible() {
2203
- const e = W(this.when), t = W(this.unless);
2474
+ const e = X(this.when), t = X(this.unless);
2204
2475
  return !(this.status === "loading" && !e.includes("loading") || e.length > 0 && !e.includes(this.status) || t.includes(this.status));
2205
2476
  }
2206
2477
  updated() {
2207
- (this.status !== "loading" || W(this.when).includes("loading")) && (this.setAttribute("ready", ""), this.style.display = "contents");
2478
+ (this.status !== "loading" || X(this.when).includes("loading")) && (this.setAttribute("ready", ""), this.style.display = "contents");
2208
2479
  }
2209
2480
  render() {
2210
- return this.visible ? s`<slot></slot>` : o;
2481
+ return this.visible ? r`<slot></slot>` : o;
2211
2482
  }
2212
2483
  };
2213
- H([
2214
- f({ type: String })
2215
- ], L.prototype, "when", 2);
2216
- H([
2217
- f({ type: String })
2218
- ], L.prototype, "unless", 2);
2219
- H([
2220
- d()
2221
- ], L.prototype, "status", 2);
2222
- L = H([
2223
- _("authui-show")
2224
- ], L);
2225
- const At = I`
2484
+ Y([
2485
+ g({ type: String })
2486
+ ], B.prototype, "when", 2);
2487
+ Y([
2488
+ g({ type: String })
2489
+ ], B.prototype, "unless", 2);
2490
+ Y([
2491
+ h()
2492
+ ], B.prototype, "status", 2);
2493
+ B = Y([
2494
+ O("authui-show")
2495
+ ], B);
2496
+ const Vt = F`
2226
2497
  :host {
2227
2498
  display: block;
2228
2499
  width: 100%;
2229
2500
  max-width: 420px;
2501
+ min-width: 0;
2230
2502
  }
2231
2503
  .panel {
2504
+ min-width: 0;
2505
+ overflow: hidden;
2232
2506
  background: var(--authui-card);
2233
2507
  color: var(--authui-card-foreground);
2234
2508
  border: 1px solid var(--authui-border);
@@ -2258,6 +2532,9 @@ const At = I`
2258
2532
  align-self: center;
2259
2533
  margin-bottom: 4px;
2260
2534
  }
2535
+ .alert:has(.dismiss) {
2536
+ padding-inline-end: 36px;
2537
+ }
2261
2538
  .alert .dismiss {
2262
2539
  position: absolute;
2263
2540
  top: 4px;
@@ -2270,7 +2547,7 @@ const At = I`
2270
2547
  height: 14px;
2271
2548
  margin: 0;
2272
2549
  }
2273
- `, m = (e) => s`<svg
2550
+ `, v = (e) => r`<svg
2274
2551
  xmlns="http://www.w3.org/2000/svg"
2275
2552
  viewBox="0 0 24 24"
2276
2553
  fill="none"
@@ -2282,185 +2559,244 @@ const At = I`
2282
2559
  >
2283
2560
  ${e}
2284
2561
  </svg>`, c = {
2285
- mail: m(
2286
- l`<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>`
2562
+ mail: v(
2563
+ d`<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>`
2287
2564
  ),
2288
- phone: m(
2289
- l`<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>`
2565
+ phone: v(
2566
+ d`<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>`
2290
2567
  ),
2291
- user: m(
2292
- l`<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>`
2568
+ user: v(
2569
+ d`<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>`
2293
2570
  ),
2294
- userX: m(
2295
- l`<path d="M2 21a8 8 0 0 1 11.873-7"/><circle cx="10" cy="8" r="5"/><path d="m17 17 5 5"/><path d="m22 17-5 5"/>`
2571
+ userX: v(
2572
+ d`<path d="M2 21a8 8 0 0 1 11.873-7"/><circle cx="10" cy="8" r="5"/><path d="m17 17 5 5"/><path d="m22 17-5 5"/>`
2296
2573
  ),
2297
- lock: m(
2298
- l`<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>`
2574
+ lock: v(
2575
+ d`<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>`
2299
2576
  ),
2300
- key: m(
2301
- l`<path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4"/><path d="m21 2-9.6 9.6"/><circle cx="7.5" cy="15.5" r="5.5"/>`
2577
+ key: v(
2578
+ d`<path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4"/><path d="m21 2-9.6 9.6"/><circle cx="7.5" cy="15.5" r="5.5"/>`
2302
2579
  ),
2303
- shield: m(
2304
- l`<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>`
2580
+ shield: v(
2581
+ d`<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>`
2305
2582
  ),
2306
- shieldCheck: m(
2307
- l`<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/>`
2583
+ shieldCheck: v(
2584
+ d`<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/>`
2308
2585
  ),
2309
- smartphone: m(
2310
- l`<rect width="14" height="20" x="5" y="2" rx="2" ry="2"/><path d="M12 18h.01"/>`
2586
+ smartphone: v(
2587
+ d`<rect width="14" height="20" x="5" y="2" rx="2" ry="2"/><path d="M12 18h.01"/>`
2311
2588
  ),
2312
- monitor: m(
2313
- l`<rect width="20" height="14" x="2" y="3" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>`
2589
+ monitor: v(
2590
+ d`<rect width="20" height="14" x="2" y="3" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>`
2314
2591
  ),
2315
- globe: m(
2316
- l`<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>`
2592
+ globe: v(
2593
+ d`<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>`
2317
2594
  ),
2318
- logOut: m(
2319
- l`<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/>`
2595
+ logOut: v(
2596
+ d`<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/>`
2320
2597
  ),
2321
- settings: m(
2322
- l`<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>`
2598
+ settings: v(
2599
+ d`<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>`
2323
2600
  ),
2324
- x: m(l`<path d="M18 6 6 18"/><path d="m6 6 12 12"/>`),
2325
- check: m(l`<path d="M20 6 9 17l-5-5"/>`),
2326
- copy: m(
2327
- l`<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>`
2601
+ x: v(d`<path d="M18 6 6 18"/><path d="m6 6 12 12"/>`),
2602
+ check: v(d`<path d="M20 6 9 17l-5-5"/>`),
2603
+ users: v(
2604
+ d`<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>`
2328
2605
  ),
2329
- eye: m(
2330
- l`<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/>`
2606
+ copy: v(
2607
+ d`<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>`
2331
2608
  ),
2332
- eyeOff: m(
2333
- l`<path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"/><path d="m2 2 20 20"/>`
2609
+ eye: v(
2610
+ d`<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/>`
2334
2611
  ),
2335
- arrowLeft: m(l`<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>`),
2336
- alert: m(
2337
- l`<circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/>`
2612
+ eyeOff: v(
2613
+ d`<path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"/><path d="m2 2 20 20"/>`
2338
2614
  ),
2339
- info: m(l`<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>`),
2340
- checkCircle: m(l`<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>`),
2341
- link: m(
2342
- l`<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>`
2615
+ arrowLeft: v(d`<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>`),
2616
+ alert: v(
2617
+ d`<circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/>`
2343
2618
  ),
2344
- activity: m(
2345
- l`<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"/>`
2619
+ info: v(d`<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>`),
2620
+ checkCircle: v(d`<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>`),
2621
+ link: v(
2622
+ d`<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>`
2346
2623
  ),
2347
- trash: m(
2348
- l`<path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>`
2624
+ activity: v(
2625
+ d`<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"/>`
2349
2626
  ),
2350
- sparkles: m(
2351
- l`<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>`
2627
+ trash: v(
2628
+ d`<path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>`
2352
2629
  ),
2353
- refresh: m(
2354
- l`<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/>`
2630
+ sparkles: v(
2631
+ d`<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>`
2355
2632
  ),
2356
- chevronDown: m(l`<path d="m6 9 6 6 6-6"/>`),
2357
- ghost: m(
2358
- l`<path d="M9 10h.01"/><path d="M15 10h.01"/><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z"/>`
2633
+ refresh: v(
2634
+ d`<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/>`
2359
2635
  ),
2360
- qr: m(
2361
- l`<rect width="5" height="5" x="3" y="3" rx="1"/><rect width="5" height="5" x="16" y="3" rx="1"/><rect width="5" height="5" x="3" y="16" rx="1"/><path d="M21 16h-3a2 2 0 0 0-2 2v3"/><path d="M21 21v.01"/><path d="M12 7v3a2 2 0 0 1-2 2H7"/><path d="M3 12h.01"/><path d="M12 3h.01"/><path d="M12 16v.01"/><path d="M16 12h1"/><path d="M21 12v.01"/><path d="M12 21v-1"/>`
2636
+ chevronDown: v(d`<path d="m6 9 6 6 6-6"/>`),
2637
+ ghost: v(
2638
+ d`<path d="M9 10h.01"/><path d="M15 10h.01"/><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z"/>`
2639
+ ),
2640
+ qr: v(
2641
+ d`<rect width="5" height="5" x="3" y="3" rx="1"/><rect width="5" height="5" x="16" y="3" rx="1"/><rect width="5" height="5" x="3" y="16" rx="1"/><path d="M21 16h-3a2 2 0 0 0-2 2v3"/><path d="M21 21v.01"/><path d="M12 7v3a2 2 0 0 1-2 2H7"/><path d="M3 12h.01"/><path d="M12 3h.01"/><path d="M12 16v.01"/><path d="M16 12h1"/><path d="M21 12v.01"/><path d="M12 21v-1"/>`
2362
2642
  )
2363
- }, w = (e, t = "0 0 24 24") => s`<svg xmlns="http://www.w3.org/2000/svg" viewBox=${t} aria-hidden="true">${e}</svg>`, Mt = {
2643
+ }, w = (e, t = "0 0 24 24") => r`<svg xmlns="http://www.w3.org/2000/svg" viewBox=${t} aria-hidden="true">${e}</svg>`, qt = {
2364
2644
  google: w(
2365
- l`<path fill="#4285F4" d="M23.49 12.27c0-.79-.07-1.54-.19-2.27H12v4.51h6.47a5.57 5.57 0 0 1-2.4 3.58v3h3.86c2.26-2.09 3.56-5.17 3.56-8.82z"/><path fill="#34A853" d="M12 24c3.24 0 5.95-1.08 7.93-2.91l-3.86-3c-1.08.72-2.45 1.16-4.07 1.16-3.13 0-5.78-2.11-6.73-4.96H1.29v3.09A11.99 11.99 0 0 0 12 24z"/><path fill="#FBBC05" d="M5.27 14.29A7.2 7.2 0 0 1 4.89 12c0-.8.14-1.57.38-2.29V6.62H1.29A11.97 11.97 0 0 0 0 12c0 1.94.46 3.77 1.29 5.38l3.98-3.09z"/><path fill="#EA4335" d="M12 4.75c1.77 0 3.35.61 4.6 1.8l3.42-3.42C17.95 1.19 15.24 0 12 0 7.31 0 3.26 2.69 1.29 6.62l3.98 3.09C6.22 6.86 8.87 4.75 12 4.75z"/>`
2645
+ d`<path fill="#4285F4" d="M23.49 12.27c0-.79-.07-1.54-.19-2.27H12v4.51h6.47a5.57 5.57 0 0 1-2.4 3.58v3h3.86c2.26-2.09 3.56-5.17 3.56-8.82z"/><path fill="#34A853" d="M12 24c3.24 0 5.95-1.08 7.93-2.91l-3.86-3c-1.08.72-2.45 1.16-4.07 1.16-3.13 0-5.78-2.11-6.73-4.96H1.29v3.09A11.99 11.99 0 0 0 12 24z"/><path fill="#FBBC05" d="M5.27 14.29A7.2 7.2 0 0 1 4.89 12c0-.8.14-1.57.38-2.29V6.62H1.29A11.97 11.97 0 0 0 0 12c0 1.94.46 3.77 1.29 5.38l3.98-3.09z"/><path fill="#EA4335" d="M12 4.75c1.77 0 3.35.61 4.6 1.8l3.42-3.42C17.95 1.19 15.24 0 12 0 7.31 0 3.26 2.69 1.29 6.62l3.98 3.09C6.22 6.86 8.87 4.75 12 4.75z"/>`
2366
2646
  ),
2367
2647
  github: w(
2368
- l`<path fill="currentColor" d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"/>`
2648
+ d`<path fill="currentColor" d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"/>`
2369
2649
  ),
2370
2650
  apple: w(
2371
- l`<path fill="currentColor" d="M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/>`
2651
+ d`<path fill="currentColor" d="M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/>`
2372
2652
  ),
2373
2653
  facebook: w(
2374
- l`<path fill="#1877F2" d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>`
2654
+ d`<path fill="#1877F2" d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>`
2375
2655
  ),
2376
2656
  x: w(
2377
- l`<path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>`
2657
+ d`<path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>`
2378
2658
  ),
2379
2659
  microsoft: w(
2380
- l`<path fill="#F25022" d="M1 1h10v10H1z"/><path fill="#7FBA00" d="M13 1h10v10H13z"/><path fill="#00A4EF" d="M1 13h10v10H1z"/><path fill="#FFB900" d="M13 13h10v10H13z"/>`
2660
+ d`<path fill="#F25022" d="M1 1h10v10H1z"/><path fill="#7FBA00" d="M13 1h10v10H13z"/><path fill="#00A4EF" d="M1 13h10v10H1z"/><path fill="#FFB900" d="M13 13h10v10H13z"/>`
2381
2661
  ),
2382
2662
  discord: w(
2383
- l`<path fill="#5865F2" d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>`
2663
+ d`<path fill="#5865F2" d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>`
2384
2664
  ),
2385
2665
  gitlab: w(
2386
- l`<path fill="#FC6D26" d="m23.6 9.593-.033-.086L20.3.98a.851.851 0 0 0-.336-.405.876.876 0 0 0-1.001.054.874.874 0 0 0-.29.44l-2.205 6.748H7.535L5.33 1.069a.857.857 0 0 0-.29-.441.876.876 0 0 0-1.001-.054.86.86 0 0 0-.336.405L.436 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.011.009.03.021 4.976 3.727 2.462 1.863 1.5 1.132a1.009 1.009 0 0 0 1.22 0l1.5-1.132 2.461-1.863 5.006-3.75.013-.01a6.068 6.068 0 0 0 2.006-7.002z"/>`
2666
+ d`<path fill="#FC6D26" d="m23.6 9.593-.033-.086L20.3.98a.851.851 0 0 0-.336-.405.876.876 0 0 0-1.001.054.874.874 0 0 0-.29.44l-2.205 6.748H7.535L5.33 1.069a.857.857 0 0 0-.29-.441.876.876 0 0 0-1.001-.054.86.86 0 0 0-.336.405L.436 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.011.009.03.021 4.976 3.727 2.462 1.863 1.5 1.132a1.009 1.009 0 0 0 1.22 0l1.5-1.132 2.461-1.863 5.006-3.75.013-.01a6.068 6.068 0 0 0 2.006-7.002z"/>`
2387
2667
  ),
2388
2668
  linkedin: w(
2389
- l`<path fill="#0A66C2" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>`
2669
+ d`<path fill="#0A66C2" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>`
2390
2670
  ),
2391
2671
  slack: w(
2392
- l`<path fill="#E01E5A" d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313z"/><path fill="#36C5F0" d="M8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312z"/><path fill="#2EB67D" d="M18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.27 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.163 0a2.528 2.528 0 0 1 2.523 2.522v6.312z"/><path fill="#ECB22E" d="M15.163 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.163 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.27a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.315A2.527 2.527 0 0 1 24 15.163a2.528 2.528 0 0 1-2.522 2.523h-6.315z"/>`
2672
+ d`<path fill="#E01E5A" d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313z"/><path fill="#36C5F0" d="M8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312z"/><path fill="#2EB67D" d="M18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.27 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.163 0a2.528 2.528 0 0 1 2.523 2.522v6.312z"/><path fill="#ECB22E" d="M15.163 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.163 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.27a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.315A2.527 2.527 0 0 1 24 15.163a2.528 2.528 0 0 1-2.522 2.523h-6.315z"/>`
2393
2673
  ),
2394
2674
  twitch: w(
2395
- l`<path fill="#9146FF" d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0 1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/>`
2675
+ d`<path fill="#9146FF" d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0 1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/>`
2396
2676
  ),
2397
2677
  spotify: w(
2398
- l`<path fill="#1DB954" d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z"/>`
2678
+ d`<path fill="#1DB954" d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z"/>`
2399
2679
  ),
2400
2680
  notion: w(
2401
- l`<path fill="currentColor" d="M4.459 4.208c.746.606 1.026.56 2.428.466l13.215-.793c.28 0 .047-.28-.046-.326L17.86 1.968c-.42-.326-.981-.7-2.055-.607L3.01 2.295c-.466.046-.56.28-.374.466zm.793 3.08v13.904c0 .747.373 1.027 1.214.98l14.523-.84c.841-.046.935-.56.935-1.167V6.354c0-.606-.233-.933-.748-.887l-15.177.887c-.56.047-.747.327-.747.933zm14.337.745c.093.42 0 .84-.42.888l-.7.14v10.264c-.608.327-1.168.514-1.635.514-.748 0-.935-.234-1.495-.933l-4.577-7.186v6.952L12.21 19s0 .84-1.168.84l-3.222.186c-.093-.186 0-.653.327-.746l.84-.233V9.854L7.822 9.76c-.094-.42.14-1.026.793-1.073l3.456-.233 4.764 7.279v-6.44l-1.215-.139c-.093-.514.28-.887.747-.933zM1.936 1.035l13.31-.98c1.634-.14 2.055-.047 3.082.7l4.249 2.986c.7.513.934.653.934 1.213v16.378c0 1.026-.373 1.634-1.68 1.726l-15.458.934c-.98.047-1.448-.093-1.962-.747l-3.129-4.06c-.56-.747-.793-1.306-.793-1.96V2.667c0-.839.374-1.54 1.447-1.632z"/>`
2681
+ d`<path fill="currentColor" d="M4.459 4.208c.746.606 1.026.56 2.428.466l13.215-.793c.28 0 .047-.28-.046-.326L17.86 1.968c-.42-.326-.981-.7-2.055-.607L3.01 2.295c-.466.046-.56.28-.374.466zm.793 3.08v13.904c0 .747.373 1.027 1.214.98l14.523-.84c.841-.046.935-.56.935-1.167V6.354c0-.606-.233-.933-.748-.887l-15.177.887c-.56.047-.747.327-.747.933zm14.337.745c.093.42 0 .84-.42.888l-.7.14v10.264c-.608.327-1.168.514-1.635.514-.748 0-.935-.234-1.495-.933l-4.577-7.186v6.952L12.21 19s0 .84-1.168.84l-3.222.186c-.093-.186 0-.653.327-.746l.84-.233V9.854L7.822 9.76c-.094-.42.14-1.026.793-1.073l3.456-.233 4.764 7.279v-6.44l-1.215-.139c-.093-.514.28-.887.747-.933zM1.936 1.035l13.31-.98c1.634-.14 2.055-.047 3.082.7l4.249 2.986c.7.513.934.653.934 1.213v16.378c0 1.026-.373 1.634-1.68 1.726l-15.458.934c-.98.047-1.448-.093-1.962-.747l-3.129-4.06c-.56-.747-.793-1.306-.793-1.96V2.667c0-.839.374-1.54 1.447-1.632z"/>`
2402
2682
  ),
2403
2683
  dropbox: w(
2404
- l`<path fill="#0061FF" d="M6 1.807 0 5.629l6 3.822 6.001-3.822L6 1.807zm12 0-6 3.822 6 3.822 6-3.822-6-3.822zM0 13.274l6 3.822 6.001-3.822L6 9.452l-6 3.822zm18-3.822-6 3.822 6 3.822 6-3.822-6-3.822zM6 18.371l6.001 3.822 6-3.822-6-3.822L6 18.371z"/>`
2684
+ d`<path fill="#0061FF" d="M6 1.807 0 5.629l6 3.822 6.001-3.822L6 1.807zm12 0-6 3.822 6 3.822 6-3.822-6-3.822zM0 13.274l6 3.822 6.001-3.822L6 9.452l-6 3.822zm18-3.822-6 3.822 6 3.822 6-3.822-6-3.822zM6 18.371l6.001 3.822 6-3.822-6-3.822L6 18.371z"/>`
2405
2685
  ),
2406
2686
  figma: w(
2407
- l`<path fill="#F24E1E" d="M8 24a4 4 0 0 0 4-4v-4H8a4 4 0 0 0 0 8z"/><path fill="#A259FF" d="M4 12a4 4 0 0 1 4-4h4v8H8a4 4 0 0 1-4-4z"/><path fill="#FF7262" d="M4 4a4 4 0 0 1 4-4h4v8H8a4 4 0 0 1-4-4z"/><path fill="#1ABCFE" d="M12 0h4a4 4 0 0 1 0 8h-4V0z"/><path fill="#0ACF83" d="M20 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0z"/>`
2687
+ d`<path fill="#F24E1E" d="M8 24a4 4 0 0 0 4-4v-4H8a4 4 0 0 0 0 8z"/><path fill="#A259FF" d="M4 12a4 4 0 0 1 4-4h4v8H8a4 4 0 0 1-4-4z"/><path fill="#FF7262" d="M4 4a4 4 0 0 1 4-4h4v8H8a4 4 0 0 1-4-4z"/><path fill="#1ABCFE" d="M12 0h4a4 4 0 0 1 0 8h-4V0z"/><path fill="#0ACF83" d="M20 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0z"/>`
2408
2688
  ),
2409
2689
  bitbucket: w(
2410
- l`<path fill="#2684FF" d="M.778 1.213a.768.768 0 0 0-.768.892l3.263 19.81c.084.5.515.868 1.022.873H19.95a.772.772 0 0 0 .77-.646l3.27-20.03a.768.768 0 0 0-.768-.891zM14.52 15.53H9.522L8.17 8.466h7.561z"/>`
2690
+ d`<path fill="#2684FF" d="M.778 1.213a.768.768 0 0 0-.768.892l3.263 19.81c.084.5.515.868 1.022.873H19.95a.772.772 0 0 0 .77-.646l3.27-20.03a.768.768 0 0 0-.768-.891zM14.52 15.53H9.522L8.17 8.466h7.561z"/>`
2411
2691
  ),
2412
2692
  amazon: w(
2413
- l`<path fill="currentColor" d="M.045 18.02c.072-.116.187-.124.348-.022 3.636 2.11 7.594 3.166 11.87 3.166 2.852 0 5.668-.533 8.447-1.595l.315-.14c.138-.06.234-.1.293-.13.226-.088.39-.046.525.13.12.174.09.336-.12.48-.256.19-.6.41-1.006.654-1.244.743-2.64 1.316-4.185 1.726a17.617 17.617 0 0 1-10.951-.577 17.88 17.88 0 0 1-5.43-3.35c-.1-.074-.151-.15-.151-.22 0-.047.021-.09.051-.13zm6.565-6.218c0-1.005.247-1.863.743-2.577.495-.71 1.17-1.25 2.04-1.615.796-.335 1.756-.575 2.912-.72.39-.046 1.033-.103 1.92-.174v-.37c0-.93-.105-1.558-.3-1.875-.302-.43-.78-.65-1.44-.65h-.182c-.48.046-.896.196-1.246.46-.35.27-.575.63-.675 1.096-.06.3-.206.465-.435.51l-2.52-.315c-.248-.06-.372-.18-.372-.39 0-.046.007-.09.022-.15.247-1.29.855-2.25 1.82-2.88.976-.616 2.1-.975 3.39-1.05h.54c1.65 0 2.957.434 3.888 1.29.135.15.27.3.405.48.12.165.224.314.283.45.075.134.15.33.195.57.06.254.105.42.135.51.03.104.062.3.076.615.01.313.02.493.02.553v5.28c0 .376.06.72.165 1.036.105.313.21.54.315.674l.51.674c.09.136.136.256.136.36 0 .12-.06.226-.18.314-1.2 1.05-1.86 1.62-1.963 1.71-.165.135-.373.15-.61.045a6.62 6.62 0 0 1-.526-.496l-.31-.347a9.858 9.858 0 0 1-.317-.42l-.3-.435c-.81.886-1.603 1.44-2.4 1.665-.494.15-1.093.227-1.83.227-1.11 0-2.04-.343-2.76-1.034-.72-.69-1.08-1.665-1.08-2.94l-.05-.076zm3.753-.438c0 .566.14 1.02.425 1.364.285.34.675.512 1.155.512.045 0 .106-.007.195-.02.09-.016.134-.023.166-.023.614-.16 1.08-.553 1.424-1.178.165-.28.285-.58.36-.91.09-.32.12-.59.135-.8.015-.195.015-.54.015-1.005v-.54c-.84 0-1.484.06-1.92.18-1.275.36-1.92 1.17-1.92 2.43l-.035-.01zm9.162 7.027c.03-.06.075-.11.132-.17.362-.243.714-.41 1.05-.5a8.094 8.094 0 0 1 1.612-.24c.14-.012.28 0 .41.03.65.06 1.05.168 1.172.33.063.09.099.228.099.39v.15c0 .51-.149 1.11-.424 1.8-.278.69-.664 1.248-1.156 1.68-.073.06-.14.09-.197.09-.03 0-.06 0-.09-.012-.09-.044-.107-.12-.064-.24.54-1.26.806-2.143.806-2.64 0-.15-.03-.27-.087-.344-.145-.166-.55-.257-1.224-.257-.243 0-.533.016-.87.045-.363.045-.7.09-1 .135-.09 0-.148-.014-.18-.044-.03-.03-.036-.06-.02-.106 0-.014.007-.03.02-.06z"/>`
2693
+ d`<path fill="currentColor" d="M.045 18.02c.072-.116.187-.124.348-.022 3.636 2.11 7.594 3.166 11.87 3.166 2.852 0 5.668-.533 8.447-1.595l.315-.14c.138-.06.234-.1.293-.13.226-.088.39-.046.525.13.12.174.09.336-.12.48-.256.19-.6.41-1.006.654-1.244.743-2.64 1.316-4.185 1.726a17.617 17.617 0 0 1-10.951-.577 17.88 17.88 0 0 1-5.43-3.35c-.1-.074-.151-.15-.151-.22 0-.047.021-.09.051-.13zm6.565-6.218c0-1.005.247-1.863.743-2.577.495-.71 1.17-1.25 2.04-1.615.796-.335 1.756-.575 2.912-.72.39-.046 1.033-.103 1.92-.174v-.37c0-.93-.105-1.558-.3-1.875-.302-.43-.78-.65-1.44-.65h-.182c-.48.046-.896.196-1.246.46-.35.27-.575.63-.675 1.096-.06.3-.206.465-.435.51l-2.52-.315c-.248-.06-.372-.18-.372-.39 0-.046.007-.09.022-.15.247-1.29.855-2.25 1.82-2.88.976-.616 2.1-.975 3.39-1.05h.54c1.65 0 2.957.434 3.888 1.29.135.15.27.3.405.48.12.165.224.314.283.45.075.134.15.33.195.57.06.254.105.42.135.51.03.104.062.3.076.615.01.313.02.493.02.553v5.28c0 .376.06.72.165 1.036.105.313.21.54.315.674l.51.674c.09.136.136.256.136.36 0 .12-.06.226-.18.314-1.2 1.05-1.86 1.62-1.963 1.71-.165.135-.373.15-.61.045a6.62 6.62 0 0 1-.526-.496l-.31-.347a9.858 9.858 0 0 1-.317-.42l-.3-.435c-.81.886-1.603 1.44-2.4 1.665-.494.15-1.093.227-1.83.227-1.11 0-2.04-.343-2.76-1.034-.72-.69-1.08-1.665-1.08-2.94l-.05-.076zm3.753-.438c0 .566.14 1.02.425 1.364.285.34.675.512 1.155.512.045 0 .106-.007.195-.02.09-.016.134-.023.166-.023.614-.16 1.08-.553 1.424-1.178.165-.28.285-.58.36-.91.09-.32.12-.59.135-.8.015-.195.015-.54.015-1.005v-.54c-.84 0-1.484.06-1.92.18-1.275.36-1.92 1.17-1.92 2.43l-.035-.01zm9.162 7.027c.03-.06.075-.11.132-.17.362-.243.714-.41 1.05-.5a8.094 8.094 0 0 1 1.612-.24c.14-.012.28 0 .41.03.65.06 1.05.168 1.172.33.063.09.099.228.099.39v.15c0 .51-.149 1.11-.424 1.8-.278.69-.664 1.248-1.156 1.68-.073.06-.14.09-.197.09-.03 0-.06 0-.09-.012-.09-.044-.107-.12-.064-.24.54-1.26.806-2.143.806-2.64 0-.15-.03-.27-.087-.344-.145-.166-.55-.257-1.224-.257-.243 0-.533.016-.87.045-.363.045-.7.09-1 .135-.09 0-.148-.014-.18-.044-.03-.03-.036-.06-.02-.106 0-.014.007-.03.02-.06z"/>`
2414
2694
  ),
2415
2695
  paypal: w(
2416
- l`<path fill="#003087" d="M7.076 21.337H2.47a.641.641 0 0 1-.633-.74L4.944.901C5.026.382 5.474 0 5.998 0h7.46c2.57 0 4.578.543 5.69 1.81 1.01 1.15 1.304 2.42 1.012 4.287-.023.143-.047.288-.077.437-.983 5.05-4.349 6.797-8.647 6.797h-2.19c-.524 0-.968.382-1.05.9l-1.12 7.106zm14.146-14.42a3.35 3.35 0 0 0-.607-.541c-.013.076-.026.175-.041.254-.93 4.778-4.005 7.201-9.138 7.201h-2.19a.563.563 0 0 0-.556.479l-1.187 7.527h-.506l-.24 1.516a.56.56 0 0 0 .554.647h3.882c.46 0 .85-.334.922-.788.06-.26.76-4.852.816-5.09a.932.932 0 0 1 .923-.788h.58c3.76 0 6.705-1.528 7.565-5.946.36-1.847.174-3.388-.777-4.471z"/>`
2696
+ d`<path fill="#003087" d="M7.076 21.337H2.47a.641.641 0 0 1-.633-.74L4.944.901C5.026.382 5.474 0 5.998 0h7.46c2.57 0 4.578.543 5.69 1.81 1.01 1.15 1.304 2.42 1.012 4.287-.023.143-.047.288-.077.437-.983 5.05-4.349 6.797-8.647 6.797h-2.19c-.524 0-.968.382-1.05.9l-1.12 7.106zm14.146-14.42a3.35 3.35 0 0 0-.607-.541c-.013.076-.026.175-.041.254-.93 4.778-4.005 7.201-9.138 7.201h-2.19a.563.563 0 0 0-.556.479l-1.187 7.527h-.506l-.24 1.516a.56.56 0 0 0 .554.647h3.882c.46 0 .85-.334.922-.788.06-.26.76-4.852.816-5.09a.932.932 0 0 1 .923-.788h.58c3.76 0 6.705-1.528 7.565-5.946.36-1.847.174-3.388-.777-4.471z"/>`
2417
2697
  )
2418
2698
  };
2419
- function K(e) {
2420
- return Mt[e] ?? c.globe;
2699
+ function tt(e) {
2700
+ return qt[e] ?? c.globe;
2701
+ }
2702
+ function st(e) {
2703
+ const t = (e.trim()[0] ?? "?").toUpperCase();
2704
+ return /[A-Z0-9]/i.test(t) ? t : c.user;
2705
+ }
2706
+ function G(e) {
2707
+ typeof document > "u" || (document.querySelector("authui-modal") || document.body.appendChild(document.createElement("authui-modal")), queueMicrotask(() => {
2708
+ window.dispatchEvent(new CustomEvent("authui:open", { detail: { view: e } }));
2709
+ }));
2710
+ }
2711
+ function se() {
2712
+ typeof window > "u" || window.dispatchEvent(new CustomEvent("authui:close"));
2421
2713
  }
2422
- var Ut = Object.defineProperty, Et = Object.getOwnPropertyDescriptor, C = (e, t, i, r) => {
2423
- for (var a = r > 1 ? void 0 : r ? Et(t, i) : t, h = e.length - 1, u; h >= 0; h--)
2424
- (u = e[h]) && (a = (r ? u(t, i, a) : u(a)) || a);
2425
- return r && a && Ut(t, i, a), a;
2714
+ function et(e) {
2715
+ const t = {
2716
+ length: e.length >= 8,
2717
+ long: e.length >= 12,
2718
+ lower: /[a-z]/.test(e),
2719
+ upper: /[A-Z]/.test(e),
2720
+ number: /\d/.test(e),
2721
+ symbol: /[^A-Za-z0-9]/.test(e)
2722
+ };
2723
+ if (!e)
2724
+ return { level: 0, percent: 0, labelKey: "passwordStrengthTooWeak", checks: t };
2725
+ let i = 0;
2726
+ t.length && (i += 1), t.long && (i += 1), t.lower && t.upper && (i += 1), t.number && (i += 1), t.symbol && (i += 1), e.length < 8 ? i = Math.min(i, 1) : e.length < 10 && (i = Math.min(i, 3));
2727
+ let s, a;
2728
+ return !t.length || i <= 1 ? (s = 1, a = "passwordStrengthTooWeak") : i === 2 ? (s = 2, a = "passwordStrengthWeak") : i === 3 ? (s = 3, a = "passwordStrengthFair") : i >= 5 && t.long && t.lower && t.upper && t.number && t.symbol ? (s = 4, a = "passwordStrengthVeryStrong") : (s = 4, a = "passwordStrengthStrong"), { level: s, percent: s * 25, labelKey: a, checks: t };
2729
+ }
2730
+ const rt = "authui:last-method";
2731
+ function V(e) {
2732
+ if (!(typeof localStorage > "u")) {
2733
+ if (!e || e === "mfa" || e === "sign-up")
2734
+ if (e === "sign-up") e = "email-password";
2735
+ else return;
2736
+ try {
2737
+ localStorage.setItem(rt, e);
2738
+ } catch {
2739
+ }
2740
+ }
2741
+ }
2742
+ function D() {
2743
+ if (typeof localStorage > "u") return null;
2744
+ try {
2745
+ return localStorage.getItem(rt);
2746
+ } catch {
2747
+ return null;
2748
+ }
2749
+ }
2750
+ function re() {
2751
+ if (!(typeof localStorage > "u"))
2752
+ try {
2753
+ localStorage.removeItem(rt);
2754
+ } catch {
2755
+ }
2756
+ }
2757
+ var Nt = Object.defineProperty, Bt = Object.getOwnPropertyDescriptor, k = (e, t, i, s) => {
2758
+ for (var a = s > 1 ? void 0 : s ? Bt(t, i) : t, l = e.length - 1, u; l >= 0; l--)
2759
+ (u = e[l]) && (a = (s ? u(t, i, a) : u(a)) || a);
2760
+ return s && a && Nt(t, i, a), a;
2426
2761
  };
2427
2762
  let $ = class extends A {
2428
2763
  constructor() {
2429
- super(...arguments), this.view = "sign-in", this.embedded = !1, this.step = "sign-in", this.busy = !1, this.error = "", this.notice = null, this.showPassword = !1, this.token = null, this.challenge = null, this.recovery = null, this.email = "", this.password = "", this.passwordConfirm = "", this.name = "", this.phone = "", this.code = "", this.onSignIn = (e) => {
2430
- e.preventDefault(), this.run(async () => {
2431
- await n.signInWithEmailPassword(this.email, this.password), this.password = "", this.fire("authui-success", { method: "email-password" });
2764
+ super(...arguments), this.view = "sign-in", this.embedded = !1, this.step = "sign-in", this.busy = !1, this.error = "", this.notice = null, this.showPassword = !1, this.token = null, this.focusOnStep = !1, this.resendCooldownUntil = 0, this.challenge = null, this.recovery = null, this.email = "", this.password = "", this.passwordConfirm = "", this.name = "", this.phone = "", this.code = "", this.onSignIn = (e) => {
2765
+ e.preventDefault(), this.requireValid(e) && this.run(async () => {
2766
+ await n.signInWithEmailPassword(this.email, this.password), this.password = "", V("email-password"), this.fire("authui-success", { method: "email-password" });
2432
2767
  });
2433
2768
  }, this.onSignUp = (e) => {
2434
- e.preventDefault(), this.run(async () => {
2435
- await n.signUp(this.email, this.password, this.name), this.password = "", this.fire("authui-success", { method: "sign-up" });
2769
+ e.preventDefault(), this.requireValid(e) && this.run(async () => {
2770
+ await n.signUp(this.email, this.password, this.name), this.password = "", V("email-password"), this.fire("authui-success", { method: "sign-up" });
2436
2771
  });
2437
2772
  }, this.onGuest = () => {
2438
2773
  this.run(async () => {
2439
- await n.signInAnonymously(), this.fire("authui-success", { method: "anonymous" });
2774
+ await n.signInAnonymously(), V("anonymous"), this.fire("authui-success", { method: "anonymous" });
2440
2775
  });
2441
2776
  }, this.onOAuth = (e) => {
2442
2777
  this.run(async () => {
2443
- if (await n.signInWithOAuth(e), n.isPreview) {
2778
+ if (V(`oauth:${e}`), await n.signInWithOAuth(e), n.isPreview) {
2444
2779
  this.fire("authui-success", { method: "oauth" });
2445
2780
  return;
2446
2781
  }
2447
2782
  await new Promise((t) => setTimeout(t, 4e3));
2448
2783
  });
2449
2784
  }, this.onForgot = (e) => {
2450
- e.preventDefault(), this.run(async () => {
2785
+ e.preventDefault(), this.requireValid(e) && this.run(async () => {
2451
2786
  await n.sendPasswordRecovery(this.email), this.notice = { tone: "success", message: this.t("resetLinkSent", { email: this.email }) };
2452
2787
  });
2453
2788
  }, this.onReset = (e) => {
2454
- if (e.preventDefault(), this.password !== this.passwordConfirm) {
2789
+ if (e.preventDefault(), !this.requireValid(e)) return;
2790
+ if (this.password !== this.passwordConfirm) {
2455
2791
  this.error = this.t("errorPasswordMismatch");
2456
2792
  return;
2457
2793
  }
2458
2794
  const t = this.recovery;
2459
2795
  t && this.run(async () => {
2460
- await n.completePasswordRecovery(t.userId, t.secret, this.password), this.password = "", this.passwordConfirm = "", this.recovery = null, this.notice = { tone: "success", message: this.t("passwordUpdated") }, this.go("sign-in");
2796
+ await n.completePasswordRecovery(t.userId, t.secret, this.password), this.password = "", this.passwordConfirm = "", this.recovery = null, this.auth.pending?.type === "reset-password" && n.setPending(null), this.notice = { tone: "success", message: this.t("passwordUpdated") }, this.go("sign-in");
2461
2797
  });
2462
2798
  }, this.onMagicUrl = (e) => {
2463
- e.preventDefault(), this.run(async () => {
2799
+ e.preventDefault(), this.requireValid(e) && this.run(async () => {
2464
2800
  const t = await n.sendMagicUrl(this.email);
2465
2801
  this.token = {
2466
2802
  userId: t.userId,
@@ -2470,7 +2806,7 @@ let $ = class extends A {
2470
2806
  };
2471
2807
  });
2472
2808
  }, this.onEmailOtp = (e) => {
2473
- e.preventDefault(), this.run(async () => {
2809
+ e.preventDefault(), this.requireValid(e) && this.run(async () => {
2474
2810
  const t = await n.sendEmailOtp(this.email);
2475
2811
  this.token = {
2476
2812
  userId: t.userId,
@@ -2480,15 +2816,15 @@ let $ = class extends A {
2480
2816
  }, this.code = "";
2481
2817
  });
2482
2818
  }, this.onPhoneOtp = (e) => {
2483
- e.preventDefault(), this.run(async () => {
2819
+ e.preventDefault(), this.requireValid(e) && this.run(async () => {
2484
2820
  const t = await n.sendPhoneOtp(this.phone);
2485
2821
  this.token = { userId: t.userId, kind: "phone", target: this.phone }, this.code = "";
2486
2822
  });
2487
2823
  }, this.onVerifyCode = (e) => {
2488
- e.preventDefault();
2824
+ if (e.preventDefault(), !this.requireValid(e)) return;
2489
2825
  const t = this.token;
2490
2826
  t && this.run(async () => {
2491
- await n.signInWithToken(t.userId, this.code), this.code = "", this.fire("authui-success", { method: t.kind });
2827
+ await n.signInWithToken(t.userId, this.code), this.code = "", this.token = null, V(t.kind), this.fire("authui-success", { method: t.kind });
2492
2828
  }, "code");
2493
2829
  }, this.onChooseFactor = (e) => {
2494
2830
  this.run(async () => {
@@ -2496,17 +2832,17 @@ let $ = class extends A {
2496
2832
  this.challenge = { id: t.$id, factor: e }, this.code = "";
2497
2833
  });
2498
2834
  }, this.onVerifyFactor = (e) => {
2499
- e.preventDefault();
2835
+ if (e.preventDefault(), !this.requireValid(e)) return;
2500
2836
  const t = this.challenge;
2501
2837
  t && this.run(async () => {
2502
- await n.completeMfaChallenge(t.id, this.code), this.code = "", this.challenge = null, this.fire("authui-success", { method: "mfa" });
2838
+ await n.completeMfaChallenge(t.id, this.code), this.code = "", this.challenge = null, this.go("sign-in"), this.fire("authui-success", { method: "mfa" });
2503
2839
  }, "code");
2504
2840
  }, this.onCancelMfa = () => {
2505
2841
  this.run(async () => {
2506
2842
  try {
2507
2843
  await n.signOut();
2508
2844
  } catch (e) {
2509
- if (!B(e, v.sessionNotFound)) throw e;
2845
+ if (!N(e, f.sessionNotFound)) throw e;
2510
2846
  }
2511
2847
  this.go("sign-in");
2512
2848
  });
@@ -2521,19 +2857,24 @@ let $ = class extends A {
2521
2857
  e.has("view") && e.get("view") !== void 0 && this.go(this.view), e.has("auth") && this.syncFromStore();
2522
2858
  }
2523
2859
  updated(e) {
2524
- e.has("step") && requestAnimationFrame(() => this.firstInput?.focus());
2860
+ e.has("step") && (this.focusOnStep || this.embedded) && (this.focusOnStep = !1, requestAnimationFrame(() => this.firstInput?.focus()));
2525
2861
  }
2526
2862
  /** React to store transitions: MFA pending, redirect results, sign in. */
2527
2863
  syncFromStore() {
2528
2864
  const { status: e, pending: t } = this.auth;
2529
- e === "mfa-required" && this.step !== "mfa" && this.go("mfa"), t?.type === "reset-password" && this.step !== "reset-password" && (this.recovery = { userId: t.userId, secret: t.secret }, this.go("reset-password")), t?.type === "oauth-failed" && (this.notice = { tone: "error", message: this.t("errorOAuth") }, n.setPending(null)), t?.type === "notice" && (this.notice = {
2865
+ e === "mfa-required" && this.step !== "mfa" && this.go("mfa");
2866
+ const i = this.step === "reset-password" || t?.type === "reset-password" || this.recovery !== null;
2867
+ (e === "signed-in" || e === "signed-out") && !i && (this.step === "mfa" || this.step === "phone" || this.step === "email-otp" || this.step === "magic-url" || this.step === "forgot-password" || this.token !== null || this.challenge !== null || e === "signed-out") && (this.token = null, this.challenge = null, this.code = "", this.password = "", this.notice = null, this.go(this.view === "sign-up" ? "sign-up" : "sign-in")), t?.type === "reset-password" && this.step !== "reset-password" && (this.recovery = { userId: t.userId, secret: t.secret }, this.go("reset-password")), t?.type === "oauth-failed" && (this.notice = { tone: "error", message: this.t("errorOAuth") }, n.setPending(null)), t?.type === "notice" && !this.notice && (this.notice = {
2530
2868
  tone: t.tone === "error" ? "error" : t.tone,
2531
2869
  message: t.message
2532
- }, n.setPending(null));
2870
+ });
2533
2871
  }
2534
2872
  /** Navigate between screens and reset transient state. */
2873
+ dismissNotice() {
2874
+ this.notice = null, this.auth.pending?.type === "notice" && n.setPending(null);
2875
+ }
2535
2876
  go(e) {
2536
- this.step = e, this.error = "", this.busy = !1, this.showPassword = !1, e !== "mfa" && (this.challenge = null), e !== "email-otp" && e !== "phone" && e !== "magic-url" && (this.token = null), this.fire("authui-view", { view: e });
2877
+ e === "sign-up" && this.config?.signUp === !1 && (e = "sign-in"), this.focusOnStep = !0, this.step = e, this.error = "", this.notice = null, this.auth.pending?.type === "notice" && n.setPending(null), this.busy = !1, this.showPassword = !1, this.password = "", this.passwordConfirm = "", e !== "mfa" && (this.challenge = null), e !== "email-otp" && e !== "phone" && e !== "magic-url" && (this.token = null), this.fire("authui-view", { view: e });
2537
2878
  }
2538
2879
  // ───────────────────────────── actions ─────────────────────────────
2539
2880
  async run(e, t = "link") {
@@ -2542,12 +2883,17 @@ let $ = class extends A {
2542
2883
  try {
2543
2884
  await e();
2544
2885
  } catch (i) {
2545
- this.error = at(i, this.strings, t);
2886
+ this.error = K(i, this.strings, t);
2546
2887
  } finally {
2547
2888
  this.busy = !1;
2548
2889
  }
2549
2890
  }
2550
2891
  }
2892
+ /** Honour native constraint validation before calling Appwrite. */
2893
+ requireValid(e) {
2894
+ const t = e.target;
2895
+ return !(t && typeof t.reportValidity == "function" && !t.reportValidity());
2896
+ }
2551
2897
  bind(e) {
2552
2898
  return (t) => {
2553
2899
  this[e] = t.target.value;
@@ -2556,15 +2902,15 @@ let $ = class extends A {
2556
2902
  // ───────────────────────────── render ─────────────────────────────
2557
2903
  render() {
2558
2904
  const e = this.renderStep();
2559
- return s`
2905
+ return r`
2560
2906
  <div class="panel ${this.embedded ? "embedded" : ""}" part="panel">
2561
2907
  ${this.renderHeader()}
2562
- ${this.notice ? s`<div class="alert alert-${this.notice.tone}" role="status">
2908
+ ${this.notice ? r`<div class="alert alert-${this.notice.tone}" role="status">
2563
2909
  ${this.notice.tone === "success" ? c.checkCircle : this.notice.tone === "error" ? c.alert : c.info}
2564
2910
  <div class="alert-body">${this.notice.message}</div>
2565
2911
  <button
2566
2912
  class="btn btn-ghost btn-icon dismiss"
2567
- @click=${() => this.notice = null}
2913
+ @click=${() => this.dismissNotice()}
2568
2914
  aria-label=${this.t("close")}
2569
2915
  >
2570
2916
  ${c.x}
@@ -2576,55 +2922,66 @@ let $ = class extends A {
2576
2922
  }
2577
2923
  renderHeader() {
2578
2924
  const e = this.config?.branding?.logo, t = this.productName;
2579
- let i = "", r = "";
2580
- switch (this.step) {
2581
- case "sign-in":
2582
- i = this.auth.status === "signed-in" ? this.t("signedInAs") : t ? this.t("signInTitle", { name: t }) : this.t("welcomeBack");
2583
- break;
2584
- case "sign-up":
2585
- i = t ? this.t("signUpTitle", { name: t }) : this.t("createAccount");
2586
- break;
2587
- case "forgot-password":
2588
- case "reset-password":
2589
- i = this.t("resetPassword");
2590
- break;
2591
- case "magic-url":
2592
- case "email-otp":
2593
- i = this.t("continueWithEmail");
2594
- break;
2595
- case "phone":
2596
- i = this.t("continueWithPhone");
2597
- break;
2598
- case "mfa":
2599
- i = this.t("mfaTitle"), r = this.t("mfaDescription");
2600
- break;
2601
- }
2602
- return s`
2603
- <header class="header">
2604
- ${e ? s`<img class="logo" src=${e} alt=${t || "Logo"} />` : o}
2605
- ${n.isPreview ? s`<span class="badge badge-info preview">${this.t("preview")}</span>` : o}
2925
+ let i = "", s = "";
2926
+ if (this.auth.status === "signed-in")
2927
+ i = this.t("signedInAs");
2928
+ else
2929
+ switch (this.step) {
2930
+ case "sign-in":
2931
+ i = t ? this.t("signInTitle", { name: t }) : this.t("welcomeBack");
2932
+ break;
2933
+ case "sign-up":
2934
+ i = t ? this.t("signUpTitle", { name: t }) : this.t("createAccount");
2935
+ break;
2936
+ case "forgot-password":
2937
+ case "reset-password":
2938
+ i = this.t("resetPassword");
2939
+ break;
2940
+ case "magic-url":
2941
+ case "email-otp":
2942
+ i = this.t("continueWithEmail");
2943
+ break;
2944
+ case "phone":
2945
+ i = this.t("continueWithPhone");
2946
+ break;
2947
+ case "mfa":
2948
+ i = this.t("mfaTitle"), s = this.t("mfaDescription");
2949
+ break;
2950
+ }
2951
+ return r`
2952
+ <div class="header">
2953
+ ${e ? r`<img
2954
+ class="logo"
2955
+ src=${e}
2956
+ alt=""
2957
+ @error=${(a) => {
2958
+ a.target.hidden = !0;
2959
+ }}
2960
+ />` : o}
2961
+ ${n.isPreview ? r`<span class="badge badge-info preview">${this.t("preview")}</span>` : o}
2606
2962
  <h2 class="title" id="authui-title">${i}</h2>
2607
- ${r ? s`<p class="description">${r}</p>` : o}
2608
- </header>
2963
+ ${s ? r`<p class="description">${s}</p>` : o}
2964
+ </div>
2609
2965
  `;
2610
2966
  }
2611
2967
  renderError() {
2612
- return this.error ? s`<div class="alert alert-error" role="alert">
2968
+ return this.error ? r`<div class="alert alert-error" role="alert">
2613
2969
  ${c.alert}
2614
2970
  <div class="alert-body">${this.error}</div>
2615
2971
  </div>` : o;
2616
2972
  }
2617
2973
  submitButton(e, t = "btn-primary") {
2618
- return s`<button class="btn ${t} btn-block" type="submit" ?disabled=${this.busy}>
2619
- ${this.busy ? s`<span class="spinner" aria-hidden="true"></span>` : o} ${e}
2974
+ return r`<button class="btn ${t} btn-block" type="submit" ?disabled=${this.busy}>
2975
+ ${this.busy ? r`<span class="spinner" aria-hidden="true"></span>` : o} ${e}
2620
2976
  </button>`;
2621
2977
  }
2622
2978
  passwordField(e) {
2623
- return s`
2979
+ const t = this[e.field], i = e.meter ? et(t) : null;
2980
+ return r`
2624
2981
  <div class="field">
2625
2982
  <label class="label" for=${e.id}>
2626
2983
  ${e.label}
2627
- ${e.forgot ? s`<button
2984
+ ${e.forgot ? r`<button
2628
2985
  type="button"
2629
2986
  class="btn btn-link small"
2630
2987
  @click=${() => this.go("forgot-password")}
@@ -2640,25 +2997,39 @@ let $ = class extends A {
2640
2997
  autocomplete=${e.autocomplete}
2641
2998
  required
2642
2999
  minlength="8"
2643
- .value=${this[e.field]}
3000
+ .value=${t}
2644
3001
  @input=${this.bind(e.field)}
2645
3002
  />
2646
3003
  <button
2647
3004
  type="button"
2648
3005
  class="btn btn-ghost btn-icon"
2649
3006
  @click=${() => this.showPassword = !this.showPassword}
2650
- aria-label=${this.showPassword ? "Hide password" : "Show password"}
3007
+ aria-label=${this.showPassword ? this.t("hidePassword") : this.t("showPassword")}
2651
3008
  tabindex="-1"
2652
3009
  >
2653
3010
  ${this.showPassword ? c.eyeOff : c.eye}
2654
3011
  </button>
2655
3012
  </div>
2656
- ${e.hint ? s`<p class="hint">${e.hint}</p>` : o}
3013
+ ${i && t ? r`<div class="strength" aria-live="polite">
3014
+ <div
3015
+ class="strength-meter"
3016
+ data-level=${String(i.level)}
3017
+ role="meter"
3018
+ aria-label=${this.t("passwordStrengthLabel")}
3019
+ aria-valuemin="0"
3020
+ aria-valuemax="4"
3021
+ aria-valuenow=${String(i.level)}
3022
+ aria-valuetext=${this.t(i.labelKey)}
3023
+ >
3024
+ <span></span><span></span><span></span><span></span>
3025
+ </div>
3026
+ <p class="strength-label">${this.t(i.labelKey)}</p>
3027
+ </div>` : e.hint ? r`<p class="hint">${e.hint}</p>` : o}
2657
3028
  </div>
2658
3029
  `;
2659
3030
  }
2660
3031
  emailField(e = "email") {
2661
- return s`
3032
+ return r`
2662
3033
  <div class="field">
2663
3034
  <label class="label" for="authui-email">${this.t("email")}</label>
2664
3035
  <input
@@ -2675,7 +3046,7 @@ let $ = class extends A {
2675
3046
  `;
2676
3047
  }
2677
3048
  codeField() {
2678
- return s`
3049
+ return r`
2679
3050
  <div class="field">
2680
3051
  <label class="label" for="authui-code">${this.t("code")}</label>
2681
3052
  <input
@@ -2684,6 +3055,8 @@ let $ = class extends A {
2684
3055
  type="text"
2685
3056
  inputmode="numeric"
2686
3057
  autocomplete="one-time-code"
3058
+ maxlength="6"
3059
+ pattern="[0-9]*"
2687
3060
  required
2688
3061
  .value=${this.code}
2689
3062
  @input=${this.bind("code")}
@@ -2693,32 +3066,37 @@ let $ = class extends A {
2693
3066
  }
2694
3067
  legal() {
2695
3068
  const e = this.config?.legal;
2696
- return !e?.termsUrl && !e?.privacyUrl ? o : s`<p class="legal">
3069
+ return !e?.termsUrl && !e?.privacyUrl ? o : r`<p class="legal">
2697
3070
  ${this.t("agreeTo")}
2698
- ${e.termsUrl ? s`<a href=${e.termsUrl} target="_blank" rel="noopener">${this.t("terms")}</a>` : o}
2699
- ${e.termsUrl && e.privacyUrl ? s` ${this.t("and")} ` : o}
2700
- ${e.privacyUrl ? s`<a href=${e.privacyUrl} target="_blank" rel="noopener">${this.t("privacy")}</a>` : o}.
3071
+ ${e.termsUrl ? r`<a href=${e.termsUrl} target="_blank" rel="noopener">${this.t("terms")}</a>` : o}
3072
+ ${e.termsUrl && e.privacyUrl ? r` ${this.t("and")} ` : o}
3073
+ ${e.privacyUrl ? r`<a href=${e.privacyUrl} target="_blank" rel="noopener">${this.t("privacy")}</a>` : o}.
2701
3074
  </p>`;
2702
3075
  }
2703
3076
  backLink(e = "sign-in") {
2704
- return s`<div class="links">
3077
+ return r`<div class="links">
2705
3078
  <button type="button" class="btn btn-link" @click=${() => this.go(e)}>
2706
3079
  ${c.arrowLeft} ${this.t("back")}
2707
3080
  </button>
2708
3081
  </div>`;
2709
3082
  }
2710
3083
  renderStep() {
3084
+ if (this.auth.configError)
3085
+ return r`<div class="alert alert-error" role="alert">
3086
+ ${c.alert}
3087
+ <div class="alert-body">${this.auth.configError}</div>
3088
+ </div>`;
2711
3089
  if (!this.auth.configured)
2712
- return s`<div class="alert alert-error" role="alert">
3090
+ return r`<div class="alert alert-error" role="alert">
2713
3091
  ${c.alert}
2714
3092
  <div class="alert-body">${this.t("errorNotConfigured")}</div>
2715
3093
  </div>`;
2716
3094
  if (this.auth.status === "loading")
2717
- return s`<div class="empty"><span class="spinner"></span></div>`;
3095
+ return r`<div class="empty"><span class="spinner"></span></div>`;
2718
3096
  if (this.auth.status === "signed-in" && this.step !== "mfa") return this.renderSignedIn();
2719
3097
  switch (this.step) {
2720
3098
  case "sign-up":
2721
- return this.renderSignUp();
3099
+ return this.config?.signUp === !1 ? this.renderSignIn() : this.renderSignUp();
2722
3100
  case "forgot-password":
2723
3101
  return this.renderForgot();
2724
3102
  case "reset-password":
@@ -2737,25 +3115,27 @@ let $ = class extends A {
2737
3115
  }
2738
3116
  renderSignedIn() {
2739
3117
  const e = this.auth.user, t = e.name || e.email || e.phone || this.t("guestAccount");
2740
- return s`
3118
+ return r`
2741
3119
  <div class="stack">
2742
3120
  <div class="row">
2743
3121
  <div class="inline">
2744
- <span class="avatar">${t[0] ?? "?"}</span>
3122
+ <span class="avatar">${st(t)}</span>
2745
3123
  <div class="row-main">
2746
- <span class="row-title">${t}</span>
2747
- ${e.email && e.name ? s`<span class="row-sub">${e.email}</span>` : o}
3124
+ <span class="row-title" title=${t}>${t}</span>
3125
+ ${e.email && e.name ? r`<span class="row-sub" title=${e.email}>${e.email}</span>` : o}
2748
3126
  </div>
2749
3127
  </div>
2750
3128
  </div>
2751
3129
  ${this.renderError()}
2752
3130
  <div class="stack-sm">
2753
- ${this.config?.successUrl ? s`<a class="btn btn-primary btn-block" href=${this.config.successUrl}
3131
+ ${this.config?.successUrl ? r`<a class="btn btn-primary btn-block" href=${this.config.successUrl}
2754
3132
  >${this.t("continue")}</a
2755
3133
  >` : o}
2756
3134
  <button
2757
3135
  class="btn btn-outline btn-block"
2758
- @click=${() => this.fire("authui-open", { view: "account" })}
3136
+ @click=${() => {
3137
+ this.embedded ? this.fire("authui-open", { view: "account" }) : G("account");
3138
+ }}
2759
3139
  >
2760
3140
  ${c.settings} ${this.t("manageAccount")}
2761
3141
  </button>
@@ -2767,63 +3147,80 @@ let $ = class extends A {
2767
3147
  `;
2768
3148
  }
2769
3149
  renderProviders() {
2770
- const e = this.config?.methods?.oauth ?? [];
3150
+ const e = [...this.config?.methods?.oauth ?? []];
2771
3151
  if (e.length === 0) return o;
2772
- const t = e.length > 2;
2773
- return s`
2774
- <div class="providers ${t ? "two" : ""}">
2775
- ${e.map(
2776
- (i) => s`<button
2777
- type="button"
2778
- class="btn btn-outline"
2779
- @click=${() => this.onOAuth(i)}
2780
- ?disabled=${this.busy}
2781
- aria-label=${this.t("continueWith", { provider: D(i) })}
3152
+ const t = D();
3153
+ e.sort((s, a) => {
3154
+ const l = t === `oauth:${s}` ? 0 : 1, u = t === `oauth:${a}` ? 0 : 1;
3155
+ return l - u;
3156
+ });
3157
+ const i = e.length > 2;
3158
+ return r`
3159
+ <div class="providers ${i ? "two" : ""}">
3160
+ ${e.map((s) => {
3161
+ const a = t === `oauth:${s}`;
3162
+ return r`<button
3163
+ type="button"
3164
+ class="btn btn-outline ${a ? "last-used" : ""}"
3165
+ @click=${() => this.onOAuth(s)}
3166
+ ?disabled=${this.busy}
3167
+ aria-label=${this.t("continueWith", { provider: q(s) })}
3168
+ >
3169
+ ${tt(s)}
3170
+ <span
3171
+ >${i ? q(s) : this.t("continueWith", { provider: q(s) })}</span
2782
3172
  >
2783
- ${K(i)}
2784
- <span
2785
- >${t ? D(i) : this.t("continueWith", { provider: D(i) })}</span
2786
- >
2787
- </button>`
2788
- )}
3173
+ ${a ? r`<span class="last-used-badge">${this.t("lastUsed")}</span>` : o}
3174
+ </button>`;
3175
+ })}
2789
3176
  </div>
2790
3177
  `;
2791
3178
  }
2792
3179
  renderSignIn() {
2793
- const e = this.config?.methods ?? {}, t = e.emailPassword !== !1, i = (e.oauth?.length ?? 0) > 0, r = [
3180
+ const e = this.config?.methods ?? {}, t = e.emailPassword !== !1, i = (e.oauth?.length ?? 0) > 0, s = [
2794
3181
  e.magicUrl ? { step: "magic-url", icon: c.link, label: this.t("sendMagicLink") } : null,
2795
3182
  e.emailOtp ? { step: "email-otp", icon: c.mail, label: this.t("continueWithEmail") } : null,
2796
3183
  e.phone ? { step: "phone", icon: c.smartphone, label: this.t("continueWithPhone") } : null
2797
3184
  ].filter(Boolean);
2798
- return s`
3185
+ return r`
2799
3186
  <div class="stack">
2800
3187
  ${this.renderProviders()}
2801
- ${i && (t || r.length > 0) ? s`<div class="separator-text">${this.t("or")}</div>` : o}
2802
- ${t ? s`<form class="form" @submit=${this.onSignIn} novalidate>
3188
+ ${i && (t || s.length > 0) ? r`<div class="separator-text">${this.t("or")}</div>` : o}
3189
+ ${t ? r`<form
3190
+ class="form ${D() === "email-password" ? "last-used-form" : ""}"
3191
+ @submit=${this.onSignIn}
3192
+ novalidate
3193
+ >
3194
+ ${D() === "email-password" ? r`<p class="hint">
3195
+ <span class="last-used-badge">${this.t("lastUsed")}</span>
3196
+ </p>` : o}
2803
3197
  ${this.emailField()}
2804
3198
  ${this.passwordField({ label: this.t("password"), autocomplete: "current-password", id: "authui-password", field: "password", forgot: !0 })}
2805
3199
  ${this.renderError()} ${this.submitButton(this.t("signIn"))}
2806
3200
  </form>` : this.renderError()}
2807
- ${r.length > 0 ? s`<div class="stack-sm">
2808
- ${r.map(
2809
- (a) => s`<button
2810
- type="button"
2811
- class="btn btn-secondary btn-block"
2812
- @click=${() => this.go(a.step)}
2813
- >
2814
- ${a.icon} ${a.label}
2815
- </button>`
2816
- )}
3201
+ ${s.length > 0 ? r`<div class="stack-sm">
3202
+ ${s.map((a) => {
3203
+ const l = D() === a.step;
3204
+ return r`<button
3205
+ type="button"
3206
+ class="btn btn-secondary btn-block ${l ? "last-used" : ""}"
3207
+ @click=${() => this.go(a.step)}
3208
+ >
3209
+ ${a.icon} ${a.label}
3210
+ ${l ? r`<span class="last-used-badge">${this.t("lastUsed")}</span>` : o}
3211
+ </button>`;
3212
+ })}
2817
3213
  </div>` : o}
2818
- ${e.anonymous ? s`<button
3214
+ ${e.anonymous ? r`<button
2819
3215
  type="button"
2820
- class="btn btn-ghost btn-block"
3216
+ class="btn btn-ghost btn-block ${D() === "anonymous" ? "last-used" : ""}"
2821
3217
  @click=${this.onGuest}
2822
3218
  ?disabled=${this.busy}
2823
3219
  >
2824
3220
  ${c.ghost} ${this.t("continueAsGuest")}
3221
+ ${D() === "anonymous" ? r`<span class="last-used-badge">${this.t("lastUsed")}</span>` : o}
2825
3222
  </button>` : o}
2826
- ${t && this.config?.signUp !== !1 ? s`<div class="links">
3223
+ ${t && this.config?.signUp !== !1 ? r`<div class="links">
2827
3224
  <span>${this.t("noAccount")}</span>
2828
3225
  <button type="button" class="btn btn-link" @click=${() => this.go("sign-up")}>
2829
3226
  ${this.t("signUp")}
@@ -2834,12 +3231,12 @@ let $ = class extends A {
2834
3231
  `;
2835
3232
  }
2836
3233
  renderSignUp() {
2837
- return s`
3234
+ return r`
2838
3235
  <div class="stack">
2839
3236
  ${this.renderProviders()}
2840
- ${(this.config?.methods?.oauth?.length ?? 0) > 0 ? s`<div class="separator-text">${this.t("or")}</div>` : o}
3237
+ ${(this.config?.methods?.oauth?.length ?? 0) > 0 ? r`<div class="separator-text">${this.t("or")}</div>` : o}
2841
3238
  <form class="form" @submit=${this.onSignUp} novalidate>
2842
- ${this.config?.requireName !== !1 ? s`<div class="field">
3239
+ ${this.config?.requireName !== !1 ? r`<div class="field">
2843
3240
  <label class="label" for="authui-name">${this.t("name")}</label>
2844
3241
  <input
2845
3242
  class="input"
@@ -2852,7 +3249,7 @@ let $ = class extends A {
2852
3249
  />
2853
3250
  </div>` : o}
2854
3251
  ${this.emailField()}
2855
- ${this.passwordField({ label: this.t("password"), autocomplete: "new-password", id: "authui-password", field: "password", hint: this.t("passwordHint") })}
3252
+ ${this.passwordField({ label: this.t("password"), autocomplete: "new-password", id: "authui-password", field: "password", hint: this.t("passwordHint"), meter: !0 })}
2856
3253
  ${this.renderError()} ${this.submitButton(this.t("createAccount"))}
2857
3254
  </form>
2858
3255
  <div class="links">
@@ -2866,7 +3263,7 @@ let $ = class extends A {
2866
3263
  `;
2867
3264
  }
2868
3265
  renderForgot() {
2869
- return s`
3266
+ return r`
2870
3267
  <div class="stack">
2871
3268
  <form class="form" @submit=${this.onForgot} novalidate>
2872
3269
  ${this.emailField()} ${this.renderError()} ${this.submitButton(this.t("sendResetLink"))}
@@ -2876,25 +3273,45 @@ let $ = class extends A {
2876
3273
  `;
2877
3274
  }
2878
3275
  renderReset() {
2879
- return this.recovery ? s`
3276
+ return this.recovery ? r`
2880
3277
  <div class="stack">
2881
3278
  <form class="form" @submit=${this.onReset} novalidate>
2882
- ${this.passwordField({ label: this.t("newPassword"), autocomplete: "new-password", id: "authui-password", field: "password", hint: this.t("passwordHint") })}
3279
+ ${this.passwordField({ label: this.t("newPassword"), autocomplete: "new-password", id: "authui-password", field: "password", hint: this.t("passwordHint"), meter: !0 })}
2883
3280
  ${this.passwordField({ label: this.t("confirmPassword"), autocomplete: "new-password", id: "authui-password-confirm", field: "passwordConfirm" })}
2884
3281
  ${this.renderError()} ${this.submitButton(this.t("resetPassword"))}
2885
3282
  </form>
2886
- ${this.backLink()}
3283
+ <div class="links">
3284
+ <button
3285
+ type="button"
3286
+ class="btn btn-link"
3287
+ @click=${() => {
3288
+ this.step = "sign-in", this.error = "", this.notice = null, this.focusOnStep = !0, this.fire("authui-view", { view: "sign-in" });
3289
+ }}
3290
+ >
3291
+ ${c.arrowLeft} ${this.t("back")}
3292
+ </button>
3293
+ </div>
2887
3294
  </div>
2888
- ` : s`<div class="stack">
3295
+ ` : r`<div class="stack">
2889
3296
  <div class="alert alert-error" role="alert">
2890
3297
  ${c.alert}
2891
3298
  <div class="alert-body">${this.t("errorInvalidToken")}</div>
2892
3299
  </div>
2893
- ${this.backLink()}
3300
+ <div class="links">
3301
+ <button
3302
+ type="button"
3303
+ class="btn btn-link"
3304
+ @click=${() => {
3305
+ this.go("forgot-password");
3306
+ }}
3307
+ >
3308
+ ${this.t("requestNewLink")}
3309
+ </button>
3310
+ </div>
2894
3311
  </div>`;
2895
3312
  }
2896
3313
  phraseBox(e) {
2897
- return e ? s`<div class="alert alert-info">
3314
+ return e ? r`<div class="alert alert-info">
2898
3315
  ${c.shield}
2899
3316
  <div class="alert-title">
2900
3317
  ${this.t("securityPhrase")}: <span class="code">${e}</span>
@@ -2903,25 +3320,44 @@ let $ = class extends A {
2903
3320
  </div>` : o;
2904
3321
  }
2905
3322
  renderMagicUrl() {
2906
- return this.token ? s`<div class="stack">
3323
+ return this.token ? r`<div class="stack">
2907
3324
  <div class="alert alert-success" role="status">
2908
3325
  ${c.mail}
2909
3326
  <div class="alert-body">${this.t("magicLinkSent", { email: this.token.target })}</div>
2910
3327
  </div>
2911
3328
  ${this.phraseBox(this.token.phrase)} ${this.backLink()}
2912
- </div>` : s`
3329
+ </div>` : r`
2913
3330
  <div class="stack">
2914
3331
  <form class="form" @submit=${this.onMagicUrl} novalidate>
2915
3332
  ${this.emailField()} ${this.renderError()} ${this.submitButton(this.t("sendMagicLink"))}
2916
3333
  </form>
2917
- ${this.backLink()}
3334
+ ${this.backLink()} ${this.legal()}
2918
3335
  </div>
2919
3336
  `;
2920
3337
  }
3338
+ async onResendCode() {
3339
+ const e = this.token;
3340
+ !e || Date.now() < this.resendCooldownUntil || (this.error = "", await this.run(async () => {
3341
+ if (e.kind === "phone") {
3342
+ const t = await n.sendPhoneOtp(e.target);
3343
+ this.token = { userId: t.userId, kind: "phone", target: e.target };
3344
+ } else {
3345
+ const t = await n.sendEmailOtp(e.target);
3346
+ this.token = {
3347
+ userId: t.userId,
3348
+ kind: "email-otp",
3349
+ target: e.target,
3350
+ phrase: t.phrase
3351
+ };
3352
+ }
3353
+ this.resendCooldownUntil = Date.now() + 3e4, window.setTimeout(() => this.requestUpdate(), 3e4);
3354
+ }));
3355
+ }
2921
3356
  renderCodeEntry() {
2922
- return s`
3357
+ const e = this.token?.kind === "phone", t = Date.now() < this.resendCooldownUntil;
3358
+ return r`
2923
3359
  <div class="alert alert-info" role="status">
2924
- ${c.mail}
3360
+ ${e ? c.smartphone : c.mail}
2925
3361
  <div class="alert-body">${this.t("codeSent", { target: this.token.target })}</div>
2926
3362
  </div>
2927
3363
  ${this.phraseBox(this.token.phrase)}
@@ -2929,28 +3365,41 @@ let $ = class extends A {
2929
3365
  ${this.codeField()} ${this.renderError()} ${this.submitButton(this.t("verifyCode"))}
2930
3366
  </form>
2931
3367
  <div class="links">
2932
- <button type="button" class="btn btn-link" @click=${() => this.token = null}>
2933
- ${this.t("sendCode")}
3368
+ <button
3369
+ type="button"
3370
+ class="btn btn-link"
3371
+ ?disabled=${t || this.busy}
3372
+ @click=${() => {
3373
+ this.onResendCode();
3374
+ }}
3375
+ >
3376
+ ${this.t("resendCode")}
2934
3377
  </button>
2935
3378
  <span aria-hidden="true">·</span>
2936
- <button type="button" class="btn btn-link" @click=${() => this.go("sign-in")}>
2937
- ${this.t("back")}
3379
+ <button
3380
+ type="button"
3381
+ class="btn btn-link"
3382
+ @click=${() => {
3383
+ this.token = null, this.error = "";
3384
+ }}
3385
+ >
3386
+ ${e ? this.t("useDifferentPhone") : this.t("useDifferentEmail")}
2938
3387
  </button>
2939
3388
  </div>
2940
3389
  `;
2941
3390
  }
2942
3391
  renderEmailOtp() {
2943
- return this.token ? s`<div class="stack">${this.renderCodeEntry()}</div>` : s`
3392
+ return this.token ? r`<div class="stack">${this.renderCodeEntry()}</div>` : r`
2944
3393
  <div class="stack">
2945
3394
  <form class="form" @submit=${this.onEmailOtp} novalidate>
2946
3395
  ${this.emailField()} ${this.renderError()} ${this.submitButton(this.t("sendCode"))}
2947
3396
  </form>
2948
- ${this.backLink()}
3397
+ ${this.backLink()} ${this.legal()}
2949
3398
  </div>
2950
3399
  `;
2951
3400
  }
2952
3401
  renderPhone() {
2953
- return this.token ? s`<div class="stack">${this.renderCodeEntry()}</div>` : s`
3402
+ return this.token ? r`<div class="stack">${this.renderCodeEntry()}</div>` : r`
2954
3403
  <div class="stack">
2955
3404
  <form class="form" @submit=${this.onPhoneOtp} novalidate>
2956
3405
  <div class="field">
@@ -2968,7 +3417,7 @@ let $ = class extends A {
2968
3417
  </div>
2969
3418
  ${this.renderError()} ${this.submitButton(this.t("sendCode"))}
2970
3419
  </form>
2971
- ${this.backLink()}
3420
+ ${this.backLink()} ${this.legal()}
2972
3421
  </div>
2973
3422
  `;
2974
3423
  }
@@ -3001,17 +3450,17 @@ let $ = class extends A {
3001
3450
  available: e?.recoveryCode ?? !0
3002
3451
  }
3003
3452
  ];
3004
- return s`
3453
+ return r`
3005
3454
  <div class="stack">
3006
3455
  <div class="stack-sm">
3007
- ${i.filter((r) => r.available).map(
3008
- (r) => s`<button
3456
+ ${i.filter((s) => s.available).map(
3457
+ (s) => r`<button
3009
3458
  type="button"
3010
3459
  class="choice"
3011
- @click=${() => this.onChooseFactor(r.factor)}
3460
+ @click=${() => this.onChooseFactor(s.factor)}
3012
3461
  ?disabled=${this.busy}
3013
3462
  >
3014
- ${r.icon}<span class="choice-title">${r.label}</span>
3463
+ ${s.icon}<span class="choice-title">${s.label}</span>
3015
3464
  </button>`
3016
3465
  )}
3017
3466
  </div>
@@ -3025,10 +3474,10 @@ let $ = class extends A {
3025
3474
  `;
3026
3475
  }
3027
3476
  const t = this.challenge.factor === "recoverycode";
3028
- return s`
3477
+ return r`
3029
3478
  <div class="stack">
3030
3479
  <form class="form" @submit=${this.onVerifyFactor} novalidate>
3031
- ${t ? s`<div class="field">
3480
+ ${t ? r`<div class="field">
3032
3481
  <label class="label" for="authui-code">${this.t("recoveryCode")}</label>
3033
3482
  <input
3034
3483
  class="input mono"
@@ -3055,102 +3504,127 @@ let $ = class extends A {
3055
3504
  `;
3056
3505
  }
3057
3506
  };
3058
- $.styles = [...A.styles, At];
3059
- C([
3060
- f({ type: String })
3507
+ $.styles = [...A.styles, Vt];
3508
+ k([
3509
+ g({ type: String })
3061
3510
  ], $.prototype, "view", 2);
3062
- C([
3063
- f({ type: Boolean })
3511
+ k([
3512
+ g({ type: Boolean })
3064
3513
  ], $.prototype, "embedded", 2);
3065
- C([
3066
- d()
3514
+ k([
3515
+ h()
3067
3516
  ], $.prototype, "step", 2);
3068
- C([
3069
- d()
3517
+ k([
3518
+ h()
3070
3519
  ], $.prototype, "busy", 2);
3071
- C([
3072
- d()
3520
+ k([
3521
+ h()
3073
3522
  ], $.prototype, "error", 2);
3074
- C([
3075
- d()
3523
+ k([
3524
+ h()
3076
3525
  ], $.prototype, "notice", 2);
3077
- C([
3078
- d()
3526
+ k([
3527
+ h()
3079
3528
  ], $.prototype, "showPassword", 2);
3080
- C([
3081
- d()
3529
+ k([
3530
+ h()
3082
3531
  ], $.prototype, "token", 2);
3083
- C([
3084
- d()
3532
+ k([
3533
+ h()
3534
+ ], $.prototype, "resendCooldownUntil", 2);
3535
+ k([
3536
+ h()
3085
3537
  ], $.prototype, "challenge", 2);
3086
- C([
3087
- d()
3538
+ k([
3539
+ h()
3088
3540
  ], $.prototype, "recovery", 2);
3089
- C([
3090
- rt("form input:not([type=hidden])")
3541
+ k([
3542
+ gt("form input:not([type=hidden])")
3091
3543
  ], $.prototype, "firstInput", 2);
3092
- $ = C([
3093
- _("authui-sign-in")
3544
+ $ = k([
3545
+ O("authui-sign-in")
3094
3546
  ], $);
3095
- var It = Object.defineProperty, _t = Object.getOwnPropertyDescriptor, g = (e, t, i, r) => {
3096
- for (var a = r > 1 ? void 0 : r ? _t(t, i) : t, h = e.length - 1, u; h >= 0; h--)
3097
- (u = e[h]) && (a = (r ? u(t, i, a) : u(a)) || a);
3098
- return r && a && It(t, i, a), a;
3547
+ var jt = Object.defineProperty, Ht = Object.getOwnPropertyDescriptor, m = (e, t, i, s) => {
3548
+ for (var a = s > 1 ? void 0 : s ? Ht(t, i) : t, l = e.length - 1, u; l >= 0; l--)
3549
+ (u = e[l]) && (a = (s ? u(t, i, a) : u(a)) || a);
3550
+ return s && a && jt(t, i, a), a;
3099
3551
  };
3100
3552
  let p = class extends A {
3101
3553
  constructor() {
3102
- super(...arguments), this.embedded = !1, this.tab = "profile", this.active = "profile", this.busy = "", this.notice = null, this.errors = {}, this.nameInput = "", this.emailInput = "", this.emailPassword = "", this.phoneInput = "", this.phonePassword = "", this.phoneCode = "", this.phoneCodeSent = !1, this.guestName = "", this.oldPassword = "", this.newPassword = "", this.newPasswordConfirm = "", this.authenticator = null, this.authenticatorCode = "", this.factors = null, this.recoveryCodes = null, this.stepUp = null, this.stepUpCode = "", this.copied = !1, this.sessions = null, this.identities = null, this.logs = null, this.logsSupported = !0, this.confirmDelete = !1, this.factorsLoading = !1, this.onUpdateName = (e) => {
3103
- e.preventDefault(), this.run("name", () => n.updateName(this.nameInput), this.t("done"));
3554
+ super(...arguments), this.embedded = !1, this.tab = "profile", this.active = "profile", this.busy = "", this.notice = null, this.errors = {}, this.nameInput = "", this.emailInput = "", this.emailPassword = "", this.phoneInput = "", this.phonePassword = "", this.phoneCode = "", this.phoneCodeSent = !1, this.guestName = "", this.oldPassword = "", this.newPassword = "", this.newPasswordConfirm = "", this.authenticator = null, this.authenticatorCode = "", this.factors = null, this.recoveryCodes = null, this.stepUp = null, this.stepUpCode = "", this.copied = !1, this.sessions = null, this.identities = null, this.logs = null, this.logsSupported = null, this.logsProbeStarted = !1, this.confirmDelete = !1, this.confirmRegenerate = !1, this.confirmRemoveAuthenticator = !1, this.confirmSignOutAll = !1, this.confirmDisconnectId = null, this.verifyEmailCooldownUntil = 0, this.onTabsKeydown = (e) => {
3555
+ const t = [...this.renderRoot?.querySelectorAll('[role="tab"]') ?? []];
3556
+ if (!t.length) return;
3557
+ const i = t.findIndex((l) => l.getAttribute("aria-selected") === "true");
3558
+ let s = i;
3559
+ if (e.key === "ArrowRight" || e.key === "ArrowDown") s = (i + 1) % t.length;
3560
+ else if (e.key === "ArrowLeft" || e.key === "ArrowUp")
3561
+ s = (i - 1 + t.length) % t.length;
3562
+ else if (e.key === "Home") s = 0;
3563
+ else if (e.key === "End") s = t.length - 1;
3564
+ else return;
3565
+ e.preventDefault();
3566
+ const a = t[s].id.replace("authui-tab-", "");
3567
+ this.select(a), requestAnimationFrame(() => t[s]?.focus());
3568
+ }, this.noticeTimer = null, this.factorsLoading = !1, this.onUpdateName = (e) => {
3569
+ e.preventDefault(), this.requireValid(e) && this.run("name", () => n.updateName(this.nameInput), this.t("nameUpdated"));
3104
3570
  }, this.onUpdateEmail = (e) => {
3105
- e.preventDefault(), this.run(
3571
+ e.preventDefault(), this.requireValid(e) && this.run(
3106
3572
  "email",
3107
3573
  async () => {
3108
3574
  await n.updateEmail(this.emailInput, this.emailPassword), this.emailPassword = "";
3109
3575
  },
3110
- this.t("done")
3576
+ this.t("emailUpdated")
3111
3577
  );
3112
3578
  }, this.onUpdatePhone = (e) => {
3113
- e.preventDefault(), this.run(
3579
+ e.preventDefault(), this.requireValid(e) && this.run(
3114
3580
  "phone",
3115
3581
  async () => {
3116
3582
  await n.updatePhone(this.phoneInput, this.phonePassword), this.phonePassword = "";
3117
3583
  },
3118
- this.t("done")
3584
+ this.t("phoneUpdated")
3119
3585
  );
3120
3586
  }, this.onConvertGuest = (e) => {
3121
- e.preventDefault(), this.run(
3587
+ e.preventDefault(), this.requireValid(e) && this.run(
3122
3588
  "guest",
3123
3589
  async () => {
3124
3590
  await n.convertGuest(this.emailInput, this.emailPassword, this.guestName), this.emailPassword = "";
3125
3591
  },
3126
- this.t("done")
3592
+ this.t("accountConverted")
3127
3593
  );
3128
3594
  }, this.onSendVerification = () => {
3129
- this.run("verify", () => n.sendEmailVerification(), this.t("verificationSent"));
3595
+ Date.now() < this.verifyEmailCooldownUntil || this.run(
3596
+ "verify",
3597
+ async () => {
3598
+ await n.sendEmailVerification(), this.verifyEmailCooldownUntil = Date.now() + 45e3, window.setTimeout(() => this.requestUpdate(), 45e3);
3599
+ },
3600
+ this.t("verificationSent")
3601
+ );
3130
3602
  }, this.onSendPhoneVerification = () => {
3131
3603
  this.run("verify-phone", async () => {
3132
3604
  await n.sendPhoneVerification(), this.phoneCodeSent = !0;
3133
3605
  });
3134
3606
  }, this.onConfirmPhoneVerification = (e) => {
3135
- e.preventDefault(), this.run(
3607
+ e.preventDefault(), this.requireValid(e) && this.run(
3136
3608
  "verify-phone-code",
3137
3609
  async () => {
3138
3610
  await n.confirmPhoneVerification(this.phoneCode), this.phoneCode = "", this.phoneCodeSent = !1;
3139
3611
  },
3140
- this.t("done")
3612
+ this.t("phoneVerified")
3141
3613
  );
3142
3614
  }, this.onChangePassword = (e) => {
3143
- if (e.preventDefault(), this.newPassword !== this.newPasswordConfirm) {
3144
- this.errors = { ...this.errors, password: this.t("errorPasswordMismatch") };
3145
- return;
3615
+ if (e.preventDefault(), !!this.requireValid(e)) {
3616
+ if (this.newPassword !== this.newPasswordConfirm) {
3617
+ this.errors = { ...this.errors, password: this.t("errorPasswordMismatch") };
3618
+ return;
3619
+ }
3620
+ this.run(
3621
+ "password",
3622
+ async () => {
3623
+ await n.updatePassword(this.newPassword, this.oldPassword), this.oldPassword = this.newPassword = this.newPasswordConfirm = "";
3624
+ },
3625
+ this.t("passwordUpdated")
3626
+ );
3146
3627
  }
3147
- this.run(
3148
- "password",
3149
- async () => {
3150
- await n.updatePassword(this.newPassword, this.oldPassword), this.oldPassword = this.newPassword = this.newPasswordConfirm = "";
3151
- },
3152
- this.t("passwordUpdated")
3153
- );
3154
3628
  }, this.onToggleMfa = () => {
3155
3629
  const e = !this.user?.mfa;
3156
3630
  this.run("mfa", async () => {
@@ -3161,15 +3635,19 @@ let p = class extends A {
3161
3635
  this.authenticator = await n.addAuthenticator(), this.authenticatorCode = "";
3162
3636
  });
3163
3637
  }, this.onVerifyAuthenticator = (e) => {
3164
- e.preventDefault(), this.run(
3638
+ e.preventDefault(), this.requireValid(e) && this.run(
3165
3639
  "authenticator-code",
3166
3640
  async () => {
3167
3641
  await n.verifyAuthenticator(this.authenticatorCode), this.authenticator = null, this.authenticatorCode = "", await this.loadFactors();
3168
3642
  },
3169
- this.t("done")
3643
+ this.t("authenticatorAdded")
3170
3644
  );
3171
3645
  }, this.onRemoveAuthenticator = () => {
3172
- this.run("remove-authenticator", async () => {
3646
+ if (!this.confirmRemoveAuthenticator) {
3647
+ this.confirmRemoveAuthenticator = !0;
3648
+ return;
3649
+ }
3650
+ this.confirmRemoveAuthenticator = !1, this.run("remove-authenticator", async () => {
3173
3651
  await n.removeAuthenticator(), await this.loadFactors();
3174
3652
  });
3175
3653
  }, this.onRecoveryCodes = () => {
@@ -3177,13 +3655,17 @@ let p = class extends A {
3177
3655
  try {
3178
3656
  this.recoveryCodes = await n.createRecoveryCodes();
3179
3657
  } catch (e) {
3180
- if (!B(e, v.recoveryCodesExist)) throw e;
3658
+ if (!N(e, f.recoveryCodesExist)) throw e;
3181
3659
  this.recoveryCodes = await n.getRecoveryCodes();
3182
3660
  }
3183
3661
  await this.loadFactors();
3184
3662
  });
3185
3663
  }, this.onRegenerateRecoveryCodes = () => {
3186
- this.run("recovery", async () => {
3664
+ if (!this.confirmRegenerate) {
3665
+ this.confirmRegenerate = !0;
3666
+ return;
3667
+ }
3668
+ this.confirmRegenerate = !1, this.run("recovery", async () => {
3187
3669
  this.recoveryCodes = await n.regenerateRecoveryCodes();
3188
3670
  });
3189
3671
  }, this.onCopyCodes = async () => {
@@ -3192,6 +3674,15 @@ let p = class extends A {
3192
3674
  await navigator.clipboard.writeText(this.recoveryCodes.join(`
3193
3675
  `)), this.copied = !0, setTimeout(() => this.copied = !1, 1500);
3194
3676
  } catch {
3677
+ this.setNotice("error", this.t("copyFailed"));
3678
+ }
3679
+ }, this.onCopySecret = async () => {
3680
+ const e = this.authenticator?.secret;
3681
+ if (e)
3682
+ try {
3683
+ await navigator.clipboard.writeText(e), this.copied = !0, setTimeout(() => this.copied = !1, 1500);
3684
+ } catch {
3685
+ this.setNotice("error", this.t("copyFailed"));
3195
3686
  }
3196
3687
  }, this.onStepUpFactor = (e) => {
3197
3688
  this.run("stepup", async () => {
@@ -3199,19 +3690,31 @@ let p = class extends A {
3199
3690
  this.stepUp = { ...this.stepUp, challenge: { id: t.$id, factor: e } }, this.stepUpCode = "";
3200
3691
  });
3201
3692
  }, this.onStepUpVerify = (e) => {
3202
- e.preventDefault();
3693
+ if (e.preventDefault(), !this.requireValid(e)) return;
3203
3694
  const t = this.stepUp;
3204
3695
  t?.challenge && this.run("stepup-code", async () => {
3205
3696
  await n.completeMfaChallenge(t.challenge.id, this.stepUpCode, { signIn: !1 }), this.stepUp = null, this.stepUpCode = "", await t.retry();
3206
3697
  });
3207
3698
  }, this.onDeleteSession = (e) => {
3208
3699
  this.run(`session-${e}`, async () => {
3209
- await n.signOut(e), this.sessions = (this.sessions ?? []).filter((t) => t.$id !== e);
3700
+ if ((this.sessions ?? []).some((i) => i.$id === e && i.current)) {
3701
+ await n.signOut(), this.sessions = [];
3702
+ return;
3703
+ }
3704
+ await n.signOut(e), this.sessions = (this.sessions ?? []).filter((i) => i.$id !== e);
3210
3705
  });
3211
3706
  }, this.onSignOutAll = () => {
3212
- this.run("sessions-all", () => n.signOutEverywhere());
3707
+ if (!this.confirmSignOutAll) {
3708
+ this.confirmSignOutAll = !0;
3709
+ return;
3710
+ }
3711
+ this.confirmSignOutAll = !1, this.run("sessions-all", () => n.signOutEverywhere());
3213
3712
  }, this.onDeleteIdentity = (e) => {
3214
- this.run(`identity-${e}`, async () => {
3713
+ if (this.confirmDisconnectId !== e) {
3714
+ this.confirmDisconnectId = e;
3715
+ return;
3716
+ }
3717
+ this.confirmDisconnectId = null, this.run(`identity-${e}`, async () => {
3215
3718
  await n.deleteIdentity(e), this.identities = (this.identities ?? []).filter((t) => t.$id !== e);
3216
3719
  });
3217
3720
  }, this.onDeleteAccount = () => {
@@ -3226,7 +3729,7 @@ let p = class extends A {
3226
3729
  }
3227
3730
  /** Lazily load data for the active tab once a user is available. */
3228
3731
  ensureLoaded() {
3229
- !this.user || this.busy || (this.active === "sessions" && this.sessions === null ? this.loadSessions() : this.active === "connections" && this.identities === null ? this.loadIdentities() : this.active === "activity" && this.logs === null ? this.loadLogs() : this.active === "security" && this.factors === null && this.loadFactors());
3732
+ !this.user || this.busy || (this.logsProbeStarted || this.probeLogsSupport(), this.active === "sessions" && this.sessions === null ? this.loadSessions() : this.active === "connections" && this.identities === null ? this.loadIdentities() : this.active === "activity" && this.logsSupported === !0 && this.logs === null ? this.loadLogs() : this.active === "activity" && this.logsSupported === !1 ? this.active = "profile" : this.active === "security" && this.factors === null && this.loadFactors());
3230
3733
  }
3231
3734
  hydrate() {
3232
3735
  const e = this.auth.user;
@@ -3242,16 +3745,36 @@ let p = class extends A {
3242
3745
  select(e) {
3243
3746
  this.active = e, this.notice = null, this.errors = {};
3244
3747
  }
3245
- /** Run an action with a busy key, surfacing errors under that key. Handles MFA step-up. */
3748
+ updated(e) {
3749
+ e.has("active") && requestAnimationFrame(() => {
3750
+ const t = this.renderRoot.querySelector(
3751
+ '.tab[aria-selected="true"]'
3752
+ );
3753
+ t && typeof t.scrollIntoView == "function" && t.scrollIntoView({ inline: "nearest", block: "nearest", behavior: "smooth" });
3754
+ });
3755
+ }
3756
+ setNotice(e, t) {
3757
+ this.notice = { tone: e, message: t }, this.noticeTimer && clearTimeout(this.noticeTimer), this.noticeTimer = setTimeout(() => {
3758
+ this.notice = null, this.noticeTimer = null;
3759
+ }, 8e3);
3760
+ }
3761
+ requireValid(e) {
3762
+ const t = e.target;
3763
+ return !(t && typeof t.reportValidity == "function" && !t.reportValidity());
3764
+ }
3246
3765
  async run(e, t, i) {
3247
3766
  if (!this.busy) {
3248
- this.busy = e, this.errors = { ...this.errors, [e]: "" };
3767
+ this.busy = e, this.errors = { ...this.errors, [e]: "" }, this.notice = null;
3249
3768
  try {
3250
- await t(), i && (this.notice = { tone: "success", message: i });
3251
- } catch (r) {
3252
- B(r, v.challengeRequired) ? this.stepUp = { retry: () => this.run(e, t, i) } : this.errors = {
3769
+ await t(), i && this.setNotice("success", i);
3770
+ } catch (s) {
3771
+ N(s, f.challengeRequired) ? this.stepUp = { retry: () => this.run(e, t, i) } : this.errors = {
3253
3772
  ...this.errors,
3254
- [e]: at(r, this.strings, e.includes("code") ? "code" : "link")
3773
+ [e]: K(
3774
+ s,
3775
+ this.strings,
3776
+ e.includes("code") ? "code" : e === "password" ? "password" : "link"
3777
+ )
3255
3778
  };
3256
3779
  } finally {
3257
3780
  this.busy = "";
@@ -3269,12 +3792,27 @@ let p = class extends A {
3269
3792
  this.identities = await n.listIdentities();
3270
3793
  });
3271
3794
  }
3795
+ /** Probe once so Activity is never shown on servers without /account/logs. */
3796
+ async probeLogsSupport() {
3797
+ if (!this.logsProbeStarted) {
3798
+ this.logsProbeStarted = !0;
3799
+ try {
3800
+ this.logs = await n.listLogs(), this.logsSupported = !0;
3801
+ } catch {
3802
+ this.logsSupported = !1, this.logs = [], this.active === "activity" && (this.active = "profile");
3803
+ }
3804
+ }
3805
+ }
3272
3806
  async loadLogs() {
3807
+ if (this.logsSupported === !1) {
3808
+ this.active === "activity" && (this.active = "profile");
3809
+ return;
3810
+ }
3273
3811
  this.busy = "logs";
3274
3812
  try {
3275
3813
  this.logs = await n.listLogs();
3276
3814
  } catch {
3277
- this.logsSupported = !1, this.logs = [];
3815
+ this.logsSupported = !1, this.logs = [], this.active === "activity" && (this.active = "profile");
3278
3816
  } finally {
3279
3817
  this.busy = "";
3280
3818
  }
@@ -3305,14 +3843,16 @@ let p = class extends A {
3305
3843
  // ─────────────────────────── render ───────────────────────────
3306
3844
  render() {
3307
3845
  if (!this.auth.configured)
3308
- return s`<div class="alert alert-error" role="alert">
3846
+ return r`<div class="alert alert-error" role="alert">
3309
3847
  ${c.alert}
3310
3848
  <div class="alert-body">${this.t("errorNotConfigured")}</div>
3311
3849
  </div>`;
3312
3850
  if (this.auth.status === "loading")
3313
- return s`<div class="empty"><span class="spinner"></span></div>`;
3851
+ return r`<div class="panel ${this.embedded ? "embedded" : ""}" part="panel">
3852
+ <div class="empty"><span class="spinner"></span></div>
3853
+ </div>`;
3314
3854
  if (!this.user)
3315
- return s`<div class="panel ${this.embedded ? "embedded" : ""}">
3855
+ return r`<div class="panel ${this.embedded ? "embedded" : ""}">
3316
3856
  <authui-sign-in embedded></authui-sign-in>
3317
3857
  </div>`;
3318
3858
  const e = [
@@ -3322,42 +3862,61 @@ let p = class extends A {
3322
3862
  { id: "connections", label: this.t("connections") },
3323
3863
  ...this.logsSupported ? [{ id: "activity", label: this.t("activity") }] : []
3324
3864
  ];
3325
- return s`
3865
+ return r`
3326
3866
  <div class="panel ${this.embedded ? "embedded" : ""}" part="panel">
3327
3867
  ${this.renderIdentity()}
3328
- <div class="tabs" role="tablist">
3868
+ <div class="tabs" role="tablist" @keydown=${this.onTabsKeydown}>
3329
3869
  ${e.map(
3330
- (t) => s`<button
3870
+ (t) => r`<button
3331
3871
  class="tab"
3332
3872
  role="tab"
3873
+ id=${`authui-tab-${t.id}`}
3874
+ aria-controls=${`authui-panel-${t.id}`}
3333
3875
  aria-selected=${this.active === t.id ? "true" : "false"}
3876
+ tabindex=${this.active === t.id ? "0" : "-1"}
3334
3877
  @click=${() => this.select(t.id)}
3335
3878
  >
3336
3879
  ${t.label}
3337
3880
  </button>`
3338
3881
  )}
3339
3882
  </div>
3340
- ${this.notice ? s`<div class="alert alert-${this.notice.tone}" role="status">
3883
+ ${this.notice ? r`<div class="alert alert-${this.notice.tone}" role="status">
3341
3884
  ${this.notice.tone === "success" ? c.checkCircle : c.info}
3342
3885
  <div class="alert-body">${this.notice.message}</div>
3886
+ <button
3887
+ class="btn btn-ghost btn-icon dismiss"
3888
+ @click=${() => {
3889
+ this.notice = null, this.noticeTimer && (clearTimeout(this.noticeTimer), this.noticeTimer = null);
3890
+ }}
3891
+ aria-label=${this.t("close")}
3892
+ >
3893
+ ${c.x}
3894
+ </button>
3343
3895
  </div>` : o}
3344
- ${this.stepUp ? this.renderStepUp() : this.renderTab()}
3896
+ ${this.stepUp ? this.renderStepUp() : r`<div
3897
+ class="tabpanel"
3898
+ role="tabpanel"
3899
+ id=${`authui-panel-${this.active}`}
3900
+ aria-labelledby=${`authui-tab-${this.active}`}
3901
+ >
3902
+ ${this.renderTab()}
3903
+ </div>`}
3345
3904
  </div>
3346
3905
  `;
3347
3906
  }
3348
3907
  renderIdentity() {
3349
3908
  const e = this.user, t = e.name || e.email || e.phone || this.t("guestAccount");
3350
- return s`
3909
+ return r`
3351
3910
  <div class="between">
3352
3911
  <div class="identity">
3353
- <span class="avatar">${t[0] ?? "?"}</span>
3912
+ <span class="avatar">${st(t)}</span>
3354
3913
  <div class="row-main">
3355
- <span class="row-title">
3914
+ <span class="row-title" title=${t}>
3356
3915
  ${t}
3357
- ${e.mfa ? s`<span class="badge badge-success">${c.shieldCheck} MFA</span>` : o}
3358
- ${n.isPreview ? s`<span class="badge badge-info">${this.t("preview")}</span>` : o}
3916
+ ${e.mfa ? r`<span class="badge badge-success">${c.shieldCheck} ${this.t("mfaBadge")}</span>` : o}
3917
+ ${n.isPreview ? r`<span class="badge badge-info">${this.t("preview")}</span>` : o}
3359
3918
  </span>
3360
- ${e.email && e.name ? s`<span class="row-sub">${e.email}</span>` : o}
3919
+ ${e.email && e.name ? r`<span class="row-sub" title=${e.email}>${e.email}</span>` : o}
3361
3920
  </div>
3362
3921
  </div>
3363
3922
  <button class="btn btn-outline btn-sm" @click=${() => n.signOut()}>
@@ -3382,35 +3941,35 @@ let p = class extends A {
3382
3941
  }
3383
3942
  error(e) {
3384
3943
  const t = this.errors[e];
3385
- return t ? s`<div class="alert alert-error" role="alert">
3944
+ return t ? r`<div class="alert alert-error" role="alert">
3386
3945
  ${c.alert}
3387
3946
  <div class="alert-body">${t}</div>
3388
3947
  </div>` : o;
3389
3948
  }
3390
3949
  spinner(e) {
3391
- return this.busy === e ? s`<span class="spinner" aria-hidden="true"></span>` : o;
3950
+ return this.busy === e ? r`<span class="spinner" aria-hidden="true"></span>` : o;
3392
3951
  }
3393
- card(e, t, i, r, a = !1) {
3394
- return s`<section class="card ${a ? "card-danger" : ""}">
3952
+ card(e, t, i, s, a = !1) {
3953
+ return r`<section class="card ${a ? "card-danger" : ""}">
3395
3954
  <div class="card-header">
3396
3955
  <h3 class="card-title">${e}</h3>
3397
- ${t ? s`<p class="card-description">${t}</p>` : o}
3956
+ ${t ? r`<p class="card-description">${t}</p>` : o}
3398
3957
  </div>
3399
3958
  <div class="card-body">${i}</div>
3400
- ${r ? s`<div class="card-footer">${r}</div>` : o}
3959
+ ${s ? r`<div class="card-footer">${s}</div>` : o}
3401
3960
  </section>`;
3402
3961
  }
3403
3962
  verifiedBadge(e) {
3404
- return e ? s`<span class="badge badge-success">${c.check} ${this.t("verified")}</span>` : s`<span class="badge badge-warning">${this.t("unverified")}</span>`;
3963
+ return e ? r`<span class="badge badge-success">${c.check} ${this.t("verified")}</span>` : r`<span class="badge badge-warning">${this.t("unverified")}</span>`;
3405
3964
  }
3406
3965
  // ── Profile ──
3407
3966
  renderProfile() {
3408
3967
  const e = this.user;
3409
- return this.isGuest ? s`<div class="section">
3968
+ return this.isGuest ? r`<div class="section">
3410
3969
  ${this.card(
3411
3970
  this.t("guestAccount"),
3412
3971
  this.t("guestAccountDescription"),
3413
- s`<form class="form" id="guest-form" @submit=${this.onConvertGuest} novalidate>
3972
+ r`<form class="form" id="guest-form" @submit=${this.onConvertGuest} novalidate>
3414
3973
  <div class="field">
3415
3974
  <label class="label" for="guest-name">${this.t("name")}</label>
3416
3975
  <input
@@ -3445,11 +4004,28 @@ let p = class extends A {
3445
4004
  @input=${this.bind("emailPassword")}
3446
4005
  autocomplete="new-password"
3447
4006
  />
3448
- <p class="hint">${this.t("passwordHint")}</p>
4007
+ ${this.emailPassword ? (() => {
4008
+ const t = et(this.emailPassword);
4009
+ return r`<div class="strength" aria-live="polite">
4010
+ <div
4011
+ class="strength-meter"
4012
+ data-level=${String(t.level)}
4013
+ role="meter"
4014
+ aria-label=${this.t("passwordStrengthLabel")}
4015
+ aria-valuemin="0"
4016
+ aria-valuemax="4"
4017
+ aria-valuenow=${String(t.level)}
4018
+ aria-valuetext=${this.t(t.labelKey)}
4019
+ >
4020
+ <span></span><span></span><span></span><span></span>
4021
+ </div>
4022
+ <p class="strength-label">${this.t(t.labelKey)}</p>
4023
+ </div>`;
4024
+ })() : r`<p class="hint">${this.t("passwordHint")}</p>`}
3449
4025
  </div>
3450
4026
  ${this.error("guest")}
3451
4027
  </form>`,
3452
- s`<button
4028
+ r`<button
3453
4029
  class="btn btn-primary btn-sm"
3454
4030
  type="submit"
3455
4031
  form="guest-form"
@@ -3458,11 +4034,11 @@ let p = class extends A {
3458
4034
  ${this.spinner("guest")} ${this.t("createAccount")}
3459
4035
  </button>`
3460
4036
  )}
3461
- </div>` : s`<div class="section">
4037
+ </div>` : r`<div class="section">
3462
4038
  ${this.card(
3463
4039
  this.t("name"),
3464
4040
  void 0,
3465
- s`<form class="form" id="name-form" @submit=${this.onUpdateName} novalidate>
4041
+ r`<form class="form" id="name-form" @submit=${this.onUpdateName} novalidate>
3466
4042
  <div class="field">
3467
4043
  <label class="label" for="acc-name">${this.t("name")}</label>
3468
4044
  <input
@@ -3476,11 +4052,11 @@ let p = class extends A {
3476
4052
  </div>
3477
4053
  ${this.error("name")}
3478
4054
  </form>`,
3479
- s`<button
4055
+ r`<button
3480
4056
  class="btn btn-primary btn-sm"
3481
4057
  type="submit"
3482
4058
  form="name-form"
3483
- ?disabled=${!!this.busy || this.nameInput === e.name}
4059
+ ?disabled=${!!this.busy || !this.nameInput.trim() || this.nameInput === e.name}
3484
4060
  >
3485
4061
  ${this.spinner("name")} ${this.t("update")}
3486
4062
  </button>`
@@ -3488,7 +4064,7 @@ let p = class extends A {
3488
4064
  ${this.card(
3489
4065
  this.t("email"),
3490
4066
  void 0,
3491
- s`<form class="form" id="email-form" @submit=${this.onUpdateEmail} novalidate>
4067
+ r`<form class="form" id="email-form" @submit=${this.onUpdateEmail} novalidate>
3492
4068
  <div class="field">
3493
4069
  <label class="label" for="acc-email"
3494
4070
  >${this.t("email")}
@@ -3504,34 +4080,43 @@ let p = class extends A {
3504
4080
  required
3505
4081
  />
3506
4082
  </div>
3507
- ${this.emailInput !== e.email ? s`<div class="field">
3508
- <label class="label" for="acc-email-password">${this.t("currentPassword")}</label>
4083
+ ${this.emailInput !== e.email ? r`<div class="field">
4084
+ <label class="label" for="acc-email-password"
4085
+ >${e.passwordUpdate ? this.t("currentPassword") : this.t("createPassword")}</label
4086
+ >
3509
4087
  <input
3510
4088
  class="input"
3511
4089
  id="acc-email-password"
3512
4090
  type="password"
3513
4091
  .value=${this.emailPassword}
3514
4092
  @input=${this.bind("emailPassword")}
3515
- autocomplete="current-password"
4093
+ autocomplete=${e.passwordUpdate ? "current-password" : "new-password"}
3516
4094
  required
3517
4095
  />
4096
+ ${e.passwordUpdate ? o : r`<p class="hint">${this.t("createPasswordHint")}</p>`}
3518
4097
  </div>` : o}
3519
4098
  ${this.error("email")} ${this.error("verify")}
3520
4099
  </form>`,
3521
- s`
3522
- ${e.email && !e.emailVerification ? s`<button
4100
+ r`
4101
+ ${e.email && !e.emailVerification ? r`<button
3523
4102
  class="btn btn-outline btn-sm"
3524
4103
  type="button"
3525
4104
  @click=${this.onSendVerification}
3526
- ?disabled=${!!this.busy}
4105
+ ?disabled=${!!this.busy || Date.now() < this.verifyEmailCooldownUntil}
3527
4106
  >
3528
- ${this.spinner("verify")} ${this.t("verifyEmail")}
4107
+ ${this.spinner("verify")}
4108
+ ${Date.now() < this.verifyEmailCooldownUntil ? this.t("verificationResendIn", {
4109
+ seconds: Math.max(
4110
+ 1,
4111
+ Math.ceil((this.verifyEmailCooldownUntil - Date.now()) / 1e3)
4112
+ )
4113
+ }) : this.t("verifyEmail")}
3529
4114
  </button>` : o}
3530
4115
  <button
3531
4116
  class="btn btn-primary btn-sm"
3532
4117
  type="submit"
3533
4118
  form="email-form"
3534
- ?disabled=${!!this.busy || this.emailInput === e.email}
4119
+ ?disabled=${!!this.busy || !this.emailInput.trim() || this.emailInput === e.email}
3535
4120
  >
3536
4121
  ${this.spinner("email")} ${this.t("update")}
3537
4122
  </button>
@@ -3540,7 +4125,7 @@ let p = class extends A {
3540
4125
  ${this.card(
3541
4126
  this.t("phone"),
3542
4127
  void 0,
3543
- s`<form class="form" id="phone-form" @submit=${this.onUpdatePhone} novalidate>
4128
+ r`<form class="form" id="phone-form" @submit=${this.onUpdatePhone} novalidate>
3544
4129
  <div class="field">
3545
4130
  <label class="label" for="acc-phone"
3546
4131
  >${this.t("phone")}
@@ -3556,33 +4141,42 @@ let p = class extends A {
3556
4141
  autocomplete="tel"
3557
4142
  />
3558
4143
  </div>
3559
- ${this.phoneInput !== e.phone ? s`<div class="field">
3560
- <label class="label" for="acc-phone-password">${this.t("currentPassword")}</label>
4144
+ ${this.phoneInput !== e.phone ? r`<div class="field">
4145
+ <label class="label" for="acc-phone-password"
4146
+ >${e.passwordUpdate ? this.t("currentPassword") : this.t("createPassword")}</label
4147
+ >
3561
4148
  <input
3562
4149
  class="input"
3563
4150
  id="acc-phone-password"
3564
4151
  type="password"
3565
4152
  .value=${this.phonePassword}
3566
4153
  @input=${this.bind("phonePassword")}
3567
- autocomplete="current-password"
4154
+ autocomplete=${e.passwordUpdate ? "current-password" : "new-password"}
3568
4155
  required
3569
4156
  />
4157
+ ${e.passwordUpdate ? o : r`<p class="hint">${this.t("createPasswordHint")}</p>`}
3570
4158
  </div>` : o}
3571
- ${this.phoneCodeSent ? s`<div class="field">
4159
+ ${this.phoneCodeSent ? r`<div class="field">
3572
4160
  <label class="label" for="acc-phone-code">${this.t("code")}</label>
3573
4161
  <input
3574
4162
  class="input input-otp"
3575
4163
  id="acc-phone-code"
3576
4164
  inputmode="numeric"
3577
4165
  autocomplete="one-time-code"
4166
+ maxlength="6"
4167
+ pattern="[0-9]*"
4168
+ required
3578
4169
  .value=${this.phoneCode}
3579
4170
  @input=${this.bind("phoneCode")}
4171
+ @keydown=${(t) => {
4172
+ t.key === "Enter" && (t.preventDefault(), this.onConfirmPhoneVerification(t));
4173
+ }}
3580
4174
  />
3581
4175
  </div>` : o}
3582
4176
  ${this.error("phone")} ${this.error("verify-phone")} ${this.error("verify-phone-code")}
3583
4177
  </form>`,
3584
- s`
3585
- ${e.phone && !e.phoneVerification && !this.phoneCodeSent ? s`<button
4178
+ r`
4179
+ ${e.phone && !e.phoneVerification && !this.phoneCodeSent ? r`<button
3586
4180
  class="btn btn-outline btn-sm"
3587
4181
  type="button"
3588
4182
  @click=${this.onSendPhoneVerification}
@@ -3590,7 +4184,7 @@ let p = class extends A {
3590
4184
  >
3591
4185
  ${this.spinner("verify-phone")} ${this.t("sendCode")}
3592
4186
  </button>` : o}
3593
- ${this.phoneCodeSent ? s`<button
4187
+ ${this.phoneCodeSent ? r`<button
3594
4188
  class="btn btn-outline btn-sm"
3595
4189
  type="button"
3596
4190
  @click=${this.onConfirmPhoneVerification}
@@ -3602,7 +4196,7 @@ let p = class extends A {
3602
4196
  class="btn btn-primary btn-sm"
3603
4197
  type="submit"
3604
4198
  form="phone-form"
3605
- ?disabled=${!!this.busy || this.phoneInput === e.phone}
4199
+ ?disabled=${!!this.busy || !this.phoneInput.trim() || this.phoneInput === e.phone}
3606
4200
  >
3607
4201
  ${this.spinner("phone")} ${this.t("update")}
3608
4202
  </button>
@@ -3615,10 +4209,10 @@ let p = class extends A {
3615
4209
  return this.card(
3616
4210
  this.t("deleteAccount"),
3617
4211
  this.t("deleteAccountDescription"),
3618
- s`${this.error("delete")}
3619
- ${this.confirmDelete ? s`<div class="inline">
4212
+ r`${this.error("delete")}
4213
+ ${this.confirmDelete ? r`<div class="inline">
3620
4214
  <button
3621
- class="btn btn-destructive btn-sm"
4215
+ class="btn btn-outline btn-sm warn"
3622
4216
  @click=${this.onDeleteAccount}
3623
4217
  ?disabled=${!!this.busy}
3624
4218
  >
@@ -3627,7 +4221,7 @@ let p = class extends A {
3627
4221
  <button class="btn btn-ghost btn-sm" @click=${() => this.confirmDelete = !1}>
3628
4222
  ${this.t("cancel")}
3629
4223
  </button>
3630
- </div>` : s`<button
4224
+ </div>` : r`<button
3631
4225
  class="btn btn-outline btn-sm warn"
3632
4226
  @click=${() => this.confirmDelete = !0}
3633
4227
  >
@@ -3640,17 +4234,17 @@ let p = class extends A {
3640
4234
  // ── Security ──
3641
4235
  renderSecurity() {
3642
4236
  const e = this.user, t = this.config?.mfa !== !1;
3643
- return s`<div class="section">
4237
+ return r`<div class="section">
3644
4238
  ${this.isGuest ? o : this.card(
3645
4239
  this.t("changePassword"),
3646
4240
  void 0,
3647
- s`<form
4241
+ r`<form
3648
4242
  class="form"
3649
4243
  id="password-form"
3650
4244
  @submit=${this.onChangePassword}
3651
4245
  novalidate
3652
4246
  >
3653
- ${e.passwordUpdate ? s`<div class="field">
4247
+ ${e.passwordUpdate ? r`<div class="field">
3654
4248
  <label class="label" for="acc-old-password"
3655
4249
  >${this.t("currentPassword")}</label
3656
4250
  >
@@ -3661,6 +4255,7 @@ let p = class extends A {
3661
4255
  .value=${this.oldPassword}
3662
4256
  @input=${this.bind("oldPassword")}
3663
4257
  autocomplete="current-password"
4258
+ required
3664
4259
  />
3665
4260
  </div>` : o}
3666
4261
  <div class="field">
@@ -3675,7 +4270,24 @@ let p = class extends A {
3675
4270
  @input=${this.bind("newPassword")}
3676
4271
  autocomplete="new-password"
3677
4272
  />
3678
- <p class="hint">${this.t("passwordHint")}</p>
4273
+ ${this.newPassword ? (() => {
4274
+ const i = et(this.newPassword);
4275
+ return r`<div class="strength" aria-live="polite">
4276
+ <div
4277
+ class="strength-meter"
4278
+ data-level=${String(i.level)}
4279
+ role="meter"
4280
+ aria-label=${this.t("passwordStrengthLabel")}
4281
+ aria-valuemin="0"
4282
+ aria-valuemax="4"
4283
+ aria-valuenow=${String(i.level)}
4284
+ aria-valuetext=${this.t(i.labelKey)}
4285
+ >
4286
+ <span></span><span></span><span></span><span></span>
4287
+ </div>
4288
+ <p class="strength-label">${this.t(i.labelKey)}</p>
4289
+ </div>`;
4290
+ })() : r`<p class="hint">${this.t("passwordHint")}</p>`}
3679
4291
  </div>
3680
4292
  <div class="field">
3681
4293
  <label class="label" for="acc-new-password-confirm"
@@ -3694,7 +4306,7 @@ let p = class extends A {
3694
4306
  </div>
3695
4307
  ${this.error("password")}
3696
4308
  </form>`,
3697
- s`<button
4309
+ r`<button
3698
4310
  class="btn btn-primary btn-sm"
3699
4311
  type="submit"
3700
4312
  form="password-form"
@@ -3708,15 +4320,15 @@ let p = class extends A {
3708
4320
  </div>`;
3709
4321
  }
3710
4322
  renderMfaCard() {
3711
- const e = this.user, t = this.factors?.totp ?? !1, i = this.authenticator ? n.isPreview ? mt(this.authenticator.uri) : new lt(n.getClient()).getQR(this.authenticator.uri, 400, 1).toString() : "";
4323
+ const e = this.user, t = this.factors?.totp ?? !1, i = this.authenticator ? n.isPreview ? St(this.authenticator.uri) : new yt(n.getClient()).getQR(this.authenticator.uri, 400, 1).toString() : "";
3712
4324
  return this.card(
3713
4325
  this.t("twoFactor"),
3714
4326
  this.t("twoFactorDescription"),
3715
- s`<div class="kv">
4327
+ r`<div class="kv">
3716
4328
  <div class="toggle-row">
3717
4329
  <div class="row-main">
3718
4330
  <span class="row-title">${this.t("twoFactor")}</span>
3719
- <span class="row-sub">${e.mfa ? this.t("enable") : this.t("disable")}d</span>
4331
+ <span class="row-sub">${e.mfa ? this.t("enabled") : this.t("disabled")}</span>
3720
4332
  </div>
3721
4333
  <button
3722
4334
  class="switch"
@@ -3727,6 +4339,22 @@ let p = class extends A {
3727
4339
  aria-label=${this.t("twoFactor")}
3728
4340
  ></button>
3729
4341
  </div>
4342
+ ${e.mfa && !(this.factors?.totp || e.emailVerification || e.phoneVerification) ? r`<div class="alert alert-warning" role="status">
4343
+ ${c.alert}
4344
+ <div class="alert-body">
4345
+ ${this.t("mfaNoFactorWarning")}
4346
+ ${this.factors?.totp ? o : r`<div class="links">
4347
+ <button
4348
+ type="button"
4349
+ class="btn btn-link"
4350
+ @click=${this.onAddAuthenticator}
4351
+ ?disabled=${!!this.busy || !!this.authenticator}
4352
+ >
4353
+ ${this.t("authenticatorAdd")}
4354
+ </button>
4355
+ </div>`}
4356
+ </div>
4357
+ </div>` : o}
3730
4358
  ${this.error("mfa")}
3731
4359
  <div class="separator"></div>
3732
4360
  <div class="toggle-row">
@@ -3736,13 +4364,27 @@ let p = class extends A {
3736
4364
  ${t ? this.verifiedBadge(!0) : o}</span
3737
4365
  >
3738
4366
  </div>
3739
- ${t ? s`<button
3740
- class="btn btn-outline btn-sm"
3741
- @click=${this.onRemoveAuthenticator}
3742
- ?disabled=${!!this.busy}
3743
- >
3744
- ${this.spinner("remove-authenticator")} ${this.t("remove")}
3745
- </button>` : this.authenticator ? o : s`<button
4367
+ ${t ? this.confirmRemoveAuthenticator ? r`<div class="inline">
4368
+ <button
4369
+ class="btn btn-outline btn-sm warn"
4370
+ @click=${this.onRemoveAuthenticator}
4371
+ ?disabled=${!!this.busy}
4372
+ >
4373
+ ${this.spinner("remove-authenticator")} ${this.t("remove")}
4374
+ </button>
4375
+ <button
4376
+ class="btn btn-ghost btn-sm"
4377
+ @click=${() => this.confirmRemoveAuthenticator = !1}
4378
+ >
4379
+ ${this.t("cancel")}
4380
+ </button>
4381
+ </div>` : r`<button
4382
+ class="btn btn-outline btn-sm"
4383
+ @click=${this.onRemoveAuthenticator}
4384
+ ?disabled=${!!this.busy}
4385
+ >
4386
+ ${this.spinner("remove-authenticator")} ${this.t("remove")}
4387
+ </button>` : this.authenticator ? o : r`<button
3746
4388
  class="btn btn-outline btn-sm"
3747
4389
  @click=${this.onAddAuthenticator}
3748
4390
  ?disabled=${!!this.busy}
@@ -3751,13 +4393,25 @@ let p = class extends A {
3751
4393
  </button>`}
3752
4394
  </div>
3753
4395
  ${this.error("authenticator")} ${this.error("remove-authenticator")}
3754
- ${this.authenticator ? s`<form class="form" @submit=${this.onVerifyAuthenticator} novalidate>
4396
+ ${this.authenticator ? r`<form class="form" @submit=${this.onVerifyAuthenticator} novalidate>
3755
4397
  <p class="hint">${this.t("authenticatorScan")}</p>
3756
- <img class="qr" src=${i} alt="QR code" />
3757
- <p class="hint center">
3758
- ${this.t("authenticatorManual")}:
3759
- <span class="code">${this.authenticator.secret}</span>
3760
- </p>
4398
+ <img class="qr" src=${i} alt=${this.t("qrCodeAlt")} />
4399
+ <p class="hint center">${this.t("authenticatorManual")}</p>
4400
+ <div class="inline">
4401
+ <span class="code"
4402
+ >${this.authenticator.secret.match(/.{1,4}/g)?.join(" ") ?? this.authenticator.secret}</span
4403
+ >
4404
+ <button
4405
+ class="btn btn-ghost btn-sm"
4406
+ type="button"
4407
+ @click=${() => {
4408
+ this.onCopySecret();
4409
+ }}
4410
+ >
4411
+ ${this.copied ? c.check : c.copy}
4412
+ ${this.copied ? this.t("copied") : this.t("authenticatorCopyKey")}
4413
+ </button>
4414
+ </div>
3761
4415
  <div class="field">
3762
4416
  <label class="label" for="acc-totp">${this.t("code")}</label>
3763
4417
  <input
@@ -3765,6 +4419,8 @@ let p = class extends A {
3765
4419
  id="acc-totp"
3766
4420
  inputmode="numeric"
3767
4421
  autocomplete="one-time-code"
4422
+ maxlength="6"
4423
+ pattern="[0-9]*"
3768
4424
  required
3769
4425
  .value=${this.authenticatorCode}
3770
4426
  @input=${this.bind("authenticatorCode")}
@@ -3791,14 +4447,14 @@ let p = class extends A {
3791
4447
  const e = this.factors?.recoveryCode ?? !1;
3792
4448
  return this.card(
3793
4449
  this.t("recoveryCodes"),
3794
- this.t("recoveryCodesDescription"),
3795
- s`<div class="kv">
3796
- ${this.recoveryCodes ? s`<div class="alert alert-warning">
4450
+ this.t("recoveryCodesDescription") + " " + this.t("recoveryCodesOnceHint"),
4451
+ r`<div class="kv">
4452
+ ${this.recoveryCodes ? r`<div class="alert alert-warning">
3797
4453
  ${c.alert}
3798
4454
  <div class="alert-body">${this.t("recoveryCodesWarning")}</div>
3799
4455
  </div>
3800
4456
  <div class="codes">
3801
- ${this.recoveryCodes.map((t) => s`<span class="code">${t}</span>`)}
4457
+ ${this.recoveryCodes.map((t) => r`<span class="code">${t}</span>`)}
3802
4458
  </div>
3803
4459
  <div class="inline">
3804
4460
  <button class="btn btn-outline btn-sm" @click=${this.onCopyCodes}>
@@ -3808,16 +4464,36 @@ let p = class extends A {
3808
4464
  <button class="btn btn-ghost btn-sm" @click=${() => this.recoveryCodes = null}>
3809
4465
  ${this.t("done")}
3810
4466
  </button>
3811
- </div>` : s`<div class="inline">
4467
+ </div>` : r`<div class="inline">
3812
4468
  <button
3813
4469
  class="btn btn-outline btn-sm"
3814
4470
  @click=${this.onRecoveryCodes}
3815
4471
  ?disabled=${!!this.busy}
3816
4472
  >
3817
4473
  ${this.spinner("recovery")} ${c.key}
3818
- ${e ? this.t("recoveryCodes") : this.t("generateRecoveryCodes")}
4474
+ ${e ? this.t("viewRecoveryCodes") : this.t("generateRecoveryCodes")}
3819
4475
  </button>
3820
- ${e ? s`<button class="btn btn-ghost btn-sm" @click=${this.onRegenerateRecoveryCodes} ?disabled=${!!this.busy}>${c.refresh} ${this.t("regenerateRecoveryCodes")}</button>` : o}
4476
+ ${e ? this.confirmRegenerate ? r`<div class="inline">
4477
+ <button
4478
+ class="btn btn-outline btn-sm warn"
4479
+ @click=${this.onRegenerateRecoveryCodes}
4480
+ ?disabled=${!!this.busy}
4481
+ >
4482
+ ${c.refresh} ${this.t("regenerateRecoveryCodes")}
4483
+ </button>
4484
+ <button
4485
+ class="btn btn-ghost btn-sm"
4486
+ @click=${() => this.confirmRegenerate = !1}
4487
+ >
4488
+ ${this.t("cancel")}
4489
+ </button>
4490
+ </div>` : r`<button
4491
+ class="btn btn-ghost btn-sm"
4492
+ @click=${this.onRegenerateRecoveryCodes}
4493
+ ?disabled=${!!this.busy}
4494
+ >
4495
+ ${c.refresh} ${this.t("regenerateRecoveryCodes")}
4496
+ </button>` : o}
3821
4497
  </div>`}
3822
4498
  ${this.error("recovery")}
3823
4499
  </div>`
@@ -3854,8 +4530,8 @@ let p = class extends A {
3854
4530
  return this.card(
3855
4531
  this.t("mfaTitle"),
3856
4532
  this.t("errorChallengeRequired"),
3857
- s`<div class="kv">
3858
- ${e.challenge ? s`<form class="form" @submit=${this.onStepUpVerify} novalidate>
4533
+ r`<div class="kv">
4534
+ ${e.challenge ? r`<form class="form" @submit=${this.onStepUpVerify} novalidate>
3859
4535
  <div class="field">
3860
4536
  <label class="label" for="acc-stepup"
3861
4537
  >${e.challenge.factor === "recoverycode" ? this.t("recoveryCode") : this.t("code")}</label
@@ -3863,6 +4539,9 @@ let p = class extends A {
3863
4539
  <input
3864
4540
  class="input ${e.challenge.factor === "recoverycode" ? "mono" : "input-otp"}"
3865
4541
  id="acc-stepup"
4542
+ inputmode=${e.challenge.factor === "recoverycode" ? "text" : "numeric"}
4543
+ maxlength=${e.challenge.factor === "recoverycode" ? "64" : "6"}
4544
+ pattern=${e.challenge.factor === "recoverycode" ? ".*" : "[0-9]*"}
3866
4545
  autocomplete="one-time-code"
3867
4546
  required
3868
4547
  .value=${this.stepUpCode}
@@ -3872,21 +4551,21 @@ let p = class extends A {
3872
4551
  <button class="btn btn-primary btn-sm" type="submit" ?disabled=${!!this.busy}>
3873
4552
  ${this.spinner("stepup-code")} ${this.t("verifyCode")}
3874
4553
  </button>
3875
- </form>` : s`<div class="stack-sm">
3876
- ${i.filter((r) => r.available).map(
3877
- (r) => s`<button
4554
+ </form>` : r`<div class="stack-sm">
4555
+ ${i.filter((s) => s.available).map(
4556
+ (s) => r`<button
3878
4557
  type="button"
3879
4558
  class="choice"
3880
- @click=${() => this.onStepUpFactor(r.factor)}
4559
+ @click=${() => this.onStepUpFactor(s.factor)}
3881
4560
  ?disabled=${!!this.busy}
3882
4561
  >
3883
- ${r.icon}<span class="choice-title">${r.label}</span>
4562
+ ${s.icon}<span class="choice-title">${s.label}</span>
3884
4563
  </button>`
3885
4564
  )}
3886
4565
  </div>`}
3887
4566
  ${this.error("stepup")} ${this.error("stepup-code")}
3888
4567
  </div>`,
3889
- s`<button class="btn btn-ghost btn-sm" @click=${() => this.stepUp = null}>
4568
+ r`<button class="btn btn-ghost btn-sm" @click=${() => this.stepUp = null}>
3890
4569
  ${this.t("cancel")}
3891
4570
  </button>`
3892
4571
  );
@@ -3898,20 +4577,20 @@ let p = class extends A {
3898
4577
  }
3899
4578
  renderSessions() {
3900
4579
  const e = this.sessions;
3901
- return s`<div class="section">
4580
+ return r`<div class="section">
3902
4581
  ${this.card(
3903
4582
  this.t("sessions"),
3904
4583
  void 0,
3905
- s`${this.error("sessions")}
3906
- ${e === null ? s`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? s`<div class="empty">${this.t("noActivity")}</div>` : e.map(
3907
- (t) => s`<div class="row">
4584
+ r`${this.error("sessions")}
4585
+ ${e === null ? r`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? r`<div class="empty">${this.t("noSessions")}</div>` : e.map(
4586
+ (t) => r`<div class="row">
3908
4587
  <div class="inline">
3909
4588
  <span class="device">${this.deviceIcon(t)}</span>
3910
4589
  <div class="row-main">
3911
4590
  <span class="row-title">
3912
4591
  ${t.clientName || t.provider}
3913
- ${t.clientVersion ? s`<span class="muted small">${t.clientVersion}</span>` : o}
3914
- ${t.current ? s`<span class="badge badge-info">${this.t("currentSession")}</span>` : o}
4592
+ ${t.clientVersion ? r`<span class="muted small">${t.clientVersion}</span>` : o}
4593
+ ${t.current ? r`<span class="badge badge-info">${this.t("currentSession")}</span>` : o}
3915
4594
  </span>
3916
4595
  <span class="row-sub"
3917
4596
  >${[t.osName, t.countryName || t.countryCode, t.ip].filter(Boolean).join(" · ")}</span
@@ -3919,7 +4598,7 @@ let p = class extends A {
3919
4598
  </div>
3920
4599
  </div>
3921
4600
  <div class="row-actions">
3922
- ${this.busy === `session-${t.$id}` ? s`<span class="spinner"></span>` : o}
4601
+ ${this.busy === `session-${t.$id}` ? r`<span class="spinner"></span>` : o}
3923
4602
  <button
3924
4603
  class="btn btn-ghost btn-sm"
3925
4604
  @click=${() => this.onDeleteSession(t.$id)}
@@ -3935,14 +4614,28 @@ let p = class extends A {
3935
4614
  ${this.card(
3936
4615
  this.t("signOutAllSessions"),
3937
4616
  this.t("signOutAllSessionsDescription"),
3938
- s`${this.error("sessions-all")}
3939
- <button
3940
- class="btn btn-outline btn-sm warn"
3941
- @click=${this.onSignOutAll}
3942
- ?disabled=${!!this.busy}
3943
- >
3944
- ${this.spinner("sessions-all")} ${c.logOut} ${this.t("signOutAllSessions")}
3945
- </button>`,
4617
+ r`${this.error("sessions-all")}
4618
+ ${this.confirmSignOutAll ? r`<div class="inline">
4619
+ <button
4620
+ class="btn btn-outline btn-sm warn"
4621
+ @click=${this.onSignOutAll}
4622
+ ?disabled=${!!this.busy}
4623
+ >
4624
+ ${this.spinner("sessions-all")} ${c.logOut} ${this.t("signOutAllSessions")}
4625
+ </button>
4626
+ <button
4627
+ class="btn btn-ghost btn-sm"
4628
+ @click=${() => this.confirmSignOutAll = !1}
4629
+ >
4630
+ ${this.t("cancel")}
4631
+ </button>
4632
+ </div>` : r`<button
4633
+ class="btn btn-outline btn-sm warn"
4634
+ @click=${this.onSignOutAll}
4635
+ ?disabled=${!!this.busy}
4636
+ >
4637
+ ${this.spinner("sessions-all")} ${c.logOut} ${this.t("signOutAllSessions")}
4638
+ </button>`}`,
3946
4639
  void 0,
3947
4640
  !0
3948
4641
  )}
@@ -3951,38 +4644,57 @@ let p = class extends A {
3951
4644
  // ── Connections ──
3952
4645
  renderConnections() {
3953
4646
  const e = this.identities, t = this.config?.methods?.oauth ?? [];
3954
- return s`<div class="section">
4647
+ return r`<div class="section">
3955
4648
  ${this.card(
3956
4649
  this.t("connections"),
3957
4650
  void 0,
3958
- s`${this.error("identities")}
3959
- ${e === null ? s`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? s`<div class="empty">${this.t("noConnections")}</div>` : e.map(
3960
- (i) => s`<div class="row">
4651
+ r`${this.error("identities")}
4652
+ ${e === null ? r`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? r`<div class="empty">${this.t("noConnections")}</div>` : e.map(
4653
+ (i) => r`<div class="row">
3961
4654
  <div class="inline">
3962
- <span class="device">${K(i.provider)}</span>
4655
+ <span class="device">${tt(i.provider)}</span>
3963
4656
  <div class="row-main">
3964
- <span class="row-title">${D(i.provider)}</span>
4657
+ <span class="row-title">${q(i.provider)}</span>
3965
4658
  <span class="row-sub">${i.providerEmail || i.providerUid}</span>
3966
4659
  </div>
3967
4660
  </div>
3968
4661
  <div class="row-actions">
3969
- <button
3970
- class="btn btn-ghost btn-sm"
3971
- @click=${() => this.onDeleteIdentity(i.$id)}
3972
- ?disabled=${!!this.busy}
3973
- >
3974
- ${this.busy === `identity-${i.$id}` ? s`<span class="spinner"></span>` : o}
3975
- ${this.t("disconnect")}
3976
- </button>
4662
+ ${this.confirmDisconnectId === i.$id ? r`<div class="inline">
4663
+ <button
4664
+ class="btn btn-outline btn-sm warn"
4665
+ @click=${() => this.onDeleteIdentity(i.$id)}
4666
+ ?disabled=${!!this.busy}
4667
+ >
4668
+ ${this.busy === `identity-${i.$id}` ? r`<span class="spinner"></span>` : o}
4669
+ ${this.t("disconnect")}
4670
+ </button>
4671
+ <button
4672
+ class="btn btn-ghost btn-sm"
4673
+ @click=${() => this.confirmDisconnectId = null}
4674
+ >
4675
+ ${this.t("cancel")}
4676
+ </button>
4677
+ </div>` : r`<button
4678
+ class="btn btn-ghost btn-sm"
4679
+ @click=${() => this.onDeleteIdentity(i.$id)}
4680
+ ?disabled=${!!this.busy}
4681
+ >
4682
+ ${this.busy === `identity-${i.$id}` ? r`<span class="spinner"></span>` : o}
4683
+ ${this.t("disconnect")}
4684
+ </button>`}
3977
4685
  </div>
3978
4686
  </div>`
3979
4687
  )}`,
3980
- t.length > 0 ? s`${t.filter((i) => !(e ?? []).some((r) => r.provider === i)).map(
3981
- (i) => s`<button
4688
+ t.length > 0 ? r`${t.filter((i) => !(e ?? []).some((s) => s.provider === i)).map(
4689
+ (i) => r`<button
3982
4690
  class="btn btn-outline btn-sm"
3983
- @click=${() => n.signInWithOAuth(i)}
4691
+ @click=${() => {
4692
+ this.run(`connect-${i}`, () => n.signInWithOAuth(i));
4693
+ }}
4694
+ ?disabled=${!!this.busy}
3984
4695
  >
3985
- ${K(i)} ${D(i)}
4696
+ ${this.spinner(`connect-${i}`)} ${tt(i)}
4697
+ ${this.t("connectProvider", { provider: q(i) })}
3986
4698
  </button>`
3987
4699
  )}` : void 0
3988
4700
  )}
@@ -3991,12 +4703,12 @@ let p = class extends A {
3991
4703
  // ── Activity ──
3992
4704
  renderActivity() {
3993
4705
  const e = this.logs;
3994
- return s`<div class="section">
4706
+ return r`<div class="section">
3995
4707
  ${this.card(
3996
4708
  this.t("activity"),
3997
4709
  void 0,
3998
- s`${e === null ? s`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? s`<div class="empty">${this.t("noActivity")}</div>` : e.map(
3999
- (t) => s`<div class="row">
4710
+ r`${e === null ? r`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? r`<div class="empty">${this.t("noActivity")}</div>` : e.map(
4711
+ (t) => r`<div class="row">
4000
4712
  <div class="row-main">
4001
4713
  <span class="row-title">${t.event}</span>
4002
4714
  <span class="row-sub"
@@ -4012,13 +4724,16 @@ let p = class extends A {
4012
4724
  };
4013
4725
  p.styles = [
4014
4726
  ...A.styles,
4015
- I`
4727
+ F`
4016
4728
  :host {
4017
4729
  display: block;
4018
4730
  width: 100%;
4019
4731
  max-width: 560px;
4732
+ min-width: 0;
4020
4733
  }
4021
4734
  .panel {
4735
+ min-width: 0;
4736
+ overflow: hidden;
4022
4737
  background: var(--authui-card);
4023
4738
  color: var(--authui-card-foreground);
4024
4739
  border: 1px solid var(--authui-border);
@@ -4039,6 +4754,22 @@ p.styles = [
4039
4754
  display: flex;
4040
4755
  align-items: center;
4041
4756
  gap: 12px;
4757
+ min-width: 0;
4758
+ flex: 1;
4759
+ }
4760
+ .identity .row-title {
4761
+ display: block;
4762
+ overflow: hidden;
4763
+ text-overflow: ellipsis;
4764
+ white-space: nowrap;
4765
+ }
4766
+ .identity .row-title .badge {
4767
+ display: inline-flex;
4768
+ vertical-align: middle;
4769
+ margin-inline-start: 6px;
4770
+ }
4771
+ .between > .btn {
4772
+ flex-shrink: 0;
4042
4773
  }
4043
4774
  .identity .avatar {
4044
4775
  width: 44px;
@@ -4089,102 +4820,117 @@ p.styles = [
4089
4820
  }
4090
4821
  `
4091
4822
  ];
4092
- g([
4093
- f({ type: Boolean })
4823
+ m([
4824
+ g({ type: Boolean })
4094
4825
  ], p.prototype, "embedded", 2);
4095
- g([
4096
- f({ type: String })
4826
+ m([
4827
+ g({ type: String })
4097
4828
  ], p.prototype, "tab", 2);
4098
- g([
4099
- d()
4829
+ m([
4830
+ h()
4100
4831
  ], p.prototype, "active", 2);
4101
- g([
4102
- d()
4832
+ m([
4833
+ h()
4103
4834
  ], p.prototype, "busy", 2);
4104
- g([
4105
- d()
4835
+ m([
4836
+ h()
4106
4837
  ], p.prototype, "notice", 2);
4107
- g([
4108
- d()
4838
+ m([
4839
+ h()
4109
4840
  ], p.prototype, "errors", 2);
4110
- g([
4111
- d()
4841
+ m([
4842
+ h()
4112
4843
  ], p.prototype, "nameInput", 2);
4113
- g([
4114
- d()
4844
+ m([
4845
+ h()
4115
4846
  ], p.prototype, "emailInput", 2);
4116
- g([
4117
- d()
4847
+ m([
4848
+ h()
4118
4849
  ], p.prototype, "emailPassword", 2);
4119
- g([
4120
- d()
4850
+ m([
4851
+ h()
4121
4852
  ], p.prototype, "phoneInput", 2);
4122
- g([
4123
- d()
4853
+ m([
4854
+ h()
4124
4855
  ], p.prototype, "phonePassword", 2);
4125
- g([
4126
- d()
4856
+ m([
4857
+ h()
4127
4858
  ], p.prototype, "phoneCode", 2);
4128
- g([
4129
- d()
4859
+ m([
4860
+ h()
4130
4861
  ], p.prototype, "phoneCodeSent", 2);
4131
- g([
4132
- d()
4862
+ m([
4863
+ h()
4133
4864
  ], p.prototype, "guestName", 2);
4134
- g([
4135
- d()
4865
+ m([
4866
+ h()
4136
4867
  ], p.prototype, "oldPassword", 2);
4137
- g([
4138
- d()
4868
+ m([
4869
+ h()
4139
4870
  ], p.prototype, "newPassword", 2);
4140
- g([
4141
- d()
4871
+ m([
4872
+ h()
4142
4873
  ], p.prototype, "newPasswordConfirm", 2);
4143
- g([
4144
- d()
4874
+ m([
4875
+ h()
4145
4876
  ], p.prototype, "authenticator", 2);
4146
- g([
4147
- d()
4877
+ m([
4878
+ h()
4148
4879
  ], p.prototype, "authenticatorCode", 2);
4149
- g([
4150
- d()
4880
+ m([
4881
+ h()
4151
4882
  ], p.prototype, "factors", 2);
4152
- g([
4153
- d()
4883
+ m([
4884
+ h()
4154
4885
  ], p.prototype, "recoveryCodes", 2);
4155
- g([
4156
- d()
4886
+ m([
4887
+ h()
4157
4888
  ], p.prototype, "stepUp", 2);
4158
- g([
4159
- d()
4889
+ m([
4890
+ h()
4160
4891
  ], p.prototype, "stepUpCode", 2);
4161
- g([
4162
- d()
4892
+ m([
4893
+ h()
4163
4894
  ], p.prototype, "copied", 2);
4164
- g([
4165
- d()
4895
+ m([
4896
+ h()
4166
4897
  ], p.prototype, "sessions", 2);
4167
- g([
4168
- d()
4898
+ m([
4899
+ h()
4169
4900
  ], p.prototype, "identities", 2);
4170
- g([
4171
- d()
4901
+ m([
4902
+ h()
4172
4903
  ], p.prototype, "logs", 2);
4173
- g([
4174
- d()
4904
+ m([
4905
+ h()
4175
4906
  ], p.prototype, "logsSupported", 2);
4176
- g([
4177
- d()
4907
+ m([
4908
+ h()
4178
4909
  ], p.prototype, "confirmDelete", 2);
4179
- p = g([
4180
- _("authui-account")
4910
+ m([
4911
+ h()
4912
+ ], p.prototype, "confirmRegenerate", 2);
4913
+ m([
4914
+ h()
4915
+ ], p.prototype, "confirmRemoveAuthenticator", 2);
4916
+ m([
4917
+ h()
4918
+ ], p.prototype, "confirmSignOutAll", 2);
4919
+ m([
4920
+ h()
4921
+ ], p.prototype, "confirmDisconnectId", 2);
4922
+ m([
4923
+ h()
4924
+ ], p.prototype, "verifyEmailCooldownUntil", 2);
4925
+ p = m([
4926
+ O("authui-account")
4181
4927
  ], p);
4182
- var Ft = Object.defineProperty, zt = Object.getOwnPropertyDescriptor, O = (e, t, i, r) => {
4183
- for (var a = r > 1 ? void 0 : r ? zt(t, i) : t, h = e.length - 1, u; h >= 0; h--)
4184
- (u = e[h]) && (a = (r ? u(t, i, a) : u(a)) || a);
4185
- return r && a && Ft(t, i, a), a;
4928
+ var Wt = Object.defineProperty, Kt = Object.getOwnPropertyDescriptor, L = (e, t, i, s) => {
4929
+ for (var a = s > 1 ? void 0 : s ? Kt(t, i) : t, l = e.length - 1, u; l >= 0; l--)
4930
+ (u = e[l]) && (a = (s ? u(t, i, a) : u(a)) || a);
4931
+ return s && a && Wt(t, i, a), a;
4186
4932
  };
4187
- let E = class extends A {
4933
+ let M = class extends A {
4188
4934
  constructor() {
4189
4935
  super(...arguments), this.open = !1, this.view = "sign-in", this.closeOnSuccess = !0, this.handledPending = null, this.onOpenEvent = (e) => {
4190
4936
  const t = e.detail ?? {};
@@ -4205,29 +4951,38 @@ let E = class extends A {
4205
4951
  super.disconnectedCallback(), window.removeEventListener("authui:open", this.onOpenEvent), window.removeEventListener("authui:close", this.onCloseEvent);
4206
4952
  }
4207
4953
  show(e) {
4208
- e ? this.view = e : this.auth.status === "signed-in" && (this.view = "account"), this.open = !0;
4954
+ e === "account" && this.auth.status !== "signed-in" ? this.view = "sign-in" : e ? this.view = e : this.auth.status === "signed-in" ? this.view = "account" : this.view = "sign-in", this.open = !0;
4209
4955
  }
4210
4956
  hide() {
4211
4957
  this.open = !1;
4212
4958
  }
4213
4959
  updated(e) {
4214
- if (e.has("open") && this.dialog && (this.open && !this.dialog.open && this.dialog.showModal(), !this.open && this.dialog.open && this.dialog.close()), e.has("auth")) {
4960
+ if (e.has("open") && this.dialog && (this.open && !this.dialog.open && (this.dialog.showModal(), requestAnimationFrame(() => this.focusPrimary())), !this.open && this.dialog.open && this.dialog.close()), e.has("auth")) {
4215
4961
  const t = this.auth.pending;
4216
- t && t !== this.handledPending && t.type !== "notice" && (this.handledPending = t, this.view = "sign-in", this.open = !0), t?.type === "notice" && t !== this.handledPending && (this.handledPending = t, this.open = !0);
4962
+ t && t !== this.handledPending && t.type !== "notice" && (this.handledPending = t, this.view = "sign-in", this.open = !0), t?.type === "notice" && t !== this.handledPending && (this.handledPending = t, this.open = !0), this.open && this.view === "account" && this.auth.status !== "signed-in" && (this.view = "sign-in"), this.open && this.auth.status === "signed-out" && this.view === "account" && (this.view = "sign-in");
4217
4963
  }
4218
4964
  }
4965
+ focusPrimary() {
4966
+ const e = this.dialog;
4967
+ if (!e) return;
4968
+ const i = e.querySelector("authui-sign-in, authui-account")?.shadowRoot;
4969
+ (i?.querySelector(".alert[role=alert], .alert[role=status]") ?? i?.querySelector(
4970
+ "input:not([type=hidden]), button.choice, [role=tab]"
4971
+ ))?.focus?.();
4972
+ }
4219
4973
  render() {
4220
- const e = this.view === "account";
4221
- return s`
4974
+ const e = this.auth.status === "signed-in", t = this.view === "account" && e;
4975
+ return r`
4222
4976
  <dialog
4223
- class=${e ? "wide" : ""}
4224
- aria-labelledby="authui-title"
4977
+ class=${t ? "wide" : ""}
4978
+ aria-label=${t ? this.t("dialogAccount") : this.t("dialogSignIn")}
4225
4979
  @close=${() => this.open = !1}
4226
- @cancel=${(t) => {
4227
- t.preventDefault(), this.hide();
4980
+ @cancel=${(i) => {
4981
+ i.preventDefault(), this.hide();
4228
4982
  }}
4229
4983
  @click=${this.onBackdrop}
4230
4984
  @authui-open=${this.onInnerOpen}
4985
+ @authui-success=${this.onSuccess}
4231
4986
  >
4232
4987
  <div class="body">
4233
4988
  <button
@@ -4237,19 +4992,18 @@ let E = class extends A {
4237
4992
  >
4238
4993
  ${c.x}
4239
4994
  </button>
4240
- ${this.open ? e ? s`<authui-account embedded></authui-account>` : s`<authui-sign-in
4995
+ ${this.open ? t ? r`<authui-account embedded></authui-account>` : r`<authui-sign-in
4241
4996
  embedded
4242
- .view=${this.view}
4243
- @authui-success=${this.onSuccess}
4997
+ .view=${this.view === "account" ? "sign-in" : this.view}
4244
4998
  ></authui-sign-in>` : o}
4245
4999
  </div>
4246
5000
  </dialog>
4247
5001
  `;
4248
5002
  }
4249
5003
  };
4250
- E.styles = [
5004
+ M.styles = [
4251
5005
  ...A.styles,
4252
- I`
5006
+ F`
4253
5007
  :host {
4254
5008
  display: contents;
4255
5009
  }
@@ -4309,36 +5063,28 @@ E.styles = [
4309
5063
  }
4310
5064
  `
4311
5065
  ];
4312
- O([
4313
- f({ type: Boolean, reflect: !0 })
4314
- ], E.prototype, "open", 2);
4315
- O([
4316
- f({ type: String })
4317
- ], E.prototype, "view", 2);
4318
- O([
4319
- f({ type: Boolean, attribute: "close-on-success" })
4320
- ], E.prototype, "closeOnSuccess", 2);
4321
- O([
4322
- d()
4323
- ], E.prototype, "handledPending", 2);
4324
- O([
4325
- rt("dialog")
4326
- ], E.prototype, "dialog", 2);
4327
- E = O([
4328
- _("authui-modal")
4329
- ], E);
4330
- function Y(e) {
4331
- typeof document > "u" || (document.querySelector("authui-modal") || document.body.appendChild(document.createElement("authui-modal")), queueMicrotask(() => {
4332
- window.dispatchEvent(new CustomEvent("authui:open", { detail: { view: e } }));
4333
- }));
4334
- }
4335
- function Bt() {
4336
- typeof window > "u" || window.dispatchEvent(new CustomEvent("authui:close"));
4337
- }
4338
- var Ot = Object.defineProperty, Dt = Object.getOwnPropertyDescriptor, j = (e, t, i, r) => {
4339
- for (var a = r > 1 ? void 0 : r ? Dt(t, i) : t, h = e.length - 1, u; h >= 0; h--)
4340
- (u = e[h]) && (a = (r ? u(t, i, a) : u(a)) || a);
4341
- return r && a && Ot(t, i, a), a;
5066
+ L([
5067
+ g({ type: Boolean, reflect: !0 })
5068
+ ], M.prototype, "open", 2);
5069
+ L([
5070
+ g({ type: String })
5071
+ ], M.prototype, "view", 2);
5072
+ L([
5073
+ g({ type: Boolean, attribute: "close-on-success" })
5074
+ ], M.prototype, "closeOnSuccess", 2);
5075
+ L([
5076
+ h()
5077
+ ], M.prototype, "handledPending", 2);
5078
+ L([
5079
+ gt("dialog")
5080
+ ], M.prototype, "dialog", 2);
5081
+ M = L([
5082
+ O("authui-modal")
5083
+ ], M);
5084
+ var Gt = Object.defineProperty, Yt = Object.getOwnPropertyDescriptor, Z = (e, t, i, s) => {
5085
+ for (var a = s > 1 ? void 0 : s ? Yt(t, i) : t, l = e.length - 1, u; l >= 0; l--)
5086
+ (u = e[l]) && (a = (s ? u(t, i, a) : u(a)) || a);
5087
+ return s && a && Gt(t, i, a), a;
4342
5088
  };
4343
5089
  let z = class extends A {
4344
5090
  constructor() {
@@ -4346,9 +5092,9 @@ let z = class extends A {
4346
5092
  }
4347
5093
  render() {
4348
5094
  const e = this.size === "md" ? "" : `btn-${this.size}`;
4349
- return s`<button
5095
+ return r`<button
4350
5096
  class="btn btn-${this.variant} ${e}"
4351
- @click=${() => Y(this.view)}
5097
+ @click=${() => G(this.view)}
4352
5098
  part="button"
4353
5099
  >
4354
5100
  <slot
@@ -4359,7 +5105,7 @@ let z = class extends A {
4359
5105
  };
4360
5106
  z.styles = [
4361
5107
  ...A.styles,
4362
- I`
5108
+ F`
4363
5109
  :host {
4364
5110
  display: inline-block;
4365
5111
  }
@@ -4368,29 +5114,52 @@ z.styles = [
4368
5114
  }
4369
5115
  `
4370
5116
  ];
4371
- j([
4372
- f({ type: String })
5117
+ Z([
5118
+ g({ type: String })
4373
5119
  ], z.prototype, "view", 2);
4374
- j([
4375
- f({ type: String })
5120
+ Z([
5121
+ g({ type: String })
4376
5122
  ], z.prototype, "variant", 2);
4377
- j([
4378
- f({ type: String })
5123
+ Z([
5124
+ g({ type: String })
4379
5125
  ], z.prototype, "size", 2);
4380
- z = j([
4381
- _("authui-button")
5126
+ z = Z([
5127
+ O("authui-button")
4382
5128
  ], z);
4383
- var Lt = Object.defineProperty, Rt = Object.getOwnPropertyDescriptor, Q = (e, t, i, r) => {
4384
- for (var a = r > 1 ? void 0 : r ? Rt(t, i) : t, h = e.length - 1, u; h >= 0; h--)
4385
- (u = e[h]) && (a = (r ? u(t, i, a) : u(a)) || a);
4386
- return r && a && Lt(t, i, a), a;
5129
+ var Zt = Object.defineProperty, Xt = Object.getOwnPropertyDescriptor, _ = (e, t, i, s) => {
5130
+ for (var a = s > 1 ? void 0 : s ? Xt(t, i) : t, l = e.length - 1, u; l >= 0; l--)
5131
+ (u = e[l]) && (a = (s ? u(t, i, a) : u(a)) || a);
5132
+ return s && a && Zt(t, i, a), a;
4387
5133
  };
4388
- let R = class extends A {
5134
+ let E = class extends A {
4389
5135
  constructor() {
4390
- super(...arguments), this.src = "", this.menuOpen = !1, this.onDocumentClick = (e) => {
5136
+ super(...arguments), this.showTeams = !1, this.src = "", this.menuOpen = !1, this.teams = [], this.teamsLoading = !1, this.activeTeamId = null, this.onDocumentClick = (e) => {
4391
5137
  e.composedPath().includes(this) || (this.menuOpen = !1);
4392
5138
  }, this.onKeydown = (e) => {
4393
- e.key === "Escape" && (this.menuOpen = !1);
5139
+ if (!this.menuOpen) {
5140
+ (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") && e.target === this.renderRoot?.querySelector(".trigger") && e.key === "ArrowDown" && (e.preventDefault(), this.menuOpen = !0, requestAnimationFrame(() => this.focusMenuItem(0)));
5141
+ return;
5142
+ }
5143
+ const t = [
5144
+ ...this.renderRoot?.querySelectorAll('[role="menuitem"]') ?? []
5145
+ ], i = t.findIndex((s) => s === this.shadowRoot?.activeElement);
5146
+ if (e.key === "Escape") {
5147
+ e.preventDefault(), this.menuOpen = !1, this.renderRoot?.querySelector(".trigger")?.focus();
5148
+ return;
5149
+ }
5150
+ e.key === "ArrowDown" ? (e.preventDefault(), this.focusMenuItem(i < 0 ? 0 : (i + 1) % t.length)) : e.key === "ArrowUp" ? (e.preventDefault(), this.focusMenuItem(
5151
+ i < 0 ? t.length - 1 : (i - 1 + t.length) % t.length
5152
+ )) : e.key === "Home" ? (e.preventDefault(), this.focusMenuItem(0)) : e.key === "End" && (e.preventDefault(), this.focusMenuItem(t.length - 1));
5153
+ }, this.toggleMenu = () => {
5154
+ this.menuOpen = !this.menuOpen, this.menuOpen && this.showTeams && this.loadTeams();
5155
+ }, this.selectTeam = (e) => {
5156
+ n.setActiveTeam({ $id: e.$id, name: e.name }), this.activeTeamId = e.$id, this.dispatchEvent(
5157
+ new CustomEvent("authui-active-team", {
5158
+ detail: { teamId: e.$id, team: e },
5159
+ bubbles: !0,
5160
+ composed: !0
5161
+ })
5162
+ );
4394
5163
  };
4395
5164
  }
4396
5165
  connectedCallback() {
@@ -4399,37 +5168,72 @@ let R = class extends A {
4399
5168
  disconnectedCallback() {
4400
5169
  super.disconnectedCallback(), document.removeEventListener("click", this.onDocumentClick, !0), document.removeEventListener("keydown", this.onKeydown), this.removeEventListener("keydown", this.onKeydown);
4401
5170
  }
5171
+ focusMenuItem(e) {
5172
+ [
5173
+ ...this.renderRoot?.querySelectorAll('[role="menuitem"]') ?? []
5174
+ ][e]?.focus();
5175
+ }
5176
+ updated(e) {
5177
+ e.has("menuOpen") && this.menuOpen && (this.showTeams && this.loadTeams(), requestAnimationFrame(() => this.focusMenuItem(0)));
5178
+ }
5179
+ async loadTeams() {
5180
+ this.teamsLoading = !0, this.activeTeamId = n.getActiveTeamId();
5181
+ try {
5182
+ this.teams = await n.listTeams(), this.activeTeamId && !this.teams.some((e) => e.$id === this.activeTeamId) && (this.activeTeamId = null, n.setActiveTeam(null));
5183
+ } catch {
5184
+ this.teams = [];
5185
+ } finally {
5186
+ this.teamsLoading = !1;
5187
+ }
5188
+ }
4402
5189
  render() {
4403
- const { status: e, user: t } = this.auth;
4404
- if (e === "loading")
4405
- return s`<span class="avatar"><span class="spinner"></span></span>`;
5190
+ const { status: e, user: t, configured: i } = this.auth;
5191
+ if (e === "loading" && i)
5192
+ return r`<span class="avatar"><span class="spinner"></span></span>`;
4406
5193
  if (e !== "signed-in" || !t)
4407
- return s`<button class="btn btn-primary btn-sm" @click=${() => Y("sign-in")}>
5194
+ return r`<button class="btn btn-primary btn-sm" @click=${() => G("sign-in")}>
4408
5195
  <slot>${this.t("signIn")}</slot>
4409
5196
  </button>`;
4410
- const i = t.name || t.email || t.phone || this.t("guestAccount");
4411
- return s`
5197
+ const s = t.name || t.email || t.phone || this.t("guestAccount");
5198
+ return r`
4412
5199
  <button
4413
5200
  class="trigger"
4414
5201
  aria-haspopup="menu"
4415
5202
  aria-expanded=${this.menuOpen ? "true" : "false"}
4416
- @click=${() => this.menuOpen = !this.menuOpen}
4417
- aria-label=${i}
5203
+ @click=${this.toggleMenu}
5204
+ aria-label=${s}
4418
5205
  >
4419
5206
  <span class="avatar"
4420
- >${this.src ? s`<img src=${this.src} alt="" />` : i[0] ?? "?"}</span
5207
+ >${this.src ? r`<img src=${this.src} alt="" />` : st(s)}</span
4421
5208
  >
4422
5209
  </button>
4423
- ${this.menuOpen ? s`<div class="menu" role="menu">
5210
+ ${this.menuOpen ? r`<div class="menu" role="menu">
4424
5211
  <div class="menu-header">
4425
- <span class="row-title">${i}</span>
4426
- ${t.email && t.name ? s`<span class="row-sub">${t.email}</span>` : o}
5212
+ <span class="row-title" title=${s}>${s}</span>
5213
+ ${t.email && t.name ? r`<span class="row-sub" title=${t.email}>${t.email}</span>` : o}
4427
5214
  </div>
5215
+ ${this.showTeams ? r`<div class="menu-section">
5216
+ <div class="menu-section-label">${this.t("teamsLabel")}</div>
5217
+ ${this.teamsLoading ? r`<div class="menu-item" aria-busy="true">
5218
+ <span class="spinner"></span>
5219
+ </div>` : this.teams.length === 0 ? r`<div class="menu-item" role="note">${this.t("noTeams")}</div>` : this.teams.map(
5220
+ (a) => r`<button
5221
+ class="menu-item ${a.$id === this.activeTeamId ? "active" : ""}"
5222
+ role="menuitemradio"
5223
+ aria-checked=${a.$id === this.activeTeamId ? "true" : "false"}
5224
+ @click=${() => this.selectTeam(a)}
5225
+ >
5226
+ ${c.users}
5227
+ <span title=${a.name}>${a.name}</span>
5228
+ ${a.$id === this.activeTeamId ? r`<span class="check">${c.check}</span>` : o}
5229
+ </button>`
5230
+ )}
5231
+ </div>` : o}
4428
5232
  <button
4429
5233
  class="menu-item"
4430
5234
  role="menuitem"
4431
5235
  @click=${() => {
4432
- this.menuOpen = !1, Y("account");
5236
+ this.menuOpen = !1, G("account");
4433
5237
  }}
4434
5238
  >
4435
5239
  ${c.settings} ${this.t("manageAccount")}
@@ -4447,9 +5251,9 @@ let R = class extends A {
4447
5251
  `;
4448
5252
  }
4449
5253
  };
4450
- R.styles = [
5254
+ E.styles = [
4451
5255
  ...A.styles,
4452
- I`
5256
+ F`
4453
5257
  :host {
4454
5258
  display: inline-block;
4455
5259
  position: relative;
@@ -4476,6 +5280,7 @@ R.styles = [
4476
5280
  top: calc(100% + 6px);
4477
5281
  inset-inline-end: 0;
4478
5282
  min-width: 220px;
5283
+ max-width: min(320px, 90vw);
4479
5284
  background: var(--authui-popover);
4480
5285
  color: var(--authui-popover-foreground);
4481
5286
  border: 1px solid var(--authui-border);
@@ -4488,6 +5293,8 @@ R.styles = [
4488
5293
  gap: 2px;
4489
5294
  }
4490
5295
  .menu-header {
5296
+ min-width: 0;
5297
+ overflow: hidden;
4491
5298
  padding: 8px 10px 10px;
4492
5299
  display: flex;
4493
5300
  flex-direction: column;
@@ -4495,6 +5302,14 @@ R.styles = [
4495
5302
  border-bottom: 1px solid var(--authui-border);
4496
5303
  margin-bottom: 4px;
4497
5304
  }
5305
+ .menu .row-title,
5306
+ .menu .row-sub {
5307
+ display: block;
5308
+ overflow: hidden;
5309
+ text-overflow: ellipsis;
5310
+ white-space: nowrap;
5311
+ }
5312
+
4498
5313
  .menu-item {
4499
5314
  display: flex;
4500
5315
  align-items: center;
@@ -4520,6 +5335,26 @@ R.styles = [
4520
5335
  height: 16px;
4521
5336
  color: var(--authui-muted-foreground);
4522
5337
  }
5338
+ .menu-section {
5339
+ border-top: 1px solid var(--authui-border);
5340
+ margin-top: 4px;
5341
+ padding-top: 4px;
5342
+ }
5343
+ .menu-section-label {
5344
+ padding: 6px 10px 2px;
5345
+ font-size: 11px;
5346
+ font-weight: 600;
5347
+ letter-spacing: 0.04em;
5348
+ text-transform: uppercase;
5349
+ color: var(--authui-muted-foreground);
5350
+ }
5351
+ .menu-item.active {
5352
+ background: var(--authui-accent);
5353
+ }
5354
+ .menu-item .check {
5355
+ margin-inline-start: auto;
5356
+ color: var(--authui-brand);
5357
+ }
4523
5358
  .avatar {
4524
5359
  width: 32px;
4525
5360
  height: 32px;
@@ -4527,32 +5362,53 @@ R.styles = [
4527
5362
  }
4528
5363
  `
4529
5364
  ];
4530
- Q([
4531
- f({ type: String })
4532
- ], R.prototype, "src", 2);
4533
- Q([
4534
- d()
4535
- ], R.prototype, "menuOpen", 2);
4536
- R = Q([
4537
- _("authui-user-button")
4538
- ], R);
5365
+ _([
5366
+ g({ type: Boolean, attribute: "show-teams" })
5367
+ ], E.prototype, "showTeams", 2);
5368
+ _([
5369
+ g({ type: String })
5370
+ ], E.prototype, "src", 2);
5371
+ _([
5372
+ h()
5373
+ ], E.prototype, "menuOpen", 2);
5374
+ _([
5375
+ h()
5376
+ ], E.prototype, "teams", 2);
5377
+ _([
5378
+ h()
5379
+ ], E.prototype, "teamsLoading", 2);
5380
+ _([
5381
+ h()
5382
+ ], E.prototype, "activeTeamId", 2);
5383
+ E = _([
5384
+ O("authui-user-button")
5385
+ ], E);
4539
5386
  export {
4540
- gt as A,
4541
- v as E,
4542
- ft as P,
5387
+ Ut as A,
5388
+ ie as C,
5389
+ f as E,
5390
+ mt as F,
5391
+ Ct as P,
4543
5392
  n as a,
4544
5393
  p as b,
4545
- Bt as c,
5394
+ se as c,
4546
5395
  z as d,
4547
5396
  b as e,
4548
5397
  A as f,
4549
- E as g,
4550
- L as h,
5398
+ M as g,
5399
+ B as h,
4551
5400
  $ as i,
4552
- R as j,
4553
- dt as k,
4554
- at as l,
4555
- Y as o,
4556
- D as p,
4557
- N as t
5401
+ E as j,
5402
+ re as k,
5403
+ wt as l,
5404
+ K as m,
5405
+ D as n,
5406
+ G as o,
5407
+ lt as p,
5408
+ Pt as q,
5409
+ q as r,
5410
+ V as s,
5411
+ et as t,
5412
+ At as u,
5413
+ R as v
4558
5414
  };