{"version":3,"file":"sign-in.mjs","names":[],"sources":["../../src/client/auth-form.js","../../src/client/auth-destinations.ts","../../src/client/sign-in.ts"],"sourcesContent":["/**\n * Adds email/OTP behavior to the auth form already rendered by the server.\n */\n\nconst OTP_LENGTH = 6;\nconst PANEL_TRANSITION_DURATION = 240;\nconst PANEL_TRANSITION_EASING = \"cubic-bezier(0.22, 1, 0.36, 1)\";\nconst RESEND_COOLDOWN_SECONDS = 60;\nconst STEP_ORDER = { options: 0, email: 1, otp: 2 };\n\nclass AuthRequestError extends Error {\n  constructor(code) {\n    super(code);\n    this.name = \"AuthRequestError\";\n    this.code = code;\n  }\n}\n\nfunction statusCode(status) {\n  if (status === 401) return \"unauthorized\";\n  if (status === 429) return \"rate_limited\";\n  return \"bad_request\";\n}\n\nfunction codeFromPayload(payload, status) {\n  const error = payload?.error;\n  return error && typeof error === \"object\" && typeof error.code === \"string\"\n    ? error.code\n    : statusCode(status);\n}\n\nasync function postJson(url, body, signal) {\n  let response;\n  try {\n    response = await fetch(url, {\n      method: \"POST\",\n      credentials: \"include\",\n      headers: { accept: \"application/json\", \"content-type\": \"application/json\" },\n      body: JSON.stringify(body),\n      signal,\n    });\n  } catch (error) {\n    if (error?.name === \"AbortError\") throw error;\n    throw new AuthRequestError(\"network\");\n  }\n\n  const payload = await response.json().catch(() => null);\n  if (!response.ok) throw new AuthRequestError(codeFromPayload(payload, response.status));\n  return payload?.data || payload || {};\n}\n\nfunction required(root, selector) {\n  const element = root.querySelector(selector);\n  if (!element) throw new Error(`Missing auth form element: ${selector}`);\n  return element;\n}\n\n/**\n * @param {HTMLElement} container containing a server-rendered auth form\n * @param {{\n *   authOrigin?: string,\n *   redirectUrl?: string,\n *   siteUrl?: string,\n *   email?: string,\n *   onAuthenticated?: (result: { account: object|null, destinations: object, redirectUrl: string|null }) => void,\n *   onStep?: (step: string, copy: { title: string, intro: string }) => void,\n * }} options\n */\nexport function mountAuthForm(container, options = {}) {\n  const root = required(container, \"[data-auth-form]\");\n  const copy = JSON.parse(root.dataset.authCopy || \"{}\");\n  const stage = required(root, \"[data-auth-stage]\");\n  const panels = Array.from(root.querySelectorAll(\"[data-auth-panel]\"));\n  const emailChoice = required(root, \"[data-auth-email-choice]\");\n  const createAccount = required(root, \"[data-auth-create-account]\");\n  const emailForm = required(root, \"[data-auth-email-form]\");\n  const emailInput = required(root, \"[data-auth-email]\");\n  const emailBack = required(root, \"[data-auth-email-back]\");\n  const otpForm = required(root, \"[data-auth-otp-form]\");\n  const otpInputs = Array.from(root.querySelectorAll(\"[data-auth-code-digit]\"));\n  if (otpInputs.length !== OTP_LENGTH) {\n    throw new Error(`Expected ${OTP_LENGTH} auth code inputs, found ${otpInputs.length}`);\n  }\n  const firstOtpInput = otpInputs[0];\n  const otpBack = required(root, \"[data-auth-otp-back]\");\n  const otpEmail = required(root, \"[data-auth-email-value]\");\n  const resend = required(root, \"[data-auth-resend]\");\n  const message = required(root, \"[data-auth-message]\");\n\n  const authBase = `${(options.authOrigin || \"\").replace(/\\/+$/, \"\")}/api/auth`;\n  const redirectUrl = options.redirectUrl || \"\";\n  const passkeyLink = root.querySelector(\"[data-auth-passkey-link]\");\n  if (passkeyLink && options.authOrigin && new URL(options.authOrigin).origin !== window.location.origin) {\n    const signIn = new URL(\"/sign-in\", options.authOrigin);\n    if (redirectUrl) signIn.searchParams.set(\"redirect_url\", redirectUrl);\n    passkeyLink.href = signIn.toString();\n    passkeyLink.hidden = false;\n  }\n  const controller = new AbortController();\n  const signal = controller.signal;\n\n  if (options.email !== undefined) emailInput.value = options.email;\n\n  let email = emailInput.value;\n  let step = root.dataset.authStep || \"email\";\n  let busy = false;\n  let authenticated = false;\n  let cooldownTimer = 0;\n  let cooldownUntil = 0;\n  let panelAnimations = [];\n  let transitionSequence = 0;\n\n  function showMessage(text, isError = false) {\n    message.textContent = text;\n    message.hidden = !text;\n    message.classList.toggle(\"pi-auth-message--error\", isError);\n    message.setAttribute(\"role\", isError ? \"alert\" : \"status\");\n  }\n\n  function updateResend() {\n    const remaining = Math.max(0, Math.ceil((cooldownUntil - Date.now()) / 1000));\n    resend.disabled = busy || remaining > 0;\n    resend.textContent = remaining > 0\n      ? copy.resendIn.replace(\"__SECONDS__\", remaining)\n      : copy.resend;\n  }\n\n  function setBusy(next) {\n    busy = next;\n    root.classList.toggle(\"pi-auth--busy\", next);\n    for (const control of root.querySelectorAll(\"button, input\")) control.disabled = next;\n    if (!next) updateResend();\n  }\n\n  function startCooldown() {\n    cooldownUntil = Date.now() + RESEND_COOLDOWN_SECONDS * 1000;\n    updateResend();\n    window.clearInterval(cooldownTimer);\n    cooldownTimer = window.setInterval(() => {\n      updateResend();\n      if (Date.now() >= cooldownUntil) window.clearInterval(cooldownTimer);\n    }, 1000);\n  }\n\n  function otpCode() {\n    return otpInputs.map((input) => input.value).join(\"\");\n  }\n\n  function setOtpInvalid(invalid) {\n    for (const input of otpInputs) {\n      input.toggleAttribute(\"aria-invalid\", invalid);\n    }\n  }\n\n  function clearOtp() {\n    for (const input of otpInputs) input.value = \"\";\n    setOtpInvalid(false);\n  }\n\n  function fillOtp(value, startIndex = 0) {\n    const digits = value.replace(/\\D/g, \"\").slice(0, OTP_LENGTH - startIndex);\n    for (let offset = 0; offset < digits.length; offset += 1) {\n      otpInputs[startIndex + offset].value = digits[offset];\n    }\n    setOtpInvalid(false);\n\n    const nextIndex = Math.min(startIndex + digits.length, OTP_LENGTH - 1);\n    otpInputs[nextIndex].focus();\n    otpInputs[nextIndex].select();\n    if (otpCode().length === OTP_LENGTH) void verifyCode();\n  }\n\n  function focusStep(next) {\n    if (next === \"email\") emailInput.focus();\n    else if (next === \"otp\") firstOtpInput.focus();\n    else emailChoice.focus();\n  }\n\n  function cancelPanelTransition() {\n    for (const animation of panelAnimations) animation.cancel();\n    panelAnimations = [];\n    stage.classList.remove(\"pi-auth-stage--transitioning\");\n    stage.style.height = \"\";\n  }\n\n  function prefersReducedMotion() {\n    return window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches;\n  }\n\n  function showStep(next, focus = true, clearMessage = true) {\n    const transition = ++transitionSequence;\n    cancelPanelTransition();\n    const previousPanel = panels.find((panel) => panel.dataset.authPanel === step);\n    const activePanel = panels.find((panel) => panel.dataset.authPanel === next);\n    for (const panel of panels) panel.hidden = panel !== previousPanel;\n\n    step = next;\n    root.dataset.authStep = next;\n    if (clearMessage) showMessage(\"\");\n    if (next === \"otp\") otpEmail.textContent = email || copy.yourEmail;\n    options.onStep?.(next, {\n      title: activePanel?.dataset.authTitle || \"\",\n      intro: activePanel?.dataset.authIntro || \"\",\n    });\n\n    const canAnimate = focus && previousPanel && activePanel && previousPanel !== activePanel &&\n      typeof previousPanel.animate === \"function\" && !prefersReducedMotion();\n    if (!canAnimate) {\n      for (const panel of panels) panel.hidden = panel !== activePanel;\n      if (focus) focusStep(next);\n      return;\n    }\n\n    activePanel.hidden = false;\n    const fromHeight = previousPanel.offsetHeight;\n    const toHeight = activePanel.offsetHeight;\n    const direction = (STEP_ORDER[next] ?? 0) >= (STEP_ORDER[previousPanel.dataset.authPanel] ?? 0) ? 1 : -1;\n\n    stage.style.height = `${fromHeight}px`;\n    stage.classList.add(\"pi-auth-stage--transitioning\");\n    panelAnimations = [\n      previousPanel.animate([\n        { opacity: 1, transform: \"translateY(0)\" },\n        { opacity: 0, transform: `translateY(${-8 * direction}px)` },\n      ], {\n        duration: PANEL_TRANSITION_DURATION,\n        easing: PANEL_TRANSITION_EASING,\n        fill: \"both\",\n      }),\n      activePanel.animate([\n        { opacity: 0, transform: `translateY(${10 * direction}px)` },\n        { opacity: 1, transform: \"translateY(0)\" },\n      ], {\n        duration: PANEL_TRANSITION_DURATION,\n        easing: PANEL_TRANSITION_EASING,\n        fill: \"both\",\n      }),\n      stage.animate([\n        { height: `${fromHeight}px` },\n        { height: `${toHeight}px` },\n      ], {\n        duration: PANEL_TRANSITION_DURATION,\n        easing: PANEL_TRANSITION_EASING,\n        fill: \"both\",\n      }),\n    ];\n\n    void Promise.allSettled(panelAnimations.map((animation) => animation.finished)).then(() => {\n      if (transition !== transitionSequence) return;\n      cancelPanelTransition();\n      for (const panel of panels) panel.hidden = panel !== activePanel;\n      focusStep(next);\n    });\n  }\n\n  async function requestCode(address) {\n    if (busy) return;\n    const value = address.trim();\n    if (!value) {\n      showMessage(copy.emailRequired, true);\n      emailInput.focus();\n      return;\n    }\n\n    email = value;\n    setBusy(true);\n    showMessage(copy.sending);\n\n    try {\n      await postJson(`${authBase}/otp/request`, { email, siteUrl: options.siteUrl || undefined }, signal);\n      clearOtp();\n      showStep(\"otp\");\n      startCooldown();\n    } catch (error) {\n      if (error.name !== \"AbortError\") {\n        showMessage(copy.errors[error.code] || copy.requestFailed, true);\n      }\n    } finally {\n      setBusy(false);\n    }\n  }\n\n  async function verifyCode() {\n    if (busy || authenticated) return;\n    const code = otpCode();\n    if (code.length !== OTP_LENGTH) {\n      setOtpInvalid(true);\n      showMessage(copy.codeLength, true);\n      (otpInputs.find((input) => !input.value) || firstOtpInput).focus();\n      return;\n    }\n\n    setBusy(true);\n    showMessage(copy.verifying);\n\n    try {\n      const result = await postJson(\n        `${authBase}/otp/verify`,\n        { email, code, redirectUrl: redirectUrl || undefined },\n        signal,\n      );\n      authenticated = true;\n      if (result.kind === \"two_factor_required\") {\n        window.location.assign(result.redirectUrl);\n        return;\n      }\n      options.onAuthenticated?.({\n        account: result.account || null,\n        destinations: result.destinations || {},\n        redirectUrl: result.redirectUrl || null,\n      });\n    } catch (error) {\n      if (error.name !== \"AbortError\") {\n        showMessage(copy.errors[error.code] || copy.verifyFailed, true);\n        setOtpInvalid(true);\n        if (error.code === \"invalid_code\" || error.code === \"invalid_auth_code\") clearOtp();\n        firstOtpInput.focus();\n        firstOtpInput.select();\n      }\n    } finally {\n      if (!authenticated) setBusy(false);\n    }\n  }\n\n  emailChoice.addEventListener(\"click\", () => showStep(\"email\"), { signal });\n  createAccount.addEventListener(\"click\", () => showStep(\"email\"), { signal });\n  emailBack.addEventListener(\"click\", () => showStep(\"options\"), { signal });\n  otpBack.addEventListener(\"click\", () => showStep(\"email\"), { signal });\n  resend.addEventListener(\"click\", () => void requestCode(email), { signal });\n\n  emailForm.addEventListener(\"submit\", (event) => {\n    event.preventDefault();\n    void requestCode(emailInput.value);\n  }, { signal });\n\n  otpForm.addEventListener(\"submit\", (event) => {\n    event.preventDefault();\n    void verifyCode();\n  }, { signal });\n\n  otpInputs.forEach((input, index) => {\n    input.addEventListener(\"input\", () => {\n      const digits = input.value.replace(/\\D/g, \"\");\n      input.value = \"\";\n      if (digits) fillOtp(digits, index);\n    }, { signal });\n\n    input.addEventListener(\"paste\", (event) => {\n      const digits = event.clipboardData?.getData(\"text\").replace(/\\D/g, \"\") || \"\";\n      if (!digits) return;\n      event.preventDefault();\n      const startIndex = digits.length >= OTP_LENGTH ? 0 : index;\n      if (startIndex === 0) clearOtp();\n      fillOtp(digits, startIndex);\n    }, { signal });\n\n    input.addEventListener(\"keydown\", (event) => {\n      if (event.key === \"Backspace\" && !input.value && index > 0) {\n        event.preventDefault();\n        otpInputs[index - 1].value = \"\";\n        otpInputs[index - 1].focus();\n      } else if (event.key === \"ArrowLeft\" && index > 0) {\n        event.preventDefault();\n        otpInputs[index - 1].focus();\n        otpInputs[index - 1].select();\n      } else if (event.key === \"ArrowRight\" && index < OTP_LENGTH - 1) {\n        event.preventDefault();\n        otpInputs[index + 1].focus();\n        otpInputs[index + 1].select();\n      }\n    }, { signal });\n\n    input.addEventListener(\"focus\", () => input.select(), { signal });\n  });\n\n  showStep(step, false, false);\n  updateResend();\n\n  function destroy() {\n    transitionSequence += 1;\n    cancelPanelTransition();\n    window.clearInterval(cooldownTimer);\n    controller.abort();\n    root.remove();\n  }\n\n  return {\n    element: root,\n    destroy,\n    showStep,\n    get email() {\n      return email;\n    },\n  };\n}\n","export type AuthDestinations = {\n  creatorUrl?: string;\n  storiesUrl?: string;\n  browseUrl?: string;\n};\n\n/** Returns the destination when auth has exactly one place for the account to go. */\nexport function singleAuthDestination(destinations: AuthDestinations): string | null {\n  const urls = [destinations.creatorUrl, destinations.storiesUrl, destinations.browseUrl]\n    .filter((url): url is string => !!url);\n  const uniqueUrls = new Set(urls);\n\n  return uniqueUrls.size === 1 ? uniqueUrls.values().next().value || null : null;\n}\n","import { mountAuthForm } from \"./auth-form.js\";\nimport { mountPasskeys } from \"./passkeys\";\nimport { mountTwoFactorChallenge } from \"./two-factor\";\nimport { singleAuthDestination, type AuthDestinations } from \"./auth-destinations\";\n\nconst COPY_IN_DURATION = 180;\nconst COPY_OUT_DURATION = 90;\nconst COPY_TRANSITION_EASING = \"cubic-bezier(0.22, 1, 0.36, 1)\";\n\ntype SessionResponse = {\n  data?: SessionPayload;\n} & SessionPayload;\n\ntype SessionPayload = {\n  authenticated?: boolean;\n  account?: SessionAccount | null;\n  destinations?: AuthDestinations;\n  redirectUrl?: string | null;\n};\n\ntype SessionAccount = {\n  email?: string;\n  name?: string;\n  pictureUrl?: string;\n  username?: string;\n};\n\nconst authApiBase = \"/api/auth\";\n\nconst body = document.body;\nconst root = document.querySelector<HTMLElement>(\"[data-auth-root]\");\nconst mount = document.querySelector<HTMLElement>(\"[data-auth-mount]\");\nconst authenticatedHome = document.querySelector<HTMLElement>(\"[data-authenticated-home]\");\nconst authenticatedAvatar = document.querySelector<HTMLImageElement>(\"[data-authenticated-avatar]\");\nconst authenticatedName = document.querySelector<HTMLElement>(\"[data-authenticated-name]\");\nconst authenticatedEmail = document.querySelector<HTMLElement>(\"[data-authenticated-email]\");\nconst desktopReturn = document.querySelector<HTMLElement>(\"[data-desktop-return]\");\nconst desktopReturnLink = document.querySelector<HTMLAnchorElement>(\"[data-desktop-return-link]\");\nconst desktopReturnCodeWrap = document.querySelector<HTMLElement>(\"[data-desktop-return-code-wrap]\");\nconst desktopReturnCode = document.querySelector<HTMLElement>(\"[data-desktop-return-code]\");\nconst desktopReturnCopy = document.querySelector<HTMLButtonElement>(\"[data-desktop-return-copy]\");\nconst creatorLink = document.querySelector<HTMLAnchorElement>(\"[data-creator-link]\");\nconst storiesLink = document.querySelector<HTMLAnchorElement>(\"[data-stories-link]\");\nconst browseLink = document.querySelector<HTMLAnchorElement>(\"[data-browse-link]\");\nconst signOutButton = document.querySelector<HTMLButtonElement>(\"[data-sign-out]\");\nconst title = document.querySelector<HTMLElement>(\"[data-sign-in-title]\");\nconst intro = document.querySelector<HTMLElement>(\"[data-sign-in-intro]\");\n\nlet completedExternalAuthCode = \"\";\nlet authForm: ReturnType<typeof mountAuthForm> | null = null;\nlet copyAnimations: Animation[] = [];\nlet copyTransitionSequence = 0;\nlet twoFactor: ReturnType<typeof mountTwoFactorChallenge> | undefined;\nconst reauthenticate = body.dataset.reauthenticate === \"true\";\n\nif (root && mount) {\n  initializeSignIn(mount);\n}\n\nfunction initializeSignIn(container: HTMLElement): void {\n  const primaryRedirect = redirectUrl();\n  authForm = mountAuthForm(container, {\n    redirectUrl: primaryRedirect,\n    onStep: (step, copy) => {\n      setCopy(copy.title, copy.intro);\n      pushOtpUrl(step);\n    },\n    onAuthenticated: (result) => {\n      redirectAfterAuth(result);\n    },\n  });\n\n  signOutButton?.addEventListener(\"click\", () => void signOut());\n  mountPasskeys(redirectAfterAuth, primaryRedirect);\n  twoFactor = mountTwoFactorChallenge(redirectAfterAuth, () => {\n    authForm?.element.setAttribute(\"hidden\", \"\");\n    authenticatedHome?.setAttribute(\"hidden\", \"\");\n    setCopy(\"Two-step verification\", \"Confirm it's you to finish signing in.\");\n  });\n\n  document.addEventListener(\"keydown\", (event) => {\n    if (event.key === \"Escape\") showOptions();\n  });\n\n  desktopReturnCopy?.addEventListener(\"click\", async () => {\n    if (!completedExternalAuthCode) return;\n\n    try {\n      await navigator.clipboard.writeText(completedExternalAuthCode);\n      desktopReturnCopy.textContent = \"Copied\";\n    } catch {\n      desktopReturnCopy.textContent = \"Copy failed\";\n    }\n  });\n\n  if (!twoFactor.pending && !reauthenticate) void redirectExistingSession();\n}\n\n/// Keeps the deep-linkable /sign-in/otp URL the previous implementation\n/// produced, so a reload during verification returns to the same step.\nfunction pushOtpUrl(step: string): void {\n  if (step !== \"otp\" || !authForm) return;\n\n  const url = new URL(\"/sign-in/otp\", window.location.origin);\n  url.searchParams.set(\"email\", authForm.email);\n  if (reauthenticate) url.searchParams.set(\"reauthenticate\", \"1\");\n\n  const target = redirectUrl();\n  if (target) url.searchParams.set(\"redirect_url\", target);\n\n  window.history.pushState({}, \"\", `${url.pathname}${url.search}`);\n}\n\nasync function redirectExistingSession(): Promise<void> {\n  const url = new URL(`${authApiBase}/session`, window.location.origin);\n  const targetRedirectUrl = redirectUrl();\n  if (targetRedirectUrl) {\n    url.searchParams.set(\"redirect_url\", targetRedirectUrl);\n  }\n\n  const response = await fetch(url, {\n    credentials: \"include\",\n    headers: { accept: \"application/json\" },\n  }).catch(() => null);\n\n  if (!response?.ok) return;\n\n  const payload = await response.json().catch(() => null) as SessionResponse | null;\n  const session = payload?.data || payload;\n  if (!session?.authenticated) return;\n\n  if (targetRedirectUrl && session.redirectUrl) {\n    redirectAfterAuth({\n      account: session.account || null,\n      destinations: session.destinations || {},\n      redirectUrl: session.redirectUrl,\n    });\n    return;\n  }\n\n  showAuthenticatedHome(session.account || null, session.destinations || {});\n}\n\nfunction showAuthenticatedHome(account: SessionAccount | null, destinations: AuthDestinations): void {\n  const onlyDestination = singleAuthDestination(destinations);\n  if (onlyDestination) {\n    window.location.assign(onlyDestination);\n    return;\n  }\n\n  authForm?.element.setAttribute(\"hidden\", \"\");\n  desktopReturn?.setAttribute(\"hidden\", \"\");\n  authenticatedHome?.removeAttribute(\"hidden\");\n\n  setCopy(\"Welcome back\", \"You're signed in. Choose where you'd like to go.\");\n\n  const displayName = account?.name || account?.username || \"Your account\";\n  if (authenticatedName) authenticatedName.textContent = displayName;\n  if (authenticatedEmail) authenticatedEmail.textContent = account?.email || \"\";\n\n  if (authenticatedAvatar && account?.pictureUrl) {\n    authenticatedAvatar.src = account.pictureUrl;\n    authenticatedAvatar.alt = \"\";\n    authenticatedAvatar.removeAttribute(\"hidden\");\n  } else {\n    authenticatedAvatar?.setAttribute(\"hidden\", \"\");\n  }\n\n  setLink(creatorLink, destinations.creatorUrl);\n  setLink(storiesLink, destinations.storiesUrl);\n  setLink(browseLink, destinations.browseUrl || appUrl());\n}\n\nfunction setLink(link: HTMLAnchorElement | null, href: string | undefined): void {\n  if (!link || !href) return;\n\n  link.href = href;\n}\n\nasync function signOut(): Promise<void> {\n  try {\n    await fetch(`${authApiBase}/logout`, {\n      method: \"POST\",\n      credentials: \"include\",\n      headers: { accept: \"application/json\" },\n    });\n  } finally {\n    showOptions();\n  }\n}\n\nfunction showOptions(): void {\n  if (twoFactor?.pending) return;\n  authenticatedHome?.setAttribute(\"hidden\", \"\");\n  desktopReturn?.setAttribute(\"hidden\", \"\");\n  authForm?.element.removeAttribute(\"hidden\");\n  authForm?.showStep(\"options\");\n}\n\nfunction redirectAfterAuth(result: {\n  account: SessionAccount | null;\n  destinations: AuthDestinations;\n  redirectUrl: string | null;\n}): void {\n  const targetUrl = result.redirectUrl;\n\n  if (targetUrl) {\n    if (isExternalAppUrl(targetUrl)) {\n      showDesktopReturn(targetUrl);\n    }\n\n    window.location.assign(targetUrl);\n    return;\n  }\n\n  if (result.account || result.destinations) {\n    showAuthenticatedHome(result.account, result.destinations);\n    return;\n  }\n\n  window.location.assign(appUrl());\n}\n\nfunction isExternalAppUrl(value: string): boolean {\n  try {\n    const url = new URL(value, window.location.href);\n    return url.protocol !== \"http:\" && url.protocol !== \"https:\";\n  } catch {\n    return false;\n  }\n}\n\nfunction showDesktopReturn(targetUrl: string): void {\n  completedExternalAuthCode = authCodeFromUrl(targetUrl);\n  authForm?.element.setAttribute(\"hidden\", \"\");\n  authenticatedHome?.setAttribute(\"hidden\", \"\");\n  desktopReturn?.removeAttribute(\"hidden\");\n\n  if (desktopReturnLink) {\n    desktopReturnLink.href = targetUrl;\n  }\n\n  if (desktopReturnCodeWrap && desktopReturnCode) {\n    desktopReturnCode.textContent = completedExternalAuthCode;\n    desktopReturnCodeWrap.toggleAttribute(\"hidden\", !completedExternalAuthCode);\n  }\n\n  if (desktopReturnCopy) {\n    desktopReturnCopy.textContent = \"Copy code\";\n  }\n\n  setCopy(\"You're signed in\", \"Return to the desktop app to continue.\");\n}\n\nfunction authCodeFromUrl(value: string): string {\n  try {\n    return new URL(value, window.location.href).searchParams.get(\"auth_code\") || \"\";\n  } catch {\n    return \"\";\n  }\n}\n\nfunction redirectUrl(): string {\n  return body.dataset.redirectUrl || \"\";\n}\n\nfunction appUrl(): string {\n  return body.dataset.appUrl || \"/\";\n}\n\nfunction setCopy(nextTitle: string, nextIntro: string): void {\n  const elements = [title, intro].filter((element): element is HTMLElement => !!element);\n  const hasChanged = title?.textContent !== nextTitle || intro?.textContent !== nextIntro;\n  if (!hasChanged) return;\n\n  const transition = ++copyTransitionSequence;\n  for (const animation of copyAnimations) animation.cancel();\n  copyAnimations = [];\n\n  if (!elements.length || window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches) {\n    if (title) title.textContent = nextTitle;\n    if (intro) intro.textContent = nextIntro;\n    return;\n  }\n\n  copyAnimations = elements.map((element) => element.animate([\n    { opacity: 1, transform: \"translateY(0)\" },\n    { opacity: 0, transform: \"translateY(-4px)\" },\n  ], {\n    duration: COPY_OUT_DURATION,\n    easing: COPY_TRANSITION_EASING,\n    fill: \"both\",\n  }));\n\n  void Promise.allSettled(copyAnimations.map((animation) => animation.finished)).then(() => {\n    if (transition !== copyTransitionSequence) return;\n    for (const animation of copyAnimations) animation.cancel();\n    if (title) title.textContent = nextTitle;\n    if (intro) intro.textContent = nextIntro;\n\n    copyAnimations = elements.map((element) => element.animate([\n      { opacity: 0, transform: \"translateY(5px)\" },\n      { opacity: 1, transform: \"translateY(0)\" },\n    ], {\n      duration: COPY_IN_DURATION,\n      easing: COPY_TRANSITION_EASING,\n      fill: \"both\",\n    }));\n\n    void Promise.allSettled(copyAnimations.map((animation) => animation.finished)).then(() => {\n      if (transition !== copyTransitionSequence) return;\n      for (const animation of copyAnimations) animation.cancel();\n      copyAnimations = [];\n    });\n  });\n}\n"],"mappings":"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"}