import {
  createDefaultEmailAddress,
  createDefaultUser,
  generateClerkId,
  nowUnix,
  userDisplayName
} from "./chunk-WVQMFHQM.js";
import {
  SignJWT,
  exportJWK,
  generateKeyPair
} from "./chunk-D6EKRYGP.js";
import "./chunk-AQ2CLRU3.js";

// ../@emulators/clerk/dist/index.js
import { randomBytes } from "crypto";
import { AsyncLocalStorage } from "async_hooks";
import { readFileSync } from "fs";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
import { timingSafeEqual } from "crypto";
var tenantContext = new AsyncLocalStorage();
function createErrorHandler(documentationUrl) {
  return async (c, next) => {
    if (documentationUrl) {
      c.set("docsUrl", documentationUrl);
    }
    await next();
  };
}
var errorHandler = createErrorHandler();
var isDebug = typeof process !== "undefined" && (process.env.DEBUG === "1" || process.env.DEBUG === "true" || process.env.EMULATE_DEBUG === "1");
var __dirname = dirname(fileURLToPath(import.meta.url));
var FONTS = {
  "geist-sans.woff2": readFileSync(join(__dirname, "fonts", "geist-sans.woff2")),
  "GeistPixel-Square.woff2": readFileSync(join(__dirname, "fonts", "GeistPixel-Square.woff2"))
};
var FAVICON = readFileSync(join(__dirname, "fonts", "favicon.ico"));
var DEFAULT_THEME = {
  slug: "default",
  name: "Emulator",
  scheme: "dark",
  bg: "oklch(0.145 0 0)",
  surface: "oklch(0.205 0 0)",
  border: "oklch(1 0 0 / 10%)",
  text: "oklch(0.985 0 0)",
  muted: "oklch(0.708 0 0)",
  accent: "oklch(0.922 0 0)",
  accentText: "oklch(0.205 0 0)",
  font: "'Geist',-apple-system,BlinkMacSystemFont,sans-serif",
  radius: "0.625rem"
};
var THEMES = {
  google: {
    slug: "google",
    name: "Google",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#dadce0",
    text: "#202124",
    muted: "#5f6368",
    accent: "#1a73e8",
    accentText: "#ffffff",
    font: "'Google Sans',Roboto,Arial,sans-serif",
    radius: "4px"
  },
  microsoft: {
    slug: "microsoft",
    name: "Microsoft",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#d1d1d1",
    text: "#1b1b1b",
    muted: "#605e5c",
    accent: "#0067b8",
    accentText: "#ffffff",
    font: "'Segoe UI',-apple-system,sans-serif",
    radius: "2px"
  },
  apple: {
    slug: "apple",
    name: "Apple",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#d2d2d7",
    text: "#1d1d1f",
    muted: "#6e6e73",
    accent: "#0066cc",
    accentText: "#ffffff",
    font: "-apple-system,'SF Pro Text',Helvetica,sans-serif",
    radius: "12px"
  },
  github: {
    slug: "github",
    name: "GitHub",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#d1d9e0",
    text: "#1f2328",
    muted: "#59636e",
    accent: "#1f883d",
    accentText: "#ffffff",
    font: "-apple-system,'Mona Sans','Segoe UI',Helvetica,sans-serif",
    radius: "6px"
  },
  okta: {
    slug: "okta",
    name: "Okta",
    scheme: "light",
    bg: "#f9f9f9",
    surface: "#ffffff",
    border: "#e1e1e1",
    text: "#1d1d21",
    muted: "#6e6e78",
    accent: "#3f59e4",
    accentText: "#ffffff",
    font: "'Aeonik',-apple-system,sans-serif",
    radius: "4px"
  },
  slack: {
    slug: "slack",
    name: "Slack",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#dddddd",
    text: "#1d1c1d",
    muted: "#616061",
    accent: "#4a154b",
    accentText: "#ffffff",
    font: "Lato,-apple-system,sans-serif",
    radius: "8px"
  },
  salesforce: {
    slug: "salesforce",
    name: "Salesforce",
    scheme: "light",
    bg: "#f4f6f9",
    surface: "#ffffff",
    border: "#c9c9c9",
    text: "#080707",
    muted: "#54698d",
    accent: "#0070d2",
    accentText: "#ffffff",
    font: "'Salesforce Sans',-apple-system,sans-serif",
    radius: "4px"
  },
  workos: {
    slug: "workos",
    name: "WorkOS",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#e4e4e7",
    text: "#18181b",
    muted: "#6b7280",
    accent: "#6363f1",
    accentText: "#ffffff",
    font: "'Inter',-apple-system,sans-serif",
    radius: "8px"
  },
  clerk: {
    slug: "clerk",
    name: "Clerk",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#eeeef0",
    text: "#212126",
    muted: "#747686",
    accent: "#6c47ff",
    accentText: "#ffffff",
    font: "'Inter',-apple-system,sans-serif",
    radius: "8px"
  },
  hubspot: {
    slug: "hubspot",
    name: "HubSpot",
    scheme: "light",
    bg: "#f5f8fa",
    surface: "#ffffff",
    border: "#cbd6e2",
    text: "#33475b",
    muted: "#516f90",
    accent: "#ff7a59",
    accentText: "#ffffff",
    font: "'Lexend Deca',-apple-system,sans-serif",
    radius: "6px"
  },
  stripe: {
    slug: "stripe",
    name: "Stripe",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#e6e6e6",
    text: "#1a1f36",
    muted: "#697386",
    accent: "#635bff",
    accentText: "#ffffff",
    font: "-apple-system,'Helvetica Neue',sans-serif",
    radius: "8px"
  },
  vercel: {
    slug: "vercel",
    name: "Vercel",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#eaeaea",
    text: "#171717",
    muted: "#888888",
    accent: "#171717",
    accentText: "#ffffff",
    font: "'Geist',-apple-system,sans-serif",
    radius: "6px"
  },
  resend: {
    slug: "resend",
    name: "Resend",
    scheme: "dark",
    bg: "#000000",
    surface: "#0c0c0c",
    border: "#262626",
    text: "#fafafa",
    muted: "#a3a3a3",
    accent: "#ffffff",
    accentText: "#000000",
    font: "-apple-system,'Inter',sans-serif",
    radius: "8px"
  },
  nango: {
    slug: "nango",
    name: "Nango",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#e5e7eb",
    text: "#111827",
    muted: "#6b7280",
    accent: "#467df4",
    accentText: "#ffffff",
    font: "'Inter',-apple-system,sans-serif",
    radius: "8px"
  },
  simpro: {
    slug: "simpro",
    name: "Simpro",
    scheme: "light",
    bg: "#ffffff",
    surface: "#ffffff",
    border: "#dde3ea",
    text: "#1f2d3d",
    muted: "#5b6b7b",
    accent: "#0a8a3f",
    accentText: "#ffffff",
    font: "-apple-system,'Open Sans',sans-serif",
    radius: "4px"
  }
};
function getTheme(service) {
  if (!service) return DEFAULT_THEME;
  return THEMES[service.toLowerCase()] ?? DEFAULT_THEME;
}
function themeOverrideCss(theme) {
  if (theme.slug === "default") return "";
  return `
body{background:${theme.bg};color:${theme.text};font-family:${theme.font};}
.emu-bar{background:${theme.scheme === "dark" ? "#000" : "#1b1b1f"};border-bottom-color:rgba(255,255,255,.08);color:#ffd166;}
.emu-bar-title{color:#fff;font-family:${theme.font};}
.emu-bar-links a{color:#bdbdbd;}
.emu-bar-links a:hover{color:#fff;}
.content-inner{background:${theme.surface};border:1px solid ${theme.border};border-radius:${theme.radius};padding:32px 28px;box-shadow:0 1px 3px rgba(0,0,0,.08);}
.card-title{color:${theme.text};font-family:${theme.font};font-weight:600;}
.card-subtitle{color:${theme.muted};}
.user-btn{background:${theme.surface};border:1px solid ${theme.border};color:${theme.text};border-radius:${theme.radius};}
.user-btn:hover{border-color:${theme.accent};background:${theme.scheme === "dark" ? "rgba(255,255,255,.04)" : "rgba(0,0,0,.02)"};}
.avatar{background:${theme.accent};color:${theme.accentText};font-family:${theme.font};}
.user-login{color:${theme.text};}
.user-meta{color:${theme.muted};}
.user-email{color:${theme.muted};opacity:.8;}
.powered-by{color:${theme.muted};}
.powered-by a{color:${theme.accent};}
.error-title{font-family:${theme.font};}
.error-msg{color:${theme.muted};}
`.trim();
}
var google = `<svg viewBox="0 0 48 48" width="42" height="42" aria-hidden="true"><path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/><path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/><path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"/><path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/></svg>`;
var microsoft = `<svg viewBox="0 0 23 23" width="36" height="36" aria-hidden="true"><path fill="#f25022" d="M1 1h10v10H1z"/><path fill="#7fba00" d="M12 1h10v10H12z"/><path fill="#00a4ef" d="M1 12h10v10H1z"/><path fill="#ffb900" d="M12 12h10v10H12z"/></svg>`;
var apple = `<svg viewBox="0 0 24 24" width="40" height="40" fill="#000" aria-hidden="true"><path d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"/></svg>`;
var github = `<svg viewBox="0 0 24 24" width="40" height="40" fill="#1f2328" aria-hidden="true"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>`;
var okta = `<svg viewBox="0 0 24 24" width="38" height="38" fill="#00297a" aria-hidden="true"><path d="M12 0C5.385 0 0 5.385 0 12s5.385 12 12 12 12-5.385 12-12S18.615 0 12 0zm0 18c-3.309 0-6-2.691-6-6s2.691-6 6-6 6 2.691 6 6-2.691 6-6 6z"/></svg>`;
var slack = `<svg viewBox="0 0 122.8 122.8" width="36" height="36" aria-hidden="true"><path d="M25.8 77.6c0 7.1-5.8 12.9-12.9 12.9S0 84.7 0 77.6s5.8-12.9 12.9-12.9h12.9v12.9zm6.5 0c0-7.1 5.8-12.9 12.9-12.9s12.9 5.8 12.9 12.9v32.3c0 7.1-5.8 12.9-12.9 12.9s-12.9-5.8-12.9-12.9V77.6z" fill="#36C5F0"/><path d="M45.2 25.8c-7.1 0-12.9-5.8-12.9-12.9S38.1 0 45.2 0s12.9 5.8 12.9 12.9v12.9H45.2zm0 6.5c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9H12.9C5.8 58.1 0 52.3 0 45.2s5.8-12.9 12.9-12.9h32.3z" fill="#2EB67D"/><path d="M97 45.2c0-7.1 5.8-12.9 12.9-12.9s12.9 5.8 12.9 12.9-5.8 12.9-12.9 12.9H97V45.2zm-6.5 0c0 7.1-5.8 12.9-12.9 12.9s-12.9-5.8-12.9-12.9V12.9C64.7 5.8 70.5 0 77.6 0s12.9 5.8 12.9 12.9v32.3z" fill="#ECB22E"/><path d="M77.6 97c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9-12.9-5.8-12.9-12.9V97h12.9zm0-6.5c-7.1 0-12.9-5.8-12.9-12.9s5.8-12.9 12.9-12.9h32.3c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9H77.6z" fill="#E01E5A"/></svg>`;
var salesforce = `<svg viewBox="0 0 24 24" width="46" height="46" fill="#00A1E0" aria-hidden="true"><path d="M9.9 6.2c.72-.78 1.79-1.3 2.96-1.3 1.55 0 2.92.86 3.64 2.16.62-.28 1.31-.43 2.03-.43 2.3 0 4.17 1.88 4.17 4.2s-1.87 4.2-4.17 4.2c-.28 0-.56-.03-.83-.08-.62 1.11-1.81 1.86-3.17 1.86-.5 0-.98-.1-1.42-.29-.63 1.4-2.03 2.38-3.66 2.38-1.66 0-3.1-1.01-3.71-2.46-.23.05-.47.07-.71.07C1.55 16.61 0 15.04 0 13.11c0-1.29.69-2.42 1.72-3.04-.13-.39-.2-.81-.2-1.24 0-2.2 1.79-3.99 4-3.99 1.29 0 2.45.62 3.18 1.57.04-.07.08-.14.2-.21z"/></svg>`;
var hubspot = `<svg viewBox="0 0 24 24" width="40" height="40" fill="#FF7A59" aria-hidden="true"><path d="M18 7.32V5.13a1.74 1.74 0 1 0-1.16 0v2.19a5.05 5.05 0 0 0-2.4.98L7.97 3.43a1.95 1.95 0 1 0-.92 1.21l6.32 4.91a5.06 5.06 0 0 0 .08 5.71l-1.92 1.92a1.63 1.63 0 0 0-.47-.07 1.65 1.65 0 1 0 1.65 1.65 1.63 1.63 0 0 0-.07-.47l1.9-1.9a5.06 5.06 0 1 0 3.46-9.07zm-1.55 7.6a2.64 2.64 0 1 1 2.64-2.64 2.64 2.64 0 0 1-2.64 2.64z"/></svg>`;
var vercel = `<svg viewBox="0 0 24 24" width="34" height="34" fill="#000" aria-hidden="true"><path d="M12 2 24 22H0z"/></svg>`;
var clerk = `<svg viewBox="0 0 40 40" width="40" height="40" aria-hidden="true"><rect width="40" height="40" rx="9" fill="#6C47FF"/><circle cx="20" cy="16.5" r="4.2" fill="#fff"/><path d="M13 28a7.6 7.6 0 0 1 14 0z" fill="#fff"/></svg>`;
var workos = `<svg viewBox="0 0 40 40" width="40" height="40" aria-hidden="true"><rect width="40" height="40" rx="9" fill="#6363F1"/><path d="M10 14l3 12 3-9 3 9 3-12" fill="none" stroke="#fff" stroke-width="2.2" stroke-linejoin="round" stroke-linecap="round"/><path d="M25 20a4.5 4.5 0 1 0 4.5 4.5" fill="none" stroke="#fff" stroke-width="2.2" stroke-linecap="round"/></svg>`;
var LOGOS = {
  google,
  microsoft,
  apple,
  github,
  okta,
  slack,
  salesforce,
  hubspot,
  vercel,
  clerk,
  workos
};
function getLogo(service) {
  if (!service) return null;
  return LOGOS[service.toLowerCase()] ?? null;
}
function escapeHtml(s) {
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
}
function escapeAttr(s) {
  return escapeHtml(s).replace(/'/g, "&#39;");
}
var CSS = `
@font-face{
  font-family:'Geist';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('/_emulate/fonts/geist-sans.woff2') format('woff2');
}
:root{
  color-scheme:dark;
  /* ElevenLabs UI \u2014 neutral dark (OKLCH). Values already avoid pure #000/#fff. */
  --bg:oklch(0.145 0 0);
  --fg:oklch(0.985 0 0);
  --card:oklch(0.205 0 0);
  --elevated:oklch(0.269 0 0);
  --muted:oklch(0.269 0 0);
  --muted-fg:oklch(0.708 0 0);
  --faint-fg:oklch(0.556 0 0);
  --border:oklch(1 0 0 / 10%);
  --border-strong:oklch(1 0 0 / 16%);
  --ring:oklch(0.556 0 0);
  --primary:oklch(0.922 0 0);
  --primary-fg:oklch(0.205 0 0);
  --danger:oklch(0.704 0.191 22.216);
  --radius:0.625rem;
  --radius-sm:0.375rem;
  --radius-lg:0.875rem;
  --radius-pill:999px;
  --space-xs:0.25rem;--space-sm:0.5rem;--space-md:0.75rem;
  --space-lg:1rem;--space-xl:1.5rem;--space-2xl:2rem;--space-3xl:3rem;
  --text-xs:0.75rem;--text-sm:0.8125rem;--text-md:0.875rem;
  --text-base:1rem;--text-lg:1.25rem;--text-xl:1.5rem;
  --font-sans:'Geist',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --font-mono:ui-monospace,'SF Mono',SFMono-Regular,Menlo,Consolas,monospace;
}
*{box-sizing:border-box;margin:0;padding:0}
body{
  font-family:var(--font-sans);font-size:var(--text-md);line-height:1.55;
  background:var(--bg);color:var(--fg);min-height:100vh;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
}
::selection{background:var(--primary);color:var(--primary-fg);}

.emu-bar{
  border-bottom:1px solid var(--border);padding:var(--space-md) var(--space-xl);
  display:flex;align-items:center;gap:var(--space-md);
  font-size:var(--text-sm);color:var(--muted-fg);
}
.emu-bar-title{font-weight:600;color:var(--fg);letter-spacing:-0.01em;}
.emu-badge{
  display:inline-flex;align-items:center;gap:var(--space-xs);
  font-size:var(--text-xs);font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  padding:3px 10px;border-radius:var(--radius-pill);
  background:var(--primary);color:var(--primary-fg);
  white-space:nowrap;flex-shrink:0;
}
.emu-badge::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor;}
.emu-watermark{
  position:fixed;bottom:var(--space-lg);right:var(--space-lg);z-index:9999;pointer-events:none;
  font-size:var(--text-xs);font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  padding:5px 11px;border-radius:var(--radius-sm);
  background:color-mix(in oklch,var(--bg) 72%,transparent);
  color:var(--muted-fg);border:1px solid var(--border-strong);
  backdrop-filter:blur(6px);
}
.emu-bar-links{margin-left:auto;display:flex;gap:var(--space-xl);}
.emu-bar-links a{
  color:var(--muted-fg);font-size:var(--text-sm);text-decoration:none;transition:color .15s;
}
.emu-bar-links a:hover{color:var(--fg);}
.emu-bar-links a .full{display:inline;}
.emu-bar-links a .short{display:none;}
@media(max-width:600px){
  .emu-bar-links a .full{display:none;}
  .emu-bar-links a .short{display:inline;}
}

.content{
  display:flex;align-items:center;justify-content:center;
  min-height:calc(100vh - 50px);padding:var(--space-2xl) var(--space-lg);
}
.content-inner{width:100%;max-width:420px;}
.brand-logo{display:flex;justify-content:center;margin-bottom:var(--space-xl);}
.brand-logo svg{display:block;}
.card-branded{text-align:center;}
.card-branded .card-title{text-align:center;}
.card-branded .card-subtitle{text-align:center;}
.card-branded .user-form{text-align:left;}
.card-title{
  font-size:var(--text-lg);font-weight:600;letter-spacing:-0.02em;
  margin-bottom:var(--space-xs);color:var(--fg);
}
.card-subtitle{color:var(--muted-fg);font-size:var(--text-sm);margin-bottom:var(--space-xl);line-height:1.5;}
.powered-by{
  position:fixed;bottom:0;left:0;right:0;
  text-align:center;padding:var(--space-md);font-size:var(--text-xs);color:var(--faint-fg);
}
.powered-by a{color:var(--muted-fg);text-decoration:none;transition:color .15s;}
.powered-by a:hover{color:var(--fg);}

.error-title{color:var(--danger);font-size:var(--text-lg);font-weight:600;margin-bottom:var(--space-sm);letter-spacing:-0.01em;}
.error-msg{color:var(--muted-fg);font-size:var(--text-md);line-height:1.5;}
.error-card{text-align:center;}

.user-form{margin-bottom:var(--space-sm);}
.user-form:last-of-type{margin-bottom:0;}
.user-btn{
  width:100%;display:flex;align-items:center;gap:var(--space-md);
  padding:var(--space-md);border:1px solid var(--border);border-radius:var(--radius);
  background:var(--card);color:inherit;cursor:pointer;text-align:left;
  font:inherit;transition:border-color .15s,background .15s;
}
.user-btn:hover{border-color:var(--border-strong);background:var(--elevated);}
.avatar{
  width:36px;height:36px;border-radius:50%;
  background:var(--elevated);color:var(--fg);font-weight:600;font-size:var(--text-md);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
}
.user-text{min-width:0;}
.user-login{font-weight:600;font-size:var(--text-md);display:block;color:var(--fg);}
.user-meta{color:var(--muted-fg);font-size:var(--text-xs);margin-top:1px;}
.user-email{font-size:var(--text-xs);color:var(--faint-fg);word-break:break-all;margin-top:1px;}

.settings-layout{
  max-width:920px;margin:0 auto;padding:var(--space-3xl) var(--space-xl);
  display:flex;gap:var(--space-3xl);
}
.settings-sidebar{width:200px;flex-shrink:0;}
.settings-sidebar a{
  display:block;padding:6px 10px;border-radius:var(--radius-sm);color:var(--muted-fg);
  text-decoration:none;font-size:var(--text-sm);transition:color .15s,background .15s;
}
.settings-sidebar a:hover{color:var(--fg);background:var(--muted);}
.settings-sidebar a.active{color:var(--fg);font-weight:600;background:var(--muted);}
.settings-main{flex:1;min-width:0;}

.s-card{
  padding:var(--space-xl) 0;margin-bottom:var(--space-lg);border-bottom:1px solid var(--border);
}
.s-card:last-child{border-bottom:none;}
.s-card-header{display:flex;align-items:center;gap:var(--space-md);margin-bottom:var(--space-lg);}
.s-icon{
  width:40px;height:40px;border-radius:var(--radius);
  background:var(--elevated);display:flex;align-items:center;justify-content:center;
  font-size:var(--text-base);font-weight:600;color:var(--muted-fg);flex-shrink:0;
}
.s-title{font-size:var(--text-lg);font-weight:600;color:var(--fg);letter-spacing:-0.01em;}
.s-subtitle{font-size:var(--text-xs);color:var(--muted-fg);margin-top:2px;}
.section-heading{
  font-size:var(--text-md);font-weight:600;margin-bottom:var(--space-md);color:var(--fg);
  display:flex;align-items:center;justify-content:space-between;
}
.perm-list{list-style:none;}
.perm-list li{padding:5px 0;font-size:var(--text-sm);display:flex;align-items:center;gap:var(--space-sm);color:var(--muted-fg);}
.check{color:var(--fg);}
.org-row{
  display:flex;align-items:center;gap:var(--space-sm);padding:7px 0;
  border-bottom:1px solid var(--border);font-size:var(--text-sm);
}
.org-row:last-child{border-bottom:none;}
.org-icon{
  width:22px;height:22px;border-radius:var(--radius-sm);background:var(--elevated);
  display:flex;align-items:center;justify-content:center;
  font-size:var(--text-xs);font-weight:600;color:var(--muted-fg);flex-shrink:0;
}
.org-name{font-weight:600;color:var(--fg);}
.badge{
  font-size:var(--text-xs);padding:2px 8px;border-radius:var(--radius-sm);font-weight:500;
  background:var(--muted);color:var(--muted-fg);border:1px solid var(--border);
}
.badge-granted{background:var(--elevated);color:var(--fg);}
.badge-denied{background:color-mix(in oklch,var(--danger) 18%,var(--bg));color:var(--danger);border-color:color-mix(in oklch,var(--danger) 30%,transparent);}
.badge-requested{background:var(--muted);color:var(--muted-fg);}
.btn-revoke{
  display:inline-block;padding:5px 14px;border-radius:var(--radius-sm);
  border:1px solid var(--border);background:transparent;color:var(--danger);
  font-size:var(--text-xs);font-weight:600;cursor:pointer;transition:border-color .15s;
}
.btn-revoke:hover{border-color:var(--danger);}
.info-text{color:var(--muted-fg);font-size:var(--text-xs);line-height:1.5;margin-top:var(--space-md);}
.app-link{
  display:flex;align-items:center;gap:var(--space-md);padding:var(--space-md);
  border:1px solid var(--border);border-radius:var(--radius);background:var(--card);
  text-decoration:none;color:inherit;margin-bottom:var(--space-sm);transition:border-color .15s,background .15s;
}
.app-link:hover{border-color:var(--border-strong);background:var(--elevated);}
.app-link-name{font-weight:600;font-size:var(--text-md);color:var(--fg);}
.app-link-scopes{font-size:var(--text-xs);color:var(--muted-fg);margin-top:1px;}
.empty{color:var(--muted-fg);text-align:center;padding:var(--space-3xl) 0;font-size:var(--text-md);}

.inspector-layout{max-width:960px;margin:0 auto;padding:var(--space-3xl) var(--space-xl);}
.inspector-tabs{
  display:flex;flex-wrap:wrap;gap:var(--space-xs);margin-bottom:var(--space-2xl);
  padding:var(--space-xs);background:var(--card);border:1px solid var(--border);
  border-radius:var(--radius);width:fit-content;max-width:100%;
}
.inspector-tabs a{
  padding:6px 14px;border-radius:var(--radius-sm);text-decoration:none;
  font-size:var(--text-sm);color:var(--muted-fg);transition:color .15s,background .15s;
}
.inspector-tabs a:hover{color:var(--fg);}
.inspector-tabs a.active{color:var(--fg);font-weight:600;background:var(--elevated);}
.inspector-section{margin-bottom:var(--space-2xl);}
.inspector-section h2{
  font-size:var(--text-lg);font-weight:600;color:var(--fg);
  margin-bottom:var(--space-md);letter-spacing:-0.01em;
}
.inspector-section h3{
  font-size:var(--text-md);font-weight:600;color:var(--muted-fg);
  margin:var(--space-xl) 0 var(--space-sm);
}
.inspector-table{width:100%;border-collapse:collapse;margin-bottom:var(--space-md);}
.inspector-table th,.inspector-table td{
  text-align:left;padding:var(--space-sm) var(--space-md);border-bottom:1px solid var(--border);
  font-size:var(--text-sm);
}
.inspector-table th{color:var(--faint-fg);font-weight:600;font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.06em;}
.inspector-table td{color:var(--fg);}
.inspector-table tbody tr{transition:background .12s;}
.inspector-table tbody tr:hover{background:var(--card);}
.inspector-empty{color:var(--muted-fg);text-align:center;padding:var(--space-xl) 0;font-size:var(--text-sm);}

/* Live activity feed (renderActivityCard) \u2014 token-driven so it stays cohesive
   with the dark control plane instead of the old hard-coded light values. */
.act-pulse{
  width:9px;height:9px;border-radius:50%;background:var(--fg);flex-shrink:0;
  position:relative;
}
.act-pulse::after{
  content:"";position:absolute;inset:-4px;border-radius:50%;
  border:1px solid var(--fg);opacity:.5;animation:act-ping 1.8s ease-out infinite;
}
@keyframes act-ping{0%{transform:scale(.6);opacity:.5}80%,100%{transform:scale(1.6);opacity:0}}
@media(prefers-reduced-motion:reduce){.act-pulse::after{animation:none;}}
.act-status.is-live{color:var(--fg);}
.act-status.is-error{color:var(--danger);}
.act-mono{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--muted-fg);white-space:nowrap;}
.act-fields{font-size:var(--text-xs);color:var(--muted-fg);}
.act-json-btn{
  font:inherit;font-size:var(--text-xs);padding:2px 9px;border:1px solid var(--border);
  border-radius:var(--radius-sm);background:transparent;color:var(--muted-fg);
  cursor:pointer;transition:border-color .15s,color .15s;
}
.act-json-btn:hover{border-color:var(--border-strong);color:var(--fg);}
.act-detail-cell{background:var(--card);padding:var(--space-sm) var(--space-md);}
.act-detail-cell pre{
  margin:0;font-family:var(--font-mono);font-size:var(--text-xs);line-height:1.5;
  color:var(--muted-fg);white-space:pre-wrap;word-break:break-word;max-height:300px;overflow:auto;
}
.inspector-table tbody tr.act-row-new td{background:color-mix(in oklch,var(--elevated) 80%,transparent);transition:background .9s;}

.checkout-layout{display:flex;min-height:calc(100vh - 50px);}
.checkout-summary{
  flex:1;background:var(--card);padding:var(--space-3xl) var(--space-2xl) var(--space-3xl) 10%;
  display:flex;flex-direction:column;justify-content:center;border-right:1px solid var(--border);
}
.checkout-form-side{
  flex:1;background:var(--bg);padding:var(--space-3xl) 10% var(--space-3xl) var(--space-2xl);
  display:flex;flex-direction:column;justify-content:center;
}
.checkout-merchant{display:flex;align-items:center;gap:var(--space-md);margin-bottom:6px;}
.checkout-merchant-name{font-size:var(--text-md);font-weight:600;color:var(--fg);}
.checkout-test-badge{
  font-size:var(--text-xs);font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  background:var(--muted);color:var(--muted-fg);padding:2px 8px;border-radius:var(--radius-sm);
}
.checkout-total{font-size:var(--text-xl);font-weight:700;color:var(--fg);margin:var(--space-sm) 0 var(--space-2xl);letter-spacing:-0.02em;}
.checkout-line-item{display:flex;align-items:center;gap:var(--space-md);padding:var(--space-lg) 0;border-bottom:1px solid var(--border);}
.checkout-line-item:first-child{border-top:1px solid var(--border);}
.checkout-item-icon{
  width:40px;height:40px;border-radius:var(--radius-sm);background:var(--elevated);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
  font-size:var(--text-md);font-weight:600;color:var(--muted-fg);
}
.checkout-item-details{flex:1;min-width:0;}
.checkout-item-name{font-size:var(--text-md);font-weight:600;color:var(--fg);}
.checkout-item-qty{font-size:var(--text-xs);color:var(--muted-fg);margin-top:2px;}
.checkout-item-price{font-size:var(--text-md);font-weight:600;color:var(--fg);text-align:right;white-space:nowrap;}
.checkout-item-unit{font-size:var(--text-xs);color:var(--muted-fg);text-align:right;margin-top:2px;}
.checkout-totals{margin-top:var(--space-xl);}
.checkout-totals-row{display:flex;justify-content:space-between;padding:6px 0;font-size:var(--text-sm);color:var(--muted-fg);}
.checkout-totals-row.total{border-top:1px solid var(--border);margin-top:var(--space-sm);padding-top:var(--space-lg);font-size:var(--text-md);font-weight:600;color:var(--fg);}
.checkout-form-section{margin-bottom:var(--space-xl);}
.checkout-form-label{font-size:var(--text-sm);font-weight:600;color:var(--fg);margin-bottom:var(--space-sm);display:block;}
.checkout-input{
  width:100%;padding:var(--space-md);border:1px solid var(--border);border-radius:var(--radius-sm);
  background:var(--card);color:var(--fg);font:inherit;font-size:var(--text-md);
  transition:border-color .15s;outline:none;
}
.checkout-input:focus{border-color:var(--ring);}
.checkout-input::placeholder{color:var(--faint-fg);}
.checkout-card-box{border:1px solid var(--border);border-radius:var(--radius-sm);padding:var(--space-lg);background:var(--card);}
.checkout-card-row{display:flex;gap:var(--space-md);margin-top:var(--space-md);}
.checkout-card-row .checkout-input{flex:1;}
.checkout-sim-note{font-size:var(--text-xs);color:var(--muted-fg);margin-top:var(--space-md);text-align:center;font-style:italic;}
.checkout-pay-btn{
  width:100%;padding:var(--space-lg);border:none;border-radius:var(--radius);
  background:var(--primary);color:var(--primary-fg);font:inherit;font-size:var(--text-md);font-weight:600;
  cursor:pointer;transition:opacity .15s;
}
.checkout-pay-btn:hover{opacity:.9;}
.checkout-cancel{text-align:center;margin-top:var(--space-lg);}
.checkout-cancel a{color:var(--muted-fg);text-decoration:none;font-size:var(--text-sm);transition:color .15s;}
.checkout-cancel a:hover{color:var(--fg);}
@media(max-width:768px){
  .checkout-layout{flex-direction:column;}
  .checkout-summary{padding:var(--space-2xl) var(--space-xl);border-right:none;border-bottom:1px solid var(--border);}
  .checkout-form-side{padding:var(--space-2xl) var(--space-xl);}
}
`;
var POWERED_BY = `<div class="powered-by">Powered by <a href="https://github.com/Vinniai/agent-emulate#readme" target="_blank" rel="noopener">agent-emulate</a></div>`;
var WATERMARK = `<div class="emu-watermark" aria-hidden="true">agent-emulate</div>`;
function emuBar(service) {
  const title = service ? `${escapeHtml(service)} Emulator` : "Emulator";
  return `<div class="emu-bar">
  <span class="emu-bar-title">${title}</span>
  <span class="emu-badge" title="This is a local emulator, not the real provider">Emulated</span>
  <nav class="emu-bar-links">
    <a href="https://github.com/Vinniai/agent-emulate/issues" target="_blank" rel="noopener"><span class="full">Report Issue</span><span class="short">Report</span></a>
    <a href="https://github.com/Vinniai/agent-emulate" target="_blank" rel="noopener"><span class="full">Source Code</span><span class="short">Source</span></a>
    <a href="https://github.com/Vinniai/agent-emulate#readme" target="_blank" rel="noopener"><span class="full">Learn More</span><span class="short">Learn</span></a>
  </nav>
</div>`;
}
function head(title, service) {
  const themeCss = themeOverrideCss(getTheme(service));
  const themeStyle = themeCss ? `<style>${themeCss}</style>` : "";
  return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<link rel="icon" href="/_emulate/favicon.ico"/>
<title>${escapeHtml(title)} | agent-emulate</title>
<style>${CSS}</style>${themeStyle}
</head>`;
}
function renderCardPage(title, subtitle, body, service) {
  const logo = getLogo(service);
  const logoHtml = logo ? `<div class="brand-logo">${logo}</div>` : "";
  return `${head(title, service)}
<body>
${emuBar(service)}
<div class="content">
  <div class="content-inner${logo ? " card-branded" : ""}">
    ${logoHtml}
    <div class="card-title">${escapeHtml(title)}</div>
    <div class="card-subtitle">${subtitle}</div>
    ${body}
  </div>
</div>
${POWERED_BY}
${WATERMARK}
</body></html>`;
}
function renderErrorPage(title, message, service) {
  const logo = getLogo(service);
  const logoHtml = logo ? `<div class="brand-logo">${logo}</div>` : "";
  return `${head(title, service)}
<body>
${emuBar(service)}
<div class="content">
  <div class="content-inner error-card">
    ${logoHtml}
    <div class="error-title">${escapeHtml(title)}</div>
    <div class="error-msg">${escapeHtml(message)}</div>
  </div>
</div>
${POWERED_BY}
${WATERMARK}
</body></html>`;
}
function renderUserButton(opts) {
  const hiddens = Object.entries(opts.hiddenFields).map(([k, v]) => `<input type="hidden" name="${escapeAttr(k)}" value="${escapeAttr(v)}"/>`).join("");
  const nameLine = opts.name ? `<div class="user-meta">${escapeHtml(opts.name)}</div>` : "";
  const emailLine = opts.email ? `<div class="user-email">${escapeHtml(opts.email)}</div>` : "";
  return `<form class="user-form" method="post" action="${escapeAttr(opts.formAction)}">
${hiddens}
<button type="submit" class="user-btn">
  <span class="avatar">${escapeHtml(opts.letter)}</span>
  <span class="user-text">
    <span class="user-login">${escapeHtml(opts.login)}</span>
    ${nameLine}${emailLine}
  </span>
</button>
</form>`;
}
function normalizeUri(uri) {
  try {
    const u = new URL(uri);
    return `${u.origin}${u.pathname.replace(/\/+$/, "")}`;
  } catch {
    return uri.replace(/\/+$/, "").split("?")[0];
  }
}
function matchesRedirectUri(incoming, registered) {
  const normalized = normalizeUri(incoming);
  return registered.some((r) => normalizeUri(r) === normalized);
}
function constantTimeSecretEqual(a, b) {
  const bufA = Buffer.from(a, "utf-8");
  const bufB = Buffer.from(b, "utf-8");
  if (bufA.length !== bufB.length) return false;
  return timingSafeEqual(bufA, bufB);
}
function bodyStr(v) {
  if (typeof v === "string") return v;
  if (Array.isArray(v) && typeof v[0] === "string") return v[0];
  return "";
}
var RING_SIZE = 200;
var ActivityBus = class {
  buffer = [];
  subscribers = /* @__PURE__ */ new Set();
  publish(event) {
    this.buffer.push(event);
    if (this.buffer.length > RING_SIZE) this.buffer.splice(0, this.buffer.length - RING_SIZE);
    for (const cb of this.subscribers) {
      try {
        cb(event);
      } catch {
      }
    }
  }
  subscribe(cb) {
    this.subscribers.add(cb);
    return () => this.subscribers.delete(cb);
  }
  recent(limit = 50, service) {
    const filtered = service ? this.buffer.filter((e) => e.service === service) : this.buffer;
    return filtered.slice(-limit).reverse();
  }
};
var activityBus = globalThis.__emulate_activity_bus__ ?? (globalThis.__emulate_activity_bus__ = new ActivityBus());
function getClerkStore(store) {
  return {
    users: store.collection("clerk.users", ["clerk_id", "username"]),
    emailAddresses: store.collection("clerk.emails", ["email_id", "user_id", "email_address"]),
    organizations: store.collection("clerk.orgs", ["clerk_id", "slug"]),
    memberships: store.collection("clerk.memberships", [
      "membership_id",
      "org_id",
      "user_id"
    ]),
    invitations: store.collection("clerk.invitations", ["invitation_id", "org_id"]),
    sessions: store.collection("clerk.sessions", ["clerk_id", "user_id"]),
    oauthApps: store.collection("clerk.oauth_apps", ["app_id", "client_id"])
  };
}
var keyPairPromise = generateKeyPair("RS256");
var KID = "emulate-clerk-1";
var CODE_TTL_MS = 10 * 60 * 1e3;
function getPendingCodes(store) {
  let map = store.getData("clerk.oauth.pendingCodes");
  if (!map) {
    map = /* @__PURE__ */ new Map();
    store.setData("clerk.oauth.pendingCodes", map);
  }
  return map;
}
function isCodeExpired(code) {
  return Date.now() - code.createdAt > CODE_TTL_MS;
}
async function createSessionToken(store, user, sessionId, baseUrl, orgId, orgRole, orgSlug, orgPermissions) {
  const { privateKey } = await keyPairPromise;
  const now = Math.floor(Date.now() / 1e3);
  const claims = {
    sid: sessionId
  };
  if (orgId) {
    claims.org_id = orgId;
    claims.org_role = orgRole ?? "org:member";
    claims.org_slug = orgSlug;
    claims.org_permissions = orgPermissions ?? [];
  }
  if (Object.keys(user.public_metadata).length > 0) {
    claims.metadata = user.public_metadata;
  }
  return new SignJWT(claims).setProtectedHeader({ alg: "RS256", kid: KID, typ: "JWT" }).setIssuer(baseUrl).setSubject(user.clerk_id).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").sign(privateKey);
}
function oauthRoutes({ app, store, baseUrl, tokenMap }) {
  const clerkStore = getClerkStore(store);
  const SERVICE_LABEL = "Clerk";
  app.get("/.well-known/openid-configuration", (c) => {
    return c.json({
      issuer: baseUrl,
      authorization_endpoint: `${baseUrl}/oauth/authorize`,
      token_endpoint: `${baseUrl}/oauth/token`,
      userinfo_endpoint: `${baseUrl}/oauth/userinfo`,
      jwks_uri: `${baseUrl}/v1/jwks`,
      response_types_supported: ["code"],
      subject_types_supported: ["public"],
      id_token_signing_alg_values_supported: ["RS256"],
      scopes_supported: ["openid", "profile", "email"],
      token_endpoint_auth_methods_supported: ["client_secret_post", "client_secret_basic"],
      claims_supported: [
        "sub",
        "iss",
        "aud",
        "exp",
        "iat",
        "nbf",
        "azp",
        "sid",
        "org_id",
        "org_role",
        "org_slug",
        "org_permissions"
      ],
      code_challenge_methods_supported: ["plain", "S256"]
    });
  });
  app.get("/v1/jwks", async (c) => {
    const { publicKey } = await keyPairPromise;
    const jwk = await exportJWK(publicKey);
    return c.json({
      keys: [{ ...jwk, kid: KID, use: "sig", alg: "RS256" }]
    });
  });
  app.get("/oauth/authorize", (c) => {
    const clientId = c.req.query("client_id") ?? "";
    const redirectUri = c.req.query("redirect_uri") ?? "";
    const scope = c.req.query("scope") ?? "openid profile email";
    const state = c.req.query("state") ?? "";
    const nonce = c.req.query("nonce") ?? "";
    const responseType = c.req.query("response_type") ?? "code";
    const codeChallenge = c.req.query("code_challenge") ?? "";
    const codeChallengeMethod = c.req.query("code_challenge_method") ?? "";
    if (responseType !== "code") {
      return c.html(
        renderErrorPage("Unsupported response_type", "Only response_type=code is supported.", SERVICE_LABEL),
        400
      );
    }
    if (!redirectUri) {
      return c.html(
        renderErrorPage("Missing redirect URI", "The redirect_uri parameter is required.", SERVICE_LABEL),
        400
      );
    }
    const oauthApps = clerkStore.oauthApps.all();
    let appName = "";
    if (oauthApps.length > 0) {
      const oauthApp = oauthApps.find((a) => a.client_id === clientId);
      if (!oauthApp) {
        return c.html(
          renderErrorPage("Application not found", `The client_id '${clientId}' is not registered.`, SERVICE_LABEL),
          400
        );
      }
      if (!matchesRedirectUri(redirectUri, oauthApp.redirect_uris)) {
        return c.html(
          renderErrorPage(
            "Redirect URI mismatch",
            "The redirect_uri is not registered for this application.",
            SERVICE_LABEL
          ),
          400
        );
      }
      appName = oauthApp.name;
    }
    const users = clerkStore.users.all();
    const buttons = users.map((user) => {
      const emails = clerkStore.emailAddresses.findBy("user_id", user.clerk_id);
      const primaryEmail = emails.find((e) => e.is_primary) ?? emails[0];
      return renderUserButton({
        letter: ((user.first_name ?? user.username ?? "?")[0] ?? "?").toUpperCase(),
        login: primaryEmail?.email_address ?? user.username ?? user.clerk_id,
        name: userDisplayName(user),
        email: primaryEmail?.email_address ?? "",
        formAction: "/oauth/authorize/callback",
        hiddenFields: {
          user_ref: user.clerk_id,
          redirect_uri: redirectUri,
          scope,
          state,
          nonce,
          client_id: clientId,
          code_challenge: codeChallenge,
          code_challenge_method: codeChallengeMethod
        }
      });
    }).join("\n");
    const subtitle = appName ? `Sign in to <strong>${escapeHtml(appName)}</strong> with your Clerk account.` : "Choose a seeded user to continue.";
    return c.html(
      renderCardPage(
        "Sign in with Clerk",
        subtitle,
        users.length > 0 ? buttons : '<p class="empty">No users in the emulator store.</p>',
        SERVICE_LABEL
      )
    );
  });
  app.post("/oauth/authorize/callback", async (c) => {
    const body = await c.req.parseBody();
    const userRef = bodyStr(body.user_ref);
    const redirectUri = bodyStr(body.redirect_uri);
    const scope = bodyStr(body.scope) || "openid profile email";
    const state = bodyStr(body.state);
    const nonce = bodyStr(body.nonce);
    const clientId = bodyStr(body.client_id);
    const codeChallenge = bodyStr(body.code_challenge);
    const codeChallengeMethod = bodyStr(body.code_challenge_method);
    if (!redirectUri) {
      return c.html(
        renderErrorPage("Missing redirect URI", "The redirect_uri parameter is required.", SERVICE_LABEL),
        400
      );
    }
    const user = clerkStore.users.findOneBy("clerk_id", userRef);
    if (!user) {
      return c.html(renderErrorPage("Unknown user", "The selected user is not available.", SERVICE_LABEL), 400);
    }
    const oauthApps = clerkStore.oauthApps.all();
    if (oauthApps.length > 0) {
      const oauthApp = oauthApps.find((a) => a.client_id === clientId);
      if (!oauthApp) {
        return c.html(
          renderErrorPage("Application not found", `The client_id '${clientId}' is not registered.`, SERVICE_LABEL),
          400
        );
      }
      if (!matchesRedirectUri(redirectUri, oauthApp.redirect_uris)) {
        return c.html(
          renderErrorPage(
            "Redirect URI mismatch",
            "The redirect_uri is not registered for this application.",
            SERVICE_LABEL
          ),
          400
        );
      }
    }
    const code = randomBytes(20).toString("hex");
    getPendingCodes(store).set(code, {
      userClerkId: user.clerk_id,
      scope,
      redirectUri,
      clientId,
      nonce: nonce || null,
      codeChallenge: codeChallenge || null,
      codeChallengeMethod: codeChallengeMethod || null,
      createdAt: Date.now()
    });
    const url = new URL(redirectUri);
    url.searchParams.set("code", code);
    if (state) url.searchParams.set("state", state);
    return c.redirect(url.toString(), 302);
  });
  app.post("/oauth/token", async (c) => {
    const contentType = c.req.header("Content-Type") ?? "";
    let body = {};
    if (contentType.includes("application/json")) {
      try {
        const parsed = await c.req.json();
        for (const [key, value] of Object.entries(parsed)) {
          if (typeof value === "string") body[key] = value;
        }
      } catch {
        body = {};
      }
    } else {
      const raw = await c.req.text();
      body = Object.fromEntries(new URLSearchParams(raw));
    }
    const grantType = body.grant_type ?? "";
    const code = body.code ?? "";
    const redirectUri = body.redirect_uri ?? "";
    const codeVerifier = body.code_verifier;
    let clientId = body.client_id ?? "";
    let clientSecret = body.client_secret ?? "";
    const authHeader = c.req.header("Authorization") ?? "";
    if (authHeader.startsWith("Basic ")) {
      const decoded = Buffer.from(authHeader.slice(6), "base64").toString("utf8");
      const sep = decoded.indexOf(":");
      if (sep !== -1) {
        if (!clientId) clientId = decodeURIComponent(decoded.slice(0, sep));
        if (!clientSecret) clientSecret = decodeURIComponent(decoded.slice(sep + 1));
      }
    }
    if (grantType !== "authorization_code") {
      return c.json(
        { error: "unsupported_grant_type", error_description: "Only authorization_code is supported." },
        400
      );
    }
    const pending = getPendingCodes(store).get(code);
    if (!pending || isCodeExpired(pending)) {
      if (pending) getPendingCodes(store).delete(code);
      return c.json({ error: "invalid_grant", error_description: "Authorization code is invalid or expired." }, 400);
    }
    if (redirectUri && redirectUri !== pending.redirectUri) {
      return c.json({ error: "invalid_grant", error_description: "redirect_uri does not match." }, 400);
    }
    const oauthApps = clerkStore.oauthApps.all();
    if (oauthApps.length > 0) {
      const oauthApp = oauthApps.find((a) => a.client_id === clientId);
      if (!oauthApp) {
        return c.json({ error: "invalid_client", error_description: "Unknown client." }, 401);
      }
      if (!oauthApp.is_public && !constantTimeSecretEqual(oauthApp.client_secret, clientSecret)) {
        return c.json({ error: "invalid_client", error_description: "Invalid client credentials." }, 401);
      }
    }
    if (pending.codeChallenge !== null) {
      if (!codeVerifier) {
        return c.json({ error: "invalid_grant", error_description: "PKCE verification failed." }, 400);
      }
      const method = (pending.codeChallengeMethod ?? "plain").toLowerCase();
      if (method === "s256") {
        const { createHash } = await import("crypto");
        const expected = createHash("sha256").update(codeVerifier).digest("base64url");
        if (expected !== pending.codeChallenge) {
          return c.json({ error: "invalid_grant", error_description: "PKCE verification failed." }, 400);
        }
      } else if (method === "plain") {
        if (codeVerifier !== pending.codeChallenge) {
          return c.json({ error: "invalid_grant", error_description: "PKCE verification failed." }, 400);
        }
      }
    }
    const user = clerkStore.users.findOneBy("clerk_id", pending.userClerkId);
    if (!user) return c.json({ error: "invalid_grant", error_description: "Unknown user." }, 400);
    getPendingCodes(store).delete(code);
    const { generateClerkId: generateClerkId2, nowUnix: nowUnix2 } = await import("./helpers-LXLP3DFE-LBOTATT5.js");
    const sessionId = generateClerkId2("sess_");
    const now = nowUnix2();
    clerkStore.sessions.insert({
      clerk_id: sessionId,
      user_id: user.clerk_id,
      client_id: clientId || "default",
      status: "active",
      last_active_at: now,
      expire_at: now + 86400,
      abandon_at: now + 604800,
      created_at_unix: now,
      updated_at_unix: now
    });
    const accessToken = `clerk_${randomBytes(20).toString("base64url")}`;
    tokenMap?.set(accessToken, {
      login: user.clerk_id,
      id: user.id,
      scopes: pending.scope.split(/\s+/).filter(Boolean)
    });
    const { privateKey } = await keyPairPromise;
    const nowSec = Math.floor(Date.now() / 1e3);
    const emails = clerkStore.emailAddresses.findBy("user_id", user.clerk_id);
    const primaryEmail = emails.find((e) => e.is_primary) ?? emails[0];
    const idToken = await new SignJWT({
      sid: sessionId,
      email: primaryEmail?.email_address,
      email_verified: primaryEmail?.verification_status === "verified",
      name: [user.first_name, user.last_name].filter(Boolean).join(" ") || void 0
    }).setProtectedHeader({ alg: "RS256", kid: KID, typ: "JWT" }).setIssuer(baseUrl).setSubject(user.clerk_id).setAudience(clientId || "default").setIssuedAt(nowSec).setExpirationTime("1h").sign(privateKey);
    return c.json({
      token_type: "Bearer",
      expires_in: 3600,
      access_token: accessToken,
      id_token: idToken,
      scope: pending.scope
    });
  });
  app.get("/oauth/userinfo", (c) => {
    const authUser = c.get("authUser");
    if (!authUser) {
      return c.json({ error: "invalid_token", error_description: "The access token is invalid." }, 401);
    }
    const user = clerkStore.users.findOneBy("clerk_id", authUser.login) ?? clerkStore.users.all()[0];
    if (!user) {
      return c.json({ error: "invalid_token", error_description: "User not found." }, 401);
    }
    const emails = clerkStore.emailAddresses.findBy("user_id", user.clerk_id);
    const primaryEmail = emails.find((e) => e.is_primary) ?? emails[0];
    return c.json({
      sub: user.clerk_id,
      name: [user.first_name, user.last_name].filter(Boolean).join(" ") || void 0,
      email: primaryEmail?.email_address,
      email_verified: primaryEmail?.verification_status === "verified",
      picture: user.image_url
    });
  });
}
function clerkError(c, status, code, message, longMessage, meta) {
  return c.json(
    {
      errors: [
        {
          code,
          message,
          long_message: longMessage ?? message,
          meta: meta ?? {}
        }
      ]
    },
    status
  );
}
function requireSecretKey(c, tokenMap) {
  const existing = c.get("authUser");
  if (existing) return existing;
  const authHeader = c.req.header("Authorization") ?? "";
  if (authHeader.startsWith("Bearer ")) {
    const token = authHeader.slice(7).trim();
    if (token.startsWith("sk_test_") || token.startsWith("sk_live_")) {
      const mapped = tokenMap?.get(token);
      if (mapped) {
        c.set("authUser", mapped);
        c.set("authToken", token);
        c.set("authScopes", mapped.scopes);
        return mapped;
      }
    }
  }
  return clerkError(c, 401, "UNAUTHORIZED", "Authentication failed", "Invalid or missing secret key");
}
function isAuthResponse(result) {
  return result instanceof Response;
}
function deletedResponse(objectType, objectId) {
  return {
    object: "deleted_object",
    id: objectId,
    slug: null,
    deleted: true
  };
}
function paginatedResponse(data, totalCount, limit, offset) {
  return {
    data,
    total_count: totalCount,
    has_more: offset + limit < totalCount
  };
}
function parsePagination(c) {
  const limit = Math.min(Math.max(Number.parseInt(c.req.query("limit") ?? "10", 10) || 10, 1), 500);
  const offset = Math.max(Number.parseInt(c.req.query("offset") ?? "0", 10) || 0, 0);
  return { limit, offset };
}
function userResponse(user, emailAddresses) {
  return {
    id: user.clerk_id,
    object: "user",
    username: user.username,
    first_name: user.first_name,
    last_name: user.last_name,
    image_url: user.image_url ?? `https://img.clerk.com/preview?seed=${user.clerk_id}`,
    profile_image_url: user.profile_image_url ?? `https://img.clerk.com/preview?seed=${user.clerk_id}`,
    has_image: user.image_url !== null,
    primary_email_address_id: user.primary_email_address_id,
    primary_phone_number_id: user.primary_phone_number_id,
    primary_web3_wallet_id: null,
    email_addresses: emailAddresses.map(emailAddressResponse),
    phone_numbers: [],
    web3_wallets: [],
    external_accounts: [],
    saml_accounts: [],
    passkeys: [],
    password_enabled: user.password_enabled,
    totp_enabled: user.totp_enabled,
    backup_code_enabled: user.backup_code_enabled,
    two_factor_enabled: user.two_factor_enabled,
    banned: user.banned,
    locked: user.locked,
    external_id: user.external_id,
    public_metadata: user.public_metadata,
    private_metadata: user.private_metadata,
    unsafe_metadata: user.unsafe_metadata,
    last_sign_in_at: user.last_sign_in_at,
    last_active_at: user.last_active_at,
    created_at: user.created_at_unix,
    updated_at: user.updated_at_unix
  };
}
function emailAddressResponse(email) {
  return {
    id: email.email_id,
    object: "email_address",
    email_address: email.email_address,
    reserved: email.reserved,
    verification: {
      status: email.verification_status,
      strategy: email.verification_strategy
    },
    linked_to: [],
    created_at: email.created_at_unix,
    updated_at: email.updated_at_unix
  };
}
function organizationResponse(org) {
  return {
    id: org.clerk_id,
    object: "organization",
    name: org.name,
    slug: org.slug,
    image_url: org.image_url,
    has_image: org.image_url !== null,
    members_count: org.members_count,
    pending_invitations_count: org.pending_invitations_count,
    max_allowed_memberships: org.max_allowed_memberships,
    admin_delete_enabled: org.admin_delete_enabled,
    public_metadata: org.public_metadata,
    private_metadata: org.private_metadata,
    created_at: org.created_at_unix,
    updated_at: org.updated_at_unix
  };
}
function membershipResponse(membership, org, user, emailAddresses) {
  return {
    id: membership.membership_id,
    object: "organization_membership",
    role: membership.role,
    permissions: membership.permissions,
    public_metadata: membership.public_metadata,
    private_metadata: membership.private_metadata,
    organization: org ? organizationResponse(org) : null,
    public_user_data: user ? {
      user_id: user.clerk_id,
      first_name: user.first_name,
      last_name: user.last_name,
      image_url: user.image_url,
      has_image: user.image_url !== null,
      identifier: emailAddresses.find((e) => e.is_primary)?.email_address ?? user.username ?? user.clerk_id
    } : null,
    created_at: membership.created_at_unix,
    updated_at: membership.updated_at_unix
  };
}
function invitationResponse(invitation) {
  return {
    id: invitation.invitation_id,
    object: "organization_invitation",
    email_address: invitation.email_address,
    role: invitation.role,
    status: invitation.status,
    organization_id: invitation.org_id,
    created_at: invitation.created_at_unix,
    updated_at: invitation.updated_at_unix
  };
}
function sessionResponse(session) {
  return {
    id: session.clerk_id,
    object: "session",
    user_id: session.user_id,
    client_id: session.client_id,
    status: session.status,
    last_active_at: session.last_active_at,
    expire_at: session.expire_at,
    abandon_at: session.abandon_at,
    created_at: session.created_at_unix,
    updated_at: session.updated_at_unix
  };
}
async function readJsonBody(c) {
  try {
    const body = await c.req.json();
    if (body && typeof body === "object") return body;
    return {};
  } catch {
    return {};
  }
}
function userRoutes({ app, store, tokenMap }) {
  const cs = getClerkStore(store);
  app.get("/v1/users", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const { limit, offset } = parsePagination(c);
    const query = c.req.query("query");
    const orderBy = c.req.query("order_by") ?? "-created_at";
    const emailFilter = c.req.queries("email_address");
    let users = cs.users.all();
    if (query) {
      const q = query.toLowerCase();
      users = users.filter((u) => {
        const emails = cs.emailAddresses.findBy("user_id", u.clerk_id);
        return u.first_name?.toLowerCase().includes(q) || u.last_name?.toLowerCase().includes(q) || u.username?.toLowerCase().includes(q) || emails.some((e) => e.email_address.toLowerCase().includes(q));
      });
    }
    if (emailFilter && emailFilter.length > 0) {
      const emailSet = new Set(emailFilter.map((e) => e.toLowerCase()));
      users = users.filter((u) => {
        const emails = cs.emailAddresses.findBy("user_id", u.clerk_id);
        return emails.some((e) => emailSet.has(e.email_address.toLowerCase()));
      });
    }
    const desc = orderBy.startsWith("-");
    const field = orderBy.replace(/^-/, "");
    users.sort((a, b) => {
      const aVal = field === "created_at" ? a.created_at_unix : a.updated_at_unix;
      const bVal = field === "created_at" ? b.created_at_unix : b.updated_at_unix;
      return desc ? bVal - aVal : aVal - bVal;
    });
    const totalCount = users.length;
    const paged = users.slice(offset, offset + limit);
    const data = paged.map((u) => {
      const emails = cs.emailAddresses.findBy("user_id", u.clerk_id);
      return userResponse(u, emails);
    });
    return c.json(paginatedResponse(data, totalCount, limit, offset));
  });
  app.get("/v1/users/count", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    return c.json({ object: "total_count", total_count: cs.users.all().length });
  });
  app.get("/v1/users/:userId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const emails = cs.emailAddresses.findBy("user_id", user.clerk_id);
    return c.json(userResponse(user, emails));
  });
  app.post("/v1/users", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const body = await readJsonBody(c);
    const now = nowUnix();
    const clerkId = generateClerkId("user_");
    const user = cs.users.insert({
      clerk_id: clerkId,
      username: body.username ?? null,
      first_name: body.first_name ?? null,
      last_name: body.last_name ?? null,
      image_url: null,
      profile_image_url: null,
      external_id: body.external_id ?? null,
      primary_email_address_id: null,
      primary_phone_number_id: null,
      password_enabled: typeof body.password === "string" && body.password.length > 0,
      password_hash: body.password ?? null,
      totp_enabled: false,
      backup_code_enabled: false,
      two_factor_enabled: false,
      banned: false,
      locked: false,
      public_metadata: body.public_metadata ?? {},
      private_metadata: body.private_metadata ?? {},
      unsafe_metadata: body.unsafe_metadata ?? {},
      last_active_at: null,
      last_sign_in_at: null,
      created_at_unix: now,
      updated_at_unix: now
    });
    const emailAddr = body.email_address ?? [];
    const emailList = Array.isArray(emailAddr) ? emailAddr : [emailAddr];
    let primaryEmailId = null;
    for (let i = 0; i < emailList.length; i++) {
      const email = cs.emailAddresses.insert({
        email_id: generateClerkId("idn_"),
        email_address: emailList[i],
        user_id: clerkId,
        verification_status: "verified",
        verification_strategy: "email_code",
        is_primary: i === 0,
        reserved: false,
        created_at_unix: now,
        updated_at_unix: now
      });
      if (i === 0) primaryEmailId = email.email_id;
    }
    if (primaryEmailId) {
      cs.users.update(user.id, { primary_email_address_id: primaryEmailId });
    }
    const emails = cs.emailAddresses.findBy("user_id", clerkId);
    const updatedUser = cs.users.findOneBy("clerk_id", clerkId);
    return c.json(userResponse(updatedUser, emails), 200);
  });
  app.patch("/v1/users/:userId", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const body = await readJsonBody(c);
    const now = nowUnix();
    const patch = { updated_at_unix: now };
    if (body.first_name !== void 0) patch.first_name = body.first_name;
    if (body.last_name !== void 0) patch.last_name = body.last_name;
    if (body.username !== void 0) patch.username = body.username;
    if (body.external_id !== void 0) patch.external_id = body.external_id;
    if (body.primary_email_address_id !== void 0)
      patch.primary_email_address_id = body.primary_email_address_id;
    if (body.primary_phone_number_id !== void 0)
      patch.primary_phone_number_id = body.primary_phone_number_id;
    if (body.public_metadata !== void 0) patch.public_metadata = body.public_metadata;
    if (body.private_metadata !== void 0) patch.private_metadata = body.private_metadata;
    if (body.unsafe_metadata !== void 0) patch.unsafe_metadata = body.unsafe_metadata;
    if (typeof body.password === "string") {
      patch.password_enabled = body.password.length > 0;
      patch.password_hash = body.password;
    }
    cs.users.update(user.id, patch);
    const updated = cs.users.findOneBy("clerk_id", userId);
    const emails = cs.emailAddresses.findBy("user_id", userId);
    return c.json(userResponse(updated, emails));
  });
  app.delete("/v1/users/:userId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    for (const email of cs.emailAddresses.findBy("user_id", userId)) {
      cs.emailAddresses.delete(email.id);
    }
    for (const membership of cs.memberships.findBy("user_id", userId)) {
      cs.memberships.delete(membership.id);
      const org = cs.organizations.findOneBy("clerk_id", membership.org_id);
      if (org) cs.organizations.update(org.id, { members_count: Math.max(0, org.members_count - 1) });
    }
    for (const session of cs.sessions.findBy("user_id", userId)) {
      cs.sessions.delete(session.id);
    }
    cs.users.delete(user.id);
    return c.json(deletedResponse("user", userId));
  });
  app.post("/v1/users/:userId/ban", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    cs.users.update(user.id, { banned: true, updated_at_unix: nowUnix() });
    const updated = cs.users.findOneBy("clerk_id", userId);
    const emails = cs.emailAddresses.findBy("user_id", userId);
    return c.json(userResponse(updated, emails));
  });
  app.post("/v1/users/:userId/unban", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    cs.users.update(user.id, { banned: false, updated_at_unix: nowUnix() });
    const updated = cs.users.findOneBy("clerk_id", userId);
    const emails = cs.emailAddresses.findBy("user_id", userId);
    return c.json(userResponse(updated, emails));
  });
  app.post("/v1/users/:userId/lock", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    cs.users.update(user.id, { locked: true, updated_at_unix: nowUnix() });
    const updated = cs.users.findOneBy("clerk_id", userId);
    const emails = cs.emailAddresses.findBy("user_id", userId);
    return c.json(userResponse(updated, emails));
  });
  app.post("/v1/users/:userId/unlock", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    cs.users.update(user.id, { locked: false, updated_at_unix: nowUnix() });
    const updated = cs.users.findOneBy("clerk_id", userId);
    const emails = cs.emailAddresses.findBy("user_id", userId);
    return c.json(userResponse(updated, emails));
  });
  app.patch("/v1/users/:userId/metadata", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const body = await readJsonBody(c);
    const patch = { updated_at_unix: nowUnix() };
    if (body.public_metadata !== void 0) {
      patch.public_metadata = { ...user.public_metadata, ...body.public_metadata };
    }
    if (body.private_metadata !== void 0) {
      patch.private_metadata = { ...user.private_metadata, ...body.private_metadata };
    }
    if (body.unsafe_metadata !== void 0) {
      patch.unsafe_metadata = { ...user.unsafe_metadata, ...body.unsafe_metadata };
    }
    cs.users.update(user.id, patch);
    const updated = cs.users.findOneBy("clerk_id", userId);
    const emails = cs.emailAddresses.findBy("user_id", userId);
    return c.json(userResponse(updated, emails));
  });
  app.post("/v1/users/:userId/verify_password", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const userId = c.req.param("userId");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const body = await readJsonBody(c);
    const password = body.password;
    const verified = user.password_hash === password;
    return c.json({ object: "verification", verified });
  });
}
function emailAddressRoutes({ app, store, tokenMap }) {
  const cs = getClerkStore(store);
  app.get("/v1/email_addresses/:emailId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const emailId = c.req.param("emailId");
    const email = cs.emailAddresses.findOneBy("email_id", emailId);
    if (!email) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Email address not found");
    return c.json(emailAddressResponse(email));
  });
  app.post("/v1/email_addresses", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const body = await readJsonBody(c);
    const userId = body.user_id;
    const emailAddr = body.email_address;
    const verified = body.verified ?? false;
    const primary = body.primary ?? false;
    if (!userId || !emailAddr) {
      return clerkError(c, 422, "INVALID_REQUEST_BODY", "user_id and email_address are required");
    }
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const now = nowUnix();
    const email = cs.emailAddresses.insert({
      email_id: generateClerkId("idn_"),
      email_address: emailAddr,
      user_id: userId,
      verification_status: verified ? "verified" : "unverified",
      verification_strategy: "email_code",
      is_primary: primary,
      reserved: false,
      created_at_unix: now,
      updated_at_unix: now
    });
    if (primary) {
      for (const existing of cs.emailAddresses.findBy("user_id", userId)) {
        if (existing.email_id !== email.email_id && existing.is_primary) {
          cs.emailAddresses.update(existing.id, { is_primary: false });
        }
      }
      cs.users.update(user.id, { primary_email_address_id: email.email_id, updated_at_unix: now });
    }
    return c.json(emailAddressResponse(email), 200);
  });
  app.patch("/v1/email_addresses/:emailId", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const emailId = c.req.param("emailId");
    const email = cs.emailAddresses.findOneBy("email_id", emailId);
    if (!email) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Email address not found");
    const body = await readJsonBody(c);
    const now = nowUnix();
    const patch = { updated_at_unix: now };
    if (body.verified !== void 0) {
      patch.verification_status = body.verified ? "verified" : "unverified";
    }
    if (body.primary === true) {
      patch.is_primary = true;
      for (const existing of cs.emailAddresses.findBy("user_id", email.user_id)) {
        if (existing.email_id !== emailId && existing.is_primary) {
          cs.emailAddresses.update(existing.id, { is_primary: false });
        }
      }
      const user = cs.users.findOneBy("clerk_id", email.user_id);
      if (user) cs.users.update(user.id, { primary_email_address_id: emailId, updated_at_unix: now });
    }
    cs.emailAddresses.update(email.id, patch);
    const updated = cs.emailAddresses.findOneBy("email_id", emailId);
    return c.json(emailAddressResponse(updated));
  });
  app.delete("/v1/email_addresses/:emailId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const emailId = c.req.param("emailId");
    const email = cs.emailAddresses.findOneBy("email_id", emailId);
    if (!email) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Email address not found");
    cs.emailAddresses.delete(email.id);
    if (email.is_primary) {
      const remaining = cs.emailAddresses.findBy("user_id", email.user_id);
      const user = cs.users.findOneBy("clerk_id", email.user_id);
      if (user) {
        const newPrimary = remaining[0];
        if (newPrimary) {
          cs.emailAddresses.update(newPrimary.id, { is_primary: true });
          cs.users.update(user.id, { primary_email_address_id: newPrimary.email_id });
        } else {
          cs.users.update(user.id, { primary_email_address_id: null });
        }
      }
    }
    return c.json(deletedResponse("email_address", emailId));
  });
}
function organizationRoutes({ app, store, tokenMap }) {
  const cs = getClerkStore(store);
  app.get("/v1/organizations", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const { limit, offset } = parsePagination(c);
    const query = c.req.query("query");
    let orgs = cs.organizations.all();
    if (query) {
      const q = query.toLowerCase();
      orgs = orgs.filter((o) => o.name.toLowerCase().includes(q) || o.slug.toLowerCase().includes(q));
    }
    orgs.sort((a, b) => b.created_at_unix - a.created_at_unix);
    const totalCount = orgs.length;
    const paged = orgs.slice(offset, offset + limit);
    return c.json(paginatedResponse(paged.map(organizationResponse), totalCount, limit, offset));
  });
  app.get("/v1/organizations/:orgId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId) ?? cs.organizations.findOneBy("slug", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    return c.json(organizationResponse(org));
  });
  app.post("/v1/organizations", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const body = await readJsonBody(c);
    const name = body.name;
    if (!name) return clerkError(c, 422, "INVALID_REQUEST_BODY", "name is required");
    const slug = body.slug ?? name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
    const now = nowUnix();
    const org = cs.organizations.insert({
      clerk_id: generateClerkId("org_"),
      name,
      slug,
      image_url: null,
      has_logo: false,
      members_count: 0,
      pending_invitations_count: 0,
      public_metadata: body.public_metadata ?? {},
      private_metadata: body.private_metadata ?? {},
      max_allowed_memberships: body.max_allowed_memberships ?? null,
      admin_delete_enabled: body.admin_delete_enabled ?? true,
      created_at_unix: now,
      updated_at_unix: now
    });
    if (body.created_by) {
      const userId = body.created_by;
      const user = cs.users.findOneBy("clerk_id", userId);
      if (user) {
        cs.memberships.insert({
          membership_id: generateClerkId("orgmem_"),
          org_id: org.clerk_id,
          user_id: userId,
          role: "org:admin",
          permissions: [
            "org:sys_profile:manage",
            "org:sys_profile:delete",
            "org:sys_memberships:read",
            "org:sys_memberships:manage",
            "org:sys_domains:read",
            "org:sys_domains:manage"
          ],
          public_metadata: {},
          private_metadata: {},
          created_at_unix: now,
          updated_at_unix: now
        });
        cs.organizations.update(org.id, { members_count: 1 });
      }
    }
    const updated = cs.organizations.findOneBy("clerk_id", org.clerk_id);
    return c.json(organizationResponse(updated), 200);
  });
  app.patch("/v1/organizations/:orgId", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const body = await readJsonBody(c);
    const now = nowUnix();
    const patch = { updated_at_unix: now };
    if (body.name !== void 0) patch.name = body.name;
    if (body.slug !== void 0) patch.slug = body.slug;
    if (body.public_metadata !== void 0) patch.public_metadata = body.public_metadata;
    if (body.private_metadata !== void 0) patch.private_metadata = body.private_metadata;
    if (body.max_allowed_memberships !== void 0) patch.max_allowed_memberships = body.max_allowed_memberships;
    if (body.admin_delete_enabled !== void 0) patch.admin_delete_enabled = body.admin_delete_enabled;
    cs.organizations.update(org.id, patch);
    const updated = cs.organizations.findOneBy("clerk_id", orgId);
    return c.json(organizationResponse(updated));
  });
  app.delete("/v1/organizations/:orgId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    for (const m of cs.memberships.findBy("org_id", orgId)) cs.memberships.delete(m.id);
    for (const inv of cs.invitations.findBy("org_id", orgId)) cs.invitations.delete(inv.id);
    cs.organizations.delete(org.id);
    return c.json(deletedResponse("organization", orgId));
  });
  app.patch("/v1/organizations/:orgId/metadata", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const body = await readJsonBody(c);
    const now = nowUnix();
    const patch = { updated_at_unix: now };
    if (body.public_metadata !== void 0) {
      patch.public_metadata = { ...org.public_metadata, ...body.public_metadata };
    }
    if (body.private_metadata !== void 0) {
      patch.private_metadata = { ...org.private_metadata, ...body.private_metadata };
    }
    cs.organizations.update(org.id, patch);
    const updated = cs.organizations.findOneBy("clerk_id", orgId);
    return c.json(organizationResponse(updated));
  });
}
function defaultPermissions(role) {
  if (role === "org:admin") {
    return [
      "org:sys_profile:manage",
      "org:sys_profile:delete",
      "org:sys_memberships:read",
      "org:sys_memberships:manage",
      "org:sys_domains:read",
      "org:sys_domains:manage"
    ];
  }
  return ["org:sys_memberships:read"];
}
function membershipRoutes({ app, store, tokenMap }) {
  const cs = getClerkStore(store);
  app.get("/v1/organizations/:orgId/memberships", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const { limit, offset } = parsePagination(c);
    const roleFilter = c.req.query("role");
    let memberships = cs.memberships.findBy("org_id", orgId);
    if (roleFilter) {
      memberships = memberships.filter((m) => m.role === roleFilter);
    }
    const totalCount = memberships.length;
    const paged = memberships.slice(offset, offset + limit);
    const data = paged.map((m) => {
      const user = cs.users.findOneBy("clerk_id", m.user_id);
      const emails = user ? cs.emailAddresses.findBy("user_id", user.clerk_id) : [];
      return membershipResponse(m, org, user, emails);
    });
    return c.json(paginatedResponse(data, totalCount, limit, offset));
  });
  app.post("/v1/organizations/:orgId/memberships", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const body = await readJsonBody(c);
    const userId = body.user_id;
    const role = body.role ?? "org:member";
    if (!userId) return clerkError(c, 422, "INVALID_REQUEST_BODY", "user_id is required");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const existing = cs.memberships.findBy("org_id", orgId).find((m) => m.user_id === userId);
    if (existing) return clerkError(c, 422, "DUPLICATE_RECORD", "User is already a member of this organization");
    const now = nowUnix();
    const membership = cs.memberships.insert({
      membership_id: generateClerkId("orgmem_"),
      org_id: orgId,
      user_id: userId,
      role,
      permissions: defaultPermissions(role),
      public_metadata: {},
      private_metadata: {},
      created_at_unix: now,
      updated_at_unix: now
    });
    cs.organizations.update(org.id, { members_count: org.members_count + 1, updated_at_unix: now });
    const emails = cs.emailAddresses.findBy("user_id", userId);
    const updatedOrg = cs.organizations.findOneBy("clerk_id", orgId);
    return c.json(membershipResponse(membership, updatedOrg, user, emails), 200);
  });
  app.patch("/v1/organizations/:orgId/memberships/:userId", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const userId = c.req.param("userId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const membership = cs.memberships.findBy("org_id", orgId).find((m) => m.user_id === userId);
    if (!membership) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Membership not found");
    const body = await readJsonBody(c);
    const now = nowUnix();
    const patch = { updated_at_unix: now };
    if (body.role !== void 0) {
      patch.role = body.role;
      patch.permissions = defaultPermissions(body.role);
    }
    cs.memberships.update(membership.id, patch);
    const updated = cs.memberships.findBy("org_id", orgId).find((m) => m.user_id === userId);
    const user = cs.users.findOneBy("clerk_id", userId);
    const emails = user ? cs.emailAddresses.findBy("user_id", userId) : [];
    return c.json(membershipResponse(updated, org, user, emails));
  });
  app.delete("/v1/organizations/:orgId/memberships/:userId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const userId = c.req.param("userId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const membership = cs.memberships.findBy("org_id", orgId).find((m) => m.user_id === userId);
    if (!membership) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Membership not found");
    cs.memberships.delete(membership.id);
    cs.organizations.update(org.id, { members_count: Math.max(0, org.members_count - 1), updated_at_unix: nowUnix() });
    return c.json(deletedResponse("organization_membership", membership.membership_id));
  });
  app.patch("/v1/organizations/:orgId/memberships/:userId/metadata", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const userId = c.req.param("userId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const membership = cs.memberships.findBy("org_id", orgId).find((m) => m.user_id === userId);
    if (!membership) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Membership not found");
    const body = await readJsonBody(c);
    const now = nowUnix();
    const patch = { updated_at_unix: now };
    if (body.public_metadata !== void 0) {
      patch.public_metadata = { ...membership.public_metadata, ...body.public_metadata };
    }
    if (body.private_metadata !== void 0) {
      patch.private_metadata = {
        ...membership.private_metadata,
        ...body.private_metadata
      };
    }
    cs.memberships.update(membership.id, patch);
    const updated = cs.memberships.findBy("org_id", orgId).find((m) => m.user_id === userId);
    const user = cs.users.findOneBy("clerk_id", userId);
    const emails = user ? cs.emailAddresses.findBy("user_id", userId) : [];
    return c.json(membershipResponse(updated, org, user, emails));
  });
}
function invitationRoutes({ app, store, tokenMap }) {
  const cs = getClerkStore(store);
  app.get("/v1/organizations/:orgId/invitations", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const { limit, offset } = parsePagination(c);
    const statusFilter = c.req.query("status");
    let invitations = cs.invitations.findBy("org_id", orgId);
    if (statusFilter) {
      invitations = invitations.filter((inv) => inv.status === statusFilter);
    }
    const totalCount = invitations.length;
    const paged = invitations.slice(offset, offset + limit);
    return c.json(paginatedResponse(paged.map(invitationResponse), totalCount, limit, offset));
  });
  app.get("/v1/organizations/:orgId/invitations/:invitationId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const invitationId = c.req.param("invitationId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const invitation = cs.invitations.findOneBy("invitation_id", invitationId);
    if (!invitation || invitation.org_id !== orgId) {
      return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Invitation not found");
    }
    return c.json(invitationResponse(invitation));
  });
  app.post("/v1/organizations/:orgId/invitations", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const body = await readJsonBody(c);
    const emailAddress = body.email_address;
    if (!emailAddress) return clerkError(c, 422, "INVALID_REQUEST_BODY", "email_address is required");
    const role = body.role ?? "org:member";
    const expiresInDays = body.expires_in_days ?? 30;
    const now = nowUnix();
    const invitation = cs.invitations.insert({
      invitation_id: generateClerkId("orginv_"),
      email_address: emailAddress,
      org_id: orgId,
      role,
      status: "pending",
      expires_at: now + expiresInDays * 86400,
      created_at_unix: now,
      updated_at_unix: now
    });
    cs.organizations.update(org.id, {
      pending_invitations_count: org.pending_invitations_count + 1,
      updated_at_unix: now
    });
    return c.json(invitationResponse(invitation), 200);
  });
  app.post("/v1/organizations/:orgId/invitations/bulk", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const body = await readJsonBody(c);
    const emailAddresses = body.email_addresses;
    if (!emailAddresses || !Array.isArray(emailAddresses)) {
      return clerkError(c, 422, "INVALID_REQUEST_BODY", "email_addresses array is required");
    }
    const role = body.role ?? "org:member";
    const expiresInDays = body.expires_in_days ?? 30;
    const now = nowUnix();
    const created = emailAddresses.map(
      (email) => cs.invitations.insert({
        invitation_id: generateClerkId("orginv_"),
        email_address: email,
        org_id: orgId,
        role,
        status: "pending",
        expires_at: now + expiresInDays * 86400,
        created_at_unix: now,
        updated_at_unix: now
      })
    );
    cs.organizations.update(org.id, {
      pending_invitations_count: org.pending_invitations_count + created.length,
      updated_at_unix: now
    });
    return c.json(created.map(invitationResponse));
  });
  app.post("/v1/organizations/:orgId/invitations/:invitationId/revoke", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const orgId = c.req.param("orgId");
    const invitationId = c.req.param("invitationId");
    const org = cs.organizations.findOneBy("clerk_id", orgId);
    if (!org) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Organization not found");
    const invitation = cs.invitations.findOneBy("invitation_id", invitationId);
    if (!invitation || invitation.org_id !== orgId) {
      return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Invitation not found");
    }
    if (invitation.status !== "pending") {
      return clerkError(c, 422, "INVALID_REQUEST_BODY", "Only pending invitations can be revoked");
    }
    const now = nowUnix();
    cs.invitations.update(invitation.id, { status: "revoked", updated_at_unix: now });
    cs.organizations.update(org.id, {
      pending_invitations_count: Math.max(0, org.pending_invitations_count - 1),
      updated_at_unix: now
    });
    const updated = cs.invitations.findOneBy("invitation_id", invitationId);
    return c.json(invitationResponse(updated));
  });
}
function sessionRoutes({ app, store, baseUrl, tokenMap }) {
  const cs = getClerkStore(store);
  app.get("/v1/sessions", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const { limit, offset } = parsePagination(c);
    const userIdFilter = c.req.query("user_id");
    let sessions = cs.sessions.all();
    if (userIdFilter) {
      sessions = sessions.filter((s) => s.user_id === userIdFilter);
    }
    sessions.sort((a, b) => b.created_at_unix - a.created_at_unix);
    const totalCount = sessions.length;
    const paged = sessions.slice(offset, offset + limit);
    return c.json(paginatedResponse(paged.map(sessionResponse), totalCount, limit, offset));
  });
  app.get("/v1/sessions/:sessionId", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const sessionId = c.req.param("sessionId");
    const session = cs.sessions.findOneBy("clerk_id", sessionId);
    if (!session) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Session not found");
    return c.json(sessionResponse(session));
  });
  app.post("/v1/sessions", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const body = await readJsonBody(c);
    const userId = body.user_id;
    if (!userId) return clerkError(c, 422, "INVALID_REQUEST_BODY", "user_id is required");
    const user = cs.users.findOneBy("clerk_id", userId);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const now = nowUnix();
    const session = cs.sessions.insert({
      clerk_id: generateClerkId("sess_"),
      user_id: userId,
      client_id: body.client_id ?? "client_emulate",
      status: "active",
      last_active_at: now,
      expire_at: now + 86400,
      abandon_at: now + 604800,
      created_at_unix: now,
      updated_at_unix: now
    });
    cs.users.update(user.id, { last_active_at: now, last_sign_in_at: now, updated_at_unix: now });
    return c.json(sessionResponse(session), 200);
  });
  app.post("/v1/sessions/:sessionId/revoke", (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const sessionId = c.req.param("sessionId");
    const session = cs.sessions.findOneBy("clerk_id", sessionId);
    if (!session) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Session not found");
    cs.sessions.update(session.id, { status: "revoked", updated_at_unix: nowUnix() });
    const updated = cs.sessions.findOneBy("clerk_id", sessionId);
    return c.json(sessionResponse(updated));
  });
  app.post("/v1/sessions/:sessionId/tokens", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const sessionId = c.req.param("sessionId");
    const session = cs.sessions.findOneBy("clerk_id", sessionId);
    if (!session) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Session not found");
    if (session.status !== "active") {
      return clerkError(c, 422, "SESSION_NOT_ACTIVE", "Session is not active");
    }
    const user = cs.users.findOneBy("clerk_id", session.user_id);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const memberships = cs.memberships.findBy("user_id", user.clerk_id);
    const firstMembership = memberships[0];
    let orgId;
    let orgRole;
    let orgSlug;
    let orgPermissions;
    if (firstMembership) {
      const org = cs.organizations.findOneBy("clerk_id", firstMembership.org_id);
      if (org) {
        orgId = org.clerk_id;
        orgRole = firstMembership.role;
        orgSlug = org.slug;
        orgPermissions = firstMembership.permissions;
      }
    }
    const jwt = await createSessionToken(store, user, sessionId, baseUrl, orgId, orgRole, orgSlug, orgPermissions);
    cs.sessions.update(session.id, { last_active_at: nowUnix() });
    return c.json({ object: "token", jwt });
  });
  app.post("/v1/sessions/:sessionId/tokens/:template", async (c) => {
    const auth = requireSecretKey(c, tokenMap);
    if (isAuthResponse(auth)) return auth;
    const sessionId = c.req.param("sessionId");
    const session = cs.sessions.findOneBy("clerk_id", sessionId);
    if (!session) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "Session not found");
    if (session.status !== "active") {
      return clerkError(c, 422, "SESSION_NOT_ACTIVE", "Session is not active");
    }
    const user = cs.users.findOneBy("clerk_id", session.user_id);
    if (!user) return clerkError(c, 404, "RESOURCE_NOT_FOUND", "User not found");
    const jwt = await createSessionToken(store, user, sessionId, baseUrl);
    cs.sessions.update(session.id, { last_active_at: nowUnix() });
    return c.json({ object: "token", jwt });
  });
}
function seedDefaults(store, _baseUrl) {
  const cs = getClerkStore(store);
  if (cs.users.all().length > 0) return;
  const userInput = createDefaultUser();
  const user = cs.users.insert(userInput);
  const email = cs.emailAddresses.insert(createDefaultEmailAddress(user.clerk_id, "test@agent-emulate.dev", true));
  cs.users.update(user.id, { primary_email_address_id: email.email_id });
  const now = nowUnix();
  cs.oauthApps.insert({
    app_id: generateClerkId("oauth_app_"),
    name: "Emulate App",
    client_id: "clerk_emulate_client",
    client_secret: "clerk_emulate_secret",
    is_public: false,
    scopes: ["openid", "profile", "email"],
    redirect_uris: ["http://localhost:3000/api/auth/callback/clerk"],
    created_at_unix: now,
    updated_at_unix: now
  });
}
function seedFromConfig(store, _baseUrl, config) {
  const cs = getClerkStore(store);
  const now = nowUnix();
  if (config.users) {
    for (const userCfg of config.users) {
      const existingEmail = userCfg.email_addresses?.[0];
      if (existingEmail) {
        const found = cs.emailAddresses.findOneBy("email_address", existingEmail);
        if (found) continue;
      }
      const clerkId = userCfg.clerk_id ?? generateClerkId("user_");
      const user = cs.users.insert({
        clerk_id: clerkId,
        username: userCfg.username ?? null,
        first_name: userCfg.first_name ?? "Test",
        last_name: userCfg.last_name ?? "User",
        image_url: null,
        profile_image_url: null,
        external_id: userCfg.external_id ?? null,
        primary_email_address_id: null,
        primary_phone_number_id: null,
        password_enabled: typeof userCfg.password === "string" && userCfg.password.length > 0,
        password_hash: userCfg.password ?? null,
        totp_enabled: false,
        backup_code_enabled: false,
        two_factor_enabled: false,
        banned: false,
        locked: false,
        public_metadata: userCfg.public_metadata ?? {},
        private_metadata: userCfg.private_metadata ?? {},
        unsafe_metadata: userCfg.unsafe_metadata ?? {},
        last_active_at: null,
        last_sign_in_at: null,
        created_at_unix: now,
        updated_at_unix: now
      });
      let primaryEmailId = null;
      if (userCfg.email_addresses) {
        for (let i = 0; i < userCfg.email_addresses.length; i++) {
          const email = cs.emailAddresses.insert(
            createDefaultEmailAddress(clerkId, userCfg.email_addresses[i], i === 0)
          );
          if (i === 0) primaryEmailId = email.email_id;
        }
      }
      if (primaryEmailId) {
        cs.users.update(user.id, { primary_email_address_id: primaryEmailId });
      }
    }
  }
  if (config.organizations) {
    for (const orgCfg of config.organizations) {
      const existingSlug = orgCfg.slug ?? orgCfg.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
      const existing = cs.organizations.findOneBy("slug", existingSlug);
      if (existing) continue;
      const orgId = orgCfg.clerk_id ?? generateClerkId("org_");
      const org = cs.organizations.insert({
        clerk_id: orgId,
        name: orgCfg.name,
        slug: existingSlug,
        image_url: null,
        has_logo: false,
        members_count: 0,
        pending_invitations_count: 0,
        public_metadata: orgCfg.public_metadata ?? {},
        private_metadata: orgCfg.private_metadata ?? {},
        max_allowed_memberships: orgCfg.max_allowed_memberships ?? null,
        admin_delete_enabled: true,
        created_at_unix: now,
        updated_at_unix: now
      });
      if (orgCfg.members) {
        let memberCount = 0;
        for (const memberCfg of orgCfg.members) {
          const emailEntry = cs.emailAddresses.findOneBy("email_address", memberCfg.email);
          if (!emailEntry) continue;
          const user = cs.users.findOneBy("clerk_id", emailEntry.user_id);
          if (!user) continue;
          const existingMembership = cs.memberships.findBy("org_id", orgId).find((m) => m.user_id === user.clerk_id);
          if (existingMembership) continue;
          const role = memberCfg.role.startsWith("org:") ? memberCfg.role : `org:${memberCfg.role}`;
          cs.memberships.insert({
            membership_id: generateClerkId("orgmem_"),
            org_id: orgId,
            user_id: user.clerk_id,
            role,
            permissions: role === "org:admin" ? [
              "org:sys_profile:manage",
              "org:sys_profile:delete",
              "org:sys_memberships:read",
              "org:sys_memberships:manage"
            ] : ["org:sys_memberships:read"],
            public_metadata: {},
            private_metadata: {},
            created_at_unix: now,
            updated_at_unix: now
          });
          memberCount++;
        }
        cs.organizations.update(org.id, { members_count: memberCount });
      }
    }
  }
  if (config.oauth_applications) {
    for (const appCfg of config.oauth_applications) {
      const existing = cs.oauthApps.findOneBy("client_id", appCfg.client_id);
      if (existing) continue;
      cs.oauthApps.insert({
        app_id: generateClerkId("oauth_app_"),
        name: appCfg.name,
        client_id: appCfg.client_id,
        client_secret: appCfg.client_secret ?? "",
        is_public: appCfg.public ?? false,
        scopes: appCfg.scopes ?? ["openid", "profile", "email"],
        redirect_uris: appCfg.redirect_uris,
        created_at_unix: now,
        updated_at_unix: now
      });
    }
  }
}
var clerkPlugin = {
  name: "clerk",
  register(app, store, webhooks, baseUrl, tokenMap) {
    const ctx = { app, store, webhooks, baseUrl, tokenMap };
    oauthRoutes(ctx);
    userRoutes(ctx);
    emailAddressRoutes(ctx);
    organizationRoutes(ctx);
    membershipRoutes(ctx);
    invitationRoutes(ctx);
    sessionRoutes(ctx);
  },
  seed(store, baseUrl) {
    seedDefaults(store, baseUrl);
  }
};
var index_default = clerkPlugin;
export {
  clerkPlugin,
  index_default as default,
  getClerkStore,
  seedFromConfig
};
//# sourceMappingURL=dist-AMC3DYXT.js.map