@popgrids/embed 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["getComputedStyle","t"],"sources":["../src/helpers/author.ts","../src/lib/backoff.ts","../src/lib/popup-auth.ts","../src/store/embed-auth-store.ts","../src/store/registry.ts","../src/styles/base.css?inline","../src/styles/buttons.css?inline","../src/styles/masks.css?inline","../src/helpers/theme.ts","../src/components/base-element.ts","../src/components/refs.ts","../src/components/pop-account-switcher.ts","../src/components/pop-auth-code.ts","../src/assets/apple-icon.png?inline","../src/assets/google-icon.png?inline","../src/assets/wordmark-svg.ts","../src/components/pop-auth-email.ts","../src/assets/swirling-ovals.gif?inline","../src/components/pop-auth-join.ts","../src/components/pop-auth-no-code.ts","../src/assets/watermark@2x.png","../src/components/pop-auth-panel.ts","../src/components/pop-button-link.ts","../src/assets/popgrids-letter-p.png?inline","../src/helpers/color.ts","../src/components/pop-comment-avatar.ts","../src/store/grid-store.ts","../src/components/pop-comment-bar.ts","../src/components/pop-comment-icon.ts","../src/components/pop-comment-input.ts","../src/components/pop-comment-thread.ts","../src/helpers/time.ts","../src/components/pop-comment.ts","../src/components/pop-feed.ts","../../../node_modules/.pnpm/@floating-ui+utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs","../../../node_modules/.pnpm/composed-offset-position@0.0.6_@floating-ui+utils@0.2.12/node_modules/composed-offset-position/dist/composed-offset-position.browser.min.mjs","../src/components/pop-grid.ts","../src/components/pop-widget.ts","../src/index.ts"],"sourcesContent":["export function getInitials(name: string | null | undefined): string {\n if (!name) return \"?\";\n return name\n .split(\" \")\n .map((p) => p[0] ?? \"\")\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n}\n","/**\n * \"Full jitter\" exponential backoff (AWS's exponential-backoff-and-jitter\n * recipe): the delay for a given attempt is a random value between 0 and the\n * exponential ceiling, not the ceiling itself. Pure exponential backoff only\n * bounds how hard one client retries — every client that disconnects at the\n * same instant (a DO/Worker blip, a deploy) computes the identical delay\n * sequence and retries in lockstep waves. Randomizing spreads a correlated\n * mass-reconnect out over time instead of turning it into a thundering herd.\n */\nexport function reconnectDelayMs(attempt: number, baseMs: number, capMs: number): number {\n const ceiling = Math.min(baseMs * 2 ** attempt, capMs);\n return Math.floor(Math.random() * ceiling);\n}\n","import type { AuthUser } from \"../types/models.js\";\n\nexport const EMBED_AUTH_SOURCE = \"popgrids-embed\";\nexport const EMBED_AUTH_SUCCESS = \"popgrids:auth:success\";\nexport const EMBED_AUTH_ERROR = \"popgrids:auth:error\";\n\nexport const EMBED_AUTH_LOGIN_PATH = \"/embed/auth/login\";\nexport const POPUP_NAME = \"popgrids-auth\";\nexport const POPUP_FEATURES = \"popup,width=480,height=640\";\nexport const AUTH_TIMEOUT_MS = 5 * 60 * 1000;\n\n// Grace window after the popup closes before treating it as a cancellation —\n// covers the message-dispatch/processing delay, not a cookie check (there's\n// no cookie fallback anymore: the server delays window.close() until after\n// postMessage so the message should already have arrived by the time we get\n// here in the normal case).\nconst POPUP_CLOSE_GRACE_MS = 250;\n\nexport class PopupAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PopupAuthError\";\n }\n}\n\n// Popup was closed without completing sign-in — not a real error, so callers can skip showing it.\nexport class PopupAuthCancelledError extends PopupAuthError {\n constructor(message = \"Sign-in was cancelled\") {\n super(message);\n this.name = \"PopupAuthCancelledError\";\n }\n}\n\nexport interface EmbedAuthSuccess {\n user: AuthUser;\n token: string;\n expiresAt: number;\n}\n\nexport const buildEmbedLoginUrl = (apiUrl: string, publicKey: string, returnOrigin: string) => {\n const url = new URL(EMBED_AUTH_LOGIN_PATH, apiUrl);\n url.searchParams.set(\"publicKey\", publicKey);\n url.searchParams.set(\"returnOrigin\", returnOrigin);\n return url.toString();\n};\n\nexport const openPopgridsLoginPopup = (apiUrl: string, publicKey: string) => {\n const popup = window.open(\n buildEmbedLoginUrl(apiUrl, publicKey, window.location.origin),\n POPUP_NAME,\n POPUP_FEATURES,\n );\n\n if (!popup) {\n throw new PopupAuthError(\"Popup blocked. Allow popups for this site and try again.\");\n }\n\n return popup;\n};\n\nconst isAuthMessage = (data: unknown, type: string) =>\n typeof data === \"object\" &&\n data !== null &&\n \"type\" in data &&\n \"source\" in data &&\n (data as { type: string; source: string }).type === type &&\n (data as { type: string; source: string }).source === EMBED_AUTH_SOURCE;\n\nconst readAuthSuccess = (data: unknown): EmbedAuthSuccess | null => {\n if (typeof data !== \"object\" || data === null || !(\"user\" in data)) {\n return null;\n }\n\n const record = data as { user?: unknown; token?: unknown; expiresAt?: unknown };\n const user = record.user;\n\n if (typeof user !== \"object\" || user === null || !(\"id\" in user)) {\n return null;\n }\n\n const userRecord = user as {\n id?: unknown;\n name?: unknown;\n email?: unknown;\n image?: unknown;\n };\n\n if (typeof userRecord.id !== \"string\") {\n return null;\n }\n\n if (typeof record.token !== \"string\" || typeof record.expiresAt !== \"number\") {\n return null;\n }\n\n return {\n user: {\n id: userRecord.id,\n name: typeof userRecord.name === \"string\" ? userRecord.name : \"\",\n email: typeof userRecord.email === \"string\" ? userRecord.email : \"\",\n image: typeof userRecord.image === \"string\" ? userRecord.image : null,\n },\n token: record.token,\n expiresAt: record.expiresAt,\n };\n};\n\nexport const waitForPopgridsAuth = (\n apiUrl: string,\n popup: Window,\n options?: {\n onAuthSuccess?: (result: EmbedAuthSuccess) => void;\n },\n) =>\n new Promise<void>((resolve, reject) => {\n const expectedOrigin = new URL(apiUrl).origin;\n let settled = false;\n\n const settle = (result: \"resolve\" | \"reject\", error?: PopupAuthError) => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n if (result === \"resolve\") {\n resolve();\n return;\n }\n reject(error ?? new PopupAuthError(\"Sign-in failed\"));\n };\n\n const onMessage = (event: MessageEvent) => {\n if (event.origin !== expectedOrigin) {\n return;\n }\n\n if (isAuthMessage(event.data, EMBED_AUTH_SUCCESS)) {\n const result = readAuthSuccess(event.data);\n if (!result) {\n settle(\"reject\", new PopupAuthError(\"Sign-in failed\"));\n return;\n }\n options?.onAuthSuccess?.(result);\n settle(\"resolve\");\n return;\n }\n\n if (isAuthMessage(event.data, EMBED_AUTH_ERROR)) {\n const message =\n typeof event.data === \"object\" &&\n event.data !== null &&\n \"error\" in event.data &&\n typeof (event.data as { error?: unknown }).error === \"string\"\n ? (event.data as { error: string }).error\n : \"Sign-in failed\";\n settle(\"reject\", new PopupAuthError(message));\n }\n };\n\n const interval = window.setInterval(() => {\n if (!popup.closed || settled) {\n return;\n }\n\n clearInterval(interval);\n\n window.setTimeout(() => {\n if (settled) return;\n settle(\"reject\", new PopupAuthCancelledError());\n }, POPUP_CLOSE_GRACE_MS);\n }, 300);\n\n const timeout = window.setTimeout(() => {\n try {\n popup.close();\n } catch {\n // ignore\n }\n settle(\"reject\", new PopupAuthError(\"Sign-in timed out\"));\n }, AUTH_TIMEOUT_MS);\n\n const cleanup = () => {\n window.removeEventListener(\"message\", onMessage);\n clearInterval(interval);\n clearTimeout(timeout);\n };\n\n window.addEventListener(\"message\", onMessage);\n });\n\nexport const signInWithPopup = async (\n apiUrl: string,\n publicKey: string,\n options?: {\n onAuthSuccess?: (result: EmbedAuthSuccess) => void;\n },\n) => {\n const popup = openPopgridsLoginPopup(apiUrl, publicKey);\n await waitForPopgridsAuth(apiUrl, popup, options);\n};\n","import { signal } from \"@preact/signals-core\";\nimport { reconnectDelayMs } from \"../lib/backoff.js\";\nimport { PopupAuthCancelledError, signInWithPopup } from \"../lib/popup-auth.js\";\nimport type { AuthUser, EmbedSession, OrgOption } from \"../types/models.js\";\n\nconst TOKEN_HEADER = \"X-PopGrids-Embed-Token\";\nconst OTP_EXPIRES_MS = 5 * 60 * 1000;\n// Better Auth's emailOTP error code for a code past its lifetime, forwarded\n// by the embed API's otp/verify route.\nconst OTP_EXPIRED_CODE = \"OTP_EXPIRED\";\nconst OTP_TOO_MANY_ATTEMPTS_CODE = \"TOO_MANY_ATTEMPTS\";\nconst OTP_INVALID_CODE = \"INVALID_OTP\";\nconst DEFAULT_NOTICE_ACTION = \"Dismiss\";\n// Better Auth's rate-limit window for the sign-in routes, used if a 429 arrives without a retry time.\nconst DEFAULT_RETRY_AFTER_S = 60;\nconst NETWORK_ERROR_MESSAGE = \"Can’t reach PopGrids. Check your connection and try again.\";\n// Same backoff ceiling as GridStore's comment socket (grid-store.ts) — kept\n// as a separate constant since this auth-only channel reconnects\n// independently of the comment socket.\nconst MAX_AUTH_RECONNECT_DELAY_MS = 30_000;\n\n// localStorage, not sessionStorage: sign-in is meant to survive a closed\n// tab and a fresh page load (see docs/adr/0009), not just live in the tab\n// that created it. That also means cross-tab sync is free — localStorage's\n// native `storage` event already fires in every *other* same-origin tab\n// whenever this key changes, so a sign-in (or a sliding-expiry renewal — see\n// checkSession) in one tab reaches every other open tab for this grid with\n// no extra channel to manage. It never fires in the tab that made the\n// write, so there's no risk of an update loop.\nconst storageKey = (publicKey: string) => `popgrids:embed-session:${publicKey}`;\n\nconst isValidSession = (value: unknown): value is EmbedSession =>\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as Partial<EmbedSession>).token === \"string\" &&\n typeof (value as Partial<EmbedSession>).expiresAt === \"number\" &&\n !!(value as Partial<EmbedSession>).user;\n\nexport type EmbedAuthView = \"idle\" | \"email\" | \"code\" | \"no-code\";\n\n/**\n * Owns auth state for one `<pop-grid>` instance — registered per-element\n * (see registry.ts) rather than as a page-global singleton, so multiple\n * widgets with different publicKeys on the same page don't share identity.\n */\nexport class EmbedAuthStore {\n readonly apiUrl: string;\n readonly publicKey: string;\n\n currentUser = signal<AuthUser | null>(null);\n authError = signal<string | null>(null);\n /** Label for the notice's button (it always just dismisses the notice). Set via showAuthError. */\n authErrorAction = signal(DEFAULT_NOTICE_ACTION);\n /**\n * Bumped each time the visitor dismisses the notice (vs. it clearing on its\n * own, e.g. the panel closing) so the auth cards can hand focus back to\n * their field — the notice made everything under it inert until now.\n */\n authNoticeDismissals = signal(0);\n /**\n * When set, the notice is a rate-limit wait: its button becomes a\n * countdown to this timestamp and the notice dismisses itself at zero.\n */\n authErrorRetryAt = signal<number | null>(null);\n authPending = signal(false);\n\n /**\n * Accounts the signed-in visitor can comment as (see switchOrganization) —\n * populated after sign-in, independent of which one is currently active.\n * The *active* account syncs across every same-browser tab (they share one\n * token — see ADR 0011); this list itself doesn't need to, since it's the\n * same accounts regardless of which is active.\n */\n organizations = signal<OrgOption[]>([]);\n /** True while an organizations fetch is in flight — drives the switcher's spinner. */\n organizationsLoading = signal(false);\n\n /**\n * Inline email+OTP sign-in state (see pop-auth-panel.ts). Kept separate\n * from authPending/authError above, which stay owned by the OAuth popup\n * flow (requestSignIn) — the two flows can be mid-progress independently.\n */\n authView = signal<EmbedAuthView>(\"idle\");\n otpEmail = signal<string>(\"\");\n otpPending = signal(false);\n otpError = signal<string | null>(null);\n otpExpiresAt = signal<number | null>(null);\n\n private session: EmbedSession | null;\n\n // Auth-only realtime channel (separate from GridStore's comment socket):\n // pushes a sign-out that happened elsewhere (main app, or another widget)\n // so this widget flips to signed-out immediately instead of only\n // discovering its key is dead on its next request. See the embed's\n // /auth/connect-ticket + /auth/connect routes and the User Durable\n // Object's sessionRevoked() on the backend.\n private authSocket: WebSocket | null = null;\n private authReconnectAttempt = 0;\n private authReconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private destroyed = false;\n\n // Cross-tab sync — see storageKey's comment. Bound as a field (not a\n // method) so removeEventListener in destroy() can target the exact same\n // function reference.\n private onStorageEvent = (event: StorageEvent): void => {\n if (event.storageArea !== window.localStorage || event.key !== storageKey(this.publicKey)) {\n return;\n }\n\n this.applyExternalChange(event.newValue);\n };\n\n /**\n * Every live store on this page. The `storage` event never fires in the\n * document that made the write, so two grids with the same publicKey on\n * one page (which share a localStorage key) would otherwise never hear\n * about each other's sign-in or sign-out until reload — see notifySiblings.\n */\n private static instances = new Set<EmbedAuthStore>();\n private static syncing = false;\n\n /** Applies a session change made elsewhere — another tab (storage event) or another grid on this page (notifySiblings). */\n private applyExternalChange(newValue: string | null): void {\n if (newValue === null) {\n // Another tab/grid cleared its session (signed out, locally or via the\n // push). Redundant with that same sign-out's own WS push reaching\n // this store, but a free, faster confirmation — and correct on its own\n // even if this store's socket happens to be mid-reconnect.\n if (this.currentUser.value) {\n this.handleSignedOut();\n }\n return;\n }\n\n try {\n const parsed: unknown = JSON.parse(newValue);\n if (isValidSession(parsed) && parsed.expiresAt > Date.now()) {\n this.writeStoredSession(parsed);\n }\n } catch {\n // Malformed value written by something else — ignore.\n }\n }\n\n /** Pushes a local session change to other grids on this page sharing our publicKey. */\n private notifySiblings(newValue: string | null): void {\n if (EmbedAuthStore.syncing) return;\n\n EmbedAuthStore.syncing = true;\n try {\n for (const store of EmbedAuthStore.instances) {\n if (store !== this && store.publicKey === this.publicKey) {\n store.applyExternalChange(newValue);\n }\n }\n } finally {\n EmbedAuthStore.syncing = false;\n }\n }\n\n constructor(opts: { apiUrl: string; publicKey: string }) {\n this.apiUrl = opts.apiUrl;\n this.publicKey = opts.publicKey;\n this.session = this.readStoredSession();\n this.currentUser.value = this.session?.user ?? null;\n\n window.addEventListener(\"storage\", this.onStorageEvent);\n EmbedAuthStore.instances.add(this);\n\n // Deliberately not connecting the auth channel here — see\n // connectAuthChannel's own comment. It's triggered from pop-feed.ts\n // once the panel actually opens, not on construction.\n }\n\n /** Closes the auth channel, cancels any pending reconnect, and stops listening for cross-tab changes — call from the owning element's disconnectedCallback. */\n destroy(): void {\n this.destroyed = true;\n this.closeAuthChannel();\n window.removeEventListener(\"storage\", this.onStorageEvent);\n EmbedAuthStore.instances.delete(this);\n }\n\n private readStoredSession(): EmbedSession | null {\n try {\n const raw = window.localStorage.getItem(storageKey(this.publicKey));\n if (!raw) return null;\n\n const parsed: unknown = JSON.parse(raw);\n if (!isValidSession(parsed)) {\n return null;\n }\n\n if (parsed.expiresAt <= Date.now()) {\n this.clearStoredSession();\n return null;\n }\n\n return parsed;\n } catch {\n return null;\n }\n }\n\n /**\n * Just the storage write, no side effects — for keeping the persisted\n * session in sync with a sliding-expiry renewal (checkSession) without\n * redoing loadOrganizations/reconnecting the auth channel for what's\n * still the same identity. writeStoredSession (below) is for an actual\n * sign-in (new or adopted from another tab), where those side effects\n * are the point.\n */\n private persistSession(session: EmbedSession): void {\n this.session = session;\n try {\n window.localStorage.setItem(storageKey(this.publicKey), JSON.stringify(session));\n } catch {\n // localStorage unavailable (private mode, quota) — auth still works\n // for the rest of this page load, just won't survive one.\n }\n this.notifySiblings(JSON.stringify(session));\n }\n\n private writeStoredSession(session: EmbedSession): void {\n this.persistSession(session);\n // Set before kicking off connectAuthChannel below — it guards on\n // currentUser being set, so callers no longer need (and must not rely\n // on) their own separate assignment after this call.\n this.currentUser.value = session.user;\n // Any pending \"signed out\" notice is stale now — including in other tabs\n // that adopt this session via the storage/BroadcastChannel path.\n this.authError.value = null;\n // Reset rather than leave whatever was cached: this write might be a\n // different identity entirely (a fresh sign-in, or a cross-tab-adopted\n // one for someone else on the same browser) whose accounts the old list\n // doesn't belong to. loadOrganizations() is lazy now (see\n // pop-account-switcher.ts) — it's fetched again next time the switcher\n // actually opens, not eagerly here.\n this.organizations.value = [];\n\n // A socket already open (or actively retrying) belongs to whichever\n // identity was signed in before this write (could be nobody, could be\n // someone else entirely — e.g. re-authenticating locally, or this\n // session was just adopted from another tab's sign-in). Only reconnect\n // if that was actually the case: a live/retrying channel means this\n // tab's panel is genuinely open and watching for pushes, so the new\n // identity needs a fresh socket right away. A tab with no channel yet\n // has never had its panel opened — leave it that way. Reconnecting here\n // regardless would mean any signed-in tab immediately re-verifies with\n // the server the instant *any other* same-browser tab writes a session\n // (a fresh sign-in, a switch, cross-tab adoption), even if this tab's\n // own panel is closed — exactly the eager-on-load verification ADR 0010\n // removed. The panel-open effect (pop-feed.ts) connects for whichever\n // identity is current the first time this tab's panel actually opens.\n const hadChannel = this.authSocket !== null || this.authReconnectTimer !== null;\n this.closeAuthChannel();\n if (hadChannel) {\n void this.connectAuthChannel();\n }\n }\n\n private clearStoredSession(): void {\n this.session = null;\n try {\n window.localStorage.removeItem(storageKey(this.publicKey));\n } catch {\n // ignore\n }\n this.notifySiblings(null);\n this.organizations.value = [];\n this.closeAuthChannel();\n }\n\n /**\n * Current token, or null if missing/expired (clearing state — and, if we\n * were signed in, showing the \"you were signed out\" message — as a side\n * effect of expiry). This is a local-only check against the last\n * `expiresAt` this tab persisted: if the credential was actually renewed\n * from a *different*, still-open tab/device while this one sat closed\n * past its own locally-known expiry, this can call it expired a little\n * early rather than re-confirming with the server — an occasional,\n * low-stakes extra sign-in prompt, traded for not hitting the server on\n * every single token read just to double-check a locally-expired date.\n */\n private get token(): string | null {\n if (!this.session) return null;\n\n if (this.session.expiresAt <= Date.now()) {\n this.handleSignedOut();\n return null;\n }\n\n return this.session.token;\n }\n\n /**\n * Attaches the stored token (if any) and returns the response as-is — no\n * retry-via-popup. Use for reads that should silently show \"signed out\"\n * on 401 rather than interrupting the visitor (grid/comments GET, session\n * check, WS connect-ticket mint — the last of which must also work for\n * anonymous/signed-out visitors).\n */\n async fetchWithToken(path: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers);\n const token = this.token;\n if (token) {\n headers.set(TOKEN_HEADER, token);\n }\n return fetch(new URL(path, this.apiUrl), { ...init, headers });\n }\n\n /**\n * Same as fetchWithToken, but on a 401 prompts sign-in inline (the\n * visitor's already looking at the open panel, mid-action — that's\n * exactly what triggered this) and retries once. Use only for actions the\n * visitor just explicitly initiated (post/edit/delete/flag a comment) —\n * never for passive/background reads, since this interrupts them with a\n * prompt.\n *\n * The request being retried already has whatever the visitor typed baked\n * into it (e.g. postComment captures the comment body into the request\n * before this ever runs) — requestInlineSignIn() only has to get them\n * back to a valid session; it doesn't need to preserve or restore\n * anything itself for the retry to pick up right where they left off.\n */\n async authorizedFetch(path: string, init: RequestInit = {}): Promise<Response> {\n let res = await this.fetchWithToken(path, init);\n\n if (res.status === 401) {\n const signedIn = await this.requestInlineSignIn();\n if (!signedIn) {\n return res;\n }\n res = await this.fetchWithToken(path, init);\n }\n\n return res;\n }\n\n private async readError(\n res: Response,\n ): Promise<{ message: string; code?: string; retryAfter?: number }> {\n try {\n const data = (await res.json()) as { error?: unknown; code?: unknown; retryAfter?: unknown };\n return {\n message:\n typeof data.error === \"string\" && data.error\n ? data.error\n : \"Something went wrong. Please try again.\",\n code: typeof data.code === \"string\" ? data.code : undefined,\n retryAfter: typeof data.retryAfter === \"number\" ? data.retryAfter : undefined,\n };\n } catch {\n // ignore — fall through to the generic message\n }\n return { message: \"Something went wrong. Please try again.\" };\n }\n\n /** Transitions from the idle \"Join the Conversation\" state into the inline email form. */\n startEmailSignIn(): void {\n this.otpError.value = null;\n this.authView.value = \"email\";\n }\n\n backToIdle(): void {\n this.otpError.value = null;\n this.otpEmail.value = \"\";\n this.otpExpiresAt.value = null;\n this.authView.value = \"idle\";\n // Leaving the flow entirely (vs. backToEmail, one step back within it)\n // is the one place that counts as abandoning a pending\n // requestInlineSignIn() prompt.\n this.resolveInlineSignIn?.(false);\n }\n\n backToEmail(): void {\n this.otpError.value = null;\n this.authView.value = \"email\";\n }\n\n /**\n * The code can no longer be used: drop back to the email step to request a\n * new one. otpEmail is kept (in memory only) so the email field can be\n * prefilled rather than making the visitor retype it.\n */\n expireOtp(): void {\n this.authView.value = \"email\";\n this.otpExpiresAt.value = null;\n this.otpError.value = null;\n }\n\n /** One step back from the no-code help card, to the code entry it was opened from. */\n backToCode(): void {\n this.authView.value = \"code\";\n }\n\n showNoCode(): void {\n this.authView.value = \"no-code\";\n }\n\n /** Sends (or resends) a sign-in code to `email`. No token yet — the visitor isn't signed in. */\n async sendOtp(email: string): Promise<boolean> {\n this.otpPending.value = true;\n this.otpError.value = null;\n\n try {\n const res = await fetch(\n new URL(`/api/v1/embed/grids/${this.publicKey}/auth/otp/send`, this.apiUrl),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email }),\n },\n );\n\n if (!res.ok) {\n const { message, retryAfter } = await this.readError(res);\n if (res.status === 429) {\n this.showRateLimited(retryAfter);\n } else {\n this.otpError.value = message;\n }\n return false;\n }\n\n this.otpEmail.value = email;\n this.otpExpiresAt.value = Date.now() + OTP_EXPIRES_MS;\n this.authView.value = \"code\";\n return true;\n } catch {\n this.showAuthError(NETWORK_ERROR_MESSAGE);\n return false;\n } finally {\n this.otpPending.value = false;\n }\n }\n\n async resendOtp(): Promise<boolean> {\n if (!this.otpEmail.value) return false;\n return this.sendOtp(this.otpEmail.value);\n }\n\n /** Verifies `code` against the in-progress email and, on success, signs the visitor in. */\n async verifyOtp(code: string): Promise<boolean> {\n this.otpPending.value = true;\n this.otpError.value = null;\n\n try {\n const res = await fetch(\n new URL(`/api/v1/embed/grids/${this.publicKey}/auth/otp/verify`, this.apiUrl),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email: this.otpEmail.value, otp: code }),\n },\n );\n\n if (!res.ok) {\n const { message, code, retryAfter } = await this.readError(res);\n if (res.status === 429) {\n this.showRateLimited(retryAfter);\n } else if (code === OTP_TOO_MANY_ATTEMPTS_CODE) {\n // The server has burned this code too, so it's the same dead end as\n // expiry — but the visitor did something, so tell them why.\n this.expireOtp();\n this.showAuthError(\"Too many attempts.\", \"Request a new code\");\n } else if (code === OTP_EXPIRED_CODE) {\n // An expired code can never succeed, so go back to re-enter the\n // email — silently, same as when the countdown hits zero.\n this.expireOtp();\n } else if (code === OTP_INVALID_CODE) {\n // Better Auth's own wording says \"OTP\"; the visitor knows it as a code.\n this.otpError.value = \"Invalid code\";\n } else {\n this.otpError.value = message;\n }\n return false;\n }\n\n const data = (await res.json()) as EmbedSession;\n this.writeStoredSession(data);\n this.authView.value = \"idle\";\n this.otpEmail.value = \"\";\n this.otpExpiresAt.value = null;\n this.resolveInlineSignIn?.(true);\n return true;\n } catch {\n this.showAuthError(NETWORK_ERROR_MESSAGE);\n return false;\n } finally {\n this.otpPending.value = false;\n }\n }\n\n async requestSignIn(): Promise<boolean> {\n this.authError.value = null;\n this.authPending.value = true;\n\n try {\n await signInWithPopup(this.apiUrl, this.publicKey, {\n onAuthSuccess: ({ user, token, expiresAt }) => {\n this.writeStoredSession({ token, expiresAt, user });\n },\n });\n\n return this.currentUser.value !== null;\n } catch (error) {\n if (!(error instanceof PopupAuthCancelledError)) {\n this.showAuthError(error instanceof Error ? error.message : \"Sign-in failed\");\n }\n return false;\n } finally {\n this.authPending.value = false;\n }\n }\n\n /**\n * Resolves the promise a pending requestInlineSignIn() call is awaiting —\n * set while one's in progress, called from verifyOtp()'s success path\n * (true) and backToIdle() (false, abandoned). Not a public method: it's\n * the completion half of requestInlineSignIn(), nothing else should call it.\n */\n private resolveInlineSignIn: ((success: boolean) => void) | null = null;\n private inlineSignInPromise: Promise<boolean> | null = null;\n\n /**\n * Reactive re-auth for authorizedFetch(): puts the widget into the inline\n * sign-in flow (the panel's already open — that's what triggered this,\n * mid-write) and waits for it to resolve, rather than opening the OAuth\n * popup the way the old checkSession-driven path did. Concurrent callers\n * (e.g. two writes racing into a 401 around the same time) join the same\n * pending prompt instead of each resetting it back to the email step.\n */\n requestInlineSignIn(): Promise<boolean> {\n if (this.inlineSignInPromise) {\n return this.inlineSignInPromise;\n }\n\n this.startEmailSignIn();\n this.inlineSignInPromise = new Promise<boolean>((resolve) => {\n this.resolveInlineSignIn = (success) => {\n this.inlineSignInPromise = null;\n this.resolveInlineSignIn = null;\n resolve(success);\n };\n });\n return this.inlineSignInPromise;\n }\n\n private showAuthError(\n message: string,\n action = DEFAULT_NOTICE_ACTION,\n retryAfterSeconds?: number,\n ): void {\n this.authErrorAction.value = action;\n this.authErrorRetryAt.value =\n retryAfterSeconds === undefined ? null : Date.now() + retryAfterSeconds * 1000;\n this.authError.value = message;\n }\n\n /** A 429: show the wait as a countdown (see authErrorRetryAt) instead of letting the visitor hammer the endpoint. */\n private showRateLimited(retryAfter: number | undefined): void {\n this.showAuthError(\n \"Too many requests.\",\n DEFAULT_NOTICE_ACTION,\n retryAfter ?? DEFAULT_RETRY_AFTER_S,\n );\n }\n\n dismissAuthError(): void {\n this.clearAuthError();\n this.authNoticeDismissals.value += 1;\n }\n\n clearAuthError(): void {\n this.authError.value = null;\n }\n\n /**\n * Fetches the accounts the signed-in visitor can comment as (for the\n * switcher UI) — lazily: called on demand when the switcher's dropdown\n * opens (pop-account-switcher.ts), not proactively on sign-in or page\n * load. Once populated, `organizations` acts as its own cache — callers\n * should check `organizations.value.length === 0` before calling this\n * rather than calling it unconditionally, which also means a prior\n * failed attempt gets retried the next time the dropdown opens rather\n * than being stuck empty forever.\n */\n async loadOrganizations(): Promise<void> {\n if (!this.currentUser.value) {\n this.organizations.value = [];\n return;\n }\n\n if (this.organizationsLoading.value) {\n return; // Already in flight (e.g. the dropdown was closed and reopened before it resolved).\n }\n\n this.organizationsLoading.value = true;\n try {\n const res = await this.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/auth/organizations`,\n );\n if (!res.ok) return;\n\n const data = (await res.json()) as { organizations: OrgOption[] };\n this.organizations.value = data.organizations;\n } catch {\n // Leave organizations empty on failure (no partial/stale data to fall\n // back to, since this only ever runs when it was already empty) — the\n // switcher shows no accounts and the next dropdown open retries.\n } finally {\n this.organizationsLoading.value = false;\n }\n }\n\n /**\n * Switches which account this widget's comments post as. Doesn't touch or\n * read the main app's active org — but the api key itself (and thus which\n * account it's scoped to server-side) is the same one every same-browser\n * tab shares via localStorage (see ADR 0009), so a switch here already\n * changes every other tab's underlying identity whether we tell them or\n * not. persistSession below keeps their displayed state honest via the\n * same native `storage` event sign-in already propagates through — see\n * ADR 0011, which corrects ADR 0008's original \"switching stays local\"\n * framing now that the token itself is shared.\n */\n async switchOrganization(organizationId: string): Promise<boolean> {\n const res = await this.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/auth/organizations/${organizationId}`,\n { method: \"POST\" },\n );\n\n if (!res.ok) {\n if (res.status === 401) {\n this.handleSignedOut();\n }\n return false;\n }\n\n const data = (await res.json()) as { user: AuthUser };\n this.currentUser.value = data.user;\n if (this.session) {\n this.persistSession({ ...this.session, user: data.user });\n }\n return true;\n }\n\n /** Signs this identity out everywhere (main app + every other widget), not just this one. */\n async signOutEverywhere(): Promise<boolean> {\n const res = await this.fetchWithToken(`/api/v1/embed/grids/${this.publicKey}/auth/sign-out`, {\n method: \"POST\",\n });\n\n if (res.ok) {\n // silent: they're looking right at the \"Sign out\" click they just\n // made — the \"you were signed out\" message below is for discovering\n // it happened somewhere else, not for confirming an action just taken.\n this.handleSignedOut({ silent: true });\n }\n\n return res.ok;\n }\n\n /** Shared cleanup for every way this widget learns it's signed out: a pushed session.revoked, a 401 from an authed call, an expired remembered sign-in, or the visitor's own sign-out. */\n private handleSignedOut(options?: { silent?: boolean }): void {\n const wasSignedIn = this.currentUser.value !== null;\n this.clearStoredSession();\n this.currentUser.value = null;\n this.authView.value = \"idle\";\n\n if (wasSignedIn && !options?.silent) {\n this.showAuthError(\"You were signed out. Sign in again to keep commenting.\");\n }\n }\n\n /**\n * Opens the auth-only push channel — and, as its one other job, the sole\n * point that verifies the token server-side and applies the sliding\n * renewal (see docs/adr/0009 and 0010). Not called on construction:\n * pop-feed.ts calls this once the panel first opens, since that's the\n * first moment the widget actually needs to know anything about auth\n * beyond what's already cached locally (the collapsed pill shows other\n * commenters, never the current visitor's own identity). Safe to call\n * repeatedly — no-ops once a socket is already open.\n */\n async connectAuthChannel(): Promise<void> {\n if (this.destroyed || this.authSocket || !this.currentUser.value) {\n return;\n }\n\n let ticket: string | null = null;\n let unauthorized = false;\n try {\n const ticketRes = await this.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/auth/connect-ticket`,\n { method: \"POST\" },\n );\n if (ticketRes.ok) {\n // The connect-ticket route now also verifies + applies the sliding\n // renewal and returns the current user — folded in here rather\n // than a separate /session call, since this request already\n // happens on every panel open regardless.\n const ticketData = (await ticketRes.json()) as {\n ticket: string;\n user: AuthUser;\n expiresAt: number | null;\n };\n ticket = ticketData.ticket;\n this.currentUser.value = ticketData.user;\n if (\n this.session &&\n ticketData.expiresAt &&\n ticketData.expiresAt !== this.session.expiresAt\n ) {\n this.persistSession({\n ...this.session,\n user: ticketData.user,\n expiresAt: ticketData.expiresAt,\n });\n }\n } else if (ticketRes.status === 401) {\n // The token is durably invalid (e.g. this tab was reopened after\n // being signed out elsewhere while closed) — stop retrying and\n // reflect it immediately instead of backing off forever.\n unauthorized = true;\n }\n } catch {\n // No auth channel this attempt — scheduleAuthReconnect will try again.\n }\n\n if (unauthorized) {\n this.handleSignedOut();\n return;\n }\n\n if (!ticket || this.destroyed || !this.currentUser.value) {\n this.scheduleAuthReconnect();\n return;\n }\n\n const wsUrl = new URL(`/api/v1/embed/grids/${this.publicKey}/auth/connect`, this.apiUrl);\n wsUrl.protocol = wsUrl.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n wsUrl.searchParams.set(\"ticket\", ticket);\n\n const socket = new WebSocket(wsUrl.toString());\n this.authSocket = socket;\n\n socket.onopen = () => {\n this.authReconnectAttempt = 0;\n };\n\n socket.onmessage = (event) => {\n try {\n const payload = JSON.parse(String(event.data)) as { type?: string };\n if (payload.type === \"session.revoked\") {\n this.handleSignedOut();\n }\n } catch {\n // Ignore malformed realtime payloads.\n }\n };\n\n socket.onclose = () => {\n this.authSocket = null;\n if (this.destroyed || !this.currentUser.value) {\n return;\n }\n this.scheduleAuthReconnect();\n };\n\n socket.onerror = () => {\n socket.close();\n };\n }\n\n private scheduleAuthReconnect(): void {\n if (this.destroyed || this.authReconnectTimer || !this.currentUser.value) {\n return;\n }\n\n const delay = reconnectDelayMs(this.authReconnectAttempt, 1000, MAX_AUTH_RECONNECT_DELAY_MS);\n this.authReconnectAttempt += 1;\n\n this.authReconnectTimer = setTimeout(() => {\n this.authReconnectTimer = null;\n void this.connectAuthChannel();\n }, delay);\n }\n\n private closeAuthChannel(): void {\n if (this.authReconnectTimer) {\n clearTimeout(this.authReconnectTimer);\n this.authReconnectTimer = null;\n }\n\n if (this.authSocket) {\n this.authSocket.onopen = null;\n this.authSocket.onmessage = null;\n this.authSocket.onclose = null;\n this.authSocket.onerror = null;\n this.authSocket.close();\n this.authSocket = null;\n }\n }\n}\n","const _registry = new WeakMap<Element, Map<any, any>>();\n\nexport const registerStore = (el: Element, store: any, key: any = store.constructor): void => {\n let stores = _registry.get(el);\n if (!stores) {\n stores = new Map();\n _registry.set(el, stores);\n }\n stores.set(key, store);\n};\n\nexport const unregisterStore = (el: Element): void => {\n _registry.delete(el);\n};\n\nexport const resolveStore = <T>(el: Element, key: any): T | null => {\n let node: Element | null = el;\n while (node) {\n const stores = _registry.get(node);\n const store = stores?.get(key);\n if (store) return store as T;\n\n const root = node.getRootNode();\n if (!(root instanceof ShadowRoot)) break;\n node = root.host;\n }\n return null;\n};\n\nexport function consume(storeKey: any) {\n return function (target: any, propertyKey: string) {\n const cacheKey = Symbol(\"context_\" + (storeKey.name || \"store\"));\n Object.defineProperty(target, propertyKey, {\n get(this: any) {\n if (this[cacheKey]) return this[cacheKey];\n const resolved = resolveStore(this, storeKey);\n if (!resolved) {\n console.error(`[Context] resolveStore failed! isConnected: ${this.isConnected}`, this);\n throw new Error(\n `[Context] Store for key \"${storeKey.name || storeKey}\" not resolved on <${this.localName}>.`\n );\n }\n this[cacheKey] = resolved;\n return resolved;\n },\n enumerable: true,\n configurable: true,\n });\n };\n}\n\n","@layer base {\n :host {\n box-sizing: border-box;\n color: var(--pop-foreground);\n font-family: \"Inter\", sans-serif;\n font-size: 16px;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n /* Color: Brand */\n --pop-color-brand-midnight-100: oklch(0.9658 0.0161 262.75);\n --pop-color-brand-midnight-900: oklch(0.15 0.03 255.43);\n --pop-color-brand-midnight-800: oklch(0.19 0.05 255.43);\n --pop-color-brand-ocean-400: oklch(0.63 0.19 255.43);\n --pop-color-brand-ocean-100: oklch(0.91 0.05 255.43);\n --pop-color-brand-forest-900: oklch(0.3866 0.0698 180.75);\n --pop-color-brand-forest-700: oklch(0.45 0.15 165.43);\n --pop-color-brand-forest-100: oklch(0.97 0.04 165.43);\n --pop-color-brand-highlight-400: oklch(0.88 0.25 105.43);\n --pop-color-brand-pumpkin-500: oklch(0.62 0.18 45.43);\n --pop-color-brand-pumpkin-200: oklch(0.89 0.08 45.43);\n --pop-color-brand-lemon-300: oklch(0.91 0.12 85.43);\n --pop-color-brand-lemon-100: oklch(0.97 0.04 85.43);\n\n /* Durations */\n --pop-duration-bouncy: 1s;\n --pop-duration-card-highlight: 0.6s;\n --pop-duration-gentle: 0.833s;\n --pop-duration-menu: 0.4s;\n --pop-duration-pop-hover: 0.6s;\n --pop-duration-pop-text: 0.3s;\n --pop-duration-quick: 0.833s;\n --pop-duration-slow: 1.167s;\n\n /* Easing */\n /* prettier-ignore */\n --pop-ease-bouncy: linear(0, 0.011, 0.045 1.3%, 0.184 2.7%, 0.911 7.4%, 1.153 9.4%, 1.301 11.2%, 1.342, 1.362 13%, 1.363, 1.355 14.4%, 1.306 16%, 1.028 21%, 0.939 23%, 0.89 24.7%, 0.876, 0.868 26.4%, 0.869, 0.882 29%, 0.907 30.5%, 1.014 35.9%, 1.038, 1.048 39.8% 41.1%, 1.043 42.5%, 0.995 49.3%, 0.987, 0.983 53.2%, 0.984 55.9%, 1.002 62.7%, 1.006 66.4%, 0.998 79.7%, 1);\n /* prettier-ignore */\n --pop-ease-card-highlight: linear(0, 0.008, 0.031 1.8%, 0.127 3.9%, 0.671 11.8%, 0.881 15.5%, 0.959, 1.02 19.2%, 1.064, 1.093 23.2%, 1.102, 1.108, 1.108, 1.104 28.7%, 1.089 31.4%, 1.038 38.1%, 1.016 41.5%, 0.999 45.4%, 0.99 49.6%, 0.989 55.3%, 1.001 74.9%, 1);\n /* prettier-ignore */\n --pop-ease-gentle: linear(0, 0.007, 0.026, 0.059 4.5%, 0.106 6.3%, 0.209 9.5%, 0.558 19.3%, 0.658, 0.742, 0.812, 0.87, 0.918, 0.957, 0.986 41.6%, 1.007 45.3%, 1.021 49.4%, 1.027 54% 60.9%, 1.007 83.2%, 1);\n /* prettier-ignore */\n --pop-ease-menu: linear(0, 0.0034 0.81%, 0.0278 2.42%, 0.097 4.84%, 0.5361 15.32%, 0.655 18.55%, 0.7314, 0.7964 23.39%, 0.8662, 0.9185, 0.9561, 0.9818, 0.9984, 1.0083 42.74%, 1.014 46.77%, 1.0145 53.22%, 1.0053 68.55%, 1.0019 77.42%, 0.9998 100%);\n /* prettier-ignore */\n --pop-ease-pop-hover: linear(0, 0.008, 0.031 1.8%, 0.127 3.9%, 0.671 11.8%, 0.881 15.5%, 0.959, 1.02 19.2%, 1.064, 1.093 23.2%, 1.102, 1.108, 1.108, 1.104 28.7%, 1.089 31.4%, 1.038 38.1%, 1.016 41.5%, 0.999 45.4%, 0.99 49.6%, 0.989 55.3%, 1.001 74.9%, 1);\n /* prettier-ignore */\n --pop-ease-pop-text: linear(0, 0.0051 0.99%, 0.0261, 0.0607 3.61%, 0.1192 5.26%, 0.2531 8.21%, 0.6509 16.1%, 0.7652 18.73%, 0.8512, 0.9232 23.33%, 0.9881 25.96%, 1.0305 28.26%, 1.0642 30.88%, 1.0782 32.53%, 1.089, 1.094 36.47%, 1.0942, 1.0896 41.07%, 1.0804 43.7%, 1.0354 53.23%, 1.0181 57.5%, 1.0061 61.44%, 0.9974 65.71%, 0.9925 70.31%, 0.991 75.9%, 0.9996 99.88%);\n /* prettier-ignore */\n --pop-ease-quick: linear(0, 0.008, 0.031 1.8%, 0.127 3.9%, 0.671 11.8%, 0.881 15.5%, 0.959, 1.02 19.2%, 1.064, 1.093 23.2%, 1.102, 1.108, 1.108, 1.104 28.7%, 1.089 31.4%, 1.038 38.1%, 1.016 41.5%, 0.999 45.4%, 0.99 49.6%, 0.989 55.3%, 1.001 74.9%, 1);\n /* prettier-ignore */\n --pop-ease-slow: linear(0, 0.005, 0.02 2%, 0.081 4.5%, 0.469 15.2%, 0.567, 0.65, 0.722 24.4%, 0.784, 0.835 31.1%, 0.878 34.9%, 0.914 39.1%, 0.942 43.8%, 0.964 49.1%, 0.979 55.4%, 0.989 62.4%, 0.995 71.1%, 1);\n\n /* Box-Shadow */\n --pop-shadow-xs: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);\n --pop-shadow-sm: 0px 1px 3px 0px rgba(16, 24, 40, 0.1), 0px 1px 2px 0px rgba(16, 24, 40, 0.06);\n --pop-shadow-md:\n 0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06);\n --pop-shadow-lg:\n 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);\n --pop-shadow-xl:\n 0px 20px 24px -4px rgba(16, 24, 40, 0.08), 0px 8px 8px -4px rgba(16, 24, 40, 0.03);\n --pop-shadow-2xl: 0px 24px 48px -12px rgba(16, 24, 40, 0.18);\n --pop-shadow-3xl: 0px 32px 48px -12px rgba(16, 24, 40, 0.32);\n --pop-shadow-4xl: 0px 24px 32px -12px rgba(16, 24, 40, 0.28);\n\n --pop-radius-none: 0; /* 0px */\n --pop-radius-xxs: 0.125rem; /* 2px */\n --pop-radius-xs: 0.25rem; /* 4px */\n --pop-radius-sm: 0.375rem; /* 6px */\n --pop-radius-md: 0.5rem; /* 8px */\n --pop-radius-lg: 0.625rem; /* 10px */\n --pop-radius-xl: 0.75rem; /* 12px */\n --pop-radius-2xl: 1rem; /* 16px */\n --pop-radius-3xl: 1.25rem; /* 20px */\n --pop-radius-4xl: 1.5rem; /* 24px */\n --pop-radius-full: 9999px; /* Creates a circle or oval */\n\n --pop-radius: 0.625rem;\n --pop-background: oklch(1 0 0);\n --pop-foreground: oklch(0 0 0);\n --pop-card: oklch(1 0 0);\n --pop-card-foreground: oklch(0.145 0 0);\n --pop-popover: oklch(1 0 0);\n --pop-popover-foreground: oklch(0 0 0);\n --pop-primary: var(--pop-color-brand-forest-900);\n --pop-primary-foreground: oklch(0.985 0 0);\n --pop-secondary: oklch(0.97 0 0);\n --pop-secondary-foreground: oklch(0.205 0 0);\n --pop-muted: oklch(0.97 0 0);\n --pop-muted-foreground: oklch(0.7152 0.0233 256.76);\n --pop-accent: oklch(0.97 0 0);\n --pop-accent-foreground: oklch(0.205 0 0);\n --pop-destructive: var(--color-error-600);\n --pop-border: oklch(0.1101 0.0763 264.05 / 10.2%);\n --pop-input: oklch(0.922 0 0);\n --pop-ring: oklch(0.5367 0.2286 262.17);\n --pop-chart-1: oklch(0.646 0.222 41.116);\n --pop-chart-2: oklch(0.6 0.118 184.704);\n --pop-chart-3: oklch(0.398 0.07 227.392);\n --pop-chart-4: oklch(0.828 0.189 84.429);\n --pop-chart-5: oklch(0.769 0.188 70.08);\n --pop-sidebar: oklch(0.985 0 0);\n --pop-sidebar-foreground: oklch(0.145 0 0);\n --pop-sidebar-primary: oklch(0.205 0 0);\n --pop-sidebar-primary-foreground: oklch(0.985 0 0);\n --pop-sidebar-accent: oklch(0.97 0 0);\n --pop-sidebar-accent-foreground: oklch(0.205 0 0);\n --pop-sidebar-border: oklch(0.922 0 0);\n --pop-sidebar-ring: oklch(0.708 0 0);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-background: oklch(0.15 0.03 255.43);\n --pop-foreground: oklch(0.66 0.006 255.43);\n --pop-card: oklch(0.205 0 0);\n --pop-card-foreground: oklch(0.985 0 0);\n --pop-popover: oklch(0.15 0.03 255.43);\n --pop-popover-foreground: oklch(0.66 0.006 255.43);\n --pop-primary: oklch(0.922 0 0);\n --pop-primary-foreground: oklch(0.205 0 0);\n --pop-secondary: oklch(0.269 0 0);\n --pop-secondary-foreground: oklch(0.985 0 0);\n --pop-muted: oklch(0.269 0 0);\n --pop-muted-foreground: oklch(0.66 0.006 255.43);\n --pop-accent: oklch(0.269 0 0);\n --pop-accent-foreground: oklch(0.985 0 0);\n --pop-destructive: var(--color-error-400);\n --pop-border: oklch(1 0 0 / 10%);\n --pop-input: oklch(1 0 0 / 15%);\n --pop-ring: oklch(0.5367 0.2286 262.17);\n --pop-chart-1: oklch(0.488 0.243 264.376);\n --pop-chart-2: oklch(0.696 0.17 162.48);\n --pop-chart-3: oklch(0.769 0.188 70.08);\n --pop-chart-4: oklch(0.627 0.265 303.9);\n --pop-chart-5: oklch(0.645 0.246 16.439);\n --pop-sidebar: oklch(0.205 0 0);\n --pop-sidebar-foreground: oklch(0.985 0 0);\n --pop-sidebar-primary: oklch(0.488 0.243 264.376);\n --pop-sidebar-primary-foreground: oklch(0.985 0 0);\n --pop-sidebar-accent: oklch(0.269 0 0);\n --pop-sidebar-accent-foreground: oklch(0.985 0 0);\n --pop-sidebar-border: oklch(1 0 0 / 10%);\n --pop-sidebar-ring: oklch(0.556 0 0);\n }\n }\n\n :host(.dark) {\n --pop-background: oklch(0.15 0.03 255.43);\n --pop-foreground: oklch(0.66 0.006 255.43);\n --pop-card: oklch(0.205 0 0);\n --pop-card-foreground: oklch(0.985 0 0);\n --pop-popover: oklch(0.15 0.03 255.43);\n --pop-popover-foreground: oklch(0.66 0.006 255.43);\n --pop-primary: oklch(0.922 0 0);\n --pop-primary-foreground: oklch(0.205 0 0);\n --pop-secondary: oklch(0.269 0 0);\n --pop-secondary-foreground: oklch(0.985 0 0);\n --pop-muted: oklch(0.269 0 0);\n --pop-muted-foreground: oklch(0.66 0.006 255.43);\n --pop-accent: oklch(0.269 0 0);\n --pop-accent-foreground: oklch(0.985 0 0);\n --pop-destructive: var(--color-error-400);\n --pop-border: oklch(1 0 0 / 10%);\n --pop-input: oklch(1 0 0 / 15%);\n --pop-ring: oklch(0.5367 0.2286 262.17);\n --pop-chart-1: oklch(0.488 0.243 264.376);\n --pop-chart-2: oklch(0.696 0.17 162.48);\n --pop-chart-3: oklch(0.769 0.188 70.08);\n --pop-chart-4: oklch(0.627 0.265 303.9);\n --pop-chart-5: oklch(0.645 0.246 16.439);\n --pop-sidebar: oklch(0.205 0 0);\n --pop-sidebar-foreground: oklch(0.985 0 0);\n --pop-sidebar-primary: oklch(0.488 0.243 264.376);\n --pop-sidebar-primary-foreground: oklch(0.985 0 0);\n --pop-sidebar-accent: oklch(0.269 0 0);\n --pop-sidebar-accent-foreground: oklch(0.985 0 0);\n --pop-sidebar-border: oklch(1 0 0 / 10%);\n --pop-sidebar-ring: oklch(0.556 0 0);\n }\n\n *,\n *::before,\n *::after {\n box-sizing: inherit;\n }\n\n html,\n body {\n padding: 0;\n margin: 0;\n }\n\n svg {\n display: block;\n }\n\n strong {\n font-weight: 600;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n\n button {\n margin: 0;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n cursor: pointer;\n }\n\n .m-0 {\n margin: 0;\n }\n\n .text-heading {\n align-self: stretch;\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-size: 13px;\n font-style: normal;\n font-weight: 600;\n letter-spacing: -0.08px;\n line-height: 18px;\n max-width: 320px;\n text-align: center;\n }\n\n .text-xs {\n font-size: 12px;\n line-height: 18px;\n }\n\n .w-full {\n width: 100%;\n }\n}\n","@layer components {\n .btn {\n align-items: center;\n background-color: var(--pop-primary);\n border-radius: 4px;\n border: 0;\n color: var(--pop-primary-foreground);\n cursor: pointer;\n display: flex;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 500;\n line-height: 20px;\n gap: 0.625rem;\n height: auto;\n justify-content: center;\n padding: 0.625rem 1.25rem;\n text-align: center;\n transition:\n background-color 0.2s,\n color 0.2s;\n }\n\n .btn:focus-visible {\n outline: 2px solid var(--pop-ring); /* focus-visible */\n outline-offset: 2px;\n }\n}\n","@layer components {\n .mask {\n -webkit-mask-size: contain;\n mask-size: contain;\n -webkit-mask-repeat: no-repeat;\n mask-repeat: no-repeat;\n -webkit-mask-position: center;\n mask-position: center;\n }\n\n .mask-squircle {\n -webkit-mask-image: url(\"data:image/svg+xml,%3csvg width='160' height='160' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M 0 80 C 0 14.12 14.12 0 80 0 C 145.88 0 160 14.12 160 80 C 160 145.88 145.88 160 80 160 C 14.12 160 0 145.88 0 80 Z'/%3e%3c/svg%3e\");\n mask-image: url(\"data:image/svg+xml,%3csvg width='160' height='160' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M 0 80 C 0 14.12 14.12 0 80 0 C 145.88 0 160 14.12 160 80 C 160 145.88 145.88 160 80 160 C 14.12 160 0 145.88 0 80 Z'/%3e%3c/svg%3e\");\n }\n}\n","let isGlobalDark = false;\nconst activeElements = new Set<HTMLElement>();\nlet globalObserver: MutationObserver | null = null;\nlet mediaQuery: MediaQueryList | null = null;\n\nfunction checkGlobalDark(): boolean {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return false;\n\n const hasDarkClass =\n document.documentElement.classList.contains(\"dark\") ||\n document.body.classList.contains(\"dark\");\n const hasLightClass =\n document.documentElement.classList.contains(\"light\") ||\n document.body.classList.contains(\"light\");\n\n if (hasDarkClass) return true;\n if (hasLightClass) return false;\n\n if (!mediaQuery) {\n mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n }\n return mediaQuery.matches;\n}\n\nfunction updateGlobalDark() {\n const newDark = checkGlobalDark();\n if (newDark !== isGlobalDark) {\n isGlobalDark = newDark;\n activeElements.forEach((el) => {\n const isDark = isGlobalDark || !!el.closest(\".dark\");\n el.classList.toggle(\"dark\", isDark);\n });\n }\n}\n\nconst mediaListener = () => {\n updateGlobalDark();\n};\n\nexport function registerThemeObserver(el: HTMLElement) {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return;\n\n if (activeElements.size === 0) {\n isGlobalDark = checkGlobalDark();\n globalObserver = new MutationObserver(() => {\n updateGlobalDark();\n });\n globalObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\"],\n });\n globalObserver.observe(document.body, {\n attributes: true,\n attributeFilter: [\"class\"],\n });\n\n mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mediaQuery.addEventListener(\"change\", mediaListener);\n }\n\n activeElements.add(el);\n\n const isDark = isGlobalDark || !!el.closest(\".dark\");\n el.classList.toggle(\"dark\", isDark);\n}\n\nexport function unregisterThemeObserver(el: HTMLElement) {\n activeElements.delete(el);\n if (activeElements.size === 0) {\n if (globalObserver) {\n globalObserver.disconnect();\n globalObserver = null;\n }\n if (mediaQuery) {\n mediaQuery.removeEventListener(\"change\", mediaListener);\n mediaQuery = null;\n }\n }\n}\n","import baseStyles from \"../styles/base.css?inline\";\nimport btnStyles from \"../styles/buttons.css?inline\";\nimport masksStyles from \"../styles/masks.css?inline\";\n\nimport { effect, untracked } from \"@preact/signals-core\";\n\nexport function createSheet(cssText: string): CSSStyleSheet {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(cssText);\n return sheet;\n}\n\nexport const sharedBaseSheet = createSheet(baseStyles);\nexport const btnSheet = createSheet(btnStyles);\nexport const masksSheet = createSheet(masksStyles);\n\nimport { registerThemeObserver, unregisterThemeObserver } from \"../helpers/theme.js\";\n\nexport abstract class BaseElement extends HTMLElement implements EventListenerObject {\n protected baseStyleSheets: CSSStyleSheet[] = [sharedBaseSheet, btnSheet, masksSheet];\n protected get styleSheets(): CSSStyleSheet[] {\n return [];\n }\n\n private _hasRendered = false;\n\n private _disposables: Array<() => void> = [];\n\n constructor() {\n super();\n this.attachShadow({ mode: \"open\" });\n if (this.shadowRoot) {\n this.shadowRoot.adoptedStyleSheets = this.styles;\n }\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (oldValue === newValue) return;\n\n const pascalName = name\n .split(\"-\")\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\");\n const methodName = `on${pascalName}Changed`;\n\n if (typeof (this as any)[methodName] === \"function\") {\n (this as any)[methodName](newValue, oldValue);\n }\n }\n\n /**\n * Use this instead of calling effect() directly to ensure\n * automatic cleanup when the component disconnects.\n */\n protected addEffect(callback: () => void) {\n this._disposables.push(effect(callback));\n }\n\n connectedCallback() {\n registerThemeObserver(this);\n untracked(() => {\n this.render();\n this._bindEvents();\n this.setupEffects();\n });\n }\n\n disconnectedCallback() {\n unregisterThemeObserver(this);\n // Kill all active subscriptions\n this._disposables.forEach((dispose) => dispose());\n this._disposables = [];\n }\n\n protected events: Record<string, string> = {};\n\n private _bindEvents() {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot) {\n return;\n }\n Object.keys(this.events).forEach((key) => {\n shadowRoot.addEventListener(key, this);\n });\n }\n\n handleEvent(event: Event): void {\n const methodName = this.events[event.type];\n\n if (methodName && typeof (this as any)[methodName] === \"function\") {\n (this as any)[methodName](event);\n }\n }\n\n protected emit<T = unknown>(eventName: string, options: CustomEventInit<T> = {}) {\n this.dispatchEvent(\n new CustomEvent<T>(eventName, {\n bubbles: true,\n composed: true,\n ...options,\n }),\n );\n }\n\n // --- Abstract & Overrideable Methods ---\n protected abstract getTemplate(): string;\n\n protected get styles(): CSSStyleSheet[] {\n return [...this.baseStyleSheets, ...this.styleSheets];\n }\n\n protected setupEffects(): void {}\n\n protected render() {\n if (!this.shadowRoot) return;\n this.shadowRoot.innerHTML = this.getTemplate();\n this._hasRendered = true;\n }\n\n protected hideElement(selector: string, shouldHide: boolean, useDisplayNone = true) {\n if (!this.shadowRoot || !this._hasRendered) {\n return;\n }\n\n const el = this.shadowRoot.querySelector(selector);\n if (!el) {\n console.warn(`Element not found for selector: ${selector}`);\n return;\n }\n\n if (useDisplayNone) {\n el.classList.toggle(\"hidden\", shouldHide);\n } else {\n el.classList.toggle(\"invisible\", shouldHide);\n }\n }\n\n protected setText(selector: string, text: string | number) {\n const el = this.shadowRoot?.querySelector(selector);\n if (el && el.textContent !== String(text)) {\n el.textContent = String(text);\n }\n }\n\n protected setAttr(selector: string, attr: string, value: string | null) {\n const el = this.shadowRoot?.querySelector(selector);\n if (!el) return;\n\n if (value === null) {\n el.removeAttribute(attr);\n } else if (el.getAttribute(attr) !== value) {\n el.setAttribute(attr, value);\n }\n }\n\n protected toggleClass(selector: string, className: string, force?: boolean) {\n const el = this.shadowRoot?.querySelector(selector);\n if (!el) return;\n\n el.classList.toggle(className, force);\n }\n\n protected getElement<T extends Element = HTMLElement>(selector: string): T | null {\n return this.shadowRoot?.querySelector(selector) ?? null;\n }\n}\n","/**\n * Selector for an element a component's JS reaches into, marked in its\n * template with `data-ref=\"<name>\"`. Keeps behavior hooks separate from the\n * CSS classes used for styling, so restyling can't silently break a lookup.\n * Works anywhere a selector does: getElement, setText, closest(), etc.\n */\nexport const ref = (name: string): string => `[data-ref=\"${name}\"]`;\n","import { autoUpdate, computePosition, flip, offset, shift } from \"@floating-ui/dom\";\nimport { getInitials } from \"../helpers/author.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n\n --pop-switcher-hover: rgba(0, 0, 32, 0.04);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-switcher-hover: rgba(255, 255, 255, 0.06);\n }\n }\n\n :host(.dark) {\n --pop-switcher-hover: rgba(255, 255, 255, 0.06);\n }\n\n .switcher {\n position: relative;\n }\n\n .switcher__trigger {\n background: none;\n border-radius: 9999px;\n border: none;\n cursor: pointer;\n display: block;\n padding: 0;\n }\n\n .switcher__dropdown {\n /* Overridden inline once floating-ui resolves an actual side (see\n openDropdown) — these defaults match this trigger's common case: an\n avatar near the bottom of the widget, menu opening upward above it. */\n --switcher-origin: bottom left;\n --switcher-slide-y: 6px;\n\n background-color: var(--pop-background);\n border-radius: 6px;\n box-shadow: var(--pop-shadow-xl);\n display: flex;\n flex-direction: column;\n font-family: Inter, sans-serif;\n gap: 2px;\n opacity: 0;\n padding: 6px;\n pointer-events: none;\n position: fixed;\n transform: scale(0.95) translateY(var(--switcher-slide-y));\n transform-origin: var(--switcher-origin);\n transition:\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n visibility 0s linear var(--pop-duration-quick);\n visibility: hidden;\n width: 200px;\n z-index: 1000;\n }\n\n .switcher__dropdown.is-open {\n opacity: 1;\n pointer-events: auto;\n transform: scale(1) translateY(0);\n transition:\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n visibility 0s linear 0s;\n visibility: visible;\n }\n\n .switcher__item {\n align-items: center;\n background: none;\n border-radius: 4px;\n border: none;\n color: var(--pop-foreground);\n cursor: pointer;\n display: flex;\n font-size: 13px;\n font-weight: 500;\n gap: 8px;\n overflow: hidden;\n padding: 6px 8px;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n }\n\n .switcher__item:hover {\n background-color: var(--pop-switcher-hover);\n }\n\n .switcher__item.is-active {\n font-weight: 700;\n }\n\n .switcher__divider {\n background-color: var(--pop-border);\n height: 1px;\n margin: 4px 2px;\n }\n\n .switcher__item--sign-out {\n color: var(--pop-destructive);\n }\n\n .switcher__loading {\n align-items: center;\n color: var(--pop-muted-foreground);\n display: flex;\n font-size: 13px;\n font-weight: 500;\n gap: 8px;\n padding: 6px 8px;\n }\n\n .switcher__spinner {\n animation: pop-switcher-spin 0.6s linear infinite;\n border: 2px solid var(--pop-border);\n border-radius: 9999px;\n border-top-color: var(--pop-foreground);\n flex-shrink: 0;\n height: 12px;\n width: 12px;\n }\n\n @keyframes pop-switcher-spin {\n to {\n transform: rotate(360deg);\n }\n }\n`);\n\n/**\n * The signed-in visitor's own avatar in the composer bar, doubling as the\n * trigger for a dropdown that lets them pick which of their accounts\n * (better-auth orgs) this widget's comments post as, sign out, and — a good\n * home for future per-widget settings as they show up.\n *\n * Account switching here never reads or changes the main app's active org —\n * but it does sync live across every other tab on this same browser (they\n * all share one persisted token — see EmbedAuthStore.switchOrganization and\n * ADR 0011), the same way a sign-in or sign-out already does.\n */\nexport class PopAccountSwitcher extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n private _dropdownOpen = false;\n private _floatingCleanup?: () => void;\n\n private _onOutsideClick = (event: MouseEvent) => {\n const path = event.composedPath();\n const dropdown = this.getElement(ref(\"dropdown\"));\n const trigger = this.getElement(ref(\"trigger\"));\n\n if (dropdown && trigger && !path.includes(dropdown) && !path.includes(trigger)) {\n this.closeDropdown();\n }\n };\n\n disconnectedCallback() {\n this.closeDropdown();\n super.disconnectedCallback();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const user = this.authStore.currentUser.value;\n const organizations = this.authStore.organizations.value;\n\n // Stay visible even signed out — this doubles as the composer's\n // avatar placeholder (\"?\"), same as before this became a switcher.\n // The dropdown itself only opens once signed in (see openDropdown).\n const avatar = this.getElement<HTMLElement>(ref(\"avatar\"));\n if (avatar) {\n avatar.setAttribute(\"data-color-key\", user?.id ?? user?.name ?? \"\");\n avatar.innerHTML = user?.image\n ? `<img src=\"${user.image}\" alt=\"${user.name ?? \"User\"}'s avatar\">`\n : getInitials(user?.name);\n }\n\n if (!user) {\n this.closeDropdown();\n return;\n }\n\n const loading = this.authStore.organizationsLoading.value;\n\n const dropdown = this.getElement(ref(\"dropdown\"));\n if (dropdown) {\n const orgItems =\n organizations.length === 0 && loading\n ? '<div class=\"switcher__loading\"><span class=\"switcher__spinner\"></span>Loading accounts…</div>'\n : organizations\n .map(\n (org) => `\n <button class=\"switcher__item${org.id === user.id ? \" is-active\" : \"\"}\" data-ref=\"item\" type=\"button\" data-org-id=\"${org.id}\">\n ${org.name}\n </button>\n `,\n )\n .join(\"\");\n\n dropdown.innerHTML = `\n ${orgItems}\n ${organizations.length > 0 ? '<div class=\"switcher__divider\"></div>' : \"\"}\n <button class=\"switcher__item switcher__item--sign-out\" data-ref=\"item\" type=\"button\" data-action=\"sign-out\">Sign out</button>\n `;\n }\n });\n }\n\n private toggleDropdown() {\n if (this._dropdownOpen) {\n this.closeDropdown();\n } else {\n this.openDropdown();\n }\n }\n\n private openDropdown() {\n if (!this.authStore.currentUser.value) return;\n\n // Lazy: fetched on first open, not on sign-in or page load — organizations\n // itself is the cache (loadOrganizations no-ops while a fetch is already\n // in flight), so reopening after a successful load doesn't re-fetch.\n if (this.authStore.organizations.value.length === 0) {\n void this.authStore.loadOrganizations();\n }\n\n this._dropdownOpen = true;\n const dropdown = this.getElement<HTMLElement>(ref(\"dropdown\"));\n const trigger = this.getElement<HTMLElement>(ref(\"trigger\"));\n\n if (dropdown && trigger) {\n dropdown.classList.add(\"is-open\");\n\n const update = () => {\n void computePosition(trigger, dropdown, {\n placement: \"bottom-start\",\n middleware: [offset(4), flip(), shift({ padding: 8 })],\n strategy: \"fixed\",\n }).then(({ x, y, placement }) => {\n Object.assign(dropdown.style, { left: `${x}px`, top: `${y}px`, position: \"fixed\" });\n\n // flip() may resolve to the opposite side of the requested\n // placement when there isn't room — keep the scale/slide anchored\n // to whichever edge actually sits against the trigger, so the\n // menu always reads as growing out of it rather than the screen.\n const opensUpward = placement.startsWith(\"top\");\n dropdown.style.setProperty(\"--switcher-origin\", opensUpward ? \"bottom left\" : \"top left\");\n dropdown.style.setProperty(\"--switcher-slide-y\", opensUpward ? \"6px\" : \"-6px\");\n });\n };\n\n this._floatingCleanup = autoUpdate(trigger, dropdown, update);\n document.addEventListener(\"mousedown\", this._onOutsideClick);\n }\n }\n\n private closeDropdown() {\n this._dropdownOpen = false;\n const dropdown = this.getElement(ref(\"dropdown\"));\n if (dropdown) {\n dropdown.classList.remove(\"is-open\");\n }\n if (this._floatingCleanup) {\n this._floatingCleanup();\n this._floatingCleanup = undefined;\n }\n document.removeEventListener(\"mousedown\", this._onOutsideClick);\n }\n\n protected onClick(event: Event) {\n const target = event.target as HTMLElement;\n\n if (target.closest(ref(\"trigger\"))) {\n event.stopPropagation();\n this.toggleDropdown();\n return;\n }\n\n const item = target.closest(ref(\"item\")) as HTMLElement | null;\n if (item) {\n event.stopPropagation();\n this.closeDropdown();\n\n if (item.getAttribute(\"data-action\") === \"sign-out\") {\n void this.authStore.signOutEverywhere();\n return;\n }\n\n const organizationId = item.getAttribute(\"data-org-id\");\n if (organizationId) {\n void this.authStore.switchOrganization(organizationId);\n }\n }\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"switcher\">\n <button\n class=\"switcher__trigger\"\n data-ref=\"trigger\"\n type=\"button\"\n aria-label=\"Account options\"\n >\n <pop-comment-avatar size=\"xs\" data-ref=\"avatar\"></pop-comment-avatar>\n </button>\n <div class=\"switcher__dropdown\" data-ref=\"dropdown\"></div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-account-switcher\")) {\n customElements.define(\"pop-account-switcher\", PopAccountSwitcher);\n}\n","import { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst CODE_LENGTH = 6;\n\nconst localSheet = createSheet(/* css */ `\n :host {\n border-top: 1px solid var(--pop-sidebar-border);\n display: block;\n padding: 20px 24px;\n font-family: Inter, sans-serif;\n text-align: center;\n }\n\n .code__body {\n align-items: center;\n align-self: stretch;\n display: flex;\n flex-direction: column;\n gap: 8px;\n justify-content: center;\n }\n\n .code__container {\n align-items: center;\n display: flex;\n flex-direction: column;\n gap: 16px;\n justify-content: center;\n }\n\n .code__heading {\n color: var(--pop-foreground);\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-size: 13px;\n font-weight: 600;\n letter-spacing: -0.08px;\n line-height: 18px;\n margin: 0;\n }\n\n .code__digits {\n display: flex;\n gap: 6px;\n justify-content: center;\n }\n\n .code__digits .code__digit:nth-child(3) {\n margin-right: 10px;\n }\n\n .code__digit {\n -webkit-appearance: none;\n appearance: none;\n background: var(--pop-background);\n border-radius: var(--pop-radius-md, 8px);\n border: 1px solid color-mix(in srgb, var(--pop-foreground) 56%, transparent);\n color: var(--pop-foreground);\n font-family: inherit;\n font-size: 24px;\n font-weight: 500;\n height: 40px;\n line-height: 36px;\n text-align: center;\n width: 40px;\n }\n\n .code__digit:focus-visible {\n border: 2px solid var(--pop-foreground);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--pop-ring, #155eef) 60%, transparent);\n outline: none;\n }\n\n .code__digit:disabled {\n opacity: 0.6;\n }\n\n .code__copy,\n .code__expiry {\n color: var(--pop-foreground);\n font-size: 12px;\n line-height: 18px;\n margin: 0;\n }\n\n .code__error {\n color: var(--pop-auth-error, #dc2626);\n font-size: 12px;\n line-height: 16px;\n }\n\n .code__footer {\n align-items: center;\n display: flex;\n justify-content: space-between;\n width: 100%;\n }\n\n .code__expiry strong {\n font-weight: 600;\n }\n`);\n\nexport class PopAuthCode extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n input: \"onInput\",\n keydown: \"onKeyDown\",\n click: \"onClick\",\n };\n\n connectedCallback() {\n super.connectedCallback();\n this.getDigitInputs()[0]?.focus();\n }\n\n private getDigitInputs(): HTMLInputElement[] {\n return Array.from(this.shadowRoot?.querySelectorAll<HTMLInputElement>(ref(\"digit\")) ?? []);\n }\n\n protected onInput(event: Event) {\n const target = event.target as HTMLInputElement;\n if (!target.matches(ref(\"digit\"))) return;\n\n target.value = target.value.replace(/[^0-9]/g, \"\").slice(0, 1);\n\n if (target.value) {\n const next = target.nextElementSibling as HTMLInputElement | null;\n next?.focus();\n }\n\n this.maybeSubmit();\n }\n\n protected onKeyDown(event: KeyboardEvent) {\n const target = event.target as HTMLInputElement;\n if (!target.matches(ref(\"digit\"))) return;\n\n if (event.key === \"Backspace\" && !target.value) {\n const prev = target.previousElementSibling as HTMLInputElement | null;\n prev?.focus();\n }\n }\n\n protected onClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (target.closest(ref(\"no-code\"))) {\n this.authStore.showNoCode();\n return;\n }\n\n if (target.closest(ref(\"back\"))) {\n this.authStore.backToEmail();\n return;\n }\n }\n\n private maybeSubmit(): void {\n const digits = this.getDigitInputs().map((input) => input.value);\n if (digits.some((digit) => !digit)) return;\n void this.authStore.verifyOtp(digits.join(\"\"));\n }\n\n /** Renders the countdown; returns true once the code has expired. */\n private renderCountdown(expiresAt: number): boolean {\n const remainingMs = expiresAt - Date.now();\n if (remainingMs <= 0) return true;\n\n const el = this.getElement<HTMLParagraphElement>(ref(\"expiry\"));\n if (!el) return false;\n\n const totalSeconds = Math.ceil(remainingMs / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n el.innerHTML = `Code expires in <strong>${minutes}:${String(seconds).padStart(2, \"0\")}</strong>`;\n return false;\n }\n\n protected setupEffects() {\n let dismissals = this.authStore.authNoticeDismissals.peek();\n this.addEffect(() => {\n const next = this.authStore.authNoticeDismissals.value;\n if (next === dismissals) return;\n dismissals = next;\n // Wait a microtask: the feed lifts `inert` off the footer in its own\n // effect for the same change.\n queueMicrotask(() => {\n const inputs = this.getDigitInputs();\n (inputs.find((input) => !input.value) ?? inputs[0])?.focus({ preventScroll: true });\n });\n });\n\n this.addEffect(() => {\n const expiresAt = this.authStore.otpExpiresAt.value;\n if (!expiresAt) return;\n\n this.renderCountdown(expiresAt);\n // An expired code can't be used, so return to the email step to\n // request a new one. Done from the tick (not this effect body) since\n // expireOtp writes otpExpiresAt, which this effect tracks.\n const interval = window.setInterval(() => {\n if (!this.renderCountdown(expiresAt)) return;\n window.clearInterval(interval);\n this.authStore.expireOtp();\n }, 1000);\n return () => window.clearInterval(interval);\n });\n\n this.addEffect(() => {\n const pending = this.authStore.otpPending.value;\n const inputs = this.getDigitInputs();\n inputs.forEach((input) => {\n input.disabled = pending;\n });\n\n // A disabled input can't take focus, and both entry points here happen\n // mid-request: sendOtp flips to this view before clearing otpPending,\n // and a rejected code sets otpError before it does. So the focus calls\n // in connectedCallback / the error effect are no-ops — claim focus once\n // the inputs are actually enabled again, unless the visitor has already\n // put it somewhere in the card (e.g. Back).\n if (!pending && !this.shadowRoot?.activeElement) {\n (inputs.find((input) => !input.value) ?? inputs[0])?.focus({ preventScroll: true });\n }\n });\n\n this.addEffect(() => {\n const error = this.authStore.otpError.value;\n\n const errorEl = this.getElement<HTMLDivElement>(ref(\"error\"));\n if (errorEl) {\n errorEl.hidden = !error;\n errorEl.textContent = error ?? \"\";\n }\n\n if (error) {\n const inputs = this.getDigitInputs();\n inputs.forEach((input) => {\n input.value = \"\";\n });\n inputs[0]?.focus();\n }\n });\n }\n\n protected getTemplate(): string {\n const digits = Array.from({ length: CODE_LENGTH })\n .map(\n (_, index) =>\n `<input class=\"code__digit\" data-ref=\"digit\" type=\"text\" inputmode=\"numeric\" maxlength=\"1\" autocomplete=\"one-time-code\" aria-label=\"Digit ${index + 1} of ${CODE_LENGTH}\" />`,\n )\n .join(\"\");\n\n return /* html */ `\n <div class=\"code__container\" role=\"group\" aria-labelledby=\"code-title\">\n <p class=\"code__heading\" id=\"code-title\">Enter Verification Code</p>\n <div class=\"code__digits\" role=\"group\" aria-labelledby=\"code-title\">${digits}</div>\n <div class=\"code__body\">\n <p class=\"code__copy\">\n A verification code has been sent to your email. Enter code to continue.\n </p>\n <p class=\"code__expiry\" data-ref=\"expiry\" role=\"timer\"></p>\n </div>\n <div class=\"code__error\" data-ref=\"error\" role=\"alert\" hidden></div>\n <div class=\"code__footer\">\n <pop-button-link data-ref=\"back\" size=\"sm\" theme=\"default\">Back</pop-button-link>\n <pop-button-link data-ref=\"no-code\" size=\"sm\" theme=\"default\" primary>\n No verification code?\n </pop-button-link>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-code\")) {\n customElements.define(\"pop-auth-code\", PopAuthCode);\n}\n","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","/**\n * The \"POPGRIDS\" wordmark, inlined so it can take `currentColor` and scale\n * cleanly inside Shadow DOM — shared by pop-auth-join.ts and pop-auth-email.ts\n * rather than duplicated (it's a sizeable path block).\n */\nexport const POPGRIDS_WORDMARK_SVG = `<svg\n width=\"100\"\n height=\"16\"\n viewBox=\"0 0 75 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M4.58333 0.265686C1.0463 0.265686 0 2.5714 0 5.47711C0 6.55283 0.115741 7.6114 0.25 8.67426C0.300926 9.08997 0.282407 9.54854 0.365741 9.96426C0.583333 11.0571 1.69444 11.5628 2.77315 11.5628C4.25 11.5628 5.23148 10.7014 5.23148 9.3214C5.23148 8.52426 4.94907 8.0014 4.13426 7.69283C4.08333 7.67569 4.03241 7.66283 4.03241 7.59854C4.03241 7.4914 4.21759 7.41426 4.33333 7.41426C4.73148 7.41426 5.36111 7.78283 5.91204 7.78283C8.06944 7.78283 9.26389 5.86283 9.26389 4.06283C9.26389 1.44854 7.18518 0.265686 4.58333 0.265686ZM4.56481 5.91854C4.43056 5.91854 4.31481 5.8114 4.31481 5.68711C4.31481 5.51997 4.56481 5.39569 4.64815 5.25854C4.8287 4.94997 4.87963 4.42711 4.87963 4.07569C4.87963 3.65997 4.76389 2.89283 4.48148 2.58426C4.39815 2.49426 4.28241 2.44711 4.28241 2.32283C4.28241 2.19854 4.41667 2.0914 4.5463 2.0914C5.11111 2.0914 5.39352 3.62997 5.39352 4.02854C5.39352 4.45711 5.24537 5.91854 4.56481 5.91854Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M14.9259 0.527108C11.4074 0.527108 9.2963 2.83282 9.2963 5.99568C9.2963 9.15854 11.4028 11.4643 14.9259 11.4643C18.4491 11.4643 20.537 9.12854 20.537 5.99568C20.537 2.86282 18.412 0.527108 14.9259 0.527108ZM15.0787 9.89997C15.0232 9.96425 14.912 10.0843 14.7778 10.0843C14.6435 10.0843 14.5139 9.97711 14.5139 9.85282C14.5139 9.80568 14.9445 9.20568 15.0139 9.02139C15.2778 8.29711 15.3287 7.51282 15.3287 6.74568C15.3287 5.71711 15.1296 4.39282 14.4491 3.54854C14.3148 3.39425 13.9028 3.10282 13.9028 2.93568C13.9028 2.81139 14.0185 2.70425 14.1528 2.70425C14.2685 2.70425 14.3843 2.79854 14.4676 2.85854C15.5278 3.67282 15.8472 5.53282 15.8472 6.74568C15.8472 7.69711 15.8056 9.08568 15.0833 9.89568L15.0787 9.89997Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M25.375 0.265686C21.838 0.265686 20.7917 2.5714 20.7917 5.47711C20.7917 6.55283 20.9074 7.6114 21.0417 8.67426C21.0926 9.08997 21.0741 9.54854 21.1574 9.96426C21.375 11.0571 22.4861 11.5628 23.5648 11.5628C25.0417 11.5628 26.0231 10.7014 26.0231 9.3214C26.0231 8.52426 25.7407 8.0014 24.9259 7.69283C24.875 7.67569 24.8241 7.66283 24.8241 7.59854C24.8241 7.4914 25.0092 7.41426 25.125 7.41426C25.5231 7.41426 26.1528 7.78283 26.7037 7.78283C28.8611 7.78283 30.0555 5.86283 30.0555 4.06283C30.0555 1.44854 27.9815 0.265686 25.375 0.265686ZM25.3611 5.91854C25.2268 5.91854 25.1111 5.8114 25.1111 5.68711C25.1111 5.51997 25.3611 5.39569 25.4444 5.25854C25.625 4.94997 25.6759 4.42711 25.6759 4.07569C25.6759 3.65997 25.5602 2.89283 25.2778 2.58426C25.1944 2.49426 25.0787 2.44711 25.0787 2.32283C25.0787 2.19854 25.213 2.0914 25.3426 2.0914C25.9074 2.0914 26.1898 3.62997 26.1898 4.02854C26.1898 4.45711 26.0417 5.91854 25.3611 5.91854Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M37.3843 4.81284C36.1898 4.81284 34.5278 5.31855 34.5278 6.64284C34.5278 7.39713 35.125 8.5157 36.0741 8.5157C36.6713 8.5157 37.0556 8.08713 37.2546 8.08713C37.3056 8.08713 37.3519 8.11713 37.3519 8.16427C37.3519 8.60998 36.4213 8.81141 36.0556 8.81141C34.7778 8.81141 34.0972 7.7957 34.0972 6.71998C34.0972 5.39998 35.4398 4.38427 36.8009 4.38427C37.1991 4.38427 37.6158 4.49141 38.0139 4.49141C39.1945 4.49141 40.0371 3.50998 40.0371 2.46427C40.0371 0.728554 37.8148 0.329982 36.3333 0.329982C32.3982 0.329982 30.1065 2.6957 30.1065 6.29141C30.1065 9.61284 31.9676 11.73 35.6528 11.73C38.0417 11.73 40.6482 10.7786 40.6482 8.19427C40.6482 6.42855 39.4028 4.81284 37.3796 4.81284H37.3843Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M48.3611 7.42711C48.0602 7.42711 47.8148 7.53426 47.5648 7.53426C47.5139 7.53426 47.5 7.48711 47.5 7.45712C47.5 7.34997 47.5509 7.30283 47.6342 7.27283C47.9167 7.18283 48.2176 7.11854 48.4954 6.99426C49.7592 6.4414 50.5046 5.45569 50.5046 4.15283C50.5046 1.79997 48.3287 0.372829 45.9398 0.372829C45.0741 0.372829 44.2315 0.604257 43.5 0.972829C41.5092 1.9714 41.125 3.40283 41.0092 5.35283C40.9583 6.11997 40.9583 6.8914 40.9583 7.65854V9.51854C40.9583 10.6843 41.787 11.6228 43.0972 11.6228C44.0416 11.6228 44.8889 10.9928 45.1065 10.1614C45.2222 9.66854 45.1574 9.08569 45.1574 8.60997C45.1574 8.56283 45.1759 8.54997 45.2222 8.54997C45.2685 8.54997 45.3241 8.57997 45.3565 8.59711C45.9398 9.90426 46.7361 11.5628 48.5417 11.5628C49.787 11.5628 50.8148 10.7485 50.8148 9.56569C50.8148 8.38283 49.6204 7.4314 48.3565 7.4314L48.3611 7.42711ZM45.6574 5.91854C45.5231 5.91854 45.4074 5.8114 45.4074 5.68711C45.4074 5.51997 45.6574 5.39569 45.7407 5.25854C45.9213 4.94997 45.9722 4.42711 45.9722 4.07569C45.9722 3.65997 45.8565 2.89283 45.5741 2.58426C45.4907 2.49426 45.3935 2.44711 45.3935 2.32283C45.3935 2.19854 45.5092 2.0914 45.6435 2.0914C46.2083 2.0914 46.4907 3.62997 46.4907 4.02854C46.4907 4.45711 46.3565 5.91854 45.662 5.91854H45.6574Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M54.8056 0.865677C54.4074 0.621391 53.8426 0.497105 53.3611 0.497105C52.3148 0.497105 51.4167 1.26425 51.3009 2.21996C51.2685 2.49853 51.2824 2.75996 51.2824 3.05139V5.66139L51.2315 8.41282V9.77996C51.2315 10.8557 52.2269 11.7 53.375 11.7C54.2222 11.7 55.1528 11.2071 55.4676 10.47C55.6482 10.0542 55.6667 9.47139 55.6667 9.02568V7.82568L55.6852 5.42996V3.03425C55.6852 2.14282 55.6667 1.43568 54.8056 0.865677Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M58.9445 0.402828C57.25 0.402828 56.4028 1.13997 56.4028 2.7214V3.3514L56.4213 4.59426V5.22426C56.4213 5.69997 56.4213 6.14568 56.4028 6.6214C56.3704 7.1914 56.287 7.75711 56.287 8.34426C56.287 10.4957 57.4815 11.5414 59.7917 11.5414C63.3426 11.5414 65.75 10.1271 65.75 6.60854C65.75 2.36568 63.5417 0.398542 58.9445 0.398542V0.402828ZM60.537 8.9014C60.4028 8.9014 60.287 8.79426 60.287 8.66997C60.287 8.62283 60.3056 8.59283 60.338 8.54568C60.7685 7.88568 60.8843 6.96426 60.8843 6.20997C60.8843 5.50283 60.8009 4.45711 60.3194 3.90426C60.2361 3.77997 60.0695 3.68997 60.0695 3.53569C60.0695 3.4114 60.1852 3.30426 60.3194 3.30426C60.5694 3.30426 60.9167 3.88711 61.0185 4.08854C61.3333 4.76569 61.3843 5.50283 61.3843 6.22283C61.3843 6.66854 61.1343 8.89711 60.537 8.89711V8.9014Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M73.5046 5.85855C72.5417 5.78141 71.162 5.47284 70.4167 4.88998C70.3194 4.81284 70.1528 4.7057 70.1528 4.56855C70.1528 4.52141 70.1713 4.44427 70.2361 4.44427C70.4167 4.44427 71.5787 5.3057 72.5787 5.3057C73.8426 5.3057 75 4.39713 75 3.20141C75 1.23427 72.1806 0.437125 70.4676 0.437125C67.9259 0.437125 66.037 1.95855 66.037 4.37141C66.037 4.89427 66.1204 5.61427 66.537 6.01713C66.7361 6.21855 67.0694 6.21855 67.3333 6.21855C68.3287 6.21855 69.5926 6.50998 70.1204 7.35427C70.1713 7.43141 70.2176 7.5557 70.2176 7.6457C70.2176 7.6757 70.2176 7.72284 70.1852 7.7057C70.088 7.6757 70.0046 7.59855 69.9352 7.53855C69.3519 7.0157 68.5555 6.49284 67.713 6.49284C66.4491 6.49284 66.0046 7.6157 66.0046 8.59713C66.0046 10.5771 67.9306 11.67 69.8889 11.67C72.213 11.67 75 10.2557 75 7.84284C75 6.95141 74.5833 5.95284 73.5046 5.86284V5.85855Z\"\n fill=\"currentColor\"\n />\n</svg>`;\n","import appleIconSrc from \"../assets/apple-icon.png?inline\";\nimport googleIconSrc from \"../assets/google-icon.png?inline\";\nimport { POPGRIDS_WORDMARK_SVG } from \"../assets/wordmark-svg.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n padding: 20px 24px;\n border-top: 1px solid var(--pop-sidebar-border);\n background: var(--pop-background);\n }\n\n .email__container {\n align-items: center;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n }\n\n .email__logo {\n color: var(--pop-foreground);\n display: flex;\n justify-content: center;\n }\n\n .email__form {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .email__input {\n -webkit-appearance: none;\n appearance: none;\n background: var(--pop-background);\n border: 1px solid var(--pop-input);\n border-radius: 6px;\n color: var(--pop-foreground);\n font-family: inherit;\n font-size: 14px;\n padding: 10px 12px;\n width: 100%;\n height: 40px;\n }\n\n .email__input::placeholder {\n color: var(--pop-muted-foreground);\n }\n\n .email__input:focus-visible {\n outline: 2px solid var(--pop-ring);\n outline-offset: -1px;\n }\n\n .email__submit {\n width: 100%;\n }\n\n .email__socials {\n align-items: center;\n display: flex;\n gap: 32px;\n justify-content: center;\n }\n\n .email__social {\n align-items: center;\n cursor: pointer;\n display: flex;\n height: 32px;\n justify-content: center;\n padding: 0;\n width: 32px;\n transition: transform 0.15s ease-out;\n }\n\n .email__social:hover {\n transform: scale(1.125);\n }\n\n .email__social img {\n width: 100%;\n height: 100%;\n }\n\n .email__error {\n color: var(--pop-auth-error, #dc2626);\n font-size: 12px;\n line-height: 16px;\n text-align: center;\n }\n\n .email__about {\n display: block;\n color: var(--pop-muted-foreground);\n font-size: 12px;\n text-align: center;\n margin-top: 14px;\n text-decoration: none;\n }\n\n .email__about:hover {\n color: var(--pop-foreground);\n }\n`);\n\nexport class PopAuthEmail extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n submit: \"onSubmit\",\n };\n\n connectedCallback() {\n super.connectedCallback();\n // Kept in memory by the store after a code expires or is burned, so the\n // visitor can just press Continue for a new one.\n const input = this.getElement<HTMLInputElement>(ref(\"input\"));\n if (input) input.value = this.authStore.otpEmail.value;\n this.focusEmailInputWhenVisible();\n }\n\n private focusEmailInputWhenVisible(): void {\n const input = this.getElement<HTMLInputElement>(ref(\"input\"));\n if (!input) return;\n\n // preventScroll: the card is still sliding up from below when this can\n // run, and a plain focus() would scroll the *host page* to bring the\n // field into view, jumping the visitor's reading position.\n const focus = () => {\n if (input.isConnected) input.focus({ preventScroll: true });\n };\n\n // Focusing mid-slide fights pop-auth-panel's entrance transition (e.g. a\n // mobile keyboard resizing the viewport under it), so wait for whatever\n // the card is currently animating. Asking the card for its running\n // transitions — rather than listening for one `transitionend` — also\n // covers the cases where none ever fires (already in place, transitions\n // disabled, reduced motion), where a listener would never focus at all.\n const card = this.closest(\".panel__card\");\n const running = card?.getAnimations() ?? [];\n if (running.length === 0) {\n focus();\n return;\n }\n\n void Promise.allSettled(running.map((animation) => animation.finished)).then(focus);\n }\n\n protected onClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (target.closest(ref(\"google\"))) {\n void this.authStore.requestSignIn();\n return;\n }\n\n if (target.closest(ref(\"apple\"))) {\n void this.authStore.requestSignIn();\n return;\n }\n }\n\n protected onSubmit(event: Event) {\n event.preventDefault();\n void this.handleContinue();\n }\n\n private async handleContinue(): Promise<void> {\n const input = this.getElement<HTMLInputElement>(ref(\"input\"));\n if (!input) return;\n\n const email = input.value.trim();\n if (!EMAIL_PATTERN.test(email)) {\n this.authStore.otpError.value = \"Enter a valid email address.\";\n return;\n }\n\n await this.authStore.sendOtp(email);\n }\n\n protected setupEffects() {\n let dismissals = this.authStore.authNoticeDismissals.peek();\n this.addEffect(() => {\n const next = this.authStore.authNoticeDismissals.value;\n if (next === dismissals) return;\n dismissals = next;\n // The feed lifts `inert` off the footer in its own effect for the same\n // change; wait a microtask so the input is focusable by then.\n queueMicrotask(() => {\n this.getElement<HTMLInputElement>(ref(\"input\"))?.focus({ preventScroll: true });\n });\n });\n\n this.addEffect(() => {\n const pending = this.authStore.otpPending.value;\n const error = this.authStore.otpError.value;\n\n const submit = this.getElement<HTMLButtonElement>(ref(\"submit\"));\n if (submit) {\n submit.disabled = pending;\n submit.textContent = pending ? \"Sending code…\" : \"Continue\";\n }\n\n const errorEl = this.getElement<HTMLDivElement>(ref(\"error\"));\n if (errorEl) {\n errorEl.hidden = !error;\n errorEl.textContent = error ?? \"\";\n }\n });\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <form class=\"email__container\">\n <div class=\"email__logo\" role=\"img\" aria-label=\"PopGrids\">${POPGRIDS_WORDMARK_SVG}</div>\n <p class=\"text-heading\">Small communities, big connections 👋</p>\n <input\n class=\"email__input\"\n data-ref=\"input\"\n type=\"email\"\n aria-label=\"Email address\"\n placeholder=\"Email\"\n autocomplete=\"email\"\n required\n />\n <button class=\"btn email__submit\" data-ref=\"submit\" type=\"submit\">Continue</button>\n <div class=\"email__error\" data-ref=\"error\" role=\"alert\" hidden></div>\n <div class=\"email__socials\">\n <button\n class=\"email__social email__social--apple\"\n data-ref=\"apple\"\n type=\"button\"\n aria-label=\"Continue with Apple\"\n >\n <img src=\"${appleIconSrc}\" alt=\"\" width=\"64\" height=\"64\" loading=\"lazy\" />\n </button>\n <button\n class=\"email__social email__social--google\"\n data-ref=\"google\"\n type=\"button\"\n aria-label=\"Continue with Google\"\n >\n <img src=\"${googleIconSrc}\" alt=\"\" width=\"64\" height=\"64\" loading=\"lazy\" />\n </button>\n </div>\n <pop-button-link href=\"https://www.popgrids.io\" target=\"_blank\" rel=\"noopener noreferrer\">\n What’s PopGrids?\n </pop-button-link>\n </form>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-email\")) {\n customElements.define(\"pop-auth-email\", PopAuthEmail);\n}\n","export default \"data:image/gif;base64,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\"","import swirlingOvalsSrc from \"../assets/swirling-ovals.gif?inline\";\nimport { POPGRIDS_WORDMARK_SVG } from \"../assets/wordmark-svg.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n }\n\n .auth-join {\n -webkit-appearance: none;\n align-items: flex-start;\n appearance: none;\n background-color: lightgray;\n background-color: var(--pop-background, #fff);\n background-image: url(\"${swirlingOvalsSrc}\"), none;\n background-position: calc(100% - 88px) center;\n background-repeat: no-repeat, repeat;\n background-size:\n 8.215% 59.149%,\n auto;\n border: none;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-sm, 6px);\n justify-content: flex-end;\n padding: 16px 8px;\n width: 100%;\n }\n\n /* Keyboard users still get a ring when they Tab here, drawn inside the bar\n so the feed's overflow:hidden can't clip it. A programmatic hand-back\n of focus (restoreFocus, after Esc/Back from a card) opts out via\n data-restored: the visitor didn't navigate here, and the ring around\n the whole bar read as an error state. */\n .auth-join:focus-visible {\n outline: 2px solid var(--pop-ring);\n outline-offset: -2px;\n }\n\n :host([data-restored]) .auth-join:focus-visible {\n outline: none;\n }\n\n .auth-join__actions {\n align-items: center;\n align-self: stretch;\n color: var(--pop-foreground, #000);\n display: flex;\n font-family: Inter, sans-serif;\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-size: 13px;\n font-weight: 600;\n justify-content: space-between;\n letter-spacing: -0.08px;\n line-height: 18px;\n padding: 0px 8px;\n }\n\n .auth-join__logo {\n align-items: center;\n color: var(--pop-foreground, #000);\n display: flex;\n flex-direction: column;\n height: 12px;\n justify-content: center;\n padding: 0;\n pointer-events: none;\n width: 75px;\n }\n`);\n\nexport class PopAuthJoin extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n keydown: \"onKeyDown\",\n focusout: \"onFocusOut\",\n };\n\n /** Puts focus on the bar without scrolling the feed (it's often still sliding into place) or drawing a focus ring. */\n restoreFocus(): void {\n this.setAttribute(\"data-restored\", \"\");\n this.getElement<HTMLButtonElement>(ref(\"join\"))?.focus({ preventScroll: true });\n }\n\n // Any real keyboard navigation from here (Tab, Enter...) means the visitor\n // is driving again, so a ring is appropriate from then on.\n protected onKeyDown() {\n this.removeAttribute(\"data-restored\");\n }\n\n protected onFocusOut() {\n this.removeAttribute(\"data-restored\");\n }\n\n protected onClick(event: MouseEvent) {\n if (!(event.target as HTMLElement).closest(ref(\"join\"))) return;\n this.handleJoin();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const pending = this.authStore.authPending.value;\n\n const joinBtn = this.getElement<HTMLButtonElement>(ref(\"join\"));\n if (joinBtn) {\n joinBtn.disabled = pending;\n }\n this.setText(ref(\"label\"), pending ? \"Signing in\\u2026\" : \"Join the Conversation\");\n });\n }\n\n private handleJoin(): void {\n this.authStore.clearAuthError();\n this.authStore.startEmailSignIn();\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <button class=\"auth-join\" data-ref=\"join\" type=\"button\">\n <div class=\"auth-join__actions\">\n <span data-ref=\"label\">Join the Conversation</span>\n <span class=\"auth-join__logo\" aria-hidden=\"true\">${POPGRIDS_WORDMARK_SVG}</span>\n </div>\n </button>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-join\")) {\n customElements.define(\"pop-auth-join\", PopAuthJoin);\n}\n","import { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n border-top: 1px solid var(--pop-sidebar-border);\n display: block;\n padding: 20px 24px;\n font-family: Inter, sans-serif;\n text-align: center;\n }\n\n .no-code__body {\n align-items: flex-start;\n align-self: stretch;\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .no-code__container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n justify-content: center;\n align-items: center;\n }\n\n .no-code__list {\n list-style: none;\n margin: 0;\n padding: 0;\n text-align: left;\n }\n\n .no-code__footer {\n align-items: center;\n display: flex;\n justify-content: space-between;\n width: 100%;\n }\n`);\n\nexport class PopAuthNoCode extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n // This card replaces the code card the visitor just clicked in, so their\n // focus would otherwise be dropped on a removed element. Land it on the\n // title so assistive tech announces the new view.\n connectedCallback() {\n super.connectedCallback();\n this.getElement<HTMLElement>(\"#no-code-title\")?.focus();\n }\n\n // After a dismissed notice (e.g. a rate-limit wait ending on Resend Code),\n // hand focus back to the card, since the notice had made it inert.\n protected setupEffects() {\n let dismissals = this.authStore.authNoticeDismissals.peek();\n this.addEffect(() => {\n const next = this.authStore.authNoticeDismissals.value;\n if (next === dismissals) return;\n dismissals = next;\n queueMicrotask(() =>\n this.getElement<HTMLElement>(\"#no-code-title\")?.focus({ preventScroll: true }),\n );\n });\n }\n\n protected onClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (target.closest(ref(\"resend\"))) {\n void this.authStore.resendOtp();\n return;\n }\n\n if (target.closest(ref(\"back\"))) {\n this.authStore.backToCode();\n return;\n }\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div\n class=\"no-code__container text-xs\"\n role=\"group\"\n aria-labelledby=\"no-code-title\"\n >\n <p class=\"text-heading m-0\" id=\"no-code-title\" tabindex=\"-1\">Steps to Take</p>\n <div class=\"no-code__body\">\n <ul class=\"no-code__list\">\n <li><strong>Check spam/junk</strong> – it might be there.</li>\n <li><strong>Verify email</strong> – check your email for typos.</li>\n <li><strong>Wait a moment</strong> – emails take a few mins.</li>\n <li><strong>Whitelist us</strong> – it may be blocked.</li>\n </ul>\n <p class=\"m-0\">Still no code?</p>\n </div>\n <div class=\"no-code__footer\">\n <pop-button-link data-ref=\"back\" size=\"sm\" theme=\"default\">Back</pop-button-link>\n <pop-button-link\n class=\"no-code__contact\"\n size=\"sm\"\n theme=\"default\"\n href=\"mailto:hello@popgrids.io?subject=Verification%20Code%20Issue\"\n >Contact Support</pop-button-link\n >\n <pop-button-link data-ref=\"resend\" size=\"sm\" theme=\"default\" primary>\n Resend Code\n </pop-button-link>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-no-code\")) {\n customElements.define(\"pop-auth-no-code\", PopAuthNoCode);\n}\n","export default \"data:image/png;base64,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\"","import watermarkSrc from \"../assets/watermark@2x.png\";\nimport { EmbedAuthStore, type EmbedAuthView } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\nimport type { PopAuthJoin } from \"./pop-auth-join.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n position: relative;\n\n --pop-auth-border: var(--pop-border, rgba(0, 0, 32, 0.04));\n --pop-auth-logo: rgba(0, 0, 32, 0.35);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-auth-border: var(--pop-border, rgba(255, 255, 255, 0.1));\n --pop-auth-logo: rgba(255, 255, 255, 0.35);\n }\n }\n\n :host(.dark) {\n --pop-auth-border: var(--pop-border, rgba(255, 255, 255, 0.1));\n --pop-auth-logo: rgba(255, 255, 255, 0.35);\n }\n\n /* Deliberately no background here. .panel's own box grows to match\n whichever of panel__join/panel__card is taller for the duration of a\n transition (the exiting one stays display:block until it finishes\n sliding away), so an opaque .panel would cover the comment list behind\n it for that whole 833ms. Leaving it transparent lets join/card's own\n (opaque) boxes show through everywhere except where they themselves\n render, so the comment list stays visible around them mid-transition. */\n .panel {\n position: relative;\n }\n\n /* Positioned relative to panel__join-group (below), not .panel — .panel's\n own box grows to match whichever of join/card is taller mid-transition,\n so a fixed offset from *it* would float away from the join bar it's\n meant to sit above. Anchoring to the group instead means it's part of\n the same box that's actually animating, so it stays put above the join\n bar and fades/slides with it, in sync, the same as border-top below. */\n .watermark {\n position: absolute;\n top: -22px;\n left: 2px;\n padding: 2px 6px;\n }\n\n /* pop-auth-join (+ its watermark) and the card (email/code/no-code) are\n two independent, always-mounted elements stacked in the same grid cell\n so they can overlap mid-transition — one slides down off-screen while\n the other slides up into place, instead of one instantly replacing the\n other. */\n .panel__stack {\n display: grid;\n grid-template-columns: 1fr;\n grid-template-rows: 1fr;\n }\n\n .panel__join-group,\n .panel__card {\n /* Grid items default to align-self: stretch — during the brief window\n where both are display:block at once (mid-transition), the row\n auto-sizes to the taller of the two and would stretch the shorter\n one's box to match, pinning its content at the top instead of the\n bottom until the row shrinks back down. Anchor both to the end\n (bottom) of the shared cell instead, matching .feed__footer's own\n grid-stack treatment in pop-feed.ts. */\n grid-area: 1 / 1;\n align-self: end;\n }\n\n .panel__card {\n position: relative;\n }\n\n /* The transform/opacity/display transition lives on this wrapper, not\n directly on <pop-auth-join>, so the watermark (absolutely positioned\n inside it) rides along as part of the same animating box instead of\n needing its own separate, easy-to-desync transition. */\n .panel__join-group {\n position: relative;\n transform: translateY(0);\n opacity: 1;\n transition:\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n display var(--pop-duration-quick) allow-discrete;\n\n @starting-style {\n transform: translateY(100%);\n opacity: 0;\n }\n }\n\n .panel--card .panel__join-group {\n display: none;\n transform: translateY(100%);\n opacity: 0;\n }\n\n /* border-top lives on the join bar's own box (not the outer .panel) so it\n enters/leaves in lockstep with the bar itself — it used to live on\n .panel, toggled instantly by the panel--card class while the actual\n slide took 833ms, so the border would snap on/off out of sync with\n the content still animating underneath it. */\n .panel__join {\n border-top: 1px solid var(--pop-auth-border);\n }\n\n /* Same reasoning as border-top above: the card's own background/radius\n live on its own box (not toggled via panel--card on the static outer\n .panel) so they're always in sync with its display/opacity/transform\n state instead of snapping the instant the view changes. */\n .panel__card {\n display: none;\n background: var(--pop-background);\n border-radius: var(--pop-radius-2xl) var(--pop-radius-2xl) 0 0;\n transform: translateY(100%);\n opacity: 0;\n transition:\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n height var(--pop-duration-quick) var(--pop-ease-quick),\n display var(--pop-duration-quick) allow-discrete;\n }\n\n /* --pop-ease-quick overshoots 1 (peaks ~1.1), so the card's translateY and\n height briefly travel past their resting values and lift its bottom edge\n off the feed's bottom, exposing the comment list underneath. This\n backing extends the card's background below its box to cover that gap;\n the feed host's overflow:hidden clips it once the card settles. A\n box-shadow rather than a pseudo-element on purpose: an absolutely\n positioned descendant below the card counts toward its scrollHeight,\n which swapCardContent measures to animate the card's height — a shadow\n doesn't. */\n .panel__card {\n box-shadow: 0 100px 0 0 var(--pop-background);\n }\n\n .panel--card .panel__card {\n display: block;\n transform: translateY(0);\n opacity: 1;\n\n @starting-style {\n transform: translateY(100%);\n opacity: 0;\n }\n }\n`);\n\n/**\n * Container for the widget's auth states. pop-auth-join and the \"card\"\n * (pop-auth-email / -code / -no-code) are separate, always-mounted elements\n * that animate independently based on EmbedAuthStore.authView — the card\n * slides up from the bottom over the join bar (which slides away beneath\n * it) and reverses on the way back to idle. Card content itself still\n * swaps by innerHTML, mirroring the footer-swap pattern in pop-feed.ts.\n */\nexport class PopAuthPanel extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n private _child: string | null = null;\n private _prevView: EmbedAuthView = \"idle\";\n private _heightAnimationFrame: number | null = null;\n private _heightTransitionEnd: ((event: TransitionEvent) => void) | null = null;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n disconnectedCallback() {\n this.cancelCardHeightAnimation();\n super.disconnectedCallback();\n }\n\n private cancelCardHeightAnimation(): void {\n if (this._heightAnimationFrame !== null) {\n window.cancelAnimationFrame(this._heightAnimationFrame);\n this._heightAnimationFrame = null;\n }\n\n const card = this.getElement<HTMLDivElement>(ref(\"card\"));\n if (this._heightTransitionEnd) {\n card?.removeEventListener(\"transitionend\", this._heightTransitionEnd);\n this._heightTransitionEnd = null;\n }\n }\n\n private swapCardContent(card: HTMLDivElement, mount: HTMLDivElement, child: string): void {\n this.cancelCardHeightAnimation();\n\n const previousHeight = card.getBoundingClientRect().height;\n card.style.height = `${previousHeight}px`;\n mount.innerHTML = `<${child}></${child}>`;\n\n this._heightAnimationFrame = window.requestAnimationFrame(() => {\n this._heightAnimationFrame = null;\n // Measure the content, not card.scrollHeight: the card is pinned to\n // previousHeight right now, and scrollHeight never reports less than\n // the element's own height — so a shorter incoming panel (email ->\n // code) would read as \"no change\" and skip the animation entirely.\n const nextHeight = mount.getBoundingClientRect().height;\n\n if (Math.abs(nextHeight - previousHeight) < 1) {\n card.style.height = \"\";\n return;\n }\n\n this._heightTransitionEnd = (event: TransitionEvent) => {\n if (event.target !== card || event.propertyName !== \"height\") return;\n card.style.height = \"\";\n card.removeEventListener(\"transitionend\", this._heightTransitionEnd!);\n this._heightTransitionEnd = null;\n };\n card.addEventListener(\"transitionend\", this._heightTransitionEnd);\n card.style.height = `${nextHeight}px`;\n });\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const view = this.authStore.authView.value;\n const desired =\n view === \"email\"\n ? \"pop-auth-email\"\n : view === \"code\"\n ? \"pop-auth-code\"\n : view === \"no-code\"\n ? \"pop-auth-no-code\"\n : null;\n\n // Checked before the class flips: once the card is display:none its\n // focused control is dropped and focus falls back to <body>. Only\n // reclaim focus when it was actually inside the card — an outside\n // click that closed it must not yank focus off wherever the visitor went.\n const cardHadFocus =\n view === \"idle\" &&\n this._prevView !== \"idle\" &&\n this.getElement(ref(\"card\"))?.matches(\":focus-within\");\n\n this.toggleClass(ref(\"panel\"), \"panel--card\", desired !== null);\n\n if (cardHadFocus) {\n this.getElement<PopAuthJoin>(\"pop-auth-join\")?.restoreFocus();\n }\n\n // Re-entering a card from idle always mounts fresh (resets any\n // abandoned input); swapping directly between card views (e.g.\n // email -> code) already remounts since the desired tag differs.\n // Content isn't cleared on the way back to idle — it stays mounted,\n // hidden under panel__card's own display:none, so the box doesn't\n // go empty mid-exit-animation.\n const enteringFromIdle = this._prevView === \"idle\" && view !== \"idle\";\n const mount = this.getElement<HTMLDivElement>(ref(\"card-content\"));\n if (mount && desired && (this._child !== desired || enteringFromIdle)) {\n const card = this.getElement<HTMLDivElement>(ref(\"card\"));\n this._child = desired;\n if (card && this._prevView !== \"idle\") {\n this.swapCardContent(card, mount, desired);\n } else {\n mount.innerHTML = `<${desired}></${desired}>`;\n }\n }\n\n this._prevView = view;\n });\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"panel\" data-ref=\"panel\">\n <div class=\"panel__stack\">\n <div class=\"panel__join-group\">\n <div class=\"watermark\">\n <img src=\"${watermarkSrc}\" alt=\"PopGrids Watermark\" width=\"64\" height=\"11\" />\n </div>\n <pop-auth-join class=\"panel__join\"></pop-auth-join>\n </div>\n <div class=\"panel__card\" data-ref=\"card\">\n <div data-ref=\"card-content\"></div>\n </div>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-panel\")) {\n customElements.define(\"pop-auth-panel\", PopAuthPanel);\n}\n","import { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: inline-flex;\n max-width: 100%;\n }\n\n .btn-link {\n position: relative;\n align-items: center;\n background-color: transparent;\n border-style: solid;\n border-color: transparent;\n border-top-width: 1px;\n border-bottom-width: 1px;\n border-left-width: 4px;\n border-right-width: 4px;\n border-radius: var(--pop-radius-xs, 4px);\n cursor: pointer;\n display: inline-flex;\n flex-shrink: 0;\n font-weight: 500;\n gap: 6px;\n justify-content: center;\n max-width: 100%;\n outline: none;\n text-decoration: none;\n transform: translateY(-1px);\n transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n }\n\n /* Sizes */\n .btn-link--size-sm,\n .btn-link--size-md {\n font-size: 14px;\n line-height: 20px;\n letter-spacing: 0;\n }\n\n .btn-link--size-lg {\n font-size: 16px;\n line-height: 24px;\n letter-spacing: 0;\n }\n\n /* Themes */\n .btn-link--theme-default {\n color: var(--pop-foreground);\n }\n\n .btn-link--theme-default.btn-link--primary {\n color: var(--pop-foreground);\n }\n\n .btn-link--theme-white {\n color: white;\n }\n\n .btn-link--theme-black {\n color: black;\n }\n\n /* Hover State */\n .btn-link--theme-default:hover,\n .btn-link--theme-black:hover {\n background-color: color-mix(in srgb, var(--pop-foreground) 10%, transparent);\n }\n\n .btn-link--theme-white:hover {\n background-color: color-mix(in srgb, white 16%, transparent);\n }\n\n /* Focus State */\n .btn-link:focus-visible {\n background-color: var(--pop-ring);\n color: white !important;\n }\n\n /* Disabled State */\n .btn-link:disabled,\n .btn-link.is-disabled {\n color: color-mix(in srgb, var(--pop-foreground) 35%, transparent) !important;\n background-color: transparent !important;\n border-color: transparent !important;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .btn-link__icon {\n align-items: center;\n display: inline-flex;\n flex-shrink: 0;\n justify-content: center;\n }\n\n .btn-link__icon ::slotted(*) {\n display: block;\n height: 18px;\n pointer-events: none;\n width: 18px;\n }\n\n :host([size=\"sm\"]) .btn-link__icon ::slotted(*) {\n height: 16px;\n width: 16px;\n }\n\n :host([size=\"lg\"]) .btn-link__icon ::slotted(*) {\n height: 20px;\n width: 20px;\n }\n\n .btn-link__label {\n min-width: 0;\n overflow: hidden;\n position: relative;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n`);\n\nconst SIZES = new Set([\"sm\", \"md\", \"lg\"]);\nconst THEMES = new Set([\"default\", \"white\", \"black\"]);\n\n/**\n * Web Component port of popgrids-ui's `<ButtonLink>` — an inline text-sized\n * link/button used for secondary actions (e.g. \"Back\", \"Resend Code\").\n * Renders an `<a>` when `href` is set, otherwise a `<button>`.\n *\n * Slots: default (label), `leading`, `trailing` (icons/elements either side\n * of the label — omit entirely rather than passing an empty slot, so no\n * unwanted gap is reserved for it).\n */\nexport class PopButtonLink extends BaseElement {\n protected get styleSheets() {\n return [localSheet];\n }\n\n static get observedAttributes() {\n return [\"href\", \"size\", \"theme\", \"primary\", \"disabled\", \"type\", \"target\", \"rel\"];\n }\n\n onHrefChanged() {\n this.render();\n }\n\n onSizeChanged() {\n this.render();\n }\n\n onThemeChanged() {\n this.render();\n }\n\n onPrimaryChanged() {\n this.render();\n }\n\n onDisabledChanged() {\n this.render();\n }\n\n onTypeChanged() {\n this.render();\n }\n\n onTargetChanged() {\n this.render();\n }\n\n onRelChanged() {\n this.render();\n }\n\n get href(): string | null {\n return this.getAttribute(\"href\");\n }\n\n set href(value: string | null) {\n if (value === null) {\n this.removeAttribute(\"href\");\n } else {\n this.setAttribute(\"href\", value);\n }\n }\n\n get size(): \"sm\" | \"md\" | \"lg\" {\n const value = this.getAttribute(\"size\");\n return value && SIZES.has(value) ? (value as \"sm\" | \"md\" | \"lg\") : \"md\";\n }\n\n set size(value: \"sm\" | \"md\" | \"lg\") {\n this.setAttribute(\"size\", value);\n }\n\n get theme(): \"default\" | \"white\" | \"black\" {\n const value = this.getAttribute(\"theme\");\n return value && THEMES.has(value) ? (value as \"default\" | \"white\" | \"black\") : \"default\";\n }\n\n set theme(value: \"default\" | \"white\" | \"black\") {\n this.setAttribute(\"theme\", value);\n }\n\n get primary(): boolean {\n return this.hasAttribute(\"primary\");\n }\n\n set primary(value: boolean) {\n if (value) {\n this.setAttribute(\"primary\", \"\");\n } else {\n this.removeAttribute(\"primary\");\n }\n }\n\n get disabled(): boolean {\n return this.hasAttribute(\"disabled\");\n }\n\n set disabled(value: boolean) {\n if (value) {\n this.setAttribute(\"disabled\", \"\");\n } else {\n this.removeAttribute(\"disabled\");\n }\n }\n\n get type(): \"button\" | \"submit\" | \"reset\" {\n const value = this.getAttribute(\"type\");\n return value === \"submit\" || value === \"reset\" ? value : \"button\";\n }\n\n set type(value: \"button\" | \"submit\" | \"reset\") {\n this.setAttribute(\"type\", value);\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: MouseEvent) {\n if (!this.disabled) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n\n private hasSlotted(name: string): boolean {\n return this.querySelector(`:scope > [slot=\"${name}\"]`) !== null;\n }\n\n /** Whether the default slot has any non-whitespace light-DOM content. */\n private hasLabel(): boolean {\n return Array.from(this.childNodes).some((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n return !(node as Element).hasAttribute(\"slot\");\n }\n return node.nodeType === Node.TEXT_NODE && !!node.textContent?.trim();\n });\n }\n\n protected getTemplate(): string {\n const classes = [\n \"btn-link\",\n `btn-link--size-${this.size}`,\n `btn-link--theme-${this.theme}`,\n this.primary ? \"btn-link--primary\" : \"\",\n this.disabled ? \"is-disabled\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const leading = this.hasSlotted(\"leading\")\n ? `<span class=\"btn-link__icon\"><slot name=\"leading\"></slot></span>`\n : \"\";\n const trailing = this.hasSlotted(\"trailing\")\n ? `<span class=\"btn-link__icon\"><slot name=\"trailing\"></slot></span>`\n : \"\";\n const label = this.hasLabel() ? `<span class=\"btn-link__label\"><slot></slot></span>` : \"\";\n const inner = `${leading}${label}${trailing}`;\n\n if (this.href !== null) {\n const disabledAttrs = this.disabled ? `aria-disabled=\"true\" tabindex=\"-1\"` : \"\";\n const target = this.getAttribute(\"target\");\n const rel = this.getAttribute(\"rel\");\n return /* html */ `\n <a\n class=\"${classes}\"\n part=\"link\"\n href=\"${this.href}\"\n ${target ? `target=\"${target}\"` : \"\"}\n ${rel ? `rel=\"${rel}\"` : \"\"}\n ${disabledAttrs}\n >${inner}</a\n >\n `;\n }\n\n return /* html */ `\n <button\n class=\"${classes}\"\n part=\"link\"\n type=\"${this.type}\"\n ${this.disabled ? \"disabled\" : \"\"}\n >\n ${inner}\n </button>\n `;\n }\n}\n\nif (!customElements.get(\"pop-button-link\")) {\n customElements.define(\"pop-button-link\", PopButtonLink);\n}\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD8AAABMCAYAAADa6W+wAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAUuSURBVHgB5ZyBceIwEEX3bq4AOsAdQAdxKggl+Co4rgKcCkgqgFRAUgGkAqACOxVAKvDpg+VRHEmWQSubuTezg8Ega7UrebWS+UG8jIXEQoZCovI9lcd1ciHHUnZCPsrXXflZ7xkISYSshByEFJ5kLWRO54bsHRGdK+dTYZNkQhbUg4aI6FyRoiNBQyQUGLj3jMJYuleNMC4v1gel67Ig/WCq5Qe144+QlM6Wb2QwGNB4PD7JaDQ6veIzKZLj8XiSPM9Pr/v9nna73UnwWUtyIb+FbMgjM3K0QBzHxXq9Lg6HQ3Et2+22WCwWpzJdr1/KjDzRqLiwZDGbzbwobCLLslNDRFEUrAEmTReBVVCxkLRohIsbICLLiA5roxJdAm9zaIAJXUBmKhCtHtraJjAuNHjBgVrcBcDsFhSXoD4NDbB2VTyyFNI7xSUODTB1UX5hKmA+nxd9Bl0AYxGZ3X9wkdWTJCluARjIYv2ULrG6T3eHhabT6SkY4sASFB1aWx23FJ+IULcqm6MBUKbF+rFO+ZQCje6qa6J8jsjQYv2FTvmMAvb1yWRSXePp6anwzWq1cnb9MQXo6yqwthyZ0Q04y9e5/k9F+VjnCpiGCrckDjCtFV51OpZTWN/lo/4Gxqryd7pvCNckTkS/rI7f39/JN5b6j1TltU10d3dHnKjl+7Y8sHhtpS+iHm3f4JyfS2RIytHvMV4ZdMt+1lvhS9OUaSdu5DUuSFk5l60hksoPWv7QK9I1kb/zjU2HRsuHIFQj17FanusWV4fD4i5I5Ye6k8PhkELAqbxlHDn2os9L5Tm6mUX5vBfKy/s7x/U+Pz9Np7q3/GazqY7VaI+j/Br7zpV/e3urjjmiSUvUWJ3QRkHcqAlHzL58g+iUzAmNLxOboGAgur+/rwYkjgnU6+ur6VROXVpezbLA6hw5A9dMTnDlZRoLinPk8CwTmm85vE76PCdIvRn0ympdQL8YGWI6y0GD1atVGzngaePLrmLua8FAaqEaBTsb7bl4fHy0hbTPdB7pv7AmjYtwraZw0eDu6OuRqrTV7T8+PuhWkHGDhUeqWV0qr43+b6XPI4RVAyYNGyHL+odS+Vz3i1tQ/vn5uUlxnPitO/FL+cL3XzEkFAFmWsjRY28eZnKXTKBQBgY3y6xN8pcM+km0O66wlhZiUMJ1lstlY1yB8y335KU2peUOTKRQtvWTyOGJypJv4FGwmlD42zl4Aq6rZnQhFyxnYYBLXb4YEemXpjlx2ENziSBaTaglncT3nhtgTS23nEkyXYEhdl417KJwtfaUrkCrPPbOhEDdqNBS6ZQcd4HbWOkugN0NIWhhfRhpQR4eM/mlHGujPEvq1ysNOXu4tHzaKidPqLO6XPcFrkCnDgIdy/IYUryYiubkEVV5bSwbSnlgW04mBhqVDxnfh16tVZXXhk8hLW9bVCQGemV5y7VyCkAnUR5APEHmezkL9RxeZ4Oey5qab5yUVxcTuXh5eTGd2lMgnkjjepg/c9JmdYWT2FQJjo3BEsusLqPAbHUV4VpMTNPUZvUFBSYxVMT7vvsGxWH1iDpgTYbbDjzg2i6AXBweMSH77C2hjsAUy/psPLwASce2OD4GuqIA2B4hxzRyrrzHbfBb8I2ZGJKODw8PVeJRxujysXDcw/FYOBKWDhFjLuSeAkV1NlJqn125RjLqqJ+bSOk/VVwSEe9fRSzJQx6Om4T8NgLKiunGSMh8O3QR/Damjmn7hyF14KpxKSM6d49IOa/7u6dX6snfPf0DiVL6IWhCmZ4AAAAASUVORK5CYII=\"","export const colors = [\n \"#DDD0BE\",\n \"#E9DCBB\",\n \"#E9DCBB\",\n \"#C7D1B0\",\n \"#C6D0CB\",\n \"#E9DCBB\",\n \"#C7D1B0\",\n \"#E9DCBB\",\n \"#DFC2C0\",\n \"#CFD4C6\",\n \"#D7E3E8\",\n \"#CFD4C6\",\n \"#D6B3B3\",\n \"#E9DCBB\",\n \"#CFCBDC\",\n \"#BFD6D7\",\n \"#E3D2C6\",\n \"#D1E2E7\",\n \"#D6B3B3\",\n \"#BFD6D7\",\n \"#E9DCBB\",\n \"#C7D1B0\",\n \"#DFC2C0\",\n \"#D1E2E7\",\n \"#CFD4C6\",\n \"#E9DCBB\",\n \"#D7E3E8\",\n \"#CFD4C6\",\n \"#C6D0CB\",\n \"#E9DCBB\",\n \"#C7D1B0\",\n \"#E9DCBB\",\n \"#CFCBDC\",\n \"#E3D2C6\",\n \"#E9DCBB\",\n];\n\nexport const sampleColor = (index?: number) => {\n if (typeof index === \"number\") {\n return colors[index % colors.length] ?? \"#e5e7eb\";\n }\n return colors[Math.floor(Math.random() * colors.length)];\n};\n\n/** 32-bit FNV-1a over UTF-8 bytes — deterministic, no lookup table. */\nexport function fnv1a32(data: string): number {\n const bytes = new TextEncoder().encode(data);\n let h = 0x811c9dc5;\n for (let i = 0; i < bytes.length; i++) {\n const byte = bytes[i] ?? 0;\n h ^= byte;\n h = Math.imul(h, 0x01000193);\n }\n return h >>> 0;\n}\n\n/** Deterministic background color from a stable string (e.g. user id, org id, slug). */\nexport function backgroundColor(id: string): string {\n return colors[fnv1a32(id) % colors.length] ?? \"#e5e7eb\";\n}\n\n","import deletedUserMarkSrc from \"../assets/popgrids-letter-p.png?inline\";\nimport { backgroundColor, sampleColor } from \"../helpers/color.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n\n --comment-avatar-border-size: 1px;\n --comment-avatar-border-color: var(--color-background, #fff);\n --comment-avatar-size: 32px;\n }\n\n .comment-avatar {\n align-items: center;\n display: flex;\n flex-shrink: 0;\n isolation: isolate;\n justify-content: center;\n position: relative;\n width: calc(var(--comment-avatar-size) + calc(var(--comment-avatar-border-size) * 2));\n height: calc(var(--comment-avatar-size) + calc(var(--comment-avatar-border-size) * 2));\n }\n\n .comment-avatar--size-xs {\n --comment-avatar-size: 32px;\n }\n\n .comment-avatar--size-sm {\n --comment-avatar-size: 56px;\n }\n\n .comment-avatar--size-md {\n --comment-avatar-size: 80px;\n }\n\n .comment-avatar--size-lg {\n --comment-avatar-size: 120px;\n }\n\n .comment-avatar--size-xl {\n --comment-avatar-size: 140px;\n }\n\n .comment-avatar__background {\n background-color: var(--comment-avatar-border-color);\n position: absolute;\n top: 0;\n left: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n }\n\n /**\n * Content\n */\n\n .comment-avatar__content {\n align-items: center;\n background-color: var(--color-surface-bg-default);\n display: flex;\n justify-content: center;\n overflow: hidden;\n position: relative;\n height: var(--comment-avatar-size);\n width: var(--comment-avatar-size);\n z-index: 20;\n\n /* Initials styling */\n font-family: Inter, sans-serif;\n font-weight: 600;\n color: #374151;\n font-size: calc(var(--comment-avatar-size) * 0.35);\n line-height: 1;\n }\n\n .comment-avatar__content::slotted(img) {\n -webkit-user-drag: none;\n align-self: stretch;\n flex: 1 0 0;\n height: var(--comment-avatar-size);\n object-fit: cover;\n pointer-events: none;\n position: absolute;\n user-select: none;\n width: var(--comment-avatar-size);\n }\n\n .comment-avatar__deleted-mark {\n -webkit-user-drag: none;\n bottom: -3px;\n height: auto;\n left: 0;\n object-fit: cover;\n pointer-events: none;\n position: absolute;\n user-select: none;\n width: 100%;\n transform: scale(0.57);\n }\n`);\n\nexport class PopCommentAvatar extends BaseElement {\n private _backgroundColor: string;\n\n constructor() {\n super();\n this._backgroundColor = sampleColor() ?? \"#e5e7eb\";\n }\n\n static get observedAttributes() {\n return [\"size\", \"data-color-key\", \"deleted\"];\n }\n\n onSizeChanged() {\n this.render();\n }\n\n onDataColorKeyChanged() {\n this.render();\n }\n\n onDeletedChanged() {\n this.render();\n }\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n get size(): string {\n return this.getAttribute(\"size\") || \"md\";\n }\n\n set size(value: string) {\n this.setAttribute(\"size\", value);\n }\n\n get deleted(): boolean {\n return this.hasAttribute(\"deleted\");\n }\n\n set deleted(value: boolean) {\n if (value) {\n this.setAttribute(\"deleted\", \"\");\n } else {\n this.removeAttribute(\"deleted\");\n }\n }\n\n protected getTemplate(): string {\n const size = this.size;\n const deleted = this.deleted;\n const key = this.getAttribute(\"data-color-key\");\n const bg = deleted\n ? \"var(--pop-muted-foreground, #e5e7eb)\"\n : key\n ? backgroundColor(key)\n : this._backgroundColor;\n\n const content = deleted\n ? `<div\n class=\"comment-avatar__content mask mask-squircle\"\n part=\"content\"\n style=\"background-color: ${bg}; opacity: 0.15\"\n ><img class=\"comment-avatar__deleted-mark\" src=\"${deletedUserMarkSrc}\" alt=\"Deleted user\" /></div>`\n : `<slot\n class=\"comment-avatar__content mask mask-squircle\"\n part=\"content\"\n style=\"background-color: ${bg};\"\n ></slot>`;\n\n return /* html */ `\n <div class=\"comment-avatar comment-avatar--size-${size}\" part=\"base\">\n <div class=\"comment-avatar__background mask mask-squircle\" part=\"background\"></div>\n ${content}\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-avatar\")) {\n customElements.define(\"pop-comment-avatar\", PopCommentAvatar);\n}\n","import { computed, signal } from \"@preact/signals-core\";\nimport { reconnectDelayMs } from \"../lib/backoff.js\";\nimport type { Comment, CommentAuthor, Grid } from \"../types/models.js\";\nimport type { EmbedAuthStore } from \"./embed-auth-store.js\";\n\nconst MAX_RECONNECT_DELAY_MS = 30_000;\nconst DEFAULT_PREVIEW_COUNT = 3;\n\nconst commentRecency = (comment: Comment) => {\n const createdAt =\n typeof comment.createdAt === \"number\"\n ? comment.createdAt\n : Date.parse(String(comment.createdAt));\n\n return Number.isFinite(createdAt) ? createdAt : 0;\n};\n\nconst resolvePreviewCount = (grid: Grid | null, fallback: number) => {\n const value = grid?.previewCount ?? fallback;\n\n return value > 0 ? value : DEFAULT_PREVIEW_COUNT;\n};\n\n/**\n * The five visual settings a `<pop-grid>` can override live via\n * `data-align`/`data-layout`/`data-position`/`data-icon`/`data-preview-count`\n * — see pop-grid.ts's observedAttributes. Never includes `undefined`-valued\n * keys: an absent/invalid attribute is simply omitted, not set to\n * `undefined`, so `mergeOverrides` can fall back to the fetched grid's value\n * for that field with a plain spread.\n */\nexport type GridOverrides = Partial<\n Pick<Grid, \"align\" | \"layout\" | \"position\" | \"icon\" | \"previewCount\">\n>;\n\nconst mergeOverrides = (fetched: Grid | null, overrides: GridOverrides): Grid | null => {\n if (!fetched) {\n return fetched;\n }\n\n return { ...fetched, ...overrides };\n};\n\nexport class GridStore {\n readonly apiUrl: string;\n readonly publicKey: string;\n readonly pageUrl: string;\n readonly externalId: string | null;\n readonly previewCount = DEFAULT_PREVIEW_COUNT;\n private readonly authStore: EmbedAuthStore;\n\n /** The grid last fetched from the API — never read directly outside this\n * class; `grid` (below) is the override-aware value every consumer uses. */\n private _fetchedGrid = signal<Grid | null>(null);\n /** The override attributes currently set on the `<pop-grid>` element. */\n private _overrides = signal<GridOverrides>({});\n\n /** Fetched grid config with any live override attributes layered on top.\n * Read-only from the outside — set via `load()` (fetched) or\n * `setOverrides()` (overrides). */\n grid = computed(() => mergeOverrides(this._fetchedGrid.value, this._overrides.value));\n comments = signal<Comment[]>([]);\n loading = signal(true);\n error = signal<string | null>(null);\n open = signal(false);\n replyingTo = signal<string | null>(null);\n editingCommentId = signal<string | null>(null);\n scrollingCommentId = signal<string | null>(null);\n\n private socket: WebSocket | null = null;\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n\n topLevelComments = computed(() =>\n this.comments.value\n .filter((c) => c.parentCommentId === null)\n .sort((a, b) => String(a.sortKey).localeCompare(String(b.sortKey))),\n );\n\n replyingToComment = computed(() => {\n const id = this.replyingTo.value;\n if (!id) return null;\n return this.comments.value.find((c) => c.id === id) ?? null;\n });\n\n editingComment = computed(() => {\n const id = this.editingCommentId.value;\n if (!id) return null;\n return this.comments.value.find((c) => c.id === id) ?? null;\n });\n\n previewComments = computed(() =>\n this.topLevelComments.value.slice(0, resolvePreviewCount(this.grid.value, this.previewCount)),\n );\n\n previewAvatars = computed((): CommentAuthor[] => {\n const limit = resolvePreviewCount(this.grid.value, this.previewCount);\n const seen = new Set<string>();\n const uniqueNewestFirst: CommentAuthor[] = [];\n\n const sorted = [...this.comments.value].sort((a, b) => commentRecency(b) - commentRecency(a));\n\n for (const comment of sorted) {\n const author = comment.author;\n\n if (!author?.id || seen.has(author.id)) {\n continue;\n }\n\n seen.add(author.id);\n uniqueNewestFirst.push(author);\n\n if (uniqueNewestFirst.length >= limit) {\n break;\n }\n }\n\n return uniqueNewestFirst.reverse();\n });\n\n constructor(opts: {\n apiUrl: string;\n publicKey: string;\n pageUrl: string;\n externalId?: string | null;\n authStore: EmbedAuthStore;\n }) {\n this.apiUrl = opts.apiUrl;\n this.publicKey = opts.publicKey;\n this.pageUrl = opts.pageUrl;\n this.externalId = opts.externalId?.trim() || null;\n this.authStore = opts.authStore;\n }\n\n /** Replaces the current override set wholesale (not a per-key merge) —\n * called with every override attribute `<pop-grid>` currently has set, so\n * removing an attribute correctly falls back to the fetched grid's value\n * for that field instead of leaving a stale override in place. */\n setOverrides(overrides: GridOverrides): void {\n this._overrides.value = overrides;\n }\n\n /** pageUrl + optional externalId — the params that identify the discussion. */\n private identityParams(): string {\n const params = new URLSearchParams({ pageUrl: this.pageUrl });\n if (this.externalId) {\n params.set(\"externalId\", this.externalId);\n }\n return params.toString();\n }\n\n repliesFor(parentId: string): Comment[] {\n const parent = this.comments.value.find((c) => c.id === parentId);\n if (!parent) return [];\n return this.comments.value\n .filter(\n (c) =>\n c.id !== parentId &&\n (c.sortKey === parent.sortKey || c.sortKey.startsWith(parent.sortKey + \"/\")),\n )\n .sort((a, b) => String(a.sortKey).localeCompare(String(b.sortKey)));\n }\n\n async load(): Promise<boolean> {\n this.loading.value = true;\n this.error.value = null;\n try {\n const gridRes = await this.authStore.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}`,\n );\n\n if (!gridRes.ok) {\n this.error.value = \"There was a problem loading the PopGrid\";\n return false;\n }\n\n const data = (await gridRes.json()) as { grid: Grid };\n this._fetchedGrid.value = data.grid;\n void this.connectRealtime();\n\n const commentsRes = await this.authStore.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/comments?${this.identityParams()}`,\n );\n\n if (commentsRes.ok) {\n const commentsData = (await commentsRes.json()) as { comments: Comment[] };\n this.comments.value = commentsData.comments;\n }\n\n return true;\n } catch {\n console.error(\"Failed to load PopGrid\");\n this.error.value = \"There was a problem loading the PopGrid\";\n return false;\n } finally {\n this.loading.value = false;\n }\n }\n\n async postComment(body: string, parentCommentId?: string): Promise<Comment | null> {\n const res = await this.authStore.authorizedFetch(\n `/api/v1/embed/grids/${this.publicKey}/comments`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n body,\n pageUrl: this.pageUrl,\n externalId: this.externalId ?? undefined,\n parentCommentId,\n }),\n },\n );\n\n if (!res.ok) {\n return null;\n }\n\n const data = (await res.json()) as { comment: Comment };\n this.upsertComment(data.comment);\n\n if (data.comment.author && !this.authStore.currentUser.value) {\n this.authStore.currentUser.value = {\n id: data.comment.author.id,\n name: data.comment.author.name ?? \"\",\n email: \"\",\n image: data.comment.author.image,\n };\n }\n\n return data.comment;\n }\n\n destroy(): void {\n this.disposed = true;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onclose = null;\n this.socket.onerror = null;\n this.socket.close();\n this.socket = null;\n }\n }\n\n private async connectRealtime(): Promise<void> {\n const connectUrl = this.grid.value?.connectUrl;\n\n if (!connectUrl || this.disposed) {\n return;\n }\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onclose = null;\n this.socket.onerror = null;\n this.socket.close();\n this.socket = null;\n }\n\n // Mint a short-lived, single-use ticket for this connection attempt\n // rather than sending the long-lived embed token in the WS URL, where it\n // could land in access logs. Works for signed-out visitors too — an\n // anonymous ticket still gets broadcast updates for public comments.\n let ticket: string | null = null;\n try {\n const ticketRes = await this.authStore.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/connect-ticket`,\n { method: \"POST\" },\n );\n if (ticketRes.ok) {\n const ticketData = (await ticketRes.json()) as { ticket: string };\n ticket = ticketData.ticket;\n }\n } catch {\n // No realtime this attempt — scheduleReconnect will try again.\n }\n\n if (!ticket || this.disposed) {\n this.scheduleReconnect();\n return;\n }\n\n const wsUrl = new URL(connectUrl, this.apiUrl);\n wsUrl.protocol = wsUrl.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n wsUrl.searchParams.set(\"ticket\", ticket);\n wsUrl.searchParams.set(\"pageUrl\", this.pageUrl);\n if (this.externalId) {\n wsUrl.searchParams.set(\"externalId\", this.externalId);\n }\n\n const socket = new WebSocket(wsUrl.toString());\n this.socket = socket;\n\n socket.onopen = () => {\n this.reconnectAttempt = 0;\n };\n\n socket.onmessage = (event) => {\n try {\n const payload = JSON.parse(String(event.data)) as {\n type?: string;\n comment?: Comment;\n };\n\n if (payload.type === \"comment.created\" && payload.comment) {\n this.upsertComment(payload.comment);\n } else if (payload.type === \"comment.updated\" && payload.comment) {\n this.updateCommentInList(payload.comment);\n }\n } catch {\n // Ignore malformed realtime payloads.\n }\n };\n\n socket.onclose = () => {\n if (this.disposed) {\n return;\n }\n\n this.scheduleReconnect();\n };\n\n socket.onerror = () => {\n socket.close();\n };\n }\n\n private scheduleReconnect(): void {\n if (this.disposed || this.reconnectTimer) {\n return;\n }\n\n const delay = reconnectDelayMs(this.reconnectAttempt, 1000, MAX_RECONNECT_DELAY_MS);\n this.reconnectAttempt += 1;\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n void this.connectRealtime();\n }, delay);\n }\n\n private upsertComment(comment: Comment): void {\n const existing = this.comments.value.some((entry) => entry.id === comment.id);\n\n if (existing) {\n return;\n }\n\n this.comments.value = [...this.comments.value, comment];\n }\n\n async editComment(commentId: string, body: string): Promise<Comment | null> {\n const res = await this.authStore.authorizedFetch(\n `/api/v1/embed/grids/${this.publicKey}/comments/${commentId}`,\n {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n body,\n pageUrl: this.pageUrl,\n externalId: this.externalId ?? undefined,\n }),\n },\n );\n\n if (!res.ok) {\n return null;\n }\n\n const data = (await res.json()) as { comment: Comment };\n this.updateCommentInList(data.comment);\n return data.comment;\n }\n\n async deleteComment(commentId: string): Promise<Comment | null> {\n const res = await this.authStore.authorizedFetch(\n `/api/v1/embed/grids/${this.publicKey}/comments/${commentId}?${this.identityParams()}`,\n { method: \"DELETE\" },\n );\n\n if (!res.ok) {\n return null;\n }\n\n const data = (await res.json()) as { comment: Comment };\n this.updateCommentInList(data.comment);\n return data.comment;\n }\n\n async flagComment(commentId: string): Promise<boolean> {\n const res = await this.authStore.authorizedFetch(\n `/api/v1/embed/grids/${this.publicKey}/comments/${commentId}/flag?${this.identityParams()}`,\n { method: \"POST\" },\n );\n\n return res.ok;\n }\n\n private updateCommentInList(comment: Comment): void {\n this.comments.value = this.comments.value.map((c) => (c.id === comment.id ? comment : c));\n }\n}\n","import { getInitials } from \"../helpers/author.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\nimport type { PopCommentInput } from \"./pop-comment-input.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n background: var(--pop-background);\n border-top: 1px solid var(--pop-bar-input-bg);\n display: block;\n padding: 6px;\n position: relative;\n\n --pop-bar-avatar-bg: #e5e7eb;\n --pop-bar-avatar-color: #374151;\n --pop-bar-avatar-border: #ffffff;\n --pop-bar-input-bg: rgba(0, 0, 32, 0.04);\n --pop-bar-send-hover: rgba(0, 0, 32, 0.06);\n --pop-bar-send-color: #000000;\n --pop-bar-watermark: rgba(0, 0, 32, 0.1);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-bar-avatar-bg: #1f2937;\n --pop-bar-avatar-color: #d1d5db;\n --pop-bar-avatar-border: var(--pop-popover, #151d2a);\n --pop-bar-input-bg: rgba(255, 255, 255, 0.05);\n --pop-bar-send-hover: rgba(255, 255, 255, 0.08);\n --pop-bar-send-color: #ffffff;\n --pop-bar-watermark: rgba(255, 255, 255, 0.1);\n }\n }\n\n :host(.dark) {\n --pop-bar-avatar-bg: #1f2937;\n --pop-bar-avatar-color: #d1d5db;\n --pop-bar-avatar-border: var(--pop-popover, #151d2a);\n --pop-bar-input-bg: rgba(255, 255, 255, 0.05);\n --pop-bar-send-hover: rgba(255, 255, 255, 0.08);\n --pop-bar-send-color: #ffffff;\n --pop-bar-watermark: rgba(255, 255, 255, 0.1);\n }\n\n .bar {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .bar__user {\n display: flex;\n align-items: center;\n align-self: flex-start;\n flex-shrink: 0;\n padding-top: 2px;\n }\n\n .bar__avatar {\n flex-shrink: 0;\n --comment-avatar-border-size: 0px;\n }\n\n .bar__avatar--reply {\n margin-right: -4px;\n z-index: 1;\n }\n\n .bar__avatar--reply.hidden {\n display: none;\n }\n\n .bar__avatar--user {\n z-index: 2;\n }\n\n .bar__user.has-reply .bar__avatar--user {\n --comment-avatar-border-size: 2px;\n --comment-avatar-border-color: var(--pop-bar-avatar-border);\n }\n\n .bar__input-wrap {\n flex: 1;\n min-width: 0;\n background: var(--pop-bar-input-bg);\n border-radius: 18px;\n overflow: hidden;\n display: flex;\n align-items: flex-end;\n padding: 4px 8px 4px 12px;\n max-height: 280px;\n }\n\n .bar__send {\n align-items: center;\n align-self: flex-end;\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n justify-content: center;\n padding-bottom: 2px;\n }\n\n .logo-watermark {\n position: absolute;\n top: -16px;\n left: 8px;\n font-family: Inter, sans-serif;\n font-size: 8px;\n font-weight: 700;\n letter-spacing: 1px;\n color: var(--pop-bar-watermark);\n text-transform: uppercase;\n border-radius: 9999px;\n padding: 2px 6px;\n pointer-events: none;\n user-select: none;\n }\n`);\n\nconst LOGO_WATERMARK_SVG = `<svg width=\"64\" height=\"11\" viewBox=\"0 0 64 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M3.91111 0C0.892839 0 0 2.11357 0 4.77714C0 5.76321 0.0987654 6.73357 0.213333 7.70786C0.25679 8.08893 0.240988 8.50929 0.312099 8.89036C0.497778 9.89214 1.44593 10.3557 2.36642 10.3557C3.62667 10.3557 4.4642 9.56607 4.4642 8.30107C4.4642 7.57036 4.22321 7.09107 3.5279 6.80821C3.48444 6.7925 3.44099 6.78071 3.44099 6.72179C3.44099 6.62357 3.59901 6.55286 3.69778 6.55286C4.03753 6.55286 4.57481 6.89071 5.04494 6.89071C6.88593 6.89071 7.90519 5.13071 7.90519 3.48071C7.90519 1.08429 6.13136 0 3.91111 0ZM3.89531 5.18179C3.78074 5.18179 3.68198 5.08357 3.68198 4.96964C3.68198 4.81643 3.89531 4.7025 3.96642 4.57679C4.12049 4.29393 4.16395 3.81464 4.16395 3.4925C4.16395 3.11143 4.06519 2.40821 3.8242 2.12536C3.75309 2.04286 3.65432 1.99964 3.65432 1.88571C3.65432 1.77179 3.76889 1.67357 3.87951 1.67357C4.36148 1.67357 4.60247 3.08393 4.60247 3.44929C4.60247 3.84214 4.47605 5.18179 3.89531 5.18179Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M12.7368 0.239637C9.73433 0.239637 7.93285 2.35321 7.93285 5.25249C7.93285 8.15178 9.73038 10.2654 12.7368 10.2654C15.7432 10.2654 17.5249 8.12428 17.5249 5.25249C17.5249 2.38071 15.7116 0.239637 12.7368 0.239637ZM12.8672 8.83142C12.8198 8.89035 12.7249 9.00035 12.6104 9.00035C12.4958 9.00035 12.3852 8.90214 12.3852 8.78821C12.3852 8.74499 12.7526 8.19499 12.8119 8.02607C13.037 7.36214 13.0805 6.64321 13.0805 5.93999C13.0805 4.99714 12.9106 3.78321 12.3299 3.00928C12.2153 2.86785 11.8637 2.60071 11.8637 2.44749C11.8637 2.33357 11.9625 2.23535 12.077 2.23535C12.1758 2.23535 12.2746 2.32178 12.3457 2.37678C13.2504 3.12321 13.523 4.82821 13.523 5.93999C13.523 6.81214 13.4874 8.08499 12.8711 8.82749L12.8672 8.83142Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M21.6533 0C18.6351 0 17.7422 2.11357 17.7422 4.77714C17.7422 5.76321 17.841 6.73357 17.9555 7.70786C17.999 8.08893 17.9832 8.50929 18.0543 8.89036C18.24 9.89214 19.1881 10.3557 20.1086 10.3557C21.3689 10.3557 22.2064 9.56607 22.2064 8.30107C22.2064 7.57036 21.9654 7.09107 21.2701 6.80821C21.2267 6.7925 21.1832 6.78071 21.1832 6.72179C21.1832 6.62357 21.3412 6.55286 21.44 6.55286C21.7797 6.55286 22.317 6.89071 22.7871 6.89071C24.6281 6.89071 25.6474 5.13071 25.6474 3.48071C25.6474 1.08429 23.8775 0 21.6533 0ZM21.6415 5.18179C21.5269 5.18179 21.4281 5.08357 21.4281 4.96964C21.4281 4.81643 21.6415 4.7025 21.7126 4.57679C21.8667 4.29393 21.9101 3.81464 21.9101 3.4925C21.9101 3.11143 21.8113 2.40821 21.5704 2.12536C21.4992 2.04286 21.4005 1.99964 21.4005 1.88571C21.4005 1.77179 21.5151 1.67357 21.6257 1.67357C22.1076 1.67357 22.3486 3.08393 22.3486 3.44929C22.3486 3.84214 22.2222 5.18179 21.6415 5.18179Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M31.9012 4.16822C30.882 4.16822 29.4637 4.6318 29.4637 5.84572C29.4637 6.53715 29.9733 7.56251 30.7832 7.56251C31.2929 7.56251 31.6208 7.16965 31.7906 7.16965C31.8341 7.16965 31.8736 7.19715 31.8736 7.24037C31.8736 7.64894 31.0795 7.83358 30.7674 7.83358C29.677 7.83358 29.0963 6.90251 29.0963 5.91644C29.0963 4.70644 30.242 3.77537 31.4035 3.77537C31.7432 3.77537 32.0988 3.87358 32.4385 3.87358C33.4459 3.87358 34.165 2.97394 34.165 2.01537C34.165 0.424295 32.2687 0.0589382 31.0045 0.0589382C27.6464 0.0589382 25.6909 2.22751 25.6909 5.52358C25.6909 8.56822 27.279 10.5089 30.4237 10.5089C32.4622 10.5089 34.6864 9.6368 34.6864 7.26787C34.6864 5.6493 33.6237 4.16822 31.8973 4.16822H31.9012Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M41.2681 6.56464C41.0113 6.56464 40.802 6.66286 40.5886 6.66286C40.5452 6.66286 40.5333 6.61964 40.5333 6.59214C40.5333 6.49393 40.5768 6.45071 40.6479 6.42321C40.8889 6.34071 41.1457 6.28179 41.3827 6.16786C42.4612 5.66107 43.0973 4.7575 43.0973 3.56321C43.0973 1.40643 41.2405 0.0982143 39.202 0.0982143C38.4632 0.0982143 37.7442 0.310357 37.12 0.648214C35.4212 1.56357 35.0933 2.87571 34.9946 4.66321C34.9511 5.36643 34.9511 6.07357 34.9511 6.77679V8.48179C34.9511 9.55036 35.6583 10.4107 36.7763 10.4107C37.5822 10.4107 38.3052 9.83321 38.4909 9.07107C38.5896 8.61929 38.5343 8.085 38.5343 7.64893C38.5343 7.60571 38.5501 7.59393 38.5896 7.59393C38.6291 7.59393 38.6765 7.62143 38.7042 7.63714C39.202 8.83536 39.8815 10.3557 41.4222 10.3557C42.4849 10.3557 43.362 9.60929 43.362 8.525C43.362 7.44071 42.3427 6.56857 41.2642 6.56857L41.2681 6.56464ZM38.961 5.18179C38.8464 5.18179 38.7476 5.08357 38.7476 4.96964C38.7476 4.81643 38.961 4.7025 39.0321 4.57679C39.1862 4.29393 39.2296 3.81464 39.2296 3.4925C39.2296 3.11143 39.1309 2.40821 38.8899 2.12536C38.8188 2.04286 38.7358 1.99964 38.7358 1.88571C38.7358 1.77179 38.8346 1.67357 38.9491 1.67357C39.4311 1.67357 39.6721 3.08393 39.6721 3.44929C39.6721 3.84214 39.5575 5.18179 38.9649 5.18179H38.961Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M46.7674 0.549991C46.4277 0.326063 45.9457 0.212134 45.5348 0.212134C44.642 0.212134 43.8756 0.915349 43.7768 1.79142C43.7491 2.04678 43.761 2.28642 43.761 2.55356V4.94606L43.7175 7.46821V8.72142C43.7175 9.70749 44.5669 10.4814 45.5467 10.4814C46.2696 10.4814 47.0637 10.0296 47.3324 9.35392C47.4864 8.97285 47.5022 8.43856 47.5022 8.02999V6.92999L47.518 4.73392V2.53785C47.518 1.72071 47.5022 1.07249 46.7674 0.549991Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M50.2993 0.125713C48.8533 0.125713 48.1304 0.801428 48.1304 2.25107V2.82857L48.1462 3.96786V4.54536C48.1462 4.98143 48.1462 5.39 48.1304 5.82607C48.1027 6.34857 48.0316 6.86714 48.0316 7.40536C48.0316 9.3775 49.0509 10.3361 51.0222 10.3361C54.0523 10.3361 56.1067 9.03964 56.1067 5.81429C56.1067 1.925 54.2222 0.121785 50.2993 0.121785V0.125713ZM51.6583 7.91607C51.5437 7.91607 51.4449 7.81786 51.4449 7.70393C51.4449 7.66071 51.4608 7.83352 51.4884 7.59C51.8558 6.985 51.9546 6.14036 51.9546 5.44893C51.9546 4.80071 51.8835 3.84214 51.4726 3.33536C51.4015 3.22143 51.2593 3.13893 51.2593 2.9975C51.2593 2.88357 51.358 2.78536 51.4726 2.78536C51.6859 2.78536 51.9822 3.31964 52.0691 3.50428C52.3378 4.125 52.3812 4.80071 52.3812 5.46071C52.3812 5.86928 52.1679 7.91214 51.6583 7.91214V7.91607Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M62.7239 5.1268C61.9022 5.05608 60.7249 4.77322 60.0889 4.23894C60.0059 4.16822 59.8637 4.07001 59.8637 3.9443C59.8637 3.90108 59.8795 3.83037 59.9348 3.83037C60.0889 3.83037 61.0805 4.62001 61.9338 4.62001C63.0123 4.62001 64 3.78715 64 2.69108C64 0.887867 61.5941 0.157152 60.1324 0.157152C57.9635 0.157152 56.3516 1.5518 56.3516 3.76358C56.3516 4.24287 56.4227 4.90287 56.7783 5.27215C56.9482 5.4568 57.2326 5.4568 57.4578 5.4568C58.3072 5.4568 59.3857 5.72394 59.836 6.49787C59.8795 6.56858 59.919 6.68251 59.919 6.76501C59.919 6.79251 59.919 6.83572 59.8914 6.82001C59.8084 6.79251 59.7373 6.7218 59.678 6.6668C59.1802 6.18751 58.5007 5.70822 57.7817 5.70822C56.7032 5.70822 56.324 6.73751 56.324 7.63715C56.324 9.45215 57.9674 10.4539 59.6385 10.4539C61.6217 10.4539 64 9.15751 64 6.94572C64 6.12858 63.6444 5.21322 62.7239 5.13072V5.1268Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n</svg>`;\n\nexport class PopCommentBar extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: MouseEvent) {\n if (!(event.target as HTMLElement).closest(ref(\"send\"))) return;\n void this.handleSend();\n }\n\n protected setupEffects() {\n let lastReplyingTo: string | null = null;\n let lastEditingCommentId: string | null = null;\n\n this.addEffect(() => {\n const parentCommentId = this.gridStore.replyingTo.value;\n\n if (parentCommentId && parentCommentId !== lastReplyingTo) {\n const input = this.getElement<PopCommentInput>(\"pop-comment-input\");\n if (input) {\n setTimeout(() => input.focus(), 0);\n }\n }\n lastReplyingTo = parentCommentId;\n });\n\n this.addEffect(() => {\n const editingComment = this.gridStore.editingComment.value;\n if (editingComment && editingComment.id !== lastEditingCommentId) {\n const input = this.getElement<PopCommentInput>(\"pop-comment-input\");\n if (input) {\n input.setValue(editingComment.body);\n setTimeout(() => input.focus(), 0);\n }\n } else if (!editingComment && lastEditingCommentId) {\n const input = this.getElement<PopCommentInput>(\"pop-comment-input\");\n if (input) {\n input.clear();\n }\n }\n lastEditingCommentId = editingComment?.id ?? null;\n });\n\n // The user's own avatar is pop-account-switcher (getTemplate below) —\n // it manages its own avatar content by consuming EmbedAuthStore\n // directly, so this effect only needs to handle the reply-context\n // avatar shown alongside it. Left as a static, always-present node\n // (rather than rebuilt via innerHTML like before) so the switcher's\n // dropdown/floating-ui state never gets torn down by an unrelated\n // reply/editing state change.\n this.addEffect(() => {\n const barUser = this.getElement<HTMLDivElement>(ref(\"user\"));\n const replyAvatar = this.getElement<HTMLElement>(ref(\"avatar-reply\"));\n if (!barUser || !replyAvatar) return;\n\n const editingComment = this.gridStore.editingComment.value;\n const parentAuthor = editingComment ? null : this.gridStore.replyingToComment.value?.author;\n\n barUser.classList.toggle(\"has-reply\", Boolean(parentAuthor));\n replyAvatar.classList.toggle(\"hidden\", !parentAuthor);\n\n if (parentAuthor) {\n const parentColorKey = parentAuthor.id ?? parentAuthor.name ?? \"\";\n replyAvatar.setAttribute(\"data-color-key\", parentColorKey);\n replyAvatar.innerHTML = parentAuthor.image\n ? `<img src=\"${parentAuthor.image}\" alt=\"${parentAuthor.name ?? \"User\"}'s avatar\">`\n : getInitials(parentAuthor.name);\n }\n });\n }\n\n private async handleSend(): Promise<void> {\n const input = this.getElement<PopCommentInput>(\"pop-comment-input\");\n if (!input) return;\n\n const body = input.getValue().trim();\n if (!body) return;\n\n const editingId = this.gridStore.editingCommentId.value;\n if (editingId) {\n input.clear();\n this.gridStore.editingCommentId.value = null;\n await this.gridStore.editComment(editingId, body);\n } else {\n input.clear();\n const comment = await this.gridStore.postComment(\n body,\n this.gridStore.replyingTo.value ?? undefined,\n );\n this.gridStore.replyingTo.value = null;\n\n if (comment) {\n this.gridStore.scrollingCommentId.value = comment.id;\n }\n }\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"logo-watermark\">${LOGO_WATERMARK_SVG}</div>\n <div class=\"bar\">\n <div class=\"bar__user\" data-ref=\"user\">\n <pop-comment-avatar\n size=\"xs\"\n class=\"bar__avatar bar__avatar--reply hidden\"\n data-ref=\"avatar-reply\"\n ></pop-comment-avatar>\n <pop-account-switcher class=\"bar__avatar bar__avatar--user\"></pop-account-switcher>\n </div>\n <div class=\"bar__input-wrap\">\n <pop-comment-input></pop-comment-input>\n </div>\n <pop-comment-icon\n class=\"bar__send\"\n data-ref=\"send\"\n theme=\"neutral\"\n variant=\"send\"\n aria-label=\"Send comment\"\n ></pop-comment-icon>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-bar\")) {\n customElements.define(\"pop-comment-bar\", PopCommentBar);\n}\n","import { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n /* Mode-level theme colors (defaults for light mode) */\n --pop-comment-color-black: #000000;\n --pop-comment-color-white: #ffffff;\n --pop-comment-color-default: #000000;\n --pop-comment-color-reversed: #ffffff;\n --pop-comment-bg-singular-resting: #121926;\n --pop-comment-bg-singular-hover: rgba(0, 0, 32, 0.08);\n --pop-comment-bg-reversed: #121926;\n --pop-comment-bg-blank-resting: #ffffff;\n\n display: flex;\n\n --pop-comment-icon-scale: 1;\n --pop-comment-icon-scale-hover: 1.1875;\n --pop-comment-icon-scale-active: 0.9375;\n --pop-comment-icon-size: 32px;\n --pop-comment-icon-color: var(--pop-foreground, #000000);\n --pop-comment-icon-color-hover: var(--pop-foreground, #000000);\n --pop-comment-icon-color-active: var(--pop-foreground, #000000);\n --pop-comment-icon-color-focused: var(--pop-foreground, #000000);\n --pop-comment-icon-background: var(\n --color-surface-buttons-singular-bg-launch-icon-hover,\n rgba(0, 0, 32, 0.08)\n );\n --pop-comment-icon-background-hover: var(\n --color-surface-buttons-singular-bg-launch-icon-hover,\n rgba(0, 0, 32, 0.08)\n );\n --pop-comment-icon-background-active: var(\n --color-surface-buttons-singular-bg-launch-icon-hover,\n rgba(0, 0, 32, 0.08)\n );\n --pop-comment-icon-background-focused: var(\n --color-surface-buttons-singular-bg-launch-icon-hover,\n rgba(0, 0, 32, 0.08)\n );\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n /* Overrides for dark mode */\n --pop-comment-color-black: #ffffff;\n --pop-comment-color-white: #000000;\n --pop-comment-color-default: #ffffff;\n --pop-comment-color-reversed: #000000;\n --pop-comment-bg-singular-resting: #ffffff;\n --pop-comment-bg-singular-hover: rgba(255, 255, 255, 0.15);\n --pop-comment-bg-reversed: #ffffff;\n --pop-comment-bg-blank-resting: #121926;\n }\n }\n\n :host(.dark) {\n /* Overrides for dark mode (.dark class on host) */\n --pop-comment-color-black: #ffffff;\n --pop-comment-color-white: #000000;\n --pop-comment-color-default: #ffffff;\n --pop-comment-color-reversed: #000000;\n --pop-comment-bg-singular-resting: #ffffff;\n --pop-comment-bg-singular-hover: rgba(255, 255, 255, 0.15);\n --pop-comment-bg-reversed: #ffffff;\n --pop-comment-bg-blank-resting: #121926;\n }\n\n .comment-icon {\n align-items: center;\n background: transparent;\n border: none;\n display: inline-flex;\n height: var(--pop-comment-icon-size);\n justify-content: center;\n padding: 0;\n position: relative;\n transform-origin: center;\n width: var(--pop-comment-icon-size);\n }\n\n .comment-icon--size-sm {\n --pop-comment-icon-size: 24px;\n }\n\n .comment-icon:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .comment-icon__focus-indicator {\n background-color: var(--pop-ring);\n display: none;\n position: absolute;\n inset: -3px;\n pointer-events: none;\n transform-origin: center;\n transform: scale(var(--pop-comment-icon-scale));\n transition: all 200ms ease-out;\n width: calc(100% + 6px);\n }\n\n .comment-icon:focus-visible .comment-icon__focus-indicator {\n display: flex;\n }\n\n .comment-icon:focus-visible {\n outline: none;\n }\n\n .comment-icon__inner {\n align-items: center;\n background: var(--pop-comment-icon-background);\n color: var(--pop-comment-icon-color);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n height: var(--pop-comment-icon-size);\n justify-content: center;\n position: absolute;\n transform-origin: center;\n transition: all 200ms ease-out;\n transform: scale(var(--pop-comment-icon-scale));\n width: var(--pop-comment-icon-size);\n }\n\n .comment-icon__icon-container {\n align-items: center;\n display: flex;\n height: 100%;\n justify-content: center;\n transition: transform ease-out 150ms;\n width: 100%;\n }\n\n .comment-icon__icon-container svg {\n width: calc(var(--pop-comment-icon-size) * 0.6875);\n height: calc(var(--pop-comment-icon-size) * 0.6875);\n }\n\n .comment-icon--variant-close.comment-icon--theme-neutral .comment-icon__icon-container svg {\n width: var(--pop-comment-icon-size);\n height: var(--pop-comment-icon-size);\n }\n\n .comment-icon__icon-image {\n display: flex;\n width: var(--pop-comment-icon-size);\n height: var(--pop-comment-icon-size);\n }\n\n .comment-icon__icon {\n display: flex;\n }\n\n .comment-icon__icon-image + .comment-icon__icon {\n display: none;\n }\n\n .comment-icon .comment-icon__inner {\n transition: transform var(--pop-ease-pop-hover) var(--pop-duration-pop-hover);\n }\n\n @media (hover: hover) and (pointer: fine) {\n .comment-icon:hover .comment-icon__inner {\n background: var(--pop-comment-icon-background-hover);\n color: var(--pop-comment-icon-color-hover);\n transform: scale(var(--pop-comment-icon-scale-hover));\n }\n\n .comment-icon:hover .comment-icon__icon-image {\n display: none;\n }\n\n .comment-icon:hover .comment-icon__icon-image + .comment-icon__icon {\n display: flex;\n }\n }\n\n .comment-icon:active .comment-icon__inner {\n background: var(--pop-comment-icon-background-active);\n color: var(--pop-comment-icon-color-active);\n transform: scale(var(--pop-comment-icon-scale-active));\n transition-duration: 200ms;\n }\n\n .comment-icon:is(:focus-visible) .comment-icon__inner {\n background: var(--pop-comment-icon-background-focused);\n color: var(--pop-comment-icon-color-focused);\n }\n\n /* Brand / Add */\n .comment-icon--theme-brand.comment-icon--variant-add {\n --pop-comment-icon-color: var(--pop-comment-color-black);\n --pop-comment-icon-color-hover: var(--pop-comment-color-black);\n --pop-comment-icon-color-active: var(--pop-comment-color-black);\n --pop-comment-icon-color-focused: var(--pop-comment-color-black);\n --pop-comment-icon-background: transparent;\n --pop-comment-icon-background-hover: var(--pop-comment-bg-singular-hover);\n --pop-comment-icon-background-active: var(--pop-comment-bg-singular-hover);\n --pop-comment-icon-background-focused: transparent;\n }\n\n /* Brand / Close */\n .comment-icon--theme-brand.comment-icon--variant-close {\n --pop-comment-icon-color: var(--pop-comment-color-white);\n --pop-comment-icon-color-hover: var(--pop-comment-color-white);\n --pop-comment-icon-color-active: var(--pop-comment-color-white);\n --pop-comment-icon-color-focused: var(--pop-comment-color-white);\n --pop-comment-icon-background: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-active: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-singular-resting);\n }\n\n /* Neutral / Add */\n .comment-icon--theme-neutral.comment-icon--variant-add {\n --pop-comment-icon-color: var(--pop-comment-color-white);\n --pop-comment-icon-color-hover: var(--pop-comment-color-white);\n --pop-comment-icon-color-active: var(--pop-comment-color-white);\n --pop-comment-icon-color-focused: var(--pop-comment-color-white);\n --pop-comment-icon-background: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-active: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-singular-resting);\n }\n\n /* Neutral / Close */\n .comment-icon--theme-neutral.comment-icon--variant-close {\n --pop-comment-icon-color: var(--pop-comment-color-white);\n --pop-comment-icon-color-hover: var(--pop-comment-color-white);\n --pop-comment-icon-color-active: var(--pop-comment-color-white);\n --pop-comment-icon-color-focused: var(--pop-comment-color-white);\n --pop-comment-icon-background: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-active: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-singular-resting);\n }\n\n /* Neutral / Send */\n .comment-icon--theme-neutral.comment-icon--variant-send {\n --pop-comment-icon-color: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-hover: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-active: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-focused: var(--pop-comment-color-reversed);\n --pop-comment-icon-background: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-active: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-reversed);\n }\n\n /* Neutral / More */\n .comment-icon--theme-neutral.comment-icon--variant-more {\n --pop-comment-icon-color: var(--pop-comment-color-default);\n --pop-comment-icon-color-hover: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-active: var(--pop-comment-color-default);\n --pop-comment-icon-color-focused: var(--pop-comment-color-default);\n --pop-comment-icon-background: var(--pop-comment-bg-blank-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-active: var(--pop-comment-bg-blank-resting);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-blank-resting);\n }\n\n /* Neutral / Cancel */\n .comment-icon--theme-neutral.comment-icon--variant-cancel {\n --pop-comment-icon-color: var(--pop-comment-color-default);\n --pop-comment-icon-color-hover: var(--pop-comment-color-default);\n --pop-comment-icon-color-active: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-focused: var(--pop-comment-color-default);\n --pop-comment-icon-background: var(--pop-comment-bg-blank-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-blank-resting);\n --pop-comment-icon-background-active: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-blank-resting);\n }\n`);\n\nexport class PopCommentIcon extends BaseElement {\n protected get styleSheets() {\n return [localSheet];\n }\n\n static get observedAttributes() {\n return [\"counter\", \"icon-url\", \"size\", \"theme\", \"variant\", \"type\", \"disabled\", \"aria-label\"];\n }\n\n onAriaLabelChanged() {\n this.render();\n }\n\n onCounterChanged() {\n this.render();\n }\n\n onIconUrlChanged() {\n this.render();\n }\n\n onSizeChanged() {\n this.render();\n }\n\n onThemeChanged() {\n this.render();\n }\n\n onVariantChanged() {\n this.render();\n }\n\n onTypeChanged() {\n this.render();\n }\n\n onDisabledChanged() {\n this.render();\n }\n\n get counter(): number {\n return Number(this.getAttribute(\"counter\") || \"0\");\n }\n\n set counter(value: number) {\n this.setAttribute(\"counter\", String(value));\n }\n\n get iconUrl(): string | undefined {\n return this.getAttribute(\"icon-url\") || undefined;\n }\n\n set iconUrl(value: string | undefined) {\n if (value === undefined) {\n this.removeAttribute(\"icon-url\");\n } else {\n this.setAttribute(\"icon-url\", value);\n }\n }\n\n get size(): string {\n return this.getAttribute(\"size\") || \"md\";\n }\n\n set size(value: string) {\n this.setAttribute(\"size\", value);\n }\n\n get theme(): \"brand\" | \"neutral\" {\n return (this.getAttribute(\"theme\") as \"brand\" | \"neutral\") || \"brand\";\n }\n\n set theme(value: \"brand\" | \"neutral\") {\n this.setAttribute(\"theme\", value);\n }\n\n get variant(): \"add\" | \"close\" | \"filter\" | \"more\" | \"send\" | \"cancel\" {\n return (this.getAttribute(\"variant\") as any) || \"add\";\n }\n\n set variant(value: \"add\" | \"close\" | \"filter\" | \"more\" | \"send\" | \"cancel\") {\n this.setAttribute(\"variant\", value);\n }\n\n get type(): \"button\" | \"submit\" | \"reset\" | \"menu\" {\n return (this.getAttribute(\"type\") as any) || \"button\";\n }\n\n set type(value: \"button\" | \"submit\" | \"reset\" | \"menu\") {\n this.setAttribute(\"type\", value);\n }\n\n get disabled(): boolean {\n return this.hasAttribute(\"disabled\");\n }\n\n set disabled(value: boolean) {\n if (value) {\n this.setAttribute(\"disabled\", \"\");\n } else {\n this.removeAttribute(\"disabled\");\n }\n }\n\n get ariaLabel(): string | null {\n return this.getAttribute(\"aria-label\");\n }\n\n set ariaLabel(value: string | null) {\n if (value === null) {\n this.removeAttribute(\"aria-label\");\n } else {\n this.setAttribute(\"aria-label\", value);\n }\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: Event) {\n if (this.disabled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return;\n }\n this.emit(\"pop-click\");\n }\n\n get icon(): string {\n let icon = \"\";\n\n if (this.theme === \"brand\") {\n if (this.variant === \"add\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11 4.58331V17.4166M4.58333 11H17.4167\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n } else if (this.variant === \"close\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M16.5 5.5L5.5 16.5M5.5 5.5L16.5 16.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n }\n } else if (this.theme === \"neutral\") {\n if (this.variant === \"add\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.0002 4.58301V17.4163M4.5835 10.9997H17.4168\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n } else if (this.variant === \"close\") {\n icon = `\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.4628 11.4627L20.5373 20.5373M11.4628 20.5373L20.5373 11.4627\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n } else if (this.variant === \"more\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12.8335 16.5L7.3335 11L12.8335 5.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n } else if (this.variant === \"send\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M18.0394 3.68048C18.2139 3.61601 18.3837 3.78583 18.3193 3.96036L12.3858 20.0241C12.314 20.2185 12.0369 20.2123 11.9739 20.0149L9.89172 13.4908C9.86908 13.4199 9.88424 13.3423 9.93191 13.2851L14.4838 7.82287C14.6536 7.61906 14.3807 7.34616 14.1769 7.516L8.71467 12.0678C8.65746 12.1155 8.57987 12.1307 8.50893 12.108L1.98489 10.0259C1.78743 9.96287 1.78121 9.68575 1.97565 9.61393L18.0394 3.68048Z\"\n fill=\"currentColor\"\n />\n </svg>\n `;\n } else if (this.variant === \"cancel\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M16.5 5.5L5.5 16.5M5.5 5.5L16.5 16.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n }\n }\n return icon;\n }\n\n protected getTemplate(): string {\n const disabledAttr = this.disabled ? \"disabled\" : \"\";\n const classes = [\n \"comment-icon\",\n this.size ? `comment-icon--size-${this.size}` : \"\",\n this.theme ? `comment-icon--theme-${this.theme}` : \"\",\n this.variant ? `comment-icon--variant-${this.variant}` : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const iconHtml = this.iconUrl\n ? `<img src=\"${this.iconUrl}\" alt=\"\" class=\"comment-icon__icon-image\" />\n <slot class=\"comment-icon__icon\" name=\"icon\">${this.icon}</slot>`\n : `<slot class=\"comment-icon__icon\" name=\"icon\">${this.icon}</slot>`;\n\n const ariaLabelAttr = this.ariaLabel ? `aria-label=\"${this.ariaLabel}\"` : \"\";\n\n return /* html */ `\n <button\n class=\"${classes}\"\n part=\"base\"\n type=\"${this.type}\"\n ${disabledAttr}\n ${ariaLabelAttr}\n >\n <pop-focus-indicator\n class=\"comment-icon__focus-indicator mask mask-squircle\"\n ></pop-focus-indicator>\n <div class=\"comment-icon__inner mask mask-squircle\">\n <div class=\"comment-icon__icon-container\" part=\"icon\">${iconHtml}</div>\n </div>\n </button>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-icon\")) {\n customElements.define(\"pop-comment-icon\", PopCommentIcon);\n}\n","import { consume } from \"../store/registry.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: flex;\n flex: 1;\n min-width: 0;\n align-items: flex-end;\n }\n\n textarea {\n flex: 1;\n min-width: 0;\n background: none;\n border: none;\n outline: none;\n resize: none;\n font-family: Inter, sans-serif;\n font-size: 13px;\n color: black;\n line-height: 18px;\n padding: 5px 0;\n max-height: 200px;\n overflow-y: auto;\n width: 100%;\n letter-spacing: -0.08px;\n }\n\n textarea::placeholder {\n color: #697586;\n }\n`);\n\nexport class PopCommentInput extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n input: \"onInput\",\n keydown: \"onKeyDown\",\n };\n\n protected onInput(event: Event) {\n const textarea = event.target as HTMLTextAreaElement;\n textarea.style.height = \"auto\";\n textarea.style.height = `${textarea.scrollHeight}px`;\n }\n\n protected onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n if (this.gridStore.editingCommentId.value || this.gridStore.replyingTo.value) {\n event.stopPropagation();\n this.gridStore.editingCommentId.value = null;\n this.gridStore.replyingTo.value = null;\n }\n }\n }\n\n getValue(): string {\n return this.getElement<HTMLTextAreaElement>(\"textarea\")?.value ?? \"\";\n }\n\n setValue(val: string): void {\n const textarea = this.getElement<HTMLTextAreaElement>(\"textarea\");\n if (!textarea) return;\n\n textarea.value = val;\n textarea.style.height = \"auto\";\n textarea.style.height = `${textarea.scrollHeight}px`;\n }\n\n clear(): void {\n const textarea = this.getElement<HTMLTextAreaElement>(\"textarea\");\n if (!textarea) return;\n\n textarea.value = \"\";\n textarea.style.height = \"auto\";\n }\n\n focus(): void {\n this.getElement<HTMLTextAreaElement>(\"textarea\")?.focus();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const parent = this.gridStore.replyingToComment.value;\n const editing = this.gridStore.editingComment.value;\n\n let placeholder = \"Comment\";\n if (editing) {\n placeholder = \"Edit comment...\";\n } else if (parent?.author?.name) {\n placeholder = `Reply to ${parent.author.name}`;\n }\n\n this.setAttr(\"textarea\", \"placeholder\", placeholder);\n });\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <textarea rows=\"1\" placeholder=\"Comment\"></textarea>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-input\")) {\n customElements.define(\"pop-comment-input\", PopCommentInput);\n}\n","import { consume } from \"../store/registry.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n\n --pop-thread-link: rgba(0, 0, 32, 0.5);\n --pop-thread-link-hover: rgba(0, 0, 32, 0.8);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-thread-link: rgba(255, 255, 255, 0.5);\n --pop-thread-link-hover: rgba(255, 255, 255, 0.8);\n }\n }\n\n :host(.dark) {\n --pop-thread-link: rgba(255, 255, 255, 0.5);\n --pop-thread-link-hover: rgba(255, 255, 255, 0.8);\n }\n\n .thread {\n align-items: stretch;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .thread__replies {\n align-items: center;\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding-left: 24px;\n }\n\n .thread__more {\n display: flex;\n align-items: center;\n font-size: 13px;\n gap: 6px;\n padding-left: 30px;\n transition: opacity 0.15s ease;\n width: 100%;\n }\n\n .thread__more:hover {\n opacity: 1;\n }\n\n .thread__more-dot {\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--pop-muted-foreground);\n flex-shrink: 0;\n opacity: 0.1;\n }\n`);\n\nconst COLLAPSED_REPLY_LIMIT = 2;\n\nexport class PopCommentThread extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n\n private _showAll = false;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: MouseEvent) {\n if (!(event.target as HTMLElement).closest(ref(\"more\"))) return;\n this._showAll = true;\n this.render();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const commentId = this.getAttribute(\"comment-id\");\n const targetId = this.gridStore.scrollingCommentId.value;\n if (commentId && targetId) {\n const replies = this.gridStore.repliesFor(commentId);\n if (replies.some((r) => r.id === targetId)) {\n this._showAll = true;\n }\n }\n\n this.gridStore.comments.value;\n this.render();\n });\n }\n\n protected getTemplate(): string {\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return \"\";\n\n const replies = this.gridStore.repliesFor(commentId);\n const visibleReplies =\n this._showAll || replies.length <= COLLAPSED_REPLY_LIMIT\n ? replies\n : replies.slice(0, COLLAPSED_REPLY_LIMIT);\n const hiddenCount = replies.length - visibleReplies.length;\n\n const moreHtml =\n hiddenCount > 0\n ? `<div class=\"thread__more\">\n <div class=\"thread__more-dot\"></div>\n <pop-button-link data-ref=\"more\" size=\"sm\" theme=\"default\">\n Show ${hiddenCount} more ${hiddenCount === 1 ? \"reply\" : \"replies\"}\n </pop-button-link>\n </div>`\n : \"\";\n\n const repliesHtml =\n replies.length > 0\n ? `<div class=\"thread__replies\">\n ${visibleReplies\n .map((reply) => `<pop-comment comment-id=\"${reply.id}\"></pop-comment>`)\n .join(\"\")}\n ${moreHtml}\n </div>`\n : \"\";\n\n return /* html */ `\n <div class=\"thread\">\n <pop-comment comment-id=\"${commentId}\"></pop-comment>\n ${repliesHtml}\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-thread\")) {\n customElements.define(\"pop-comment-thread\", PopCommentThread);\n}\n","export function timeAgo(date: Date | string | number): string {\n const d = date instanceof Date ? date : new Date(date);\n const seconds = (Date.now() - d.getTime()) / 1000;\n\n if (seconds < 1) return \"now\";\n if (seconds < 60) return `${Math.floor(seconds)}s`;\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;\n if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;\n if (seconds < 604800) return `${Math.floor(seconds / 86400)}d`;\n return `${Math.floor(seconds / 604800)}w`;\n}\n","import { getInitials } from \"../helpers/author.js\";\nimport { timeAgo } from \"../helpers/time.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\nimport { computePosition, autoUpdate, flip, offset, shift } from \"@floating-ui/dom\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n width: 100%;\n --pop-comment-hover: rgba(0, 0, 32, 0.04);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-comment-hover: rgba(255, 255, 255, 0.04);\n }\n }\n\n .comment {\n display: flex;\n width: 100%;\n gap: 8px;\n align-items: center;\n background-color: transparent;\n border: none;\n padding: 0;\n border-radius: var(--pop-radius-md);\n outline: 6px solid transparent;\n text-align: left;\n transition:\n background-color 150ms ease,\n outline-color 150ms ease;\n }\n\n :host([data-size=\"sm\"]) .comment,\n :host:not([data-size]) .comment {\n --avatar-size: 32px;\n --width: 32px;\n gap: 8px;\n }\n\n :host([data-size=\"lg\"]) .comment {\n --avatar-size: 56px;\n --width: 56px;\n gap: 12px;\n }\n\n .comment--is-selected {\n background-color: var(--pop-muted);\n outline-color: var(--pop-muted);\n }\n\n :host(.is-signed-in) .comment {\n cursor: pointer;\n }\n\n @media (hover: hover) and (pointer: fine) {\n .comment:hover .comment__avatar {\n --avatar-translate-x: 2px;\n }\n\n .comment__avatar:hover {\n /* --avatar-scale: 1.06; */\n }\n\n .comment .comment__menu {\n display: none;\n }\n\n .comment:hover .comment__menu {\n display: flex;\n }\n }\n\n .comment--is-selected .comment__avatar {\n --avatar-translate-x: 2px;\n }\n\n .comment__avatar {\n --comment-avatar-border-size: 0;\n --avatar-translate-x: 0px;\n --avatar-scale: 1;\n width: var(--avatar-size);\n height: var(--avatar-size);\n transform: translateX(var(--avatar-translate-x)) scale(var(--avatar-scale));\n transition: transform var(--pop-duration-quick) var(--pop-ease-quick);\n }\n\n .comment__user {\n display: flex;\n width: var(--width);\n align-items: flex-start;\n gap: 10px;\n flex-shrink: 0;\n align-self: stretch;\n }\n\n .comment__content {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n flex: 1 0 0;\n align-self: stretch;\n }\n\n .comment__info {\n display: flex;\n align-items: flex-start;\n align-self: stretch;\n }\n\n .comment__menu {\n display: flex;\n justify-self: flex-end;\n }\n\n .comment__menu-trigger {\n background: none;\n border: none;\n cursor: pointer;\n border-radius: 9999px;\n aspect-ratio: 1;\n position: relative;\n }\n\n .comment__menu-trigger:before {\n content: \"\";\n height: 40px;\n left: 50%;\n position: absolute;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 40px;\n }\n\n .comment__user-meta {\n display: flex;\n align-items: flex-start;\n gap: 4px;\n flex-shrink: 0;\n align-self: stretch;\n flex-grow: 1;\n }\n\n .comment__user-name {\n color: var(--pop-foreground);\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-family: Inter, sans-serif;\n font-size: var(--text-widget-base, 13px);\n font-style: normal;\n font-weight: 500;\n line-height: var(--text-widget-base--line-height, 18px);\n letter-spacing: -0.08px;\n }\n\n .comment__timestamp {\n color: var(--pop-muted-foreground);\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-family: Inter, sans-serif;\n font-size: var(--text-widget-base, 13px);\n font-style: normal;\n font-weight: 400;\n line-height: var(--text-widget-base--line-height, 18px);\n letter-spacing: -0.08px;\n opacity: 0.5;\n }\n\n .comment__text {\n align-self: stretch;\n color: var(--pop-foreground);\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-family: Inter, sans-serif;\n font-size: 13px;\n font-style: normal;\n font-weight: 400;\n line-height: 18px;\n letter-spacing: -0.08px;\n text-align: left;\n\n /* Clamping when not expanded */\n display: -webkit-box;\n -webkit-line-clamp: 4;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .comment__text.expanded,\n .comment--is-selected .comment__text {\n -webkit-line-clamp: initial;\n display: block;\n }\n\n .comment__mention {\n color: #155eef;\n font-weight: 500;\n }\n\n .comment__menu {\n position: relative;\n }\n\n .comment__dropdown {\n background-color: var(--pop-background);\n border-radius: 6px;\n box-shadow: var(--pop-shadow-xl);\n display: none;\n flex-direction: column;\n gap: 6px;\n padding: 6px;\n pointer-events: auto;\n position: fixed;\n width: 120px;\n z-index: 1000;\n }\n\n .comment__dropdown.is-open {\n display: flex;\n }\n\n .comment__dropdown-item {\n align-items: center;\n background: none;\n border-radius: 4px;\n border: none;\n color: var(--pop-foreground);\n cursor: pointer;\n display: flex;\n flex: 1 0 0;\n font-family: Inter, sans-serif;\n font-size: 14px;\n font-weight: 500;\n justify-content: center;\n min-height: 40px;\n padding: 0 12px;\n text-align: left;\n transition: background-color 100ms ease;\n width: 100%;\n }\n\n .comment__dropdown-item:hover {\n background-color: var(--pop-comment-hover, rgba(0, 0, 0, 0.04));\n }\n\n .comment__dropdown-item--danger {\n color: #ef4444;\n }\n\n .comment__edit-form {\n display: flex;\n flex-direction: column;\n width: 100%;\n gap: 8px;\n margin-top: 4px;\n }\n\n .comment__edit-input {\n width: 100%;\n background: var(--pop-background, #ffffff);\n color: var(--pop-foreground, #000000);\n border: 1px solid var(--pop-border, #e4e4e7);\n border-radius: var(--pop-radius-sm, 4px);\n padding: 6px 8px;\n font-family: Inter, sans-serif;\n font-size: 13px;\n line-height: 18px;\n resize: vertical;\n outline: none;\n }\n\n .comment__edit-input:focus {\n border-color: var(--pop-ring, #000020);\n }\n\n .comment__edit-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n .comment__edit-save,\n .comment__edit-cancel {\n font-size: 12px;\n padding: 4px 8px;\n cursor: pointer;\n }\n\n .comment--deleted .comment__text {\n color: var(--pop-muted-foreground, #697586);\n font-style: italic;\n opacity: 0.8;\n }\n`);\n\nexport class PopComment extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n static get observedAttributes() {\n return [\"data-size\", \"comment-id\"];\n }\n\n onDataSizeChanged() {\n this.render();\n }\n\n onCommentIdChanged() {\n this.render();\n }\n\n get size(): \"sm\" | \"lg\" {\n return (this.getAttribute(\"data-size\") as \"sm\" | \"lg\") || \"sm\";\n }\n\n get commentAvatarSize(): \"xs\" | \"sm\" {\n return this.size === \"sm\" ? \"xs\" : \"sm\";\n }\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n private _expanded = false;\n private _dropdownOpen = false;\n private _floatingCleanup?: () => void;\n\n private _onOutsideClick = (event: MouseEvent) => {\n const path = event.composedPath();\n const dropdown = this.getElement(ref(\"dropdown\"));\n const trigger = this.getElement(ref(\"menu-trigger\"));\n\n if (dropdown && trigger && !path.includes(dropdown) && !path.includes(trigger)) {\n this.closeDropdown();\n }\n };\n\n private toggleDropdown() {\n if (this._dropdownOpen) {\n this.closeDropdown();\n } else {\n this.openDropdown();\n }\n }\n\n private openDropdown() {\n this._dropdownOpen = true;\n const dropdown = this.getElement<HTMLElement>(ref(\"dropdown\"));\n const trigger = this.getElement<HTMLElement>(ref(\"menu-trigger\"));\n\n if (dropdown && trigger) {\n dropdown.classList.add(\"is-open\");\n\n const update = () => {\n computePosition(trigger, dropdown, {\n placement: \"bottom-end\",\n middleware: [offset(4), flip(), shift({ padding: 8 })],\n strategy: \"fixed\",\n }).then(({ x, y }) => {\n Object.assign(dropdown.style, {\n left: `${x}px`,\n top: `${y}px`,\n position: \"fixed\",\n });\n });\n };\n\n this._floatingCleanup = autoUpdate(trigger, dropdown, update);\n document.addEventListener(\"mousedown\", this._onOutsideClick);\n }\n }\n\n private closeDropdown() {\n this._dropdownOpen = false;\n const dropdown = this.getElement(ref(\"dropdown\"));\n if (dropdown) {\n dropdown.classList.remove(\"is-open\");\n }\n if (this._floatingCleanup) {\n this._floatingCleanup();\n this._floatingCleanup = undefined;\n }\n document.removeEventListener(\"mousedown\", this._onOutsideClick);\n }\n\n private async deleteComment() {\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return;\n\n if (confirm(\"Are you sure you want to delete this comment?\")) {\n await this.gridStore.deleteComment(commentId);\n }\n }\n\n private async flagComment() {\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return;\n\n const success = await this.gridStore.flagComment(commentId);\n if (success) {\n alert(\"Comment flagged successfully.\");\n } else {\n alert(\"Failed to flag comment.\");\n }\n }\n\n protected onClick(event: Event) {\n const target = event.target as HTMLElement;\n\n // Handle menu trigger click\n if (target.closest(ref(\"menu-trigger\"))) {\n event.stopPropagation();\n this.toggleDropdown();\n return;\n }\n\n // Handle dropdown item click\n const dropdownItem = target.closest(ref(\"dropdown-item\")) as HTMLElement;\n if (dropdownItem) {\n event.stopPropagation();\n const action = dropdownItem.getAttribute(\"data-action\");\n const commentId = this.getAttribute(\"comment-id\");\n if (action === \"edit\" && commentId) {\n this.gridStore.replyingTo.value = null;\n this.gridStore.editingCommentId.value = commentId;\n } else if (action === \"delete\") {\n this.deleteComment();\n } else if (action === \"flag\") {\n this.flagComment();\n }\n this.closeDropdown();\n return;\n }\n\n // Don't trigger reply if clicking inside the dropdown\n if (target.closest(ref(\"dropdown\"))) {\n event.stopPropagation();\n return;\n }\n\n // Default reply action\n if (!this.authStore.currentUser.value) return;\n\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return;\n\n const comment = this.gridStore.comments.value.find((c) => c.id === commentId);\n if (comment?.status === \"deleted\") return;\n\n if (this.gridStore.replyingTo.value === commentId) {\n this.gridStore.replyingTo.value = null;\n } else {\n this.gridStore.replyingTo.value = commentId;\n }\n\n this.expandText();\n }\n\n private expandText() {\n const textEl = this.getElement<HTMLElement>(ref(\"text\"));\n if (!this._expanded && textEl) {\n const startHeight = textEl.offsetHeight;\n this._expanded = true;\n this.render();\n\n const newTextEl = this.getElement<HTMLElement>(ref(\"text\"));\n if (newTextEl) {\n const endHeight = newTextEl.scrollHeight;\n\n newTextEl.style.height = `${startHeight}px`;\n newTextEl.style.overflow = \"hidden\";\n\n // Force a reflow\n void newTextEl.offsetHeight;\n\n newTextEl.style.transition = \"height var(--pop-duration-quick) var(--pop-ease-quick)\";\n newTextEl.style.height = `${endHeight}px`;\n\n setTimeout(() => {\n newTextEl.style.height = \"\";\n newTextEl.style.overflow = \"\";\n }, 300);\n }\n }\n }\n\n private _timeUpdateTimer: ReturnType<typeof setTimeout> | null = null;\n\n disconnectedCallback() {\n this.closeDropdown();\n this.stopTimeUpdates();\n super.disconnectedCallback();\n }\n\n private startTimeUpdates() {\n this.stopTimeUpdates();\n\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return;\n\n const comment = this.gridStore.comments.value.find((c) => c.id === commentId);\n if (!comment) return;\n\n const update = () => {\n const timeSpan = this.getElement<HTMLSpanElement>(ref(\"timestamp\"));\n if (timeSpan) {\n timeSpan.textContent = timeAgo(comment.createdAt);\n }\n\n const ageMs =\n Date.now() -\n (typeof comment.createdAt === \"number\"\n ? comment.createdAt\n : Date.parse(String(comment.createdAt)));\n let delay = 60000;\n\n if (ageMs < 60000) {\n delay = 5000;\n } else if (ageMs < 3600000) {\n delay = 60000;\n } else {\n delay = 1800000;\n }\n\n this._timeUpdateTimer = setTimeout(update, delay);\n };\n\n const ageMs =\n Date.now() -\n (typeof comment.createdAt === \"number\"\n ? comment.createdAt\n : Date.parse(String(comment.createdAt)));\n const initialDelay = ageMs < 60000 ? 5000 : 60000;\n this._timeUpdateTimer = setTimeout(update, initialDelay);\n }\n\n private stopTimeUpdates() {\n if (this._timeUpdateTimer) {\n clearTimeout(this._timeUpdateTimer);\n this._timeUpdateTimer = null;\n }\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const commentId = this.getAttribute(\"comment-id\");\n const user = this.authStore.currentUser.value;\n const replyingToId = this.gridStore.replyingTo.value;\n const editingId = this.gridStore.editingCommentId.value;\n const targetId = this.gridStore.scrollingCommentId.value;\n\n this.classList.toggle(\"is-signed-in\", user !== null);\n this.classList.toggle(\"is-replying\", commentId !== null && replyingToId === commentId);\n this.classList.toggle(\"is-editing\", commentId !== null && editingId === commentId);\n\n this.gridStore.comments.value;\n this.render();\n this.startTimeUpdates();\n\n if (commentId && targetId === commentId) {\n setTimeout(() => {\n const innerComment = this.shadowRoot?.querySelector(`#comment-${commentId}`);\n if (innerComment) {\n innerComment.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n } else {\n this.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n this.gridStore.scrollingCommentId.value = null;\n }, 50);\n }\n });\n }\n\n protected getTemplate(): string {\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return \"\";\n\n const comment = this.gridStore.comments.value.find((c) => c.id === commentId);\n if (!comment) return \"\";\n\n const isDeleted = comment.status === \"deleted\";\n const isAuthorDeleted = comment.authorDeleted === true;\n const showDeletedAvatar = isDeleted || isAuthorDeleted;\n\n const avatarContent = showDeletedAvatar\n ? \"\"\n : comment.author?.image\n ? `<img src=\"${comment.author.image}\" alt=\"${comment.author.name ?? \"User avatar\"}\" />`\n : getInitials(comment.author?.name);\n\n const replyingToId = this.gridStore.replyingTo.value;\n const isReplying = commentId !== null && replyingToId === commentId;\n const size = this.size;\n\n // Determine if signed-in user is the author\n const user = this.authStore.currentUser.value;\n const isAuthor = user && comment.author && user.id === comment.author.id;\n\n // Dropdown HTML (only if signed in and comment is not deleted)\n const menuHtml =\n user && !isDeleted\n ? `<div class=\"comment__menu\">\n <button class=\"comment__menu-trigger\" data-ref=\"menu-trigger\" type=\"button\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M9 9.5C9.27614 9.5 9.5 9.27614 9.5 9C9.5 8.72386 9.27614 8.5 9 8.5C8.72386 8.5 8.5 8.72386 8.5 9C8.5 9.27614 8.72386 9.5 9 9.5Z\"\n fill=\"white\"\n />\n <path\n d=\"M12.5 9.5C12.7761 9.5 13 9.27614 13 9C13 8.72386 12.7761 8.5 12.5 8.5C12.2239 8.5 12 8.72386 12 9C12 9.27614 12.2239 9.5 12.5 9.5Z\"\n fill=\"white\"\n />\n <path\n d=\"M5.5 9.5C5.77614 9.5 6 9.27614 6 9C6 8.72386 5.77614 8.5 5.5 8.5C5.22386 8.5 5 8.72386 5 9C5 9.27614 5.22386 9.5 5.5 9.5Z\"\n fill=\"white\"\n />\n <path\n d=\"M9 9.5C9.27614 9.5 9.5 9.27614 9.5 9C9.5 8.72386 9.27614 8.5 9 8.5C8.72386 8.5 8.5 8.72386 8.5 9C8.5 9.27614 8.72386 9.5 9 9.5Z\"\n stroke=\"#000020\"\n stroke-opacity=\"0.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M12.5 9.5C12.7761 9.5 13 9.27614 13 9C13 8.72386 12.7761 8.5 12.5 8.5C12.2239 8.5 12 8.72386 12 9C12 9.27614 12.2239 9.5 12.5 9.5Z\"\n stroke=\"#000020\"\n stroke-opacity=\"0.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M5.5 9.5C5.77614 9.5 6 9.27614 6 9C6 8.72386 5.77614 8.5 5.5 8.5C5.22386 8.5 5 8.72386 5 9C5 9.27614 5.22386 9.5 5.5 9.5Z\"\n stroke=\"#000020\"\n stroke-opacity=\"0.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <div class=\"comment__dropdown\" data-ref=\"dropdown\">\n ${\n isAuthor\n ? `<button class=\"comment__dropdown-item\" data-ref=\"dropdown-item\" type=\"button\" data-action=\"edit\">Edit</button>\n <button class=\"comment__dropdown-item comment__dropdown-item--danger\" data-ref=\"dropdown-item\" type=\"button\" data-action=\"delete\">Delete</button>`\n : \"\"\n }\n <button class=\"comment__dropdown-item\" data-ref=\"dropdown-item\" type=\"button\" data-action=\"flag\">Flag</button>\n </div>\n </div>`\n : \"\";\n\n return /* html */ `\n <div\n class=\"comment comment--size-${size}${isReplying ? \" comment--is-selected\" : \"\"}${isDeleted\n ? \" comment--deleted\"\n : \"\"}\"\n id=\"comment-${commentId}\"\n >\n <div class=\"comment__user\">\n <pop-comment-avatar\n class=\"comment__avatar\"\n size=\"${this.commentAvatarSize}\"\n data-color-key=\"${comment.author?.id ?? comment.author?.name ?? \"\"}\"\n ${showDeletedAvatar ? \"deleted\" : \"\"}\n >\n ${avatarContent}\n </pop-comment-avatar>\n </div>\n <div class=\"comment__content\">\n <div class=\"comment__info\">\n <div class=\"comment__user-meta\">\n <div class=\"comment__user-name\">\n ${isDeleted ? \"[Deleted]\" : isAuthorDeleted ? \"[Deleted user]\" : (comment.author?.name ?? \"\")}\n </div>\n <div class=\"comment__timestamp\" data-ref=\"timestamp\">${timeAgo(comment.createdAt)}</div>\n </div>\n ${menuHtml}\n </div>\n <div class=\"comment__text${this._expanded ? \" expanded\" : \"\"}\" data-ref=\"text\">${comment.body}</div>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment\")) {\n customElements.define(\"pop-comment\", PopComment);\n}\n","import { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: flex;\n background: var(--pop-background);\n border-radius: var(--pop-radius-2xl);\n /* border: 1px solid var(--pop-background); */\n box-shadow: var(--pop-shadow-3xl);\n display: block;\n left: 0;\n max-height: 340px;\n max-width: 400px;\n min-width: 343px;\n opacity: 0;\n overflow: hidden;\n padding: 0;\n pointer-events: none;\n position: fixed;\n top: 0;\n width: 100%;\n z-index: 9999;\n transform: scale(0.94);\n transition:\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n display var(--pop-duration-quick) allow-discrete;\n }\n\n :host([data-current-placement=\"top-start\"]) {\n transform-origin: left bottom;\n }\n\n :host([data-current-placement=\"bottom-start\"]) {\n transform-origin: left top;\n }\n\n :host([data-current-placement=\"top-end\"]) {\n transform-origin: right bottom;\n }\n\n :host([data-current-placement=\"bottom-end\"]) {\n transform-origin: right top;\n }\n\n :host([data-current-placement=\"top\"]) {\n transform-origin: bottom;\n }\n\n :host([data-current-placement=\"bottom\"]) {\n transform-origin: top;\n }\n\n :host([open]) {\n opacity: 1;\n pointer-events: auto;\n transform: scale(1);\n\n @starting-style {\n display: flex;\n opacity: 0;\n transform: scale(0.94);\n }\n }\n\n /* .feed__content and .feed__footer are stacked in the same grid cell\n (see grid-area below) rather than laid out as flex siblings, so the\n footer can grow taller (email/code/no-code states) and overlay the\n comment list instead of pushing it — the grid row auto-sizes to\n whichever of the two is taller, which a manual absolute-position +\n fixed-height-reservation approach can't do without clipping against\n :host's overflow:hidden when the footer is the tall one. */\n .feed {\n display: grid;\n grid-template-columns: 1fr;\n grid-template-rows: 1fr;\n /* height (not just max-height) gives the grid row a definite size to\n shrink to — otherwise an auto-height grid container sizes its 1fr\n row to content's max-content height regardless of max-height,\n clipping instead of scrolling. */\n height: fit-content(340px);\n max-height: 340px;\n }\n\n .feed__content {\n align-items: flex-start;\n /* stretch (not start) so .feed__main inherits a bounded height to\n scroll within, instead of growing to fit all comments. */\n align-self: stretch;\n display: flex;\n gap: 8px;\n grid-area: 1 / 1;\n min-height: 0;\n width: 100%;\n }\n\n .feed__empty {\n padding: 24px 16px 24px 8px;\n text-align: center;\n font-family: Inter, sans-serif;\n font-size: 13px;\n color: var(--pop-muted-foreground);\n line-height: 18px;\n }\n\n .feed__footer {\n align-self: end;\n grid-area: 1 / 1;\n width: 100%;\n z-index: 1;\n }\n\n /* Full-widget scrim for auth errors (e.g. \"You were signed out\"). Sits in\n the same grid cell as the content and footer, above both, so the message\n never takes layout space from the join bar. Click to dismiss. */\n .feed__notice {\n align-items: center;\n background: color-mix(in srgb, var(--pop-background) 80%, transparent);\n color: var(--pop-foreground);\n cursor: pointer;\n display: flex;\n font-family: Inter, sans-serif;\n font-size: 13px;\n grid-area: 1 / 1;\n justify-content: center;\n line-height: 18px;\n padding: 24px;\n text-align: center;\n z-index: 2;\n }\n\n .feed__notice-box {\n align-items: center;\n background: var(--pop-background);\n border: 1px solid var(--pop-border);\n border-radius: var(--pop-radius-sm);\n cursor: default;\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n }\n\n .feed__notice-box:focus {\n outline: none;\n }\n\n .feed__notice[hidden] {\n display: none;\n }\n\n .feed__notice-dismiss {\n background: var(--pop-foreground);\n border: none;\n border-radius: var(--pop-radius-xs);\n color: var(--pop-background);\n cursor: pointer;\n font: inherit;\n font-weight: 600;\n padding: 6px 12px;\n }\n\n .feed__notice-dismiss:focus-visible {\n outline: 2px solid var(--pop-ring);\n outline-offset: 2px;\n }\n\n .feed__main {\n align-items: stretch;\n align-self: stretch;\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n gap: 16px;\n min-height: 0;\n overflow: hidden auto;\n /* Bottom padding reserves space for the idle \"Join the Conversation\"\n bar (~50px) so comments end above it, same as before this became an\n overlay — a taller auth-panel state then naturally covers more. */\n padding: 8px 10px 58px 8px;\n }\n\n .feed__main::-webkit-scrollbar {\n width: 4px;\n }\n\n .feed__main::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .feed__main::-webkit-scrollbar-thumb {\n background: var(--pop-border);\n border-radius: 100px;\n }\n`);\n\nexport class PopFeed extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n private _footerChild: string | null = null;\n private _wasOpen = false;\n private _noticeTimer: number | undefined;\n private _noticeRetryAt: number | null = null;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: MouseEvent) {\n if (!(event.target as HTMLElement).closest(ref(\"notice\"))) return;\n // A rate-limit wait dismisses itself when the countdown ends.\n if (this.authStore.authErrorRetryAt.value !== null) return;\n this.authStore.dismissAuthError();\n }\n\n connectedCallback() {\n super.connectedCallback();\n document.addEventListener(\"mousedown\", this);\n document.addEventListener(\"keydown\", this);\n }\n\n disconnectedCallback() {\n document.removeEventListener(\"mousedown\", this);\n document.removeEventListener(\"keydown\", this);\n window.clearInterval(this._noticeTimer);\n super.disconnectedCallback();\n }\n\n handleEvent(event: Event): void {\n if (event.type === \"mousedown\") {\n this.onOutsideClick(event as MouseEvent);\n return;\n }\n\n if (event.type === \"keydown\") {\n this.onKeyDown(event as KeyboardEvent);\n return;\n }\n\n super.handleEvent(event);\n }\n\n private onOutsideClick(event: MouseEvent) {\n if (!this.gridStore.open.value) return;\n\n const path = event.composedPath();\n const root = this.getRootNode();\n const host = root instanceof ShadowRoot ? root.host : null;\n if (!path.includes(this) && (!host || !path.includes(host))) {\n if (this.authStore.authView.value !== \"idle\") {\n this.authStore.backToIdle();\n return;\n }\n this.gridStore.open.value = false;\n }\n }\n\n private onKeyDown(event: KeyboardEvent) {\n if (event.key !== \"Escape\") return;\n\n if (this.authStore.authError.value) {\n this.authStore.clearAuthError();\n return;\n }\n\n if (this.authStore.authView.value !== \"idle\") {\n this.authStore.backToIdle();\n return;\n }\n this.gridStore.open.value = false;\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const open = this.gridStore.open.value;\n\n if (open && !this._wasOpen && this.gridStore.grid.value) {\n // First real moment the widget needs to know anything about auth\n // beyond what's cached locally — the collapsed pill never shows the\n // current visitor's own identity, only other commenters. See\n // EmbedAuthStore.connectAuthChannel's own comment.\n void this.authStore.connectAuthChannel();\n }\n\n // A notice is only meant to be seen once: don't let it linger and\n // reappear the next time the panel opens.\n if (!open && this._wasOpen) {\n this.authStore.clearAuthError();\n }\n\n this._wasOpen = open;\n this.update();\n });\n }\n\n /**\n * For a rate-limit notice, swaps the dismiss button for a plain countdown\n * (there's nothing for the visitor to do but wait) and dismisses the notice\n * when it reaches zero. Keyed on the target time so the unrelated\n * re-renders that call update() don't restart the timer.\n */\n private syncNoticeCountdown(retryAt: number | null): void {\n if (retryAt === this._noticeRetryAt) return;\n this._noticeRetryAt = retryAt;\n window.clearInterval(this._noticeTimer);\n\n const dismiss = this.getElement<HTMLButtonElement>(ref(\"notice-dismiss\"));\n if (dismiss) dismiss.hidden = retryAt !== null;\n const countdown = this.getElement<HTMLElement>(ref(\"notice-countdown\"));\n if (countdown) countdown.hidden = retryAt === null;\n if (!countdown || retryAt === null) return;\n\n const render = (): boolean => {\n const remaining = Math.max(0, Math.ceil((retryAt - Date.now()) / 1000));\n const minutes = Math.floor(remaining / 60);\n countdown.textContent = `Try again in ${minutes}:${String(remaining % 60).padStart(2, \"0\")}`;\n return remaining === 0;\n };\n\n render();\n this._noticeTimer = window.setInterval(() => {\n if (!render()) return;\n window.clearInterval(this._noticeTimer);\n this.authStore.dismissAuthError();\n }, 1000);\n }\n\n private update(): void {\n if (this.gridStore.open.value) {\n this.setAttribute(\"open\", \"\");\n } else {\n this.removeAttribute(\"open\");\n }\n\n const content = this.getElement<HTMLDivElement>(ref(\"main\"));\n if (content) {\n const threads = this.gridStore.topLevelComments.value;\n\n if (threads.length === 0) {\n const isEmpty = content.querySelector(ref(\"empty\"));\n if (!isEmpty) {\n content.innerHTML = `<div class=\"feed__empty\" data-ref=\"empty\">Waiting for your thoughts…</div>`;\n }\n } else {\n const existingIds = Array.from(content.querySelectorAll(\"pop-comment-thread\")).map((el) =>\n el.getAttribute(\"comment-id\"),\n );\n\n const newIds = threads.map((c) => c.id);\n const needsRebuild =\n existingIds.length !== newIds.length || existingIds.some((id, i) => id !== newIds[i]);\n\n if (needsRebuild) {\n content.innerHTML = threads\n .map(\n (comment) => `<pop-comment-thread comment-id=\"${comment.id}\"></pop-comment-thread>`,\n )\n .join(\"\");\n }\n }\n }\n\n const error = this.authStore.authError.value;\n const notice = this.getElement<HTMLDivElement>(ref(\"notice\"));\n if (notice) {\n const wasHidden = notice.hidden;\n notice.hidden = !error;\n this.setText(ref(\"notice-message\"), error ?? \"\");\n const retryAt = error ? this.authStore.authErrorRetryAt.value : null;\n if (error) this.setText(ref(\"notice-dismiss\"), this.authStore.authErrorAction.value);\n this.syncNoticeCountdown(retryAt);\n // Keep keyboard/AT focus out of what the scrim visually covers.\n this.getElement(ref(\"content\"))?.toggleAttribute(\"inert\", Boolean(error));\n this.getElement(ref(\"footer\"))?.toggleAttribute(\"inert\", Boolean(error));\n if (error && wasHidden && this.gridStore.open.value) {\n // A countdown has no control to focus, so focus the box itself.\n this.getElement<HTMLElement>(\n ref(retryAt === null ? \"notice-dismiss\" : \"notice-box\"),\n )?.focus();\n }\n }\n\n const footer = this.getElement<HTMLDivElement>(ref(\"footer\"));\n\n if (footer) {\n const authed = this.authStore.currentUser.value !== null;\n const desired = authed ? \"pop-comment-bar\" : \"pop-auth-panel\";\n if (this._footerChild !== desired) {\n this._footerChild = desired;\n footer.innerHTML = `<${desired}></${desired}>`;\n }\n }\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"feed\">\n <div class=\"feed__content\" data-ref=\"content\">\n <div class=\"feed__main\" data-ref=\"main\"></div>\n </div>\n <div class=\"feed__footer\" data-ref=\"footer\"></div>\n <div class=\"feed__notice\" data-ref=\"notice\" role=\"alert\" hidden>\n <div class=\"feed__notice-box\" data-ref=\"notice-box\" tabindex=\"-1\">\n <span data-ref=\"notice-message\"></span>\n <span data-ref=\"notice-countdown\" role=\"timer\" hidden></span>\n <button class=\"feed__notice-dismiss\" data-ref=\"notice-dismiss\" type=\"button\">\n Dismiss\n </button>\n </div>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-feed\")) {\n customElements.define(\"pop-feed\", PopFeed);\n}\n","function hasWindow() {\n return typeof window !== 'undefined';\n}\nfunction getNodeName(node) {\n if (isNode(node)) {\n return (node.nodeName || '').toLowerCase();\n }\n // Mocked nodes in testing environments may not be instances of Node. By\n // returning `#document` an infinite loop won't occur.\n // https://github.com/floating-ui/floating-ui/issues/2317\n return '#document';\n}\nfunction getWindow(node) {\n var _node$ownerDocument;\n return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;\n}\nfunction getDocumentElement(node) {\n var _ref;\n return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;\n}\nfunction isNode(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof Node || value instanceof getWindow(value).Node;\n}\nfunction isElement(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof Element || value instanceof getWindow(value).Element;\n}\nfunction isHTMLElement(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;\n}\nfunction isShadowRoot(value) {\n if (!hasWindow() || typeof ShadowRoot === 'undefined') {\n return false;\n }\n return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;\n}\nfunction isOverflowElement(element) {\n const {\n overflow,\n overflowX,\n overflowY,\n display\n } = getComputedStyle(element);\n return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';\n}\nfunction isTableElement(element) {\n return /^(table|td|th)$/.test(getNodeName(element));\n}\nfunction isTopLayer(element) {\n try {\n if (element.matches(':popover-open')) {\n return true;\n }\n } catch (_e) {\n // no-op\n }\n try {\n return element.matches(':modal');\n } catch (_e) {\n return false;\n }\n}\nconst willChangeRe = /transform|translate|scale|rotate|perspective|filter/;\nconst containRe = /paint|layout|strict|content/;\nconst isNotNone = value => !!value && value !== 'none';\nlet isWebKitValue;\nfunction isContainingBlock(elementOrCss) {\n const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n // https://drafts.csswg.org/css-transforms-2/#individual-transforms\n return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');\n}\nfunction getContainingBlock(element) {\n let currentNode = getParentNode(element);\n while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {\n if (isContainingBlock(currentNode)) {\n return currentNode;\n } else if (isTopLayer(currentNode)) {\n return null;\n }\n currentNode = getParentNode(currentNode);\n }\n return null;\n}\nfunction isWebKit() {\n if (isWebKitValue == null) {\n isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');\n }\n return isWebKitValue;\n}\nfunction isLastTraversableNode(node) {\n return /^(html|body|#document)$/.test(getNodeName(node));\n}\nfunction getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}\nfunction getNodeScroll(element) {\n if (isElement(element)) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n }\n return {\n scrollLeft: element.scrollX,\n scrollTop: element.scrollY\n };\n}\nfunction getParentNode(node) {\n if (getNodeName(node) === 'html') {\n return node;\n }\n const result =\n // Step into the shadow DOM of the parent of a slotted node.\n node.assignedSlot ||\n // DOM Element detected.\n node.parentNode ||\n // ShadowRoot detected.\n isShadowRoot(node) && node.host ||\n // Fallback.\n getDocumentElement(node);\n return isShadowRoot(result) ? result.host : result;\n}\nfunction getNearestOverflowAncestor(node) {\n const parentNode = getParentNode(node);\n if (isLastTraversableNode(parentNode)) {\n return (node.ownerDocument || node).body;\n }\n if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {\n return parentNode;\n }\n return getNearestOverflowAncestor(parentNode);\n}\nfunction getOverflowAncestors(node, list, traverseIframes) {\n var _node$ownerDocument2;\n if (list === void 0) {\n list = [];\n }\n if (traverseIframes === void 0) {\n traverseIframes = true;\n }\n const scrollableAncestor = getNearestOverflowAncestor(node);\n const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);\n const win = getWindow(scrollableAncestor);\n if (isBody) {\n const frameElement = getFrameElement(win);\n return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);\n } else {\n return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));\n }\n}\nfunction getFrameElement(win) {\n return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;\n}\n\nexport { getComputedStyle, getContainingBlock, getDocumentElement, getFrameElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isTopLayer, isWebKit };\n","import{isContainingBlock as t}from\"@floating-ui/utils/dom\";function e(t){return i(t)}function n(t){return f(t,\"offsetTop\")}function o(t){return f(t,\"offsetLeft\")}function r(t){return t.assignedSlot?t.assignedSlot:t.parentNode instanceof ShadowRoot?t.parentNode.host:t.parentNode}function i(e){for(let t=e;t;t=r(t))if(t instanceof Element&&\"none\"===getComputedStyle(t).display)return null;for(let n=r(e);n;n=r(n)){if(!(n instanceof Element))continue;const e=getComputedStyle(n);if(\"contents\"!==e.display){if(\"static\"!==e.position||t(e))return n;if(\"BODY\"===n.tagName)return n}}return null}function f(t,e){let n=t[e],o=i(t);const r=function(t){const e=new Set;let n=t.getRootNode();for(;n;)e.add(n),n=n.parentNode?n.parentNode.getRootNode():null;return e}(t);for(;o&&!r.has(o.getRootNode());)n-=o[e],o=i(o);return n}export{o as offsetLeft,e as offsetParent,n as offsetTop};\n","import {\n type Middleware,\n autoUpdate,\n computePosition,\n flip,\n offset,\n platform,\n} from \"@floating-ui/dom\";\nimport { offsetParent } from \"composed-offset-position\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { GridStore, type GridOverrides } from \"../store/grid-store.js\";\nimport { registerStore, unregisterStore } from \"../store/registry.js\";\nimport type { Grid } from \"../types/models.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst DEFAULT_API_URL = \"https://www.popgrids.io\";\n\nconst ALIGN_VALUES = new Set<string>([\"start\", \"center\", \"end\"] satisfies Grid[\"align\"][]);\nconst LAYOUT_VALUES = new Set<string>([\"sm\", \"lg\"] satisfies Grid[\"layout\"][]);\nconst POSITION_VALUES = new Set<string>([\"auto\", \"up\", \"down\"] satisfies Grid[\"position\"][]);\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n position: relative;\n }\n\n .grid {\n display: flex;\n height: 100%;\n position: relative;\n width: 100%;\n }\n\n .grid--align-start {\n justify-content: flex-start;\n }\n\n .grid--align-center {\n justify-content: center;\n }\n\n .grid--align-end {\n justify-content: flex-end;\n }\n`);\n\nexport class PopGrid extends BaseElement {\n private _initialized = false;\n private _floatingCleanup?: () => void;\n private _store!: GridStore;\n private _authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n // Only the five visual-override attributes are observed/reactive.\n // data-key/data-api-url/data-page-url/data-id stay connect-once — changing\n // them would mean tearing down and re-establishing the fetch/websocket,\n // which is out of scope here.\n static get observedAttributes() {\n return [\"data-align\", \"data-layout\", \"data-position\", \"data-icon\", \"data-preview-count\"];\n }\n\n connectedCallback() {\n if (this._initialized) return;\n this._initialized = true;\n\n const publicKey = this.getAttribute(\"data-key\") ?? this.getAttribute(\"public-key\") ?? \"\";\n\n const apiUrl =\n this.getAttribute(\"data-api-url\") ??\n this.getAttribute(\"api-url\") ??\n DEFAULT_API_URL;\n\n const pageUrl =\n this.getAttribute(\"data-page-url\") ?? this.getAttribute(\"page-url\") ?? location.href;\n\n // Names the discussion thread (Disqus-style identifier): embeds sharing a\n // data-id share one thread across pages; without it the thread is keyed\n // by the page's canonical URL.\n const externalId = this.getAttribute(\"data-id\");\n\n this._authStore = new EmbedAuthStore({ apiUrl, publicKey });\n registerStore(this, this._authStore);\n\n this._store = new GridStore({\n apiUrl,\n publicKey,\n pageUrl,\n externalId,\n authStore: this._authStore,\n });\n registerStore(this, this._store);\n\n super.connectedCallback();\n\n // Picks up any override attributes already present at connect time —\n // attributeChangedCallback can fire for these before _store exists (the\n // browser calls it for observed attributes present at upgrade, ahead of\n // connectedCallback), so each onData*Changed handler below no-ops until\n // this runs.\n this._store.setOverrides(this._readOverridesFromAttributes());\n\n // Auth is intentionally not verified here — pop-feed.ts's effect calls\n // authStore.connectAuthChannel() once the panel actually opens, the\n // first moment the widget needs to know anything about it beyond\n // what's already cached locally in currentUser.\n void this._store.load();\n }\n\n private _readOverridesFromAttributes(): GridOverrides {\n const overrides: GridOverrides = {};\n\n const align = this.getAttribute(\"data-align\");\n if (align && ALIGN_VALUES.has(align)) {\n overrides.align = align as Grid[\"align\"];\n }\n\n const layout = this.getAttribute(\"data-layout\");\n if (layout && LAYOUT_VALUES.has(layout)) {\n overrides.layout = layout as Grid[\"layout\"];\n }\n\n const position = this.getAttribute(\"data-position\");\n if (position && POSITION_VALUES.has(position)) {\n overrides.position = position as Grid[\"position\"];\n }\n\n const icon = this.getAttribute(\"data-icon\");\n if (icon) {\n overrides.icon = icon;\n }\n\n const previewCountAttr = this.getAttribute(\"data-preview-count\");\n if (previewCountAttr !== null) {\n const previewCount = Number(previewCountAttr);\n if (Number.isInteger(previewCount) && previewCount > 0) {\n overrides.previewCount = previewCount;\n }\n }\n\n return overrides;\n }\n\n private _applyOverridesFromAttributes(): void {\n // Attributes present at upgrade can trigger this before connectedCallback\n // constructs _store — connectedCallback re-reads everything once it does.\n if (!this._store) return;\n this._store.setOverrides(this._readOverridesFromAttributes());\n }\n\n onDataAlignChanged() {\n this._applyOverridesFromAttributes();\n }\n\n onDataLayoutChanged() {\n this._applyOverridesFromAttributes();\n }\n\n onDataPositionChanged() {\n this._applyOverridesFromAttributes();\n }\n\n onDataIconChanged() {\n this._applyOverridesFromAttributes();\n }\n\n onDataPreviewCountChanged() {\n this._applyOverridesFromAttributes();\n }\n\n disconnectedCallback() {\n this._floatingCleanup?.();\n this._store.destroy();\n this._authStore.destroy();\n unregisterStore(this);\n super.disconnectedCallback();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const grid = this._store.grid.value;\n const gridEl = this.getElement(ref(\"grid\"));\n if (!gridEl) return;\n\n // Remove any existing grid-- classes\n const toRemove = Array.from(gridEl.classList).filter((cls) => cls.startsWith(\"grid--\"));\n if (toRemove.length > 0) {\n gridEl.classList.remove(...toRemove);\n }\n\n if (grid) {\n if (grid.align) gridEl.classList.add(`grid--align-${grid.align}`);\n if (grid.appearance) gridEl.classList.add(`grid--appearance-${grid.appearance}`);\n if (grid.icon) gridEl.classList.add(`grid--icon-${grid.icon}`);\n if (grid.layout) gridEl.classList.add(`grid--layout-${grid.layout}`);\n if (grid.position) gridEl.classList.add(`grid--position-${grid.position}`);\n\n const previewVal = grid.previewCount ?? this._store.previewCount;\n gridEl.classList.add(`grid--preview-${previewVal}`);\n }\n });\n\n this.addEffect(() => {\n const open = this._store.open.value;\n\n if (this._floatingCleanup) {\n this._floatingCleanup();\n this._floatingCleanup = undefined;\n }\n\n if (!open) return;\n\n const widget = this.getElement(\"pop-widget\");\n const feed = this.getElement(\"pop-feed\");\n if (!widget || !feed) return;\n\n const grid = this._store.grid.value;\n if (!grid) return;\n\n // Offset\n let middleware: Middleware[] = [];\n\n middleware = [\n offset({\n mainAxis: grid.position === \"down\" ? -16 : -54,\n crossAxis: -18,\n }),\n ];\n\n // Flip\n if (!grid.position || grid.position === \"auto\") {\n middleware.push(\n flip({\n fallbackPlacements: [\"bottom-start\", \"top-start\"],\n fallbackStrategy: \"bestFit\",\n padding: 16,\n }),\n );\n }\n\n const getOffsetParent = (element: Element) => platform.getOffsetParent(element, offsetParent);\n\n const update = () => {\n void computePosition(widget, feed, {\n placement: grid.position === \"down\" ? \"bottom-start\" : \"top-start\",\n middleware,\n strategy: \"fixed\",\n platform: {\n ...platform,\n getOffsetParent,\n },\n }).then(({ x, y, placement }) => {\n feed.setAttribute(\"data-current-placement\", placement);\n\n Object.assign(feed.style, {\n left: `${x}px`,\n top: `${y}px`,\n });\n });\n };\n\n this._floatingCleanup = autoUpdate(widget, feed, update);\n });\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"grid\" data-ref=\"grid\">\n <pop-widget></pop-widget>\n <pop-feed></pop-feed>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-grid\")) {\n customElements.define(\"pop-grid\", PopGrid);\n}\n","import { getInitials } from \"../helpers/author.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n --error-badge-bg: #fef2f2;\n --error-badge-text: #991b1b;\n --error-badge-border: #fecaca;\n\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --error-badge-bg: #450a0a;\n --error-badge-text: #fca5a5;\n --error-badge-border: #7f1d1d;\n }\n }\n\n :host(.dark) {\n --error-badge-bg: #450a0a;\n --error-badge-text: #fca5a5;\n --error-badge-border: #7f1d1d;\n }\n\n :host([data-error]) {\n cursor: default;\n }\n\n .error-badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: var(--pop-radius-full);\n border: 1px solid var(--error-badge-border);\n background: var(--error-badge-bg);\n color: var(--error-badge-text);\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n white-space: nowrap;\n }\n\n .widget {\n display: inline-flex;\n align-items: flex-start;\n }\n\n .widget > :not([hidden]) ~ :not([hidden]) {\n margin-left: -6px;\n }\n\n .skeleton {\n width: 32px;\n height: 32px;\n background: var(--pop-muted);\n animation: pulse 1.5s ease-in-out infinite;\n }\n\n @keyframes pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n }\n\n .count {\n --count-size: calc(32px + var(--count-border-size));\n --count-background: var(--pop-background);\n --count-border-color: rgba(0 0 32 / 16%);\n --count-border-size: 1px;\n --count-color: var(--pop-foreground);\n\n align-items: center;\n background-color: var(--pop-background);\n display: flex;\n flex-shrink: 0;\n justify-content: center;\n padding: calc(var(--count-border-size) / 2);\n position: relative;\n z-index: 10;\n\n width: calc(var(--count-size) + (calc(var(--count-border-size))));\n height: calc(var(--count-size) + (calc(var(--count-border-size))));\n }\n\n .count__background {\n background-color: var(--count-border-color);\n position: absolute;\n top: 0;\n left: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n }\n\n .count__content {\n align-items: center;\n background: var(--count-background);\n display: flex;\n justify-content: center;\n overflow: hidden;\n height: var(--count-size);\n width: var(--count-size);\n }\n\n .count__label {\n color: var(--count-color);\n font-size: 16px;\n font-style: normal;\n font-weight: 500;\n letter-spacing: -0.96px;\n line-height: 28px;\n text-align: center;\n user-select: none;\n }\n\n .count__label-container {\n align-items: center;\n background: var(--pop-background);\n display: flex;\n height: calc(100% - calc(var(--count-border-size) * 2));\n justify-content: center;\n position: relative;\n text-indent: calc(calc(var(--count-border-size) * 2) * -1);\n width: calc(100% - calc(var(--count-border-size) * 2));\n z-index: 20;\n }\n\n /* Above .count (z-index: 10) — otherwise it paints underneath despite\n * coming later in the widget's facepile, since z-index only applies to\n * positioned elements and this one had neither. */\n .widget pop-comment-icon {\n position: relative;\n z-index: 20;\n top: 1px;\n }\n`);\n\nexport class PopWidget extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick() {\n if (this.gridStore.error.value) {\n return;\n }\n\n this.gridStore.open.value = !this.gridStore.open.value;\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n this.gridStore.loading.value;\n this.gridStore.error.value;\n this.gridStore.previewAvatars.value;\n this.gridStore.comments.value;\n this.gridStore.grid.value;\n\n const hasError = Boolean(this.gridStore.error.value);\n this.toggleAttribute(\"data-error\", hasError);\n\n if (hasError && this.gridStore.open.value) {\n this.gridStore.open.value = false;\n }\n\n this.render();\n });\n }\n\n protected getTemplate(): string {\n if (this.gridStore.loading.value) {\n return `<div class=\"widget\"><div class=\"skeleton mask mask-squircle\"></div></div>`;\n }\n\n if (this.gridStore.error.value) {\n return `<div class=\"error-badge\">Error: there was a problem loading the PopGrid</div>`;\n }\n\n const avatars = this.gridStore.previewAvatars.value;\n const totalCount = this.gridStore.comments.value.length;\n const grid = this.gridStore.grid.value;\n\n // \"sm\"/null -&gt; today's default (32px); \"lg\" -&gt; a clearly larger step (80px).\n const avatarSize = grid?.layout === \"lg\" ? \"md\" : \"xs\";\n const iconTheme = grid?.icon === \"brand\" ? \"brand\" : \"neutral\";\n\n const avatarsHtml = avatars\n .map((author, idx) => {\n const zIndex = avatars.length + idx;\n const colorKey = author?.id ?? author?.name ?? \"\";\n\n if (author?.image) {\n return `<pop-comment-avatar size=\"${avatarSize}\" style=\"z-index: ${zIndex}\" data-color-key=\"${colorKey}\">\n <img src=\"${author.image}\" alt=\"${author.name ?? \"User\"}\" />\n </pop-comment-avatar>`;\n }\n\n return `<pop-comment-avatar size=\"${avatarSize}\" style=\"z-index: ${zIndex}\" data-color-key=\"${colorKey}\">\n ${getInitials(author?.name)}\n </pop-comment-avatar>`;\n })\n .join(\"\");\n\n return /* html */ `\n <div class=\"widget\">\n ${avatarsHtml}\n <div class=\"count mask mask-squircle\">\n <span class=\"count__content mask mask-squircle\">\n <div class=\"count__background mask mask-squircle\"></div>\n <div class=\"count__label-container mask mask-squircle\">\n <div class=\"count__label\">${totalCount}</div>\n </div>\n </span>\n </div>\n <pop-comment-icon variant=\"add\" theme=\"${iconTheme}\" size=\"xs\"></pop-comment-icon>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-widget\")) {\n customElements.define(\"pop-widget\", PopWidget);\n}\n","if (typeof document !== \"undefined\") {\n const fontUrl = \"https://rsms.me/inter/inter.css\";\n if (!document.querySelector(`link[href=\"${fontUrl}\"]`)) {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = fontUrl;\n document.head.appendChild(link);\n }\n}\n\nimport \"./components/pop-account-switcher.js\";\nimport \"./components/pop-auth-code.js\";\nimport \"./components/pop-auth-email.js\";\nimport \"./components/pop-auth-join.js\";\nimport \"./components/pop-auth-no-code.js\";\nimport \"./components/pop-auth-panel.js\";\nimport \"./components/pop-button-link.js\";\nimport \"./components/pop-comment-avatar.js\";\nimport \"./components/pop-comment-bar.js\";\nimport \"./components/pop-comment-icon.js\";\nimport \"./components/pop-comment-input.js\";\nimport \"./components/pop-comment-thread.js\";\nimport \"./components/pop-comment.js\";\nimport \"./components/pop-feed.js\";\nimport \"./components/pop-grid.js\";\nimport \"./components/pop-widget.js\";\n\nexport type { AuthUser, Comment, CommentAuthor, Grid, OrgOption } from \"./types/models.js\";\n"],"x_google_ignoreList":[34,35],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["getComputedStyle","t"],"sources":["../src/helpers/author.ts","../src/lib/backoff.ts","../src/lib/popup-auth.ts","../src/store/embed-auth-store.ts","../src/store/registry.ts","../src/styles/base.css?inline","../src/styles/buttons.css?inline","../src/styles/masks.css?inline","../src/helpers/theme.ts","../src/components/base-element.ts","../src/components/refs.ts","../src/components/pop-account-switcher.ts","../src/components/pop-auth-code.ts","../src/assets/apple-icon.png?inline","../src/assets/google-icon.png?inline","../src/assets/wordmark-svg.ts","../src/components/pop-auth-email.ts","../src/assets/swirling-ovals.gif?inline","../src/components/pop-auth-join.ts","../src/components/pop-auth-no-code.ts","../src/assets/watermark@2x.png","../src/components/pop-auth-panel.ts","../src/components/pop-button-link.ts","../src/assets/popgrids-letter-p.png?inline","../src/helpers/color.ts","../src/components/pop-comment-avatar.ts","../src/store/grid-store.ts","../src/components/pop-comment-bar.ts","../src/components/pop-comment-icon.ts","../src/components/pop-comment-input.ts","../src/components/pop-comment-thread.ts","../src/helpers/time.ts","../src/components/pop-comment.ts","../src/components/pop-feed.ts","../../../node_modules/.pnpm/@floating-ui+utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs","../../../node_modules/.pnpm/composed-offset-position@0.0.6_@floating-ui+utils@0.2.12/node_modules/composed-offset-position/dist/composed-offset-position.browser.min.mjs","../src/lib/position-feed.ts","../src/components/pop-grid.ts","../src/components/pop-widget.ts","../src/index.ts"],"sourcesContent":["export function getInitials(name: string | null | undefined): string {\n if (!name) return \"?\";\n return name\n .split(\" \")\n .map((p) => p[0] ?? \"\")\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n}\n","/**\n * \"Full jitter\" exponential backoff (AWS's exponential-backoff-and-jitter\n * recipe): the delay for a given attempt is a random value between 0 and the\n * exponential ceiling, not the ceiling itself. Pure exponential backoff only\n * bounds how hard one client retries — every client that disconnects at the\n * same instant (a DO/Worker blip, a deploy) computes the identical delay\n * sequence and retries in lockstep waves. Randomizing spreads a correlated\n * mass-reconnect out over time instead of turning it into a thundering herd.\n */\nexport function reconnectDelayMs(attempt: number, baseMs: number, capMs: number): number {\n const ceiling = Math.min(baseMs * 2 ** attempt, capMs);\n return Math.floor(Math.random() * ceiling);\n}\n","import type { AuthUser } from \"../types/models.js\";\n\nexport const EMBED_AUTH_SOURCE = \"popgrids-embed\";\nexport const EMBED_AUTH_SUCCESS = \"popgrids:auth:success\";\nexport const EMBED_AUTH_ERROR = \"popgrids:auth:error\";\n\nexport const EMBED_AUTH_LOGIN_PATH = \"/embed/auth/login\";\nexport const POPUP_NAME = \"popgrids-auth\";\nexport const POPUP_FEATURES = \"popup,width=480,height=640\";\nexport const AUTH_TIMEOUT_MS = 5 * 60 * 1000;\n\n// Grace window after the popup closes before treating it as a cancellation —\n// covers the message-dispatch/processing delay, not a cookie check (there's\n// no cookie fallback anymore: the server delays window.close() until after\n// postMessage so the message should already have arrived by the time we get\n// here in the normal case).\nconst POPUP_CLOSE_GRACE_MS = 250;\n\nexport class PopupAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PopupAuthError\";\n }\n}\n\n// Popup was closed without completing sign-in — not a real error, so callers can skip showing it.\nexport class PopupAuthCancelledError extends PopupAuthError {\n constructor(message = \"Sign-in was cancelled\") {\n super(message);\n this.name = \"PopupAuthCancelledError\";\n }\n}\n\nexport interface EmbedAuthSuccess {\n user: AuthUser;\n token: string;\n expiresAt: number;\n}\n\nexport const buildEmbedLoginUrl = (apiUrl: string, publicKey: string, returnOrigin: string) => {\n const url = new URL(EMBED_AUTH_LOGIN_PATH, apiUrl);\n url.searchParams.set(\"publicKey\", publicKey);\n url.searchParams.set(\"returnOrigin\", returnOrigin);\n return url.toString();\n};\n\nexport const openPopgridsLoginPopup = (apiUrl: string, publicKey: string) => {\n const popup = window.open(\n buildEmbedLoginUrl(apiUrl, publicKey, window.location.origin),\n POPUP_NAME,\n POPUP_FEATURES,\n );\n\n if (!popup) {\n throw new PopupAuthError(\"Popup blocked. Allow popups for this site and try again.\");\n }\n\n return popup;\n};\n\nconst isAuthMessage = (data: unknown, type: string) =>\n typeof data === \"object\" &&\n data !== null &&\n \"type\" in data &&\n \"source\" in data &&\n (data as { type: string; source: string }).type === type &&\n (data as { type: string; source: string }).source === EMBED_AUTH_SOURCE;\n\nconst readAuthSuccess = (data: unknown): EmbedAuthSuccess | null => {\n if (typeof data !== \"object\" || data === null || !(\"user\" in data)) {\n return null;\n }\n\n const record = data as { user?: unknown; token?: unknown; expiresAt?: unknown };\n const user = record.user;\n\n if (typeof user !== \"object\" || user === null || !(\"id\" in user)) {\n return null;\n }\n\n const userRecord = user as {\n id?: unknown;\n name?: unknown;\n email?: unknown;\n image?: unknown;\n };\n\n if (typeof userRecord.id !== \"string\") {\n return null;\n }\n\n if (typeof record.token !== \"string\" || typeof record.expiresAt !== \"number\") {\n return null;\n }\n\n return {\n user: {\n id: userRecord.id,\n name: typeof userRecord.name === \"string\" ? userRecord.name : \"\",\n email: typeof userRecord.email === \"string\" ? userRecord.email : \"\",\n image: typeof userRecord.image === \"string\" ? userRecord.image : null,\n },\n token: record.token,\n expiresAt: record.expiresAt,\n };\n};\n\nexport const waitForPopgridsAuth = (\n apiUrl: string,\n popup: Window,\n options?: {\n onAuthSuccess?: (result: EmbedAuthSuccess) => void;\n },\n) =>\n new Promise<void>((resolve, reject) => {\n const expectedOrigin = new URL(apiUrl).origin;\n let settled = false;\n\n const settle = (result: \"resolve\" | \"reject\", error?: PopupAuthError) => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n if (result === \"resolve\") {\n resolve();\n return;\n }\n reject(error ?? new PopupAuthError(\"Sign-in failed\"));\n };\n\n const onMessage = (event: MessageEvent) => {\n if (event.origin !== expectedOrigin) {\n return;\n }\n\n if (isAuthMessage(event.data, EMBED_AUTH_SUCCESS)) {\n const result = readAuthSuccess(event.data);\n if (!result) {\n settle(\"reject\", new PopupAuthError(\"Sign-in failed\"));\n return;\n }\n options?.onAuthSuccess?.(result);\n settle(\"resolve\");\n return;\n }\n\n if (isAuthMessage(event.data, EMBED_AUTH_ERROR)) {\n const message =\n typeof event.data === \"object\" &&\n event.data !== null &&\n \"error\" in event.data &&\n typeof (event.data as { error?: unknown }).error === \"string\"\n ? (event.data as { error: string }).error\n : \"Sign-in failed\";\n settle(\"reject\", new PopupAuthError(message));\n }\n };\n\n const interval = window.setInterval(() => {\n if (!popup.closed || settled) {\n return;\n }\n\n clearInterval(interval);\n\n window.setTimeout(() => {\n if (settled) return;\n settle(\"reject\", new PopupAuthCancelledError());\n }, POPUP_CLOSE_GRACE_MS);\n }, 300);\n\n const timeout = window.setTimeout(() => {\n try {\n popup.close();\n } catch {\n // ignore\n }\n settle(\"reject\", new PopupAuthError(\"Sign-in timed out\"));\n }, AUTH_TIMEOUT_MS);\n\n const cleanup = () => {\n window.removeEventListener(\"message\", onMessage);\n clearInterval(interval);\n clearTimeout(timeout);\n };\n\n window.addEventListener(\"message\", onMessage);\n });\n\nexport const signInWithPopup = async (\n apiUrl: string,\n publicKey: string,\n options?: {\n onAuthSuccess?: (result: EmbedAuthSuccess) => void;\n },\n) => {\n const popup = openPopgridsLoginPopup(apiUrl, publicKey);\n await waitForPopgridsAuth(apiUrl, popup, options);\n};\n","import { signal } from \"@preact/signals-core\";\nimport { reconnectDelayMs } from \"../lib/backoff.js\";\nimport { PopupAuthCancelledError, signInWithPopup } from \"../lib/popup-auth.js\";\nimport type { AuthUser, EmbedSession, OrgOption } from \"../types/models.js\";\n\nconst TOKEN_HEADER = \"X-PopGrids-Embed-Token\";\nconst OTP_EXPIRES_MS = 5 * 60 * 1000;\n// Better Auth's emailOTP error code for a code past its lifetime, forwarded\n// by the embed API's otp/verify route.\nconst OTP_EXPIRED_CODE = \"OTP_EXPIRED\";\nconst OTP_TOO_MANY_ATTEMPTS_CODE = \"TOO_MANY_ATTEMPTS\";\nconst OTP_INVALID_CODE = \"INVALID_OTP\";\nconst DEFAULT_NOTICE_ACTION = \"Dismiss\";\n// Better Auth's rate-limit window for the sign-in routes, used if a 429 arrives without a retry time.\nconst DEFAULT_RETRY_AFTER_S = 60;\nconst NETWORK_ERROR_MESSAGE = \"Can’t reach PopGrids. Check your connection and try again.\";\n// Same backoff ceiling as GridStore's comment socket (grid-store.ts) — kept\n// as a separate constant since this auth-only channel reconnects\n// independently of the comment socket.\nconst MAX_AUTH_RECONNECT_DELAY_MS = 30_000;\n\n// localStorage, not sessionStorage: sign-in is meant to survive a closed\n// tab and a fresh page load (see docs/adr/0009), not just live in the tab\n// that created it. That also means cross-tab sync is free — localStorage's\n// native `storage` event already fires in every *other* same-origin tab\n// whenever this key changes, so a sign-in (or a sliding-expiry renewal — see\n// checkSession) in one tab reaches every other open tab for this grid with\n// no extra channel to manage. It never fires in the tab that made the\n// write, so there's no risk of an update loop.\nconst storageKey = (publicKey: string) => `popgrids:embed-session:${publicKey}`;\n\nconst isValidSession = (value: unknown): value is EmbedSession =>\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as Partial<EmbedSession>).token === \"string\" &&\n typeof (value as Partial<EmbedSession>).expiresAt === \"number\" &&\n !!(value as Partial<EmbedSession>).user;\n\nexport type EmbedAuthView = \"idle\" | \"email\" | \"code\" | \"no-code\";\n\n/**\n * Owns auth state for one `<pop-grid>` instance — registered per-element\n * (see registry.ts) rather than as a page-global singleton, so multiple\n * widgets with different publicKeys on the same page don't share identity.\n */\nexport class EmbedAuthStore {\n readonly apiUrl: string;\n readonly publicKey: string;\n /** In demo mode nobody signs in: no stored session, no cross-tab sync, no requests. */\n readonly demo: boolean;\n\n currentUser = signal<AuthUser | null>(null);\n authError = signal<string | null>(null);\n /** Label for the notice's button (it always just dismisses the notice). Set via showAuthError. */\n authErrorAction = signal(DEFAULT_NOTICE_ACTION);\n /**\n * Bumped each time the visitor dismisses the notice (vs. it clearing on its\n * own, e.g. the panel closing) so the auth cards can hand focus back to\n * their field — the notice made everything under it inert until now.\n */\n authNoticeDismissals = signal(0);\n /**\n * When set, the notice is a rate-limit wait: its button becomes a\n * countdown to this timestamp and the notice dismisses itself at zero.\n */\n authErrorRetryAt = signal<number | null>(null);\n authPending = signal(false);\n\n /**\n * Accounts the signed-in visitor can comment as (see switchOrganization) —\n * populated after sign-in, independent of which one is currently active.\n * The *active* account syncs across every same-browser tab (they share one\n * token — see ADR 0011); this list itself doesn't need to, since it's the\n * same accounts regardless of which is active.\n */\n organizations = signal<OrgOption[]>([]);\n /** True while an organizations fetch is in flight — drives the switcher's spinner. */\n organizationsLoading = signal(false);\n\n /**\n * Inline email+OTP sign-in state (see pop-auth-panel.ts). Kept separate\n * from authPending/authError above, which stay owned by the OAuth popup\n * flow (requestSignIn) — the two flows can be mid-progress independently.\n */\n authView = signal<EmbedAuthView>(\"idle\");\n otpEmail = signal<string>(\"\");\n otpPending = signal(false);\n otpError = signal<string | null>(null);\n otpExpiresAt = signal<number | null>(null);\n\n private session: EmbedSession | null = null;\n\n // Auth-only realtime channel (separate from GridStore's comment socket):\n // pushes a sign-out that happened elsewhere (main app, or another widget)\n // so this widget flips to signed-out immediately instead of only\n // discovering its key is dead on its next request. See the embed's\n // /auth/connect-ticket + /auth/connect routes and the User Durable\n // Object's sessionRevoked() on the backend.\n private authSocket: WebSocket | null = null;\n private authReconnectAttempt = 0;\n private authReconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private destroyed = false;\n\n // Cross-tab sync — see storageKey's comment. Bound as a field (not a\n // method) so removeEventListener in destroy() can target the exact same\n // function reference.\n private onStorageEvent = (event: StorageEvent): void => {\n if (event.storageArea !== window.localStorage || event.key !== storageKey(this.publicKey)) {\n return;\n }\n\n this.applyExternalChange(event.newValue);\n };\n\n /**\n * Every live store on this page. The `storage` event never fires in the\n * document that made the write, so two grids with the same publicKey on\n * one page (which share a localStorage key) would otherwise never hear\n * about each other's sign-in or sign-out until reload — see notifySiblings.\n */\n private static instances = new Set<EmbedAuthStore>();\n private static syncing = false;\n\n /** Applies a session change made elsewhere — another tab (storage event) or another grid on this page (notifySiblings). */\n private applyExternalChange(newValue: string | null): void {\n if (newValue === null) {\n // Another tab/grid cleared its session (signed out, locally or via the\n // push). Redundant with that same sign-out's own WS push reaching\n // this store, but a free, faster confirmation — and correct on its own\n // even if this store's socket happens to be mid-reconnect.\n if (this.currentUser.value) {\n this.handleSignedOut();\n }\n return;\n }\n\n try {\n const parsed: unknown = JSON.parse(newValue);\n if (isValidSession(parsed) && parsed.expiresAt > Date.now()) {\n this.writeStoredSession(parsed);\n }\n } catch {\n // Malformed value written by something else — ignore.\n }\n }\n\n /** Pushes a local session change to other grids on this page sharing our publicKey. */\n private notifySiblings(newValue: string | null): void {\n if (EmbedAuthStore.syncing) return;\n\n EmbedAuthStore.syncing = true;\n try {\n for (const store of EmbedAuthStore.instances) {\n if (store !== this && store.publicKey === this.publicKey) {\n store.applyExternalChange(newValue);\n }\n }\n } finally {\n EmbedAuthStore.syncing = false;\n }\n }\n\n constructor(opts: { apiUrl: string; publicKey: string; demo?: boolean }) {\n this.apiUrl = opts.apiUrl;\n this.publicKey = opts.publicKey;\n this.demo = opts.demo ?? false;\n if (this.demo) return;\n\n this.session = this.readStoredSession();\n this.currentUser.value = this.session?.user ?? null;\n\n window.addEventListener(\"storage\", this.onStorageEvent);\n EmbedAuthStore.instances.add(this);\n\n // Deliberately not connecting the auth channel here — see\n // connectAuthChannel's own comment. It's triggered from pop-feed.ts\n // once the panel actually opens, not on construction.\n }\n\n /** Closes the auth channel, cancels any pending reconnect, and stops listening for cross-tab changes — call from the owning element's disconnectedCallback. */\n destroy(): void {\n this.destroyed = true;\n this.closeAuthChannel();\n window.removeEventListener(\"storage\", this.onStorageEvent);\n EmbedAuthStore.instances.delete(this);\n }\n\n private readStoredSession(): EmbedSession | null {\n try {\n const raw = window.localStorage.getItem(storageKey(this.publicKey));\n if (!raw) return null;\n\n const parsed: unknown = JSON.parse(raw);\n if (!isValidSession(parsed)) {\n return null;\n }\n\n if (parsed.expiresAt <= Date.now()) {\n this.clearStoredSession();\n return null;\n }\n\n return parsed;\n } catch {\n return null;\n }\n }\n\n /**\n * Just the storage write, no side effects — for keeping the persisted\n * session in sync with a sliding-expiry renewal (checkSession) without\n * redoing loadOrganizations/reconnecting the auth channel for what's\n * still the same identity. writeStoredSession (below) is for an actual\n * sign-in (new or adopted from another tab), where those side effects\n * are the point.\n */\n private persistSession(session: EmbedSession): void {\n this.session = session;\n try {\n window.localStorage.setItem(storageKey(this.publicKey), JSON.stringify(session));\n } catch {\n // localStorage unavailable (private mode, quota) — auth still works\n // for the rest of this page load, just won't survive one.\n }\n this.notifySiblings(JSON.stringify(session));\n }\n\n private writeStoredSession(session: EmbedSession): void {\n this.persistSession(session);\n // Set before kicking off connectAuthChannel below — it guards on\n // currentUser being set, so callers no longer need (and must not rely\n // on) their own separate assignment after this call.\n this.currentUser.value = session.user;\n // Any pending \"signed out\" notice is stale now — including in other tabs\n // that adopt this session via the storage/BroadcastChannel path.\n this.authError.value = null;\n // Reset rather than leave whatever was cached: this write might be a\n // different identity entirely (a fresh sign-in, or a cross-tab-adopted\n // one for someone else on the same browser) whose accounts the old list\n // doesn't belong to. loadOrganizations() is lazy now (see\n // pop-account-switcher.ts) — it's fetched again next time the switcher\n // actually opens, not eagerly here.\n this.organizations.value = [];\n\n // A socket already open (or actively retrying) belongs to whichever\n // identity was signed in before this write (could be nobody, could be\n // someone else entirely — e.g. re-authenticating locally, or this\n // session was just adopted from another tab's sign-in). Only reconnect\n // if that was actually the case: a live/retrying channel means this\n // tab's panel is genuinely open and watching for pushes, so the new\n // identity needs a fresh socket right away. A tab with no channel yet\n // has never had its panel opened — leave it that way. Reconnecting here\n // regardless would mean any signed-in tab immediately re-verifies with\n // the server the instant *any other* same-browser tab writes a session\n // (a fresh sign-in, a switch, cross-tab adoption), even if this tab's\n // own panel is closed — exactly the eager-on-load verification ADR 0010\n // removed. The panel-open effect (pop-feed.ts) connects for whichever\n // identity is current the first time this tab's panel actually opens.\n const hadChannel = this.authSocket !== null || this.authReconnectTimer !== null;\n this.closeAuthChannel();\n if (hadChannel) {\n void this.connectAuthChannel();\n }\n }\n\n private clearStoredSession(): void {\n this.session = null;\n try {\n window.localStorage.removeItem(storageKey(this.publicKey));\n } catch {\n // ignore\n }\n this.notifySiblings(null);\n this.organizations.value = [];\n this.closeAuthChannel();\n }\n\n /**\n * Current token, or null if missing/expired (clearing state — and, if we\n * were signed in, showing the \"you were signed out\" message — as a side\n * effect of expiry). This is a local-only check against the last\n * `expiresAt` this tab persisted: if the credential was actually renewed\n * from a *different*, still-open tab/device while this one sat closed\n * past its own locally-known expiry, this can call it expired a little\n * early rather than re-confirming with the server — an occasional,\n * low-stakes extra sign-in prompt, traded for not hitting the server on\n * every single token read just to double-check a locally-expired date.\n */\n private get token(): string | null {\n if (!this.session) return null;\n\n if (this.session.expiresAt <= Date.now()) {\n this.handleSignedOut();\n return null;\n }\n\n return this.session.token;\n }\n\n /**\n * Attaches the stored token (if any) and returns the response as-is — no\n * retry-via-popup. Use for reads that should silently show \"signed out\"\n * on 401 rather than interrupting the visitor (grid/comments GET, session\n * check, WS connect-ticket mint — the last of which must also work for\n * anonymous/signed-out visitors).\n */\n async fetchWithToken(path: string, init: RequestInit = {}): Promise<Response> {\n if (this.demo) throw new Error(\"PopGrids: no requests in demo mode\");\n\n const headers = new Headers(init.headers);\n const token = this.token;\n if (token) {\n headers.set(TOKEN_HEADER, token);\n }\n return fetch(new URL(path, this.apiUrl), { ...init, headers });\n }\n\n /**\n * Same as fetchWithToken, but on a 401 prompts sign-in inline (the\n * visitor's already looking at the open panel, mid-action — that's\n * exactly what triggered this) and retries once. Use only for actions the\n * visitor just explicitly initiated (post/edit/delete/flag a comment) —\n * never for passive/background reads, since this interrupts them with a\n * prompt.\n *\n * The request being retried already has whatever the visitor typed baked\n * into it (e.g. postComment captures the comment body into the request\n * before this ever runs) — requestInlineSignIn() only has to get them\n * back to a valid session; it doesn't need to preserve or restore\n * anything itself for the retry to pick up right where they left off.\n */\n async authorizedFetch(path: string, init: RequestInit = {}): Promise<Response> {\n let res = await this.fetchWithToken(path, init);\n\n if (res.status === 401) {\n const signedIn = await this.requestInlineSignIn();\n if (!signedIn) {\n return res;\n }\n res = await this.fetchWithToken(path, init);\n }\n\n return res;\n }\n\n private async readError(\n res: Response,\n ): Promise<{ message: string; code?: string; retryAfter?: number }> {\n try {\n const data = (await res.json()) as { error?: unknown; code?: unknown; retryAfter?: unknown };\n return {\n message:\n typeof data.error === \"string\" && data.error\n ? data.error\n : \"Something went wrong. Please try again.\",\n code: typeof data.code === \"string\" ? data.code : undefined,\n retryAfter: typeof data.retryAfter === \"number\" ? data.retryAfter : undefined,\n };\n } catch {\n // ignore — fall through to the generic message\n }\n return { message: \"Something went wrong. Please try again.\" };\n }\n\n /** Transitions from the idle \"Join the Conversation\" state into the inline email form. */\n startEmailSignIn(): void {\n this.otpError.value = null;\n this.authView.value = \"email\";\n }\n\n backToIdle(): void {\n this.otpError.value = null;\n this.otpEmail.value = \"\";\n this.otpExpiresAt.value = null;\n this.authView.value = \"idle\";\n // Leaving the flow entirely (vs. backToEmail, one step back within it)\n // is the one place that counts as abandoning a pending\n // requestInlineSignIn() prompt.\n this.resolveInlineSignIn?.(false);\n }\n\n backToEmail(): void {\n this.otpError.value = null;\n this.authView.value = \"email\";\n }\n\n /**\n * The code can no longer be used: drop back to the email step to request a\n * new one. otpEmail is kept (in memory only) so the email field can be\n * prefilled rather than making the visitor retype it.\n */\n expireOtp(): void {\n this.authView.value = \"email\";\n this.otpExpiresAt.value = null;\n this.otpError.value = null;\n }\n\n /** One step back from the no-code help card, to the code entry it was opened from. */\n backToCode(): void {\n this.authView.value = \"code\";\n }\n\n showNoCode(): void {\n this.authView.value = \"no-code\";\n }\n\n /** Sends (or resends) a sign-in code to `email`. No token yet — the visitor isn't signed in. */\n async sendOtp(email: string): Promise<boolean> {\n this.otpPending.value = true;\n this.otpError.value = null;\n\n try {\n const res = await fetch(\n new URL(`/api/v1/embed/grids/${this.publicKey}/auth/otp/send`, this.apiUrl),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email }),\n },\n );\n\n if (!res.ok) {\n const { message, retryAfter } = await this.readError(res);\n if (res.status === 429) {\n this.showRateLimited(retryAfter);\n } else {\n this.otpError.value = message;\n }\n return false;\n }\n\n this.otpEmail.value = email;\n this.otpExpiresAt.value = Date.now() + OTP_EXPIRES_MS;\n this.authView.value = \"code\";\n return true;\n } catch {\n this.showAuthError(NETWORK_ERROR_MESSAGE);\n return false;\n } finally {\n this.otpPending.value = false;\n }\n }\n\n async resendOtp(): Promise<boolean> {\n if (!this.otpEmail.value) return false;\n return this.sendOtp(this.otpEmail.value);\n }\n\n /** Verifies `code` against the in-progress email and, on success, signs the visitor in. */\n async verifyOtp(code: string): Promise<boolean> {\n this.otpPending.value = true;\n this.otpError.value = null;\n\n try {\n const res = await fetch(\n new URL(`/api/v1/embed/grids/${this.publicKey}/auth/otp/verify`, this.apiUrl),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email: this.otpEmail.value, otp: code }),\n },\n );\n\n if (!res.ok) {\n const { message, code, retryAfter } = await this.readError(res);\n if (res.status === 429) {\n this.showRateLimited(retryAfter);\n } else if (code === OTP_TOO_MANY_ATTEMPTS_CODE) {\n // The server has burned this code too, so it's the same dead end as\n // expiry — but the visitor did something, so tell them why.\n this.expireOtp();\n this.showAuthError(\"Too many attempts.\", \"Request a new code\");\n } else if (code === OTP_EXPIRED_CODE) {\n // An expired code can never succeed, so go back to re-enter the\n // email — silently, same as when the countdown hits zero.\n this.expireOtp();\n } else if (code === OTP_INVALID_CODE) {\n // Better Auth's own wording says \"OTP\"; the visitor knows it as a code.\n this.otpError.value = \"Invalid code\";\n } else {\n this.otpError.value = message;\n }\n return false;\n }\n\n const data = (await res.json()) as EmbedSession;\n this.writeStoredSession(data);\n this.authView.value = \"idle\";\n this.otpEmail.value = \"\";\n this.otpExpiresAt.value = null;\n this.resolveInlineSignIn?.(true);\n return true;\n } catch {\n this.showAuthError(NETWORK_ERROR_MESSAGE);\n return false;\n } finally {\n this.otpPending.value = false;\n }\n }\n\n async requestSignIn(): Promise<boolean> {\n this.authError.value = null;\n this.authPending.value = true;\n\n try {\n await signInWithPopup(this.apiUrl, this.publicKey, {\n onAuthSuccess: ({ user, token, expiresAt }) => {\n this.writeStoredSession({ token, expiresAt, user });\n },\n });\n\n return this.currentUser.value !== null;\n } catch (error) {\n if (!(error instanceof PopupAuthCancelledError)) {\n this.showAuthError(error instanceof Error ? error.message : \"Sign-in failed\");\n }\n return false;\n } finally {\n this.authPending.value = false;\n }\n }\n\n /**\n * Resolves the promise a pending requestInlineSignIn() call is awaiting —\n * set while one's in progress, called from verifyOtp()'s success path\n * (true) and backToIdle() (false, abandoned). Not a public method: it's\n * the completion half of requestInlineSignIn(), nothing else should call it.\n */\n private resolveInlineSignIn: ((success: boolean) => void) | null = null;\n private inlineSignInPromise: Promise<boolean> | null = null;\n\n /**\n * Reactive re-auth for authorizedFetch(): puts the widget into the inline\n * sign-in flow (the panel's already open — that's what triggered this,\n * mid-write) and waits for it to resolve, rather than opening the OAuth\n * popup the way the old checkSession-driven path did. Concurrent callers\n * (e.g. two writes racing into a 401 around the same time) join the same\n * pending prompt instead of each resetting it back to the email step.\n */\n requestInlineSignIn(): Promise<boolean> {\n if (this.inlineSignInPromise) {\n return this.inlineSignInPromise;\n }\n\n this.startEmailSignIn();\n this.inlineSignInPromise = new Promise<boolean>((resolve) => {\n this.resolveInlineSignIn = (success) => {\n this.inlineSignInPromise = null;\n this.resolveInlineSignIn = null;\n resolve(success);\n };\n });\n return this.inlineSignInPromise;\n }\n\n private showAuthError(\n message: string,\n action = DEFAULT_NOTICE_ACTION,\n retryAfterSeconds?: number,\n ): void {\n this.authErrorAction.value = action;\n this.authErrorRetryAt.value =\n retryAfterSeconds === undefined ? null : Date.now() + retryAfterSeconds * 1000;\n this.authError.value = message;\n }\n\n /** A 429: show the wait as a countdown (see authErrorRetryAt) instead of letting the visitor hammer the endpoint. */\n private showRateLimited(retryAfter: number | undefined): void {\n this.showAuthError(\n \"Too many requests.\",\n DEFAULT_NOTICE_ACTION,\n retryAfter ?? DEFAULT_RETRY_AFTER_S,\n );\n }\n\n dismissAuthError(): void {\n this.clearAuthError();\n this.authNoticeDismissals.value += 1;\n }\n\n clearAuthError(): void {\n this.authError.value = null;\n }\n\n /**\n * Fetches the accounts the signed-in visitor can comment as (for the\n * switcher UI) — lazily: called on demand when the switcher's dropdown\n * opens (pop-account-switcher.ts), not proactively on sign-in or page\n * load. Once populated, `organizations` acts as its own cache — callers\n * should check `organizations.value.length === 0` before calling this\n * rather than calling it unconditionally, which also means a prior\n * failed attempt gets retried the next time the dropdown opens rather\n * than being stuck empty forever.\n */\n async loadOrganizations(): Promise<void> {\n if (!this.currentUser.value) {\n this.organizations.value = [];\n return;\n }\n\n if (this.organizationsLoading.value) {\n return; // Already in flight (e.g. the dropdown was closed and reopened before it resolved).\n }\n\n this.organizationsLoading.value = true;\n try {\n const res = await this.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/auth/organizations`,\n );\n if (!res.ok) return;\n\n const data = (await res.json()) as { organizations: OrgOption[] };\n this.organizations.value = data.organizations;\n } catch {\n // Leave organizations empty on failure (no partial/stale data to fall\n // back to, since this only ever runs when it was already empty) — the\n // switcher shows no accounts and the next dropdown open retries.\n } finally {\n this.organizationsLoading.value = false;\n }\n }\n\n /**\n * Switches which account this widget's comments post as. Doesn't touch or\n * read the main app's active org — but the api key itself (and thus which\n * account it's scoped to server-side) is the same one every same-browser\n * tab shares via localStorage (see ADR 0009), so a switch here already\n * changes every other tab's underlying identity whether we tell them or\n * not. persistSession below keeps their displayed state honest via the\n * same native `storage` event sign-in already propagates through — see\n * ADR 0011, which corrects ADR 0008's original \"switching stays local\"\n * framing now that the token itself is shared.\n */\n async switchOrganization(organizationId: string): Promise<boolean> {\n const res = await this.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/auth/organizations/${organizationId}`,\n { method: \"POST\" },\n );\n\n if (!res.ok) {\n if (res.status === 401) {\n this.handleSignedOut();\n }\n return false;\n }\n\n const data = (await res.json()) as { user: AuthUser };\n this.currentUser.value = data.user;\n if (this.session) {\n this.persistSession({ ...this.session, user: data.user });\n }\n return true;\n }\n\n /** Signs this identity out everywhere (main app + every other widget), not just this one. */\n async signOutEverywhere(): Promise<boolean> {\n const res = await this.fetchWithToken(`/api/v1/embed/grids/${this.publicKey}/auth/sign-out`, {\n method: \"POST\",\n });\n\n if (res.ok) {\n // silent: they're looking right at the \"Sign out\" click they just\n // made — the \"you were signed out\" message below is for discovering\n // it happened somewhere else, not for confirming an action just taken.\n this.handleSignedOut({ silent: true });\n }\n\n return res.ok;\n }\n\n /** Shared cleanup for every way this widget learns it's signed out: a pushed session.revoked, a 401 from an authed call, an expired remembered sign-in, or the visitor's own sign-out. */\n private handleSignedOut(options?: { silent?: boolean }): void {\n const wasSignedIn = this.currentUser.value !== null;\n this.clearStoredSession();\n this.currentUser.value = null;\n this.authView.value = \"idle\";\n\n if (wasSignedIn && !options?.silent) {\n this.showAuthError(\"You were signed out. Sign in again to keep commenting.\");\n }\n }\n\n /**\n * Opens the auth-only push channel — and, as its one other job, the sole\n * point that verifies the token server-side and applies the sliding\n * renewal (see docs/adr/0009 and 0010). Not called on construction:\n * pop-feed.ts calls this once the panel first opens, since that's the\n * first moment the widget actually needs to know anything about auth\n * beyond what's already cached locally (the collapsed pill shows other\n * commenters, never the current visitor's own identity). Safe to call\n * repeatedly — no-ops once a socket is already open.\n */\n async connectAuthChannel(): Promise<void> {\n if (this.demo || this.destroyed || this.authSocket || !this.currentUser.value) {\n return;\n }\n\n let ticket: string | null = null;\n let unauthorized = false;\n try {\n const ticketRes = await this.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/auth/connect-ticket`,\n { method: \"POST\" },\n );\n if (ticketRes.ok) {\n // The connect-ticket route now also verifies + applies the sliding\n // renewal and returns the current user — folded in here rather\n // than a separate /session call, since this request already\n // happens on every panel open regardless.\n const ticketData = (await ticketRes.json()) as {\n ticket: string;\n user: AuthUser;\n expiresAt: number | null;\n };\n ticket = ticketData.ticket;\n this.currentUser.value = ticketData.user;\n if (\n this.session &&\n ticketData.expiresAt &&\n ticketData.expiresAt !== this.session.expiresAt\n ) {\n this.persistSession({\n ...this.session,\n user: ticketData.user,\n expiresAt: ticketData.expiresAt,\n });\n }\n } else if (ticketRes.status === 401) {\n // The token is durably invalid (e.g. this tab was reopened after\n // being signed out elsewhere while closed) — stop retrying and\n // reflect it immediately instead of backing off forever.\n unauthorized = true;\n }\n } catch {\n // No auth channel this attempt — scheduleAuthReconnect will try again.\n }\n\n if (unauthorized) {\n this.handleSignedOut();\n return;\n }\n\n if (!ticket || this.destroyed || !this.currentUser.value) {\n this.scheduleAuthReconnect();\n return;\n }\n\n const wsUrl = new URL(`/api/v1/embed/grids/${this.publicKey}/auth/connect`, this.apiUrl);\n wsUrl.protocol = wsUrl.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n wsUrl.searchParams.set(\"ticket\", ticket);\n\n const socket = new WebSocket(wsUrl.toString());\n this.authSocket = socket;\n\n socket.onopen = () => {\n this.authReconnectAttempt = 0;\n };\n\n socket.onmessage = (event) => {\n try {\n const payload = JSON.parse(String(event.data)) as { type?: string };\n if (payload.type === \"session.revoked\") {\n this.handleSignedOut();\n }\n } catch {\n // Ignore malformed realtime payloads.\n }\n };\n\n socket.onclose = () => {\n this.authSocket = null;\n if (this.destroyed || !this.currentUser.value) {\n return;\n }\n this.scheduleAuthReconnect();\n };\n\n socket.onerror = () => {\n socket.close();\n };\n }\n\n private scheduleAuthReconnect(): void {\n if (this.destroyed || this.authReconnectTimer || !this.currentUser.value) {\n return;\n }\n\n const delay = reconnectDelayMs(this.authReconnectAttempt, 1000, MAX_AUTH_RECONNECT_DELAY_MS);\n this.authReconnectAttempt += 1;\n\n this.authReconnectTimer = setTimeout(() => {\n this.authReconnectTimer = null;\n void this.connectAuthChannel();\n }, delay);\n }\n\n private closeAuthChannel(): void {\n if (this.authReconnectTimer) {\n clearTimeout(this.authReconnectTimer);\n this.authReconnectTimer = null;\n }\n\n if (this.authSocket) {\n this.authSocket.onopen = null;\n this.authSocket.onmessage = null;\n this.authSocket.onclose = null;\n this.authSocket.onerror = null;\n this.authSocket.close();\n this.authSocket = null;\n }\n }\n}\n","const _registry = new WeakMap<Element, Map<any, any>>();\n\nexport const registerStore = (el: Element, store: any, key: any = store.constructor): void => {\n let stores = _registry.get(el);\n if (!stores) {\n stores = new Map();\n _registry.set(el, stores);\n }\n stores.set(key, store);\n};\n\nexport const unregisterStore = (el: Element): void => {\n _registry.delete(el);\n};\n\nexport const resolveStore = <T>(el: Element, key: any): T | null => {\n let node: Element | null = el;\n while (node) {\n const stores = _registry.get(node);\n const store = stores?.get(key);\n if (store) return store as T;\n\n const root = node.getRootNode();\n if (!(root instanceof ShadowRoot)) break;\n node = root.host;\n }\n return null;\n};\n\nexport function consume(storeKey: any) {\n return function (target: any, propertyKey: string) {\n const cacheKey = Symbol(\"context_\" + (storeKey.name || \"store\"));\n Object.defineProperty(target, propertyKey, {\n get(this: any) {\n if (this[cacheKey]) return this[cacheKey];\n const resolved = resolveStore(this, storeKey);\n if (!resolved) {\n console.error(`[Context] resolveStore failed! isConnected: ${this.isConnected}`, this);\n throw new Error(\n `[Context] Store for key \"${storeKey.name || storeKey}\" not resolved on <${this.localName}>.`\n );\n }\n this[cacheKey] = resolved;\n return resolved;\n },\n enumerable: true,\n configurable: true,\n });\n };\n}\n\n","@layer base {\n :host {\n box-sizing: border-box;\n color: var(--pop-foreground);\n font-family: \"Inter\", sans-serif;\n font-size: 16px;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n /* Color: Brand */\n --pop-color-brand-midnight-100: oklch(0.9658 0.0161 262.75);\n --pop-color-brand-midnight-900: oklch(0.15 0.03 255.43);\n --pop-color-brand-midnight-800: oklch(0.19 0.05 255.43);\n --pop-color-brand-ocean-400: oklch(0.63 0.19 255.43);\n --pop-color-brand-ocean-100: oklch(0.91 0.05 255.43);\n --pop-color-brand-forest-900: oklch(0.3866 0.0698 180.75);\n --pop-color-brand-forest-700: oklch(0.45 0.15 165.43);\n --pop-color-brand-forest-100: oklch(0.97 0.04 165.43);\n --pop-color-brand-highlight-400: oklch(0.88 0.25 105.43);\n --pop-color-brand-pumpkin-500: oklch(0.62 0.18 45.43);\n --pop-color-brand-pumpkin-200: oklch(0.89 0.08 45.43);\n --pop-color-brand-lemon-300: oklch(0.91 0.12 85.43);\n --pop-color-brand-lemon-100: oklch(0.97 0.04 85.43);\n\n /* Durations */\n --pop-duration-bouncy: 1s;\n --pop-duration-card-highlight: 0.6s;\n --pop-duration-gentle: 0.833s;\n --pop-duration-menu: 0.4s;\n --pop-duration-pop-hover: 0.6s;\n --pop-duration-pop-text: 0.3s;\n --pop-duration-quick: 0.833s;\n --pop-duration-slow: 1.167s;\n\n /* Easing */\n /* prettier-ignore */\n --pop-ease-bouncy: linear(0, 0.011, 0.045 1.3%, 0.184 2.7%, 0.911 7.4%, 1.153 9.4%, 1.301 11.2%, 1.342, 1.362 13%, 1.363, 1.355 14.4%, 1.306 16%, 1.028 21%, 0.939 23%, 0.89 24.7%, 0.876, 0.868 26.4%, 0.869, 0.882 29%, 0.907 30.5%, 1.014 35.9%, 1.038, 1.048 39.8% 41.1%, 1.043 42.5%, 0.995 49.3%, 0.987, 0.983 53.2%, 0.984 55.9%, 1.002 62.7%, 1.006 66.4%, 0.998 79.7%, 1);\n /* prettier-ignore */\n --pop-ease-card-highlight: linear(0, 0.008, 0.031 1.8%, 0.127 3.9%, 0.671 11.8%, 0.881 15.5%, 0.959, 1.02 19.2%, 1.064, 1.093 23.2%, 1.102, 1.108, 1.108, 1.104 28.7%, 1.089 31.4%, 1.038 38.1%, 1.016 41.5%, 0.999 45.4%, 0.99 49.6%, 0.989 55.3%, 1.001 74.9%, 1);\n /* prettier-ignore */\n --pop-ease-gentle: linear(0, 0.007, 0.026, 0.059 4.5%, 0.106 6.3%, 0.209 9.5%, 0.558 19.3%, 0.658, 0.742, 0.812, 0.87, 0.918, 0.957, 0.986 41.6%, 1.007 45.3%, 1.021 49.4%, 1.027 54% 60.9%, 1.007 83.2%, 1);\n /* prettier-ignore */\n --pop-ease-menu: linear(0, 0.0034 0.81%, 0.0278 2.42%, 0.097 4.84%, 0.5361 15.32%, 0.655 18.55%, 0.7314, 0.7964 23.39%, 0.8662, 0.9185, 0.9561, 0.9818, 0.9984, 1.0083 42.74%, 1.014 46.77%, 1.0145 53.22%, 1.0053 68.55%, 1.0019 77.42%, 0.9998 100%);\n /* prettier-ignore */\n --pop-ease-pop-hover: linear(0, 0.008, 0.031 1.8%, 0.127 3.9%, 0.671 11.8%, 0.881 15.5%, 0.959, 1.02 19.2%, 1.064, 1.093 23.2%, 1.102, 1.108, 1.108, 1.104 28.7%, 1.089 31.4%, 1.038 38.1%, 1.016 41.5%, 0.999 45.4%, 0.99 49.6%, 0.989 55.3%, 1.001 74.9%, 1);\n /* prettier-ignore */\n --pop-ease-pop-text: linear(0, 0.0051 0.99%, 0.0261, 0.0607 3.61%, 0.1192 5.26%, 0.2531 8.21%, 0.6509 16.1%, 0.7652 18.73%, 0.8512, 0.9232 23.33%, 0.9881 25.96%, 1.0305 28.26%, 1.0642 30.88%, 1.0782 32.53%, 1.089, 1.094 36.47%, 1.0942, 1.0896 41.07%, 1.0804 43.7%, 1.0354 53.23%, 1.0181 57.5%, 1.0061 61.44%, 0.9974 65.71%, 0.9925 70.31%, 0.991 75.9%, 0.9996 99.88%);\n /* prettier-ignore */\n --pop-ease-quick: linear(0, 0.008, 0.031 1.8%, 0.127 3.9%, 0.671 11.8%, 0.881 15.5%, 0.959, 1.02 19.2%, 1.064, 1.093 23.2%, 1.102, 1.108, 1.108, 1.104 28.7%, 1.089 31.4%, 1.038 38.1%, 1.016 41.5%, 0.999 45.4%, 0.99 49.6%, 0.989 55.3%, 1.001 74.9%, 1);\n /* prettier-ignore */\n --pop-ease-slow: linear(0, 0.005, 0.02 2%, 0.081 4.5%, 0.469 15.2%, 0.567, 0.65, 0.722 24.4%, 0.784, 0.835 31.1%, 0.878 34.9%, 0.914 39.1%, 0.942 43.8%, 0.964 49.1%, 0.979 55.4%, 0.989 62.4%, 0.995 71.1%, 1);\n\n /* Box-Shadow */\n --pop-shadow-xs: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);\n --pop-shadow-sm: 0px 1px 3px 0px rgba(16, 24, 40, 0.1), 0px 1px 2px 0px rgba(16, 24, 40, 0.06);\n --pop-shadow-md:\n 0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06);\n --pop-shadow-lg:\n 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);\n --pop-shadow-xl:\n 0px 20px 24px -4px rgba(16, 24, 40, 0.08), 0px 8px 8px -4px rgba(16, 24, 40, 0.03);\n --pop-shadow-2xl: 0px 24px 48px -12px rgba(16, 24, 40, 0.18);\n --pop-shadow-3xl: 0px 32px 48px -12px rgba(16, 24, 40, 0.32);\n --pop-shadow-4xl: 0px 24px 32px -12px rgba(16, 24, 40, 0.28);\n\n --pop-radius-none: 0; /* 0px */\n --pop-radius-xxs: 0.125rem; /* 2px */\n --pop-radius-xs: 0.25rem; /* 4px */\n --pop-radius-sm: 0.375rem; /* 6px */\n --pop-radius-md: 0.5rem; /* 8px */\n --pop-radius-lg: 0.625rem; /* 10px */\n --pop-radius-xl: 0.75rem; /* 12px */\n --pop-radius-2xl: 1rem; /* 16px */\n --pop-radius-3xl: 1.25rem; /* 20px */\n --pop-radius-4xl: 1.5rem; /* 24px */\n --pop-radius-full: 9999px; /* Creates a circle or oval */\n\n --pop-radius: 0.625rem;\n --pop-background: oklch(1 0 0);\n --pop-foreground: oklch(0 0 0);\n --pop-card: oklch(1 0 0);\n --pop-card-foreground: oklch(0.145 0 0);\n --pop-popover: oklch(1 0 0);\n --pop-popover-foreground: oklch(0 0 0);\n --pop-primary: var(--pop-color-brand-forest-900);\n --pop-primary-foreground: oklch(0.985 0 0);\n --pop-secondary: oklch(0.97 0 0);\n --pop-secondary-foreground: oklch(0.205 0 0);\n --pop-muted: oklch(0.97 0 0);\n --pop-muted-foreground: oklch(0.7152 0.0233 256.76);\n --pop-accent: oklch(0.97 0 0);\n --pop-accent-foreground: oklch(0.205 0 0);\n --pop-destructive: var(--color-error-600);\n --pop-border: oklch(0.1101 0.0763 264.05 / 10.2%);\n --pop-input: oklch(0.922 0 0);\n --pop-ring: oklch(0.5367 0.2286 262.17);\n --pop-chart-1: oklch(0.646 0.222 41.116);\n --pop-chart-2: oklch(0.6 0.118 184.704);\n --pop-chart-3: oklch(0.398 0.07 227.392);\n --pop-chart-4: oklch(0.828 0.189 84.429);\n --pop-chart-5: oklch(0.769 0.188 70.08);\n --pop-sidebar: oklch(0.985 0 0);\n --pop-sidebar-foreground: oklch(0.145 0 0);\n --pop-sidebar-primary: oklch(0.205 0 0);\n --pop-sidebar-primary-foreground: oklch(0.985 0 0);\n --pop-sidebar-accent: oklch(0.97 0 0);\n --pop-sidebar-accent-foreground: oklch(0.205 0 0);\n --pop-sidebar-border: oklch(0.922 0 0);\n --pop-sidebar-ring: oklch(0.708 0 0);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-background: oklch(0.15 0.03 255.43);\n --pop-foreground: oklch(0.66 0.006 255.43);\n --pop-card: oklch(0.205 0 0);\n --pop-card-foreground: oklch(0.985 0 0);\n --pop-popover: oklch(0.15 0.03 255.43);\n --pop-popover-foreground: oklch(0.66 0.006 255.43);\n --pop-primary: oklch(0.922 0 0);\n --pop-primary-foreground: oklch(0.205 0 0);\n --pop-secondary: oklch(0.269 0 0);\n --pop-secondary-foreground: oklch(0.985 0 0);\n --pop-muted: oklch(0.269 0 0);\n --pop-muted-foreground: oklch(0.66 0.006 255.43);\n --pop-accent: oklch(0.269 0 0);\n --pop-accent-foreground: oklch(0.985 0 0);\n --pop-destructive: var(--color-error-400);\n --pop-border: oklch(1 0 0 / 10%);\n --pop-input: oklch(1 0 0 / 15%);\n --pop-ring: oklch(0.5367 0.2286 262.17);\n --pop-chart-1: oklch(0.488 0.243 264.376);\n --pop-chart-2: oklch(0.696 0.17 162.48);\n --pop-chart-3: oklch(0.769 0.188 70.08);\n --pop-chart-4: oklch(0.627 0.265 303.9);\n --pop-chart-5: oklch(0.645 0.246 16.439);\n --pop-sidebar: oklch(0.205 0 0);\n --pop-sidebar-foreground: oklch(0.985 0 0);\n --pop-sidebar-primary: oklch(0.488 0.243 264.376);\n --pop-sidebar-primary-foreground: oklch(0.985 0 0);\n --pop-sidebar-accent: oklch(0.269 0 0);\n --pop-sidebar-accent-foreground: oklch(0.985 0 0);\n --pop-sidebar-border: oklch(1 0 0 / 10%);\n --pop-sidebar-ring: oklch(0.556 0 0);\n }\n }\n\n :host(.dark) {\n --pop-background: oklch(0.15 0.03 255.43);\n --pop-foreground: oklch(0.66 0.006 255.43);\n --pop-card: oklch(0.205 0 0);\n --pop-card-foreground: oklch(0.985 0 0);\n --pop-popover: oklch(0.15 0.03 255.43);\n --pop-popover-foreground: oklch(0.66 0.006 255.43);\n --pop-primary: oklch(0.922 0 0);\n --pop-primary-foreground: oklch(0.205 0 0);\n --pop-secondary: oklch(0.269 0 0);\n --pop-secondary-foreground: oklch(0.985 0 0);\n --pop-muted: oklch(0.269 0 0);\n --pop-muted-foreground: oklch(0.66 0.006 255.43);\n --pop-accent: oklch(0.269 0 0);\n --pop-accent-foreground: oklch(0.985 0 0);\n --pop-destructive: var(--color-error-400);\n --pop-border: oklch(1 0 0 / 10%);\n --pop-input: oklch(1 0 0 / 15%);\n --pop-ring: oklch(0.5367 0.2286 262.17);\n --pop-chart-1: oklch(0.488 0.243 264.376);\n --pop-chart-2: oklch(0.696 0.17 162.48);\n --pop-chart-3: oklch(0.769 0.188 70.08);\n --pop-chart-4: oklch(0.627 0.265 303.9);\n --pop-chart-5: oklch(0.645 0.246 16.439);\n --pop-sidebar: oklch(0.205 0 0);\n --pop-sidebar-foreground: oklch(0.985 0 0);\n --pop-sidebar-primary: oklch(0.488 0.243 264.376);\n --pop-sidebar-primary-foreground: oklch(0.985 0 0);\n --pop-sidebar-accent: oklch(0.269 0 0);\n --pop-sidebar-accent-foreground: oklch(0.985 0 0);\n --pop-sidebar-border: oklch(1 0 0 / 10%);\n --pop-sidebar-ring: oklch(0.556 0 0);\n }\n\n *,\n *::before,\n *::after {\n box-sizing: inherit;\n }\n\n html,\n body {\n padding: 0;\n margin: 0;\n }\n\n svg {\n display: block;\n }\n\n strong {\n font-weight: 600;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n\n button {\n margin: 0;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n cursor: pointer;\n }\n\n .m-0 {\n margin: 0;\n }\n\n .text-heading {\n align-self: stretch;\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-size: 13px;\n font-style: normal;\n font-weight: 600;\n letter-spacing: -0.08px;\n line-height: 18px;\n max-width: 320px;\n text-align: center;\n }\n\n .text-xs {\n font-size: 12px;\n line-height: 18px;\n }\n\n .w-full {\n width: 100%;\n }\n}\n","@layer components {\n .btn {\n align-items: center;\n background-color: var(--pop-primary);\n border-radius: 4px;\n border: 0;\n color: var(--pop-primary-foreground);\n cursor: pointer;\n display: flex;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 500;\n line-height: 20px;\n gap: 0.625rem;\n height: auto;\n justify-content: center;\n padding: 0.625rem 1.25rem;\n text-align: center;\n transition:\n background-color 0.2s,\n color 0.2s;\n }\n\n .btn:focus-visible {\n outline: 2px solid var(--pop-ring); /* focus-visible */\n outline-offset: 2px;\n }\n}\n","@layer components {\n .mask {\n -webkit-mask-size: contain;\n mask-size: contain;\n -webkit-mask-repeat: no-repeat;\n mask-repeat: no-repeat;\n -webkit-mask-position: center;\n mask-position: center;\n }\n\n .mask-squircle {\n -webkit-mask-image: url(\"data:image/svg+xml,%3csvg width='160' height='160' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M 0 80 C 0 14.12 14.12 0 80 0 C 145.88 0 160 14.12 160 80 C 160 145.88 145.88 160 80 160 C 14.12 160 0 145.88 0 80 Z'/%3e%3c/svg%3e\");\n mask-image: url(\"data:image/svg+xml,%3csvg width='160' height='160' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M 0 80 C 0 14.12 14.12 0 80 0 C 145.88 0 160 14.12 160 80 C 160 145.88 145.88 160 80 160 C 14.12 160 0 145.88 0 80 Z'/%3e%3c/svg%3e\");\n }\n}\n","let isGlobalDark = false;\nconst activeElements = new Set<HTMLElement>();\nlet globalObserver: MutationObserver | null = null;\nlet mediaQuery: MediaQueryList | null = null;\n\nfunction checkGlobalDark(): boolean {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return false;\n\n const hasDarkClass =\n document.documentElement.classList.contains(\"dark\") ||\n document.body.classList.contains(\"dark\");\n const hasLightClass =\n document.documentElement.classList.contains(\"light\") ||\n document.body.classList.contains(\"light\");\n\n if (hasDarkClass) return true;\n if (hasLightClass) return false;\n\n if (!mediaQuery) {\n mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n }\n return mediaQuery.matches;\n}\n\nfunction updateGlobalDark() {\n const newDark = checkGlobalDark();\n if (newDark !== isGlobalDark) {\n isGlobalDark = newDark;\n activeElements.forEach((el) => {\n const isDark = isGlobalDark || !!el.closest(\".dark\");\n el.classList.toggle(\"dark\", isDark);\n });\n }\n}\n\nconst mediaListener = () => {\n updateGlobalDark();\n};\n\nexport function registerThemeObserver(el: HTMLElement) {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return;\n\n if (activeElements.size === 0) {\n isGlobalDark = checkGlobalDark();\n globalObserver = new MutationObserver(() => {\n updateGlobalDark();\n });\n globalObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\"],\n });\n globalObserver.observe(document.body, {\n attributes: true,\n attributeFilter: [\"class\"],\n });\n\n mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mediaQuery.addEventListener(\"change\", mediaListener);\n }\n\n activeElements.add(el);\n\n const isDark = isGlobalDark || !!el.closest(\".dark\");\n el.classList.toggle(\"dark\", isDark);\n}\n\nexport function unregisterThemeObserver(el: HTMLElement) {\n activeElements.delete(el);\n if (activeElements.size === 0) {\n if (globalObserver) {\n globalObserver.disconnect();\n globalObserver = null;\n }\n if (mediaQuery) {\n mediaQuery.removeEventListener(\"change\", mediaListener);\n mediaQuery = null;\n }\n }\n}\n","import baseStyles from \"../styles/base.css?inline\";\nimport btnStyles from \"../styles/buttons.css?inline\";\nimport masksStyles from \"../styles/masks.css?inline\";\n\nimport { effect, untracked } from \"@preact/signals-core\";\n\nexport function createSheet(cssText: string): CSSStyleSheet {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(cssText);\n return sheet;\n}\n\nexport const sharedBaseSheet = createSheet(baseStyles);\nexport const btnSheet = createSheet(btnStyles);\nexport const masksSheet = createSheet(masksStyles);\n\nimport { registerThemeObserver, unregisterThemeObserver } from \"../helpers/theme.js\";\n\nexport abstract class BaseElement extends HTMLElement implements EventListenerObject {\n protected baseStyleSheets: CSSStyleSheet[] = [sharedBaseSheet, btnSheet, masksSheet];\n protected get styleSheets(): CSSStyleSheet[] {\n return [];\n }\n\n private _hasRendered = false;\n\n private _disposables: Array<() => void> = [];\n\n constructor() {\n super();\n this.attachShadow({ mode: \"open\" });\n if (this.shadowRoot) {\n this.shadowRoot.adoptedStyleSheets = this.styles;\n }\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (oldValue === newValue) return;\n\n const pascalName = name\n .split(\"-\")\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\");\n const methodName = `on${pascalName}Changed`;\n\n if (typeof (this as any)[methodName] === \"function\") {\n (this as any)[methodName](newValue, oldValue);\n }\n }\n\n /**\n * Use this instead of calling effect() directly to ensure\n * automatic cleanup when the component disconnects.\n */\n protected addEffect(callback: () => void) {\n this._disposables.push(effect(callback));\n }\n\n connectedCallback() {\n registerThemeObserver(this);\n untracked(() => {\n this.render();\n this._bindEvents();\n this.setupEffects();\n });\n }\n\n disconnectedCallback() {\n unregisterThemeObserver(this);\n // Kill all active subscriptions\n this._disposables.forEach((dispose) => dispose());\n this._disposables = [];\n }\n\n protected events: Record<string, string> = {};\n\n private _bindEvents() {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot) {\n return;\n }\n Object.keys(this.events).forEach((key) => {\n shadowRoot.addEventListener(key, this);\n });\n }\n\n handleEvent(event: Event): void {\n const methodName = this.events[event.type];\n\n if (methodName && typeof (this as any)[methodName] === \"function\") {\n (this as any)[methodName](event);\n }\n }\n\n protected emit<T = unknown>(eventName: string, options: CustomEventInit<T> = {}) {\n this.dispatchEvent(\n new CustomEvent<T>(eventName, {\n bubbles: true,\n composed: true,\n ...options,\n }),\n );\n }\n\n // --- Abstract & Overrideable Methods ---\n protected abstract getTemplate(): string;\n\n protected get styles(): CSSStyleSheet[] {\n return [...this.baseStyleSheets, ...this.styleSheets];\n }\n\n protected setupEffects(): void {}\n\n protected render() {\n if (!this.shadowRoot) return;\n this.shadowRoot.innerHTML = this.getTemplate();\n this._hasRendered = true;\n }\n\n protected hideElement(selector: string, shouldHide: boolean, useDisplayNone = true) {\n if (!this.shadowRoot || !this._hasRendered) {\n return;\n }\n\n const el = this.shadowRoot.querySelector(selector);\n if (!el) {\n console.warn(`Element not found for selector: ${selector}`);\n return;\n }\n\n if (useDisplayNone) {\n el.classList.toggle(\"hidden\", shouldHide);\n } else {\n el.classList.toggle(\"invisible\", shouldHide);\n }\n }\n\n protected setText(selector: string, text: string | number) {\n const el = this.shadowRoot?.querySelector(selector);\n if (el && el.textContent !== String(text)) {\n el.textContent = String(text);\n }\n }\n\n protected setAttr(selector: string, attr: string, value: string | null) {\n const el = this.shadowRoot?.querySelector(selector);\n if (!el) return;\n\n if (value === null) {\n el.removeAttribute(attr);\n } else if (el.getAttribute(attr) !== value) {\n el.setAttribute(attr, value);\n }\n }\n\n protected toggleClass(selector: string, className: string, force?: boolean) {\n const el = this.shadowRoot?.querySelector(selector);\n if (!el) return;\n\n el.classList.toggle(className, force);\n }\n\n protected getElement<T extends Element = HTMLElement>(selector: string): T | null {\n return this.shadowRoot?.querySelector(selector) ?? null;\n }\n}\n","/**\n * Selector for an element a component's JS reaches into, marked in its\n * template with `data-ref=\"<name>\"`. Keeps behavior hooks separate from the\n * CSS classes used for styling, so restyling can't silently break a lookup.\n * Works anywhere a selector does: getElement, setText, closest(), etc.\n */\nexport const ref = (name: string): string => `[data-ref=\"${name}\"]`;\n","import { autoUpdate, computePosition, flip, offset, shift } from \"@floating-ui/dom\";\nimport { getInitials } from \"../helpers/author.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n\n --pop-switcher-hover: rgba(0, 0, 32, 0.04);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-switcher-hover: rgba(255, 255, 255, 0.06);\n }\n }\n\n :host(.dark) {\n --pop-switcher-hover: rgba(255, 255, 255, 0.06);\n }\n\n .switcher {\n position: relative;\n }\n\n .switcher__trigger {\n background: none;\n border-radius: 9999px;\n border: none;\n cursor: pointer;\n display: block;\n padding: 0;\n }\n\n .switcher__dropdown {\n /* Overridden inline once floating-ui resolves an actual side (see\n openDropdown) — these defaults match this trigger's common case: an\n avatar near the bottom of the widget, menu opening upward above it. */\n --switcher-origin: bottom left;\n --switcher-slide-y: 6px;\n\n background-color: var(--pop-background);\n border-radius: 6px;\n box-shadow: var(--pop-shadow-xl);\n display: flex;\n flex-direction: column;\n font-family: Inter, sans-serif;\n gap: 2px;\n opacity: 0;\n padding: 6px;\n pointer-events: none;\n position: fixed;\n transform: scale(0.95) translateY(var(--switcher-slide-y));\n transform-origin: var(--switcher-origin);\n transition:\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n visibility 0s linear var(--pop-duration-quick);\n visibility: hidden;\n width: 200px;\n z-index: 1000;\n }\n\n .switcher__dropdown.is-open {\n opacity: 1;\n pointer-events: auto;\n transform: scale(1) translateY(0);\n transition:\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n visibility 0s linear 0s;\n visibility: visible;\n }\n\n .switcher__item {\n align-items: center;\n background: none;\n border-radius: 4px;\n border: none;\n color: var(--pop-foreground);\n cursor: pointer;\n display: flex;\n font-size: 13px;\n font-weight: 500;\n gap: 8px;\n overflow: hidden;\n padding: 6px 8px;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n }\n\n .switcher__item:hover {\n background-color: var(--pop-switcher-hover);\n }\n\n .switcher__item.is-active {\n font-weight: 700;\n }\n\n .switcher__divider {\n background-color: var(--pop-border);\n height: 1px;\n margin: 4px 2px;\n }\n\n .switcher__item--sign-out {\n color: var(--pop-destructive);\n }\n\n .switcher__loading {\n align-items: center;\n color: var(--pop-muted-foreground);\n display: flex;\n font-size: 13px;\n font-weight: 500;\n gap: 8px;\n padding: 6px 8px;\n }\n\n .switcher__spinner {\n animation: pop-switcher-spin 0.6s linear infinite;\n border: 2px solid var(--pop-border);\n border-radius: 9999px;\n border-top-color: var(--pop-foreground);\n flex-shrink: 0;\n height: 12px;\n width: 12px;\n }\n\n @keyframes pop-switcher-spin {\n to {\n transform: rotate(360deg);\n }\n }\n`);\n\n/**\n * The signed-in visitor's own avatar in the composer bar, doubling as the\n * trigger for a dropdown that lets them pick which of their accounts\n * (better-auth orgs) this widget's comments post as, sign out, and — a good\n * home for future per-widget settings as they show up.\n *\n * Account switching here never reads or changes the main app's active org —\n * but it does sync live across every other tab on this same browser (they\n * all share one persisted token — see EmbedAuthStore.switchOrganization and\n * ADR 0011), the same way a sign-in or sign-out already does.\n */\nexport class PopAccountSwitcher extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n private _dropdownOpen = false;\n private _floatingCleanup?: () => void;\n\n private _onOutsideClick = (event: MouseEvent) => {\n const path = event.composedPath();\n const dropdown = this.getElement(ref(\"dropdown\"));\n const trigger = this.getElement(ref(\"trigger\"));\n\n if (dropdown && trigger && !path.includes(dropdown) && !path.includes(trigger)) {\n this.closeDropdown();\n }\n };\n\n disconnectedCallback() {\n this.closeDropdown();\n super.disconnectedCallback();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const user = this.authStore.currentUser.value;\n const organizations = this.authStore.organizations.value;\n\n // Stay visible even signed out — this doubles as the composer's\n // avatar placeholder (\"?\"), same as before this became a switcher.\n // The dropdown itself only opens once signed in (see openDropdown).\n const avatar = this.getElement<HTMLElement>(ref(\"avatar\"));\n if (avatar) {\n avatar.setAttribute(\"data-color-key\", user?.id ?? user?.name ?? \"\");\n avatar.innerHTML = user?.image\n ? `<img src=\"${user.image}\" alt=\"${user.name ?? \"User\"}'s avatar\">`\n : getInitials(user?.name);\n }\n\n if (!user) {\n this.closeDropdown();\n return;\n }\n\n const loading = this.authStore.organizationsLoading.value;\n\n const dropdown = this.getElement(ref(\"dropdown\"));\n if (dropdown) {\n const orgItems =\n organizations.length === 0 && loading\n ? '<div class=\"switcher__loading\"><span class=\"switcher__spinner\"></span>Loading accounts…</div>'\n : organizations\n .map(\n (org) => `\n <button class=\"switcher__item${org.id === user.id ? \" is-active\" : \"\"}\" data-ref=\"item\" type=\"button\" data-org-id=\"${org.id}\">\n ${org.name}\n </button>\n `,\n )\n .join(\"\");\n\n dropdown.innerHTML = `\n ${orgItems}\n ${organizations.length > 0 ? '<div class=\"switcher__divider\"></div>' : \"\"}\n <button class=\"switcher__item switcher__item--sign-out\" data-ref=\"item\" type=\"button\" data-action=\"sign-out\">Sign out</button>\n `;\n }\n });\n }\n\n private toggleDropdown() {\n if (this._dropdownOpen) {\n this.closeDropdown();\n } else {\n this.openDropdown();\n }\n }\n\n private openDropdown() {\n if (!this.authStore.currentUser.value) return;\n\n // Lazy: fetched on first open, not on sign-in or page load — organizations\n // itself is the cache (loadOrganizations no-ops while a fetch is already\n // in flight), so reopening after a successful load doesn't re-fetch.\n if (this.authStore.organizations.value.length === 0) {\n void this.authStore.loadOrganizations();\n }\n\n this._dropdownOpen = true;\n const dropdown = this.getElement<HTMLElement>(ref(\"dropdown\"));\n const trigger = this.getElement<HTMLElement>(ref(\"trigger\"));\n\n if (dropdown && trigger) {\n dropdown.classList.add(\"is-open\");\n\n const update = () => {\n void computePosition(trigger, dropdown, {\n placement: \"bottom-start\",\n middleware: [offset(4), flip(), shift({ padding: 8 })],\n strategy: \"fixed\",\n }).then(({ x, y, placement }) => {\n Object.assign(dropdown.style, { left: `${x}px`, top: `${y}px`, position: \"fixed\" });\n\n // flip() may resolve to the opposite side of the requested\n // placement when there isn't room — keep the scale/slide anchored\n // to whichever edge actually sits against the trigger, so the\n // menu always reads as growing out of it rather than the screen.\n const opensUpward = placement.startsWith(\"top\");\n dropdown.style.setProperty(\"--switcher-origin\", opensUpward ? \"bottom left\" : \"top left\");\n dropdown.style.setProperty(\"--switcher-slide-y\", opensUpward ? \"6px\" : \"-6px\");\n });\n };\n\n this._floatingCleanup = autoUpdate(trigger, dropdown, update);\n document.addEventListener(\"mousedown\", this._onOutsideClick);\n }\n }\n\n private closeDropdown() {\n this._dropdownOpen = false;\n const dropdown = this.getElement(ref(\"dropdown\"));\n if (dropdown) {\n dropdown.classList.remove(\"is-open\");\n }\n if (this._floatingCleanup) {\n this._floatingCleanup();\n this._floatingCleanup = undefined;\n }\n document.removeEventListener(\"mousedown\", this._onOutsideClick);\n }\n\n protected onClick(event: Event) {\n const target = event.target as HTMLElement;\n\n if (target.closest(ref(\"trigger\"))) {\n event.stopPropagation();\n this.toggleDropdown();\n return;\n }\n\n const item = target.closest(ref(\"item\")) as HTMLElement | null;\n if (item) {\n event.stopPropagation();\n this.closeDropdown();\n\n if (item.getAttribute(\"data-action\") === \"sign-out\") {\n void this.authStore.signOutEverywhere();\n return;\n }\n\n const organizationId = item.getAttribute(\"data-org-id\");\n if (organizationId) {\n void this.authStore.switchOrganization(organizationId);\n }\n }\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"switcher\">\n <button\n class=\"switcher__trigger\"\n data-ref=\"trigger\"\n type=\"button\"\n aria-label=\"Account options\"\n >\n <pop-comment-avatar size=\"xs\" data-ref=\"avatar\"></pop-comment-avatar>\n </button>\n <div class=\"switcher__dropdown\" data-ref=\"dropdown\"></div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-account-switcher\")) {\n customElements.define(\"pop-account-switcher\", PopAccountSwitcher);\n}\n","import { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst CODE_LENGTH = 6;\n\nconst localSheet = createSheet(/* css */ `\n :host {\n border-top: 1px solid var(--pop-sidebar-border);\n display: block;\n padding: 20px 24px;\n font-family: Inter, sans-serif;\n text-align: center;\n }\n\n .code__body {\n align-items: center;\n align-self: stretch;\n display: flex;\n flex-direction: column;\n gap: 8px;\n justify-content: center;\n }\n\n .code__container {\n align-items: center;\n display: flex;\n flex-direction: column;\n gap: 16px;\n justify-content: center;\n }\n\n .code__heading {\n color: var(--pop-foreground);\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-size: 13px;\n font-weight: 600;\n letter-spacing: -0.08px;\n line-height: 18px;\n margin: 0;\n }\n\n .code__digits {\n display: flex;\n gap: 6px;\n justify-content: center;\n }\n\n .code__digits .code__digit:nth-child(3) {\n margin-right: 10px;\n }\n\n .code__digit {\n -webkit-appearance: none;\n appearance: none;\n background: var(--pop-background);\n border-radius: var(--pop-radius-md, 8px);\n border: 1px solid color-mix(in srgb, var(--pop-foreground) 56%, transparent);\n color: var(--pop-foreground);\n font-family: inherit;\n font-size: 24px;\n font-weight: 500;\n height: 40px;\n line-height: 36px;\n text-align: center;\n width: 40px;\n }\n\n .code__digit:focus-visible {\n border: 2px solid var(--pop-foreground);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--pop-ring, #155eef) 60%, transparent);\n outline: none;\n }\n\n .code__digit:disabled {\n opacity: 0.6;\n }\n\n .code__copy,\n .code__expiry {\n color: var(--pop-foreground);\n font-size: 12px;\n line-height: 18px;\n margin: 0;\n }\n\n .code__error {\n color: var(--pop-auth-error, #dc2626);\n font-size: 12px;\n line-height: 16px;\n }\n\n .code__footer {\n align-items: center;\n display: flex;\n justify-content: space-between;\n width: 100%;\n }\n\n .code__expiry strong {\n font-weight: 600;\n }\n`);\n\nexport class PopAuthCode extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n input: \"onInput\",\n keydown: \"onKeyDown\",\n click: \"onClick\",\n };\n\n connectedCallback() {\n super.connectedCallback();\n this.getDigitInputs()[0]?.focus();\n }\n\n private getDigitInputs(): HTMLInputElement[] {\n return Array.from(this.shadowRoot?.querySelectorAll<HTMLInputElement>(ref(\"digit\")) ?? []);\n }\n\n protected onInput(event: Event) {\n const target = event.target as HTMLInputElement;\n if (!target.matches(ref(\"digit\"))) return;\n\n target.value = target.value.replace(/[^0-9]/g, \"\").slice(0, 1);\n\n if (target.value) {\n const next = target.nextElementSibling as HTMLInputElement | null;\n next?.focus();\n }\n\n this.maybeSubmit();\n }\n\n protected onKeyDown(event: KeyboardEvent) {\n const target = event.target as HTMLInputElement;\n if (!target.matches(ref(\"digit\"))) return;\n\n if (event.key === \"Backspace\" && !target.value) {\n const prev = target.previousElementSibling as HTMLInputElement | null;\n prev?.focus();\n }\n }\n\n protected onClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (target.closest(ref(\"no-code\"))) {\n this.authStore.showNoCode();\n return;\n }\n\n if (target.closest(ref(\"back\"))) {\n this.authStore.backToEmail();\n return;\n }\n }\n\n private maybeSubmit(): void {\n const digits = this.getDigitInputs().map((input) => input.value);\n if (digits.some((digit) => !digit)) return;\n void this.authStore.verifyOtp(digits.join(\"\"));\n }\n\n /** Renders the countdown; returns true once the code has expired. */\n private renderCountdown(expiresAt: number): boolean {\n const remainingMs = expiresAt - Date.now();\n if (remainingMs <= 0) return true;\n\n const el = this.getElement<HTMLParagraphElement>(ref(\"expiry\"));\n if (!el) return false;\n\n const totalSeconds = Math.ceil(remainingMs / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n el.innerHTML = `Code expires in <strong>${minutes}:${String(seconds).padStart(2, \"0\")}</strong>`;\n return false;\n }\n\n protected setupEffects() {\n let dismissals = this.authStore.authNoticeDismissals.peek();\n this.addEffect(() => {\n const next = this.authStore.authNoticeDismissals.value;\n if (next === dismissals) return;\n dismissals = next;\n // Wait a microtask: the feed lifts `inert` off the footer in its own\n // effect for the same change.\n queueMicrotask(() => {\n const inputs = this.getDigitInputs();\n (inputs.find((input) => !input.value) ?? inputs[0])?.focus({ preventScroll: true });\n });\n });\n\n this.addEffect(() => {\n const expiresAt = this.authStore.otpExpiresAt.value;\n if (!expiresAt) return;\n\n this.renderCountdown(expiresAt);\n // An expired code can't be used, so return to the email step to\n // request a new one. Done from the tick (not this effect body) since\n // expireOtp writes otpExpiresAt, which this effect tracks.\n const interval = window.setInterval(() => {\n if (!this.renderCountdown(expiresAt)) return;\n window.clearInterval(interval);\n this.authStore.expireOtp();\n }, 1000);\n return () => window.clearInterval(interval);\n });\n\n this.addEffect(() => {\n const pending = this.authStore.otpPending.value;\n const inputs = this.getDigitInputs();\n inputs.forEach((input) => {\n input.disabled = pending;\n });\n\n // A disabled input can't take focus, and both entry points here happen\n // mid-request: sendOtp flips to this view before clearing otpPending,\n // and a rejected code sets otpError before it does. So the focus calls\n // in connectedCallback / the error effect are no-ops — claim focus once\n // the inputs are actually enabled again, unless the visitor has already\n // put it somewhere in the card (e.g. Back).\n if (!pending && !this.shadowRoot?.activeElement) {\n (inputs.find((input) => !input.value) ?? inputs[0])?.focus({ preventScroll: true });\n }\n });\n\n this.addEffect(() => {\n const error = this.authStore.otpError.value;\n\n const errorEl = this.getElement<HTMLDivElement>(ref(\"error\"));\n if (errorEl) {\n errorEl.hidden = !error;\n errorEl.textContent = error ?? \"\";\n }\n\n if (error) {\n const inputs = this.getDigitInputs();\n inputs.forEach((input) => {\n input.value = \"\";\n });\n inputs[0]?.focus();\n }\n });\n }\n\n protected getTemplate(): string {\n const digits = Array.from({ length: CODE_LENGTH })\n .map(\n (_, index) =>\n `<input class=\"code__digit\" data-ref=\"digit\" type=\"text\" inputmode=\"numeric\" maxlength=\"1\" autocomplete=\"one-time-code\" aria-label=\"Digit ${index + 1} of ${CODE_LENGTH}\" />`,\n )\n .join(\"\");\n\n return /* html */ `\n <div class=\"code__container\" role=\"group\" aria-labelledby=\"code-title\">\n <p class=\"code__heading\" id=\"code-title\">Enter Verification Code</p>\n <div class=\"code__digits\" role=\"group\" aria-labelledby=\"code-title\">${digits}</div>\n <div class=\"code__body\">\n <p class=\"code__copy\">\n A verification code has been sent to your email. Enter code to continue.\n </p>\n <p class=\"code__expiry\" data-ref=\"expiry\" role=\"timer\"></p>\n </div>\n <div class=\"code__error\" data-ref=\"error\" role=\"alert\" hidden></div>\n <div class=\"code__footer\">\n <pop-button-link data-ref=\"back\" size=\"sm\" theme=\"default\">Back</pop-button-link>\n <pop-button-link data-ref=\"no-code\" size=\"sm\" theme=\"default\" primary>\n No verification code?\n </pop-button-link>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-code\")) {\n customElements.define(\"pop-auth-code\", PopAuthCode);\n}\n","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","/**\n * The \"POPGRIDS\" wordmark, inlined so it can take `currentColor` and scale\n * cleanly inside Shadow DOM — shared by pop-auth-join.ts and pop-auth-email.ts\n * rather than duplicated (it's a sizeable path block).\n */\nexport const POPGRIDS_WORDMARK_SVG = `<svg\n width=\"100\"\n height=\"16\"\n viewBox=\"0 0 75 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n>\n <path\n d=\"M4.58333 0.265686C1.0463 0.265686 0 2.5714 0 5.47711C0 6.55283 0.115741 7.6114 0.25 8.67426C0.300926 9.08997 0.282407 9.54854 0.365741 9.96426C0.583333 11.0571 1.69444 11.5628 2.77315 11.5628C4.25 11.5628 5.23148 10.7014 5.23148 9.3214C5.23148 8.52426 4.94907 8.0014 4.13426 7.69283C4.08333 7.67569 4.03241 7.66283 4.03241 7.59854C4.03241 7.4914 4.21759 7.41426 4.33333 7.41426C4.73148 7.41426 5.36111 7.78283 5.91204 7.78283C8.06944 7.78283 9.26389 5.86283 9.26389 4.06283C9.26389 1.44854 7.18518 0.265686 4.58333 0.265686ZM4.56481 5.91854C4.43056 5.91854 4.31481 5.8114 4.31481 5.68711C4.31481 5.51997 4.56481 5.39569 4.64815 5.25854C4.8287 4.94997 4.87963 4.42711 4.87963 4.07569C4.87963 3.65997 4.76389 2.89283 4.48148 2.58426C4.39815 2.49426 4.28241 2.44711 4.28241 2.32283C4.28241 2.19854 4.41667 2.0914 4.5463 2.0914C5.11111 2.0914 5.39352 3.62997 5.39352 4.02854C5.39352 4.45711 5.24537 5.91854 4.56481 5.91854Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M14.9259 0.527108C11.4074 0.527108 9.2963 2.83282 9.2963 5.99568C9.2963 9.15854 11.4028 11.4643 14.9259 11.4643C18.4491 11.4643 20.537 9.12854 20.537 5.99568C20.537 2.86282 18.412 0.527108 14.9259 0.527108ZM15.0787 9.89997C15.0232 9.96425 14.912 10.0843 14.7778 10.0843C14.6435 10.0843 14.5139 9.97711 14.5139 9.85282C14.5139 9.80568 14.9445 9.20568 15.0139 9.02139C15.2778 8.29711 15.3287 7.51282 15.3287 6.74568C15.3287 5.71711 15.1296 4.39282 14.4491 3.54854C14.3148 3.39425 13.9028 3.10282 13.9028 2.93568C13.9028 2.81139 14.0185 2.70425 14.1528 2.70425C14.2685 2.70425 14.3843 2.79854 14.4676 2.85854C15.5278 3.67282 15.8472 5.53282 15.8472 6.74568C15.8472 7.69711 15.8056 9.08568 15.0833 9.89568L15.0787 9.89997Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M25.375 0.265686C21.838 0.265686 20.7917 2.5714 20.7917 5.47711C20.7917 6.55283 20.9074 7.6114 21.0417 8.67426C21.0926 9.08997 21.0741 9.54854 21.1574 9.96426C21.375 11.0571 22.4861 11.5628 23.5648 11.5628C25.0417 11.5628 26.0231 10.7014 26.0231 9.3214C26.0231 8.52426 25.7407 8.0014 24.9259 7.69283C24.875 7.67569 24.8241 7.66283 24.8241 7.59854C24.8241 7.4914 25.0092 7.41426 25.125 7.41426C25.5231 7.41426 26.1528 7.78283 26.7037 7.78283C28.8611 7.78283 30.0555 5.86283 30.0555 4.06283C30.0555 1.44854 27.9815 0.265686 25.375 0.265686ZM25.3611 5.91854C25.2268 5.91854 25.1111 5.8114 25.1111 5.68711C25.1111 5.51997 25.3611 5.39569 25.4444 5.25854C25.625 4.94997 25.6759 4.42711 25.6759 4.07569C25.6759 3.65997 25.5602 2.89283 25.2778 2.58426C25.1944 2.49426 25.0787 2.44711 25.0787 2.32283C25.0787 2.19854 25.213 2.0914 25.3426 2.0914C25.9074 2.0914 26.1898 3.62997 26.1898 4.02854C26.1898 4.45711 26.0417 5.91854 25.3611 5.91854Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M37.3843 4.81284C36.1898 4.81284 34.5278 5.31855 34.5278 6.64284C34.5278 7.39713 35.125 8.5157 36.0741 8.5157C36.6713 8.5157 37.0556 8.08713 37.2546 8.08713C37.3056 8.08713 37.3519 8.11713 37.3519 8.16427C37.3519 8.60998 36.4213 8.81141 36.0556 8.81141C34.7778 8.81141 34.0972 7.7957 34.0972 6.71998C34.0972 5.39998 35.4398 4.38427 36.8009 4.38427C37.1991 4.38427 37.6158 4.49141 38.0139 4.49141C39.1945 4.49141 40.0371 3.50998 40.0371 2.46427C40.0371 0.728554 37.8148 0.329982 36.3333 0.329982C32.3982 0.329982 30.1065 2.6957 30.1065 6.29141C30.1065 9.61284 31.9676 11.73 35.6528 11.73C38.0417 11.73 40.6482 10.7786 40.6482 8.19427C40.6482 6.42855 39.4028 4.81284 37.3796 4.81284H37.3843Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M48.3611 7.42711C48.0602 7.42711 47.8148 7.53426 47.5648 7.53426C47.5139 7.53426 47.5 7.48711 47.5 7.45712C47.5 7.34997 47.5509 7.30283 47.6342 7.27283C47.9167 7.18283 48.2176 7.11854 48.4954 6.99426C49.7592 6.4414 50.5046 5.45569 50.5046 4.15283C50.5046 1.79997 48.3287 0.372829 45.9398 0.372829C45.0741 0.372829 44.2315 0.604257 43.5 0.972829C41.5092 1.9714 41.125 3.40283 41.0092 5.35283C40.9583 6.11997 40.9583 6.8914 40.9583 7.65854V9.51854C40.9583 10.6843 41.787 11.6228 43.0972 11.6228C44.0416 11.6228 44.8889 10.9928 45.1065 10.1614C45.2222 9.66854 45.1574 9.08569 45.1574 8.60997C45.1574 8.56283 45.1759 8.54997 45.2222 8.54997C45.2685 8.54997 45.3241 8.57997 45.3565 8.59711C45.9398 9.90426 46.7361 11.5628 48.5417 11.5628C49.787 11.5628 50.8148 10.7485 50.8148 9.56569C50.8148 8.38283 49.6204 7.4314 48.3565 7.4314L48.3611 7.42711ZM45.6574 5.91854C45.5231 5.91854 45.4074 5.8114 45.4074 5.68711C45.4074 5.51997 45.6574 5.39569 45.7407 5.25854C45.9213 4.94997 45.9722 4.42711 45.9722 4.07569C45.9722 3.65997 45.8565 2.89283 45.5741 2.58426C45.4907 2.49426 45.3935 2.44711 45.3935 2.32283C45.3935 2.19854 45.5092 2.0914 45.6435 2.0914C46.2083 2.0914 46.4907 3.62997 46.4907 4.02854C46.4907 4.45711 46.3565 5.91854 45.662 5.91854H45.6574Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M54.8056 0.865677C54.4074 0.621391 53.8426 0.497105 53.3611 0.497105C52.3148 0.497105 51.4167 1.26425 51.3009 2.21996C51.2685 2.49853 51.2824 2.75996 51.2824 3.05139V5.66139L51.2315 8.41282V9.77996C51.2315 10.8557 52.2269 11.7 53.375 11.7C54.2222 11.7 55.1528 11.2071 55.4676 10.47C55.6482 10.0542 55.6667 9.47139 55.6667 9.02568V7.82568L55.6852 5.42996V3.03425C55.6852 2.14282 55.6667 1.43568 54.8056 0.865677Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M58.9445 0.402828C57.25 0.402828 56.4028 1.13997 56.4028 2.7214V3.3514L56.4213 4.59426V5.22426C56.4213 5.69997 56.4213 6.14568 56.4028 6.6214C56.3704 7.1914 56.287 7.75711 56.287 8.34426C56.287 10.4957 57.4815 11.5414 59.7917 11.5414C63.3426 11.5414 65.75 10.1271 65.75 6.60854C65.75 2.36568 63.5417 0.398542 58.9445 0.398542V0.402828ZM60.537 8.9014C60.4028 8.9014 60.287 8.79426 60.287 8.66997C60.287 8.62283 60.3056 8.59283 60.338 8.54568C60.7685 7.88568 60.8843 6.96426 60.8843 6.20997C60.8843 5.50283 60.8009 4.45711 60.3194 3.90426C60.2361 3.77997 60.0695 3.68997 60.0695 3.53569C60.0695 3.4114 60.1852 3.30426 60.3194 3.30426C60.5694 3.30426 60.9167 3.88711 61.0185 4.08854C61.3333 4.76569 61.3843 5.50283 61.3843 6.22283C61.3843 6.66854 61.1343 8.89711 60.537 8.89711V8.9014Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M73.5046 5.85855C72.5417 5.78141 71.162 5.47284 70.4167 4.88998C70.3194 4.81284 70.1528 4.7057 70.1528 4.56855C70.1528 4.52141 70.1713 4.44427 70.2361 4.44427C70.4167 4.44427 71.5787 5.3057 72.5787 5.3057C73.8426 5.3057 75 4.39713 75 3.20141C75 1.23427 72.1806 0.437125 70.4676 0.437125C67.9259 0.437125 66.037 1.95855 66.037 4.37141C66.037 4.89427 66.1204 5.61427 66.537 6.01713C66.7361 6.21855 67.0694 6.21855 67.3333 6.21855C68.3287 6.21855 69.5926 6.50998 70.1204 7.35427C70.1713 7.43141 70.2176 7.5557 70.2176 7.6457C70.2176 7.6757 70.2176 7.72284 70.1852 7.7057C70.088 7.6757 70.0046 7.59855 69.9352 7.53855C69.3519 7.0157 68.5555 6.49284 67.713 6.49284C66.4491 6.49284 66.0046 7.6157 66.0046 8.59713C66.0046 10.5771 67.9306 11.67 69.8889 11.67C72.213 11.67 75 10.2557 75 7.84284C75 6.95141 74.5833 5.95284 73.5046 5.86284V5.85855Z\"\n fill=\"currentColor\"\n />\n</svg>`;\n","import appleIconSrc from \"../assets/apple-icon.png?inline\";\nimport googleIconSrc from \"../assets/google-icon.png?inline\";\nimport { POPGRIDS_WORDMARK_SVG } from \"../assets/wordmark-svg.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n padding: 20px 24px;\n border-top: 1px solid var(--pop-sidebar-border);\n background: var(--pop-background);\n }\n\n .email__container {\n align-items: center;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n }\n\n .email__logo {\n color: var(--pop-foreground);\n display: flex;\n justify-content: center;\n }\n\n .email__form {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .email__input {\n -webkit-appearance: none;\n appearance: none;\n background: var(--pop-background);\n border: 1px solid var(--pop-input);\n border-radius: 6px;\n color: var(--pop-foreground);\n font-family: inherit;\n font-size: 14px;\n padding: 10px 12px;\n width: 100%;\n height: 40px;\n }\n\n .email__input::placeholder {\n color: var(--pop-muted-foreground);\n }\n\n .email__input:focus-visible {\n outline: 2px solid var(--pop-ring);\n outline-offset: -1px;\n }\n\n .email__submit {\n width: 100%;\n }\n\n .email__socials {\n align-items: center;\n display: flex;\n gap: 32px;\n justify-content: center;\n }\n\n .email__social {\n align-items: center;\n cursor: pointer;\n display: flex;\n height: 32px;\n justify-content: center;\n padding: 0;\n width: 32px;\n transition: transform 0.15s ease-out;\n }\n\n .email__social:hover {\n transform: scale(1.125);\n }\n\n .email__social img {\n width: 100%;\n height: 100%;\n }\n\n .email__error {\n color: var(--pop-auth-error, #dc2626);\n font-size: 12px;\n line-height: 16px;\n text-align: center;\n }\n\n .email__about {\n display: block;\n color: var(--pop-muted-foreground);\n font-size: 12px;\n text-align: center;\n margin-top: 14px;\n text-decoration: none;\n }\n\n .email__about:hover {\n color: var(--pop-foreground);\n }\n`);\n\nexport class PopAuthEmail extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n submit: \"onSubmit\",\n };\n\n connectedCallback() {\n super.connectedCallback();\n // Kept in memory by the store after a code expires or is burned, so the\n // visitor can just press Continue for a new one.\n const input = this.getElement<HTMLInputElement>(ref(\"input\"));\n if (input) input.value = this.authStore.otpEmail.value;\n this.focusEmailInputWhenVisible();\n }\n\n private focusEmailInputWhenVisible(): void {\n const input = this.getElement<HTMLInputElement>(ref(\"input\"));\n if (!input) return;\n\n // preventScroll: the card is still sliding up from below when this can\n // run, and a plain focus() would scroll the *host page* to bring the\n // field into view, jumping the visitor's reading position.\n const focus = () => {\n if (input.isConnected) input.focus({ preventScroll: true });\n };\n\n // Focusing mid-slide fights pop-auth-panel's entrance transition (e.g. a\n // mobile keyboard resizing the viewport under it), so wait for whatever\n // the card is currently animating. Asking the card for its running\n // transitions — rather than listening for one `transitionend` — also\n // covers the cases where none ever fires (already in place, transitions\n // disabled, reduced motion), where a listener would never focus at all.\n const card = this.closest(\".panel__card\");\n const running = card?.getAnimations() ?? [];\n if (running.length === 0) {\n focus();\n return;\n }\n\n void Promise.allSettled(running.map((animation) => animation.finished)).then(focus);\n }\n\n protected onClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (target.closest(ref(\"google\"))) {\n void this.authStore.requestSignIn();\n return;\n }\n\n if (target.closest(ref(\"apple\"))) {\n void this.authStore.requestSignIn();\n return;\n }\n }\n\n protected onSubmit(event: Event) {\n event.preventDefault();\n void this.handleContinue();\n }\n\n private async handleContinue(): Promise<void> {\n const input = this.getElement<HTMLInputElement>(ref(\"input\"));\n if (!input) return;\n\n const email = input.value.trim();\n if (!EMAIL_PATTERN.test(email)) {\n this.authStore.otpError.value = \"Enter a valid email address.\";\n return;\n }\n\n await this.authStore.sendOtp(email);\n }\n\n protected setupEffects() {\n let dismissals = this.authStore.authNoticeDismissals.peek();\n this.addEffect(() => {\n const next = this.authStore.authNoticeDismissals.value;\n if (next === dismissals) return;\n dismissals = next;\n // The feed lifts `inert` off the footer in its own effect for the same\n // change; wait a microtask so the input is focusable by then.\n queueMicrotask(() => {\n this.getElement<HTMLInputElement>(ref(\"input\"))?.focus({ preventScroll: true });\n });\n });\n\n this.addEffect(() => {\n const pending = this.authStore.otpPending.value;\n const error = this.authStore.otpError.value;\n\n const submit = this.getElement<HTMLButtonElement>(ref(\"submit\"));\n if (submit) {\n submit.disabled = pending;\n submit.textContent = pending ? \"Sending code…\" : \"Continue\";\n }\n\n const errorEl = this.getElement<HTMLDivElement>(ref(\"error\"));\n if (errorEl) {\n errorEl.hidden = !error;\n errorEl.textContent = error ?? \"\";\n }\n });\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <form class=\"email__container\">\n <div class=\"email__logo\" role=\"img\" aria-label=\"PopGrids\">${POPGRIDS_WORDMARK_SVG}</div>\n <p class=\"text-heading\">Small communities, big connections 👋</p>\n <input\n class=\"email__input\"\n data-ref=\"input\"\n type=\"email\"\n aria-label=\"Email address\"\n placeholder=\"Email\"\n autocomplete=\"email\"\n required\n />\n <button class=\"btn email__submit\" data-ref=\"submit\" type=\"submit\">Continue</button>\n <div class=\"email__error\" data-ref=\"error\" role=\"alert\" hidden></div>\n <div class=\"email__socials\">\n <button\n class=\"email__social email__social--apple\"\n data-ref=\"apple\"\n type=\"button\"\n aria-label=\"Continue with Apple\"\n >\n <img src=\"${appleIconSrc}\" alt=\"\" width=\"64\" height=\"64\" loading=\"lazy\" />\n </button>\n <button\n class=\"email__social email__social--google\"\n data-ref=\"google\"\n type=\"button\"\n aria-label=\"Continue with Google\"\n >\n <img src=\"${googleIconSrc}\" alt=\"\" width=\"64\" height=\"64\" loading=\"lazy\" />\n </button>\n </div>\n <pop-button-link href=\"https://www.popgrids.io\" target=\"_blank\" rel=\"noopener noreferrer\">\n What’s PopGrids?\n </pop-button-link>\n </form>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-email\")) {\n customElements.define(\"pop-auth-email\", PopAuthEmail);\n}\n","export default \"data:image/gif;base64,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\"","import swirlingOvalsSrc from \"../assets/swirling-ovals.gif?inline\";\nimport { POPGRIDS_WORDMARK_SVG } from \"../assets/wordmark-svg.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n }\n\n .auth-join {\n -webkit-appearance: none;\n align-items: flex-start;\n appearance: none;\n background-color: lightgray;\n background-color: var(--pop-background, #fff);\n background-image: url(\"${swirlingOvalsSrc}\"), none;\n background-position: calc(100% - 88px) center;\n background-repeat: no-repeat, repeat;\n background-size:\n 8.215% 59.149%,\n auto;\n border: none;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-sm, 6px);\n justify-content: flex-end;\n padding: 16px 8px;\n width: 100%;\n }\n\n /* Keyboard users still get a ring when they Tab here, drawn inside the bar\n so the feed's overflow:hidden can't clip it. A programmatic hand-back\n of focus (restoreFocus, after Esc/Back from a card) opts out via\n data-restored: the visitor didn't navigate here, and the ring around\n the whole bar read as an error state. */\n .auth-join:focus-visible {\n outline: 2px solid var(--pop-ring);\n outline-offset: -2px;\n }\n\n :host([data-restored]) .auth-join:focus-visible {\n outline: none;\n }\n\n .auth-join__actions {\n align-items: center;\n align-self: stretch;\n color: var(--pop-foreground, #000);\n display: flex;\n font-family: Inter, sans-serif;\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-size: 13px;\n font-weight: 600;\n justify-content: space-between;\n letter-spacing: -0.08px;\n line-height: 18px;\n padding: 0px 8px;\n }\n\n .auth-join__logo {\n align-items: center;\n color: var(--pop-foreground, #000);\n display: flex;\n flex-direction: column;\n height: 12px;\n justify-content: center;\n padding: 0;\n pointer-events: none;\n width: 75px;\n }\n`);\n\nexport class PopAuthJoin extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n keydown: \"onKeyDown\",\n focusout: \"onFocusOut\",\n };\n\n /** Puts focus on the bar without scrolling the feed (it's often still sliding into place) or drawing a focus ring. */\n restoreFocus(): void {\n this.setAttribute(\"data-restored\", \"\");\n this.getElement<HTMLButtonElement>(ref(\"join\"))?.focus({ preventScroll: true });\n }\n\n // Any real keyboard navigation from here (Tab, Enter...) means the visitor\n // is driving again, so a ring is appropriate from then on.\n protected onKeyDown() {\n this.removeAttribute(\"data-restored\");\n }\n\n protected onFocusOut() {\n this.removeAttribute(\"data-restored\");\n }\n\n protected onClick(event: MouseEvent) {\n if (!(event.target as HTMLElement).closest(ref(\"join\"))) return;\n this.handleJoin();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const pending = this.authStore.authPending.value;\n\n const joinBtn = this.getElement<HTMLButtonElement>(ref(\"join\"));\n if (joinBtn) {\n joinBtn.disabled = pending;\n }\n this.setText(ref(\"label\"), pending ? \"Signing in\\u2026\" : \"Join the Conversation\");\n });\n }\n\n private handleJoin(): void {\n this.authStore.clearAuthError();\n this.authStore.startEmailSignIn();\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <button class=\"auth-join\" data-ref=\"join\" type=\"button\">\n <div class=\"auth-join__actions\">\n <span data-ref=\"label\">Join the Conversation</span>\n <span class=\"auth-join__logo\" aria-hidden=\"true\">${POPGRIDS_WORDMARK_SVG}</span>\n </div>\n </button>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-join\")) {\n customElements.define(\"pop-auth-join\", PopAuthJoin);\n}\n","import { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n border-top: 1px solid var(--pop-sidebar-border);\n display: block;\n padding: 20px 24px;\n font-family: Inter, sans-serif;\n text-align: center;\n }\n\n .no-code__body {\n align-items: flex-start;\n align-self: stretch;\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .no-code__container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n justify-content: center;\n align-items: center;\n }\n\n .no-code__list {\n list-style: none;\n margin: 0;\n padding: 0;\n text-align: left;\n }\n\n .no-code__footer {\n align-items: center;\n display: flex;\n justify-content: space-between;\n width: 100%;\n }\n`);\n\nexport class PopAuthNoCode extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n // This card replaces the code card the visitor just clicked in, so their\n // focus would otherwise be dropped on a removed element. Land it on the\n // title so assistive tech announces the new view.\n connectedCallback() {\n super.connectedCallback();\n this.getElement<HTMLElement>(\"#no-code-title\")?.focus();\n }\n\n // After a dismissed notice (e.g. a rate-limit wait ending on Resend Code),\n // hand focus back to the card, since the notice had made it inert.\n protected setupEffects() {\n let dismissals = this.authStore.authNoticeDismissals.peek();\n this.addEffect(() => {\n const next = this.authStore.authNoticeDismissals.value;\n if (next === dismissals) return;\n dismissals = next;\n queueMicrotask(() =>\n this.getElement<HTMLElement>(\"#no-code-title\")?.focus({ preventScroll: true }),\n );\n });\n }\n\n protected onClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (target.closest(ref(\"resend\"))) {\n void this.authStore.resendOtp();\n return;\n }\n\n if (target.closest(ref(\"back\"))) {\n this.authStore.backToCode();\n return;\n }\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div\n class=\"no-code__container text-xs\"\n role=\"group\"\n aria-labelledby=\"no-code-title\"\n >\n <p class=\"text-heading m-0\" id=\"no-code-title\" tabindex=\"-1\">Steps to Take</p>\n <div class=\"no-code__body\">\n <ul class=\"no-code__list\">\n <li><strong>Check spam/junk</strong> – it might be there.</li>\n <li><strong>Verify email</strong> – check your email for typos.</li>\n <li><strong>Wait a moment</strong> – emails take a few mins.</li>\n <li><strong>Whitelist us</strong> – it may be blocked.</li>\n </ul>\n <p class=\"m-0\">Still no code?</p>\n </div>\n <div class=\"no-code__footer\">\n <pop-button-link data-ref=\"back\" size=\"sm\" theme=\"default\">Back</pop-button-link>\n <pop-button-link\n class=\"no-code__contact\"\n size=\"sm\"\n theme=\"default\"\n href=\"mailto:hello@popgrids.io?subject=Verification%20Code%20Issue\"\n >Contact Support</pop-button-link\n >\n <pop-button-link data-ref=\"resend\" size=\"sm\" theme=\"default\" primary>\n Resend Code\n </pop-button-link>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-no-code\")) {\n customElements.define(\"pop-auth-no-code\", PopAuthNoCode);\n}\n","export default \"data:image/png;base64,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\"","import watermarkSrc from \"../assets/watermark@2x.png\";\nimport { EmbedAuthStore, type EmbedAuthView } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\nimport type { PopAuthJoin } from \"./pop-auth-join.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n position: relative;\n\n --pop-auth-border: var(--pop-border, rgba(0, 0, 32, 0.04));\n --pop-auth-logo: rgba(0, 0, 32, 0.35);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-auth-border: var(--pop-border, rgba(255, 255, 255, 0.1));\n --pop-auth-logo: rgba(255, 255, 255, 0.35);\n }\n }\n\n :host(.dark) {\n --pop-auth-border: var(--pop-border, rgba(255, 255, 255, 0.1));\n --pop-auth-logo: rgba(255, 255, 255, 0.35);\n }\n\n /* Deliberately no background here. .panel's own box grows to match\n whichever of panel__join/panel__card is taller for the duration of a\n transition (the exiting one stays display:block until it finishes\n sliding away), so an opaque .panel would cover the comment list behind\n it for that whole 833ms. Leaving it transparent lets join/card's own\n (opaque) boxes show through everywhere except where they themselves\n render, so the comment list stays visible around them mid-transition. */\n .panel {\n position: relative;\n }\n\n /* Positioned relative to panel__join-group (below), not .panel — .panel's\n own box grows to match whichever of join/card is taller mid-transition,\n so a fixed offset from *it* would float away from the join bar it's\n meant to sit above. Anchoring to the group instead means it's part of\n the same box that's actually animating, so it stays put above the join\n bar and fades/slides with it, in sync, the same as border-top below. */\n .watermark {\n position: absolute;\n top: -22px;\n left: 2px;\n padding: 2px 6px;\n }\n\n /* pop-auth-join (+ its watermark) and the card (email/code/no-code) are\n two independent, always-mounted elements stacked in the same grid cell\n so they can overlap mid-transition — one slides down off-screen while\n the other slides up into place, instead of one instantly replacing the\n other. */\n .panel__stack {\n display: grid;\n grid-template-columns: 1fr;\n grid-template-rows: 1fr;\n }\n\n .panel__join-group,\n .panel__card {\n /* Grid items default to align-self: stretch — during the brief window\n where both are display:block at once (mid-transition), the row\n auto-sizes to the taller of the two and would stretch the shorter\n one's box to match, pinning its content at the top instead of the\n bottom until the row shrinks back down. Anchor both to the end\n (bottom) of the shared cell instead, matching .feed__footer's own\n grid-stack treatment in pop-feed.ts. */\n grid-area: 1 / 1;\n align-self: end;\n }\n\n .panel__card {\n position: relative;\n }\n\n /* The transform/opacity/display transition lives on this wrapper, not\n directly on <pop-auth-join>, so the watermark (absolutely positioned\n inside it) rides along as part of the same animating box instead of\n needing its own separate, easy-to-desync transition. */\n .panel__join-group {\n position: relative;\n transform: translateY(0);\n opacity: 1;\n transition:\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n display var(--pop-duration-quick) allow-discrete;\n\n @starting-style {\n transform: translateY(100%);\n opacity: 0;\n }\n }\n\n .panel--card .panel__join-group {\n display: none;\n transform: translateY(100%);\n opacity: 0;\n }\n\n /* border-top lives on the join bar's own box (not the outer .panel) so it\n enters/leaves in lockstep with the bar itself — it used to live on\n .panel, toggled instantly by the panel--card class while the actual\n slide took 833ms, so the border would snap on/off out of sync with\n the content still animating underneath it. */\n .panel__join {\n border-top: 1px solid var(--pop-auth-border);\n }\n\n /* Same reasoning as border-top above: the card's own background/radius\n live on its own box (not toggled via panel--card on the static outer\n .panel) so they're always in sync with its display/opacity/transform\n state instead of snapping the instant the view changes. */\n .panel__card {\n display: none;\n background: var(--pop-background);\n border-radius: var(--pop-radius-2xl) var(--pop-radius-2xl) 0 0;\n transform: translateY(100%);\n opacity: 0;\n transition:\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n height var(--pop-duration-quick) var(--pop-ease-quick),\n display var(--pop-duration-quick) allow-discrete;\n }\n\n /* --pop-ease-quick overshoots 1 (peaks ~1.1), so the card's translateY and\n height briefly travel past their resting values and lift its bottom edge\n off the feed's bottom, exposing the comment list underneath. This\n backing extends the card's background below its box to cover that gap;\n the feed host's overflow:hidden clips it once the card settles. A\n box-shadow rather than a pseudo-element on purpose: an absolutely\n positioned descendant below the card counts toward its scrollHeight,\n which swapCardContent measures to animate the card's height — a shadow\n doesn't. */\n .panel__card {\n box-shadow: 0 100px 0 0 var(--pop-background);\n }\n\n .panel--card .panel__card {\n display: block;\n transform: translateY(0);\n opacity: 1;\n\n @starting-style {\n transform: translateY(100%);\n opacity: 0;\n }\n }\n`);\n\n/**\n * Container for the widget's auth states. pop-auth-join and the \"card\"\n * (pop-auth-email / -code / -no-code) are separate, always-mounted elements\n * that animate independently based on EmbedAuthStore.authView — the card\n * slides up from the bottom over the join bar (which slides away beneath\n * it) and reverses on the way back to idle. Card content itself still\n * swaps by innerHTML, mirroring the footer-swap pattern in pop-feed.ts.\n */\nexport class PopAuthPanel extends BaseElement {\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n private _child: string | null = null;\n private _prevView: EmbedAuthView = \"idle\";\n private _heightAnimationFrame: number | null = null;\n private _heightTransitionEnd: ((event: TransitionEvent) => void) | null = null;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n disconnectedCallback() {\n this.cancelCardHeightAnimation();\n super.disconnectedCallback();\n }\n\n private cancelCardHeightAnimation(): void {\n if (this._heightAnimationFrame !== null) {\n window.cancelAnimationFrame(this._heightAnimationFrame);\n this._heightAnimationFrame = null;\n }\n\n const card = this.getElement<HTMLDivElement>(ref(\"card\"));\n if (this._heightTransitionEnd) {\n card?.removeEventListener(\"transitionend\", this._heightTransitionEnd);\n this._heightTransitionEnd = null;\n }\n }\n\n private swapCardContent(card: HTMLDivElement, mount: HTMLDivElement, child: string): void {\n this.cancelCardHeightAnimation();\n\n const previousHeight = card.getBoundingClientRect().height;\n card.style.height = `${previousHeight}px`;\n mount.innerHTML = `<${child}></${child}>`;\n\n this._heightAnimationFrame = window.requestAnimationFrame(() => {\n this._heightAnimationFrame = null;\n // Measure the content, not card.scrollHeight: the card is pinned to\n // previousHeight right now, and scrollHeight never reports less than\n // the element's own height — so a shorter incoming panel (email ->\n // code) would read as \"no change\" and skip the animation entirely.\n const nextHeight = mount.getBoundingClientRect().height;\n\n if (Math.abs(nextHeight - previousHeight) < 1) {\n card.style.height = \"\";\n return;\n }\n\n this._heightTransitionEnd = (event: TransitionEvent) => {\n if (event.target !== card || event.propertyName !== \"height\") return;\n card.style.height = \"\";\n card.removeEventListener(\"transitionend\", this._heightTransitionEnd!);\n this._heightTransitionEnd = null;\n };\n card.addEventListener(\"transitionend\", this._heightTransitionEnd);\n card.style.height = `${nextHeight}px`;\n });\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const view = this.authStore.authView.value;\n const desired =\n view === \"email\"\n ? \"pop-auth-email\"\n : view === \"code\"\n ? \"pop-auth-code\"\n : view === \"no-code\"\n ? \"pop-auth-no-code\"\n : null;\n\n // Checked before the class flips: once the card is display:none its\n // focused control is dropped and focus falls back to <body>. Only\n // reclaim focus when it was actually inside the card — an outside\n // click that closed it must not yank focus off wherever the visitor went.\n const cardHadFocus =\n view === \"idle\" &&\n this._prevView !== \"idle\" &&\n this.getElement(ref(\"card\"))?.matches(\":focus-within\");\n\n this.toggleClass(ref(\"panel\"), \"panel--card\", desired !== null);\n\n if (cardHadFocus) {\n this.getElement<PopAuthJoin>(\"pop-auth-join\")?.restoreFocus();\n }\n\n // Re-entering a card from idle always mounts fresh (resets any\n // abandoned input); swapping directly between card views (e.g.\n // email -> code) already remounts since the desired tag differs.\n // Content isn't cleared on the way back to idle — it stays mounted,\n // hidden under panel__card's own display:none, so the box doesn't\n // go empty mid-exit-animation.\n const enteringFromIdle = this._prevView === \"idle\" && view !== \"idle\";\n const mount = this.getElement<HTMLDivElement>(ref(\"card-content\"));\n if (mount && desired && (this._child !== desired || enteringFromIdle)) {\n const card = this.getElement<HTMLDivElement>(ref(\"card\"));\n this._child = desired;\n if (card && this._prevView !== \"idle\") {\n this.swapCardContent(card, mount, desired);\n } else {\n mount.innerHTML = `<${desired}></${desired}>`;\n }\n }\n\n this._prevView = view;\n });\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"panel\" data-ref=\"panel\">\n <div class=\"panel__stack\">\n <div class=\"panel__join-group\">\n <div class=\"watermark\">\n <img src=\"${watermarkSrc}\" alt=\"PopGrids Watermark\" width=\"64\" height=\"11\" />\n </div>\n <pop-auth-join class=\"panel__join\"></pop-auth-join>\n </div>\n <div class=\"panel__card\" data-ref=\"card\">\n <div data-ref=\"card-content\"></div>\n </div>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-auth-panel\")) {\n customElements.define(\"pop-auth-panel\", PopAuthPanel);\n}\n","import { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: inline-flex;\n max-width: 100%;\n }\n\n .btn-link {\n position: relative;\n align-items: center;\n background-color: transparent;\n border-style: solid;\n border-color: transparent;\n border-top-width: 1px;\n border-bottom-width: 1px;\n border-left-width: 4px;\n border-right-width: 4px;\n border-radius: var(--pop-radius-xs, 4px);\n cursor: pointer;\n display: inline-flex;\n flex-shrink: 0;\n font-weight: 500;\n gap: 6px;\n justify-content: center;\n max-width: 100%;\n outline: none;\n text-decoration: none;\n transform: translateY(-1px);\n transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n }\n\n /* Sizes */\n .btn-link--size-sm,\n .btn-link--size-md {\n font-size: 14px;\n line-height: 20px;\n letter-spacing: 0;\n }\n\n .btn-link--size-lg {\n font-size: 16px;\n line-height: 24px;\n letter-spacing: 0;\n }\n\n /* Themes */\n .btn-link--theme-default {\n color: var(--pop-foreground);\n }\n\n .btn-link--theme-default.btn-link--primary {\n color: var(--pop-foreground);\n }\n\n .btn-link--theme-white {\n color: white;\n }\n\n .btn-link--theme-black {\n color: black;\n }\n\n /* Hover State */\n .btn-link--theme-default:hover,\n .btn-link--theme-black:hover {\n background-color: color-mix(in srgb, var(--pop-foreground) 10%, transparent);\n }\n\n .btn-link--theme-white:hover {\n background-color: color-mix(in srgb, white 16%, transparent);\n }\n\n /* Focus State */\n .btn-link:focus-visible {\n background-color: var(--pop-ring);\n color: white !important;\n }\n\n /* Disabled State */\n .btn-link:disabled,\n .btn-link.is-disabled {\n color: color-mix(in srgb, var(--pop-foreground) 35%, transparent) !important;\n background-color: transparent !important;\n border-color: transparent !important;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .btn-link__icon {\n align-items: center;\n display: inline-flex;\n flex-shrink: 0;\n justify-content: center;\n }\n\n .btn-link__icon ::slotted(*) {\n display: block;\n height: 18px;\n pointer-events: none;\n width: 18px;\n }\n\n :host([size=\"sm\"]) .btn-link__icon ::slotted(*) {\n height: 16px;\n width: 16px;\n }\n\n :host([size=\"lg\"]) .btn-link__icon ::slotted(*) {\n height: 20px;\n width: 20px;\n }\n\n .btn-link__label {\n min-width: 0;\n overflow: hidden;\n position: relative;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n`);\n\nconst SIZES = new Set([\"sm\", \"md\", \"lg\"]);\nconst THEMES = new Set([\"default\", \"white\", \"black\"]);\n\n/**\n * Web Component port of popgrids-ui's `<ButtonLink>` — an inline text-sized\n * link/button used for secondary actions (e.g. \"Back\", \"Resend Code\").\n * Renders an `<a>` when `href` is set, otherwise a `<button>`.\n *\n * Slots: default (label), `leading`, `trailing` (icons/elements either side\n * of the label — omit entirely rather than passing an empty slot, so no\n * unwanted gap is reserved for it).\n */\nexport class PopButtonLink extends BaseElement {\n protected get styleSheets() {\n return [localSheet];\n }\n\n static get observedAttributes() {\n return [\"href\", \"size\", \"theme\", \"primary\", \"disabled\", \"type\", \"target\", \"rel\"];\n }\n\n onHrefChanged() {\n this.render();\n }\n\n onSizeChanged() {\n this.render();\n }\n\n onThemeChanged() {\n this.render();\n }\n\n onPrimaryChanged() {\n this.render();\n }\n\n onDisabledChanged() {\n this.render();\n }\n\n onTypeChanged() {\n this.render();\n }\n\n onTargetChanged() {\n this.render();\n }\n\n onRelChanged() {\n this.render();\n }\n\n get href(): string | null {\n return this.getAttribute(\"href\");\n }\n\n set href(value: string | null) {\n if (value === null) {\n this.removeAttribute(\"href\");\n } else {\n this.setAttribute(\"href\", value);\n }\n }\n\n get size(): \"sm\" | \"md\" | \"lg\" {\n const value = this.getAttribute(\"size\");\n return value && SIZES.has(value) ? (value as \"sm\" | \"md\" | \"lg\") : \"md\";\n }\n\n set size(value: \"sm\" | \"md\" | \"lg\") {\n this.setAttribute(\"size\", value);\n }\n\n get theme(): \"default\" | \"white\" | \"black\" {\n const value = this.getAttribute(\"theme\");\n return value && THEMES.has(value) ? (value as \"default\" | \"white\" | \"black\") : \"default\";\n }\n\n set theme(value: \"default\" | \"white\" | \"black\") {\n this.setAttribute(\"theme\", value);\n }\n\n get primary(): boolean {\n return this.hasAttribute(\"primary\");\n }\n\n set primary(value: boolean) {\n if (value) {\n this.setAttribute(\"primary\", \"\");\n } else {\n this.removeAttribute(\"primary\");\n }\n }\n\n get disabled(): boolean {\n return this.hasAttribute(\"disabled\");\n }\n\n set disabled(value: boolean) {\n if (value) {\n this.setAttribute(\"disabled\", \"\");\n } else {\n this.removeAttribute(\"disabled\");\n }\n }\n\n get type(): \"button\" | \"submit\" | \"reset\" {\n const value = this.getAttribute(\"type\");\n return value === \"submit\" || value === \"reset\" ? value : \"button\";\n }\n\n set type(value: \"button\" | \"submit\" | \"reset\") {\n this.setAttribute(\"type\", value);\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: MouseEvent) {\n if (!this.disabled) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n\n private hasSlotted(name: string): boolean {\n return this.querySelector(`:scope > [slot=\"${name}\"]`) !== null;\n }\n\n /** Whether the default slot has any non-whitespace light-DOM content. */\n private hasLabel(): boolean {\n return Array.from(this.childNodes).some((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n return !(node as Element).hasAttribute(\"slot\");\n }\n return node.nodeType === Node.TEXT_NODE && !!node.textContent?.trim();\n });\n }\n\n protected getTemplate(): string {\n const classes = [\n \"btn-link\",\n `btn-link--size-${this.size}`,\n `btn-link--theme-${this.theme}`,\n this.primary ? \"btn-link--primary\" : \"\",\n this.disabled ? \"is-disabled\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const leading = this.hasSlotted(\"leading\")\n ? `<span class=\"btn-link__icon\"><slot name=\"leading\"></slot></span>`\n : \"\";\n const trailing = this.hasSlotted(\"trailing\")\n ? `<span class=\"btn-link__icon\"><slot name=\"trailing\"></slot></span>`\n : \"\";\n const label = this.hasLabel() ? `<span class=\"btn-link__label\"><slot></slot></span>` : \"\";\n const inner = `${leading}${label}${trailing}`;\n\n if (this.href !== null) {\n const disabledAttrs = this.disabled ? `aria-disabled=\"true\" tabindex=\"-1\"` : \"\";\n const target = this.getAttribute(\"target\");\n const rel = this.getAttribute(\"rel\");\n return /* html */ `\n <a\n class=\"${classes}\"\n part=\"link\"\n href=\"${this.href}\"\n ${target ? `target=\"${target}\"` : \"\"}\n ${rel ? `rel=\"${rel}\"` : \"\"}\n ${disabledAttrs}\n >${inner}</a\n >\n `;\n }\n\n return /* html */ `\n <button\n class=\"${classes}\"\n part=\"link\"\n type=\"${this.type}\"\n ${this.disabled ? \"disabled\" : \"\"}\n >\n ${inner}\n </button>\n `;\n }\n}\n\nif (!customElements.get(\"pop-button-link\")) {\n customElements.define(\"pop-button-link\", PopButtonLink);\n}\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD8AAABMCAYAAADa6W+wAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAUuSURBVHgB5ZyBceIwEEX3bq4AOsAdQAdxKggl+Co4rgKcCkgqgFRAUgGkAqACOxVAKvDpg+VRHEmWQSubuTezg8Ega7UrebWS+UG8jIXEQoZCovI9lcd1ciHHUnZCPsrXXflZ7xkISYSshByEFJ5kLWRO54bsHRGdK+dTYZNkQhbUg4aI6FyRoiNBQyQUGLj3jMJYuleNMC4v1gel67Ig/WCq5Qe144+QlM6Wb2QwGNB4PD7JaDQ6veIzKZLj8XiSPM9Pr/v9nna73UnwWUtyIb+FbMgjM3K0QBzHxXq9Lg6HQ3Et2+22WCwWpzJdr1/KjDzRqLiwZDGbzbwobCLLslNDRFEUrAEmTReBVVCxkLRohIsbICLLiA5roxJdAm9zaIAJXUBmKhCtHtraJjAuNHjBgVrcBcDsFhSXoD4NDbB2VTyyFNI7xSUODTB1UX5hKmA+nxd9Bl0AYxGZ3X9wkdWTJCluARjIYv2ULrG6T3eHhabT6SkY4sASFB1aWx23FJ+IULcqm6MBUKbF+rFO+ZQCje6qa6J8jsjQYv2FTvmMAvb1yWRSXePp6anwzWq1cnb9MQXo6yqwthyZ0Q04y9e5/k9F+VjnCpiGCrckDjCtFV51OpZTWN/lo/4Gxqryd7pvCNckTkS/rI7f39/JN5b6j1TltU10d3dHnKjl+7Y8sHhtpS+iHm3f4JyfS2RIytHvMV4ZdMt+1lvhS9OUaSdu5DUuSFk5l60hksoPWv7QK9I1kb/zjU2HRsuHIFQj17FanusWV4fD4i5I5Ye6k8PhkELAqbxlHDn2os9L5Tm6mUX5vBfKy/s7x/U+Pz9Np7q3/GazqY7VaI+j/Br7zpV/e3urjjmiSUvUWJ3QRkHcqAlHzL58g+iUzAmNLxOboGAgur+/rwYkjgnU6+ur6VROXVpezbLA6hw5A9dMTnDlZRoLinPk8CwTmm85vE76PCdIvRn0ympdQL8YGWI6y0GD1atVGzngaePLrmLua8FAaqEaBTsb7bl4fHy0hbTPdB7pv7AmjYtwraZw0eDu6OuRqrTV7T8+PuhWkHGDhUeqWV0qr43+b6XPI4RVAyYNGyHL+odS+Vz3i1tQ/vn5uUlxnPitO/FL+cL3XzEkFAFmWsjRY28eZnKXTKBQBgY3y6xN8pcM+km0O66wlhZiUMJ1lstlY1yB8y335KU2peUOTKRQtvWTyOGJypJv4FGwmlD42zl4Aq6rZnQhFyxnYYBLXb4YEemXpjlx2ENziSBaTaglncT3nhtgTS23nEkyXYEhdl417KJwtfaUrkCrPPbOhEDdqNBS6ZQcd4HbWOkugN0NIWhhfRhpQR4eM/mlHGujPEvq1ysNOXu4tHzaKidPqLO6XPcFrkCnDgIdy/IYUryYiubkEVV5bSwbSnlgW04mBhqVDxnfh16tVZXXhk8hLW9bVCQGemV5y7VyCkAnUR5APEHmezkL9RxeZ4Oey5qab5yUVxcTuXh5eTGd2lMgnkjjepg/c9JmdYWT2FQJjo3BEsusLqPAbHUV4VpMTNPUZvUFBSYxVMT7vvsGxWH1iDpgTYbbDjzg2i6AXBweMSH77C2hjsAUy/psPLwASce2OD4GuqIA2B4hxzRyrrzHbfBb8I2ZGJKODw8PVeJRxujysXDcw/FYOBKWDhFjLuSeAkV1NlJqn125RjLqqJ+bSOk/VVwSEe9fRSzJQx6Om4T8NgLKiunGSMh8O3QR/Damjmn7hyF14KpxKSM6d49IOa/7u6dX6snfPf0DiVL6IWhCmZ4AAAAASUVORK5CYII=\"","export const colors = [\n \"#DDD0BE\",\n \"#E9DCBB\",\n \"#E9DCBB\",\n \"#C7D1B0\",\n \"#C6D0CB\",\n \"#E9DCBB\",\n \"#C7D1B0\",\n \"#E9DCBB\",\n \"#DFC2C0\",\n \"#CFD4C6\",\n \"#D7E3E8\",\n \"#CFD4C6\",\n \"#D6B3B3\",\n \"#E9DCBB\",\n \"#CFCBDC\",\n \"#BFD6D7\",\n \"#E3D2C6\",\n \"#D1E2E7\",\n \"#D6B3B3\",\n \"#BFD6D7\",\n \"#E9DCBB\",\n \"#C7D1B0\",\n \"#DFC2C0\",\n \"#D1E2E7\",\n \"#CFD4C6\",\n \"#E9DCBB\",\n \"#D7E3E8\",\n \"#CFD4C6\",\n \"#C6D0CB\",\n \"#E9DCBB\",\n \"#C7D1B0\",\n \"#E9DCBB\",\n \"#CFCBDC\",\n \"#E3D2C6\",\n \"#E9DCBB\",\n];\n\nexport const sampleColor = (index?: number) => {\n if (typeof index === \"number\") {\n return colors[index % colors.length] ?? \"#e5e7eb\";\n }\n return colors[Math.floor(Math.random() * colors.length)];\n};\n\n/** 32-bit FNV-1a over UTF-8 bytes — deterministic, no lookup table. */\nexport function fnv1a32(data: string): number {\n const bytes = new TextEncoder().encode(data);\n let h = 0x811c9dc5;\n for (let i = 0; i < bytes.length; i++) {\n const byte = bytes[i] ?? 0;\n h ^= byte;\n h = Math.imul(h, 0x01000193);\n }\n return h >>> 0;\n}\n\n/** Deterministic background color from a stable string (e.g. user id, org id, slug). */\nexport function backgroundColor(id: string): string {\n return colors[fnv1a32(id) % colors.length] ?? \"#e5e7eb\";\n}\n\n","import deletedUserMarkSrc from \"../assets/popgrids-letter-p.png?inline\";\nimport { backgroundColor, sampleColor } from \"../helpers/color.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n\n --comment-avatar-border-size: 1px;\n --comment-avatar-border-color: var(--color-background, #fff);\n --comment-avatar-size: 32px;\n }\n\n .comment-avatar {\n align-items: center;\n display: flex;\n flex-shrink: 0;\n isolation: isolate;\n justify-content: center;\n position: relative;\n width: calc(var(--comment-avatar-size) + calc(var(--comment-avatar-border-size) * 2));\n height: calc(var(--comment-avatar-size) + calc(var(--comment-avatar-border-size) * 2));\n }\n\n .comment-avatar--size-xs {\n --comment-avatar-size: 32px;\n }\n\n .comment-avatar--size-sm {\n --comment-avatar-size: 56px;\n }\n\n .comment-avatar--size-md {\n --comment-avatar-size: 80px;\n }\n\n .comment-avatar--size-lg {\n --comment-avatar-size: 120px;\n }\n\n .comment-avatar--size-xl {\n --comment-avatar-size: 140px;\n }\n\n .comment-avatar__background {\n background-color: var(--comment-avatar-border-color);\n position: absolute;\n top: 0;\n left: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n }\n\n /**\n * Content\n */\n\n .comment-avatar__content {\n align-items: center;\n background-color: var(--color-surface-bg-default);\n display: flex;\n justify-content: center;\n overflow: hidden;\n position: relative;\n height: var(--comment-avatar-size);\n width: var(--comment-avatar-size);\n z-index: 20;\n\n /* Initials styling */\n font-family: Inter, sans-serif;\n font-weight: 600;\n color: #374151;\n font-size: calc(var(--comment-avatar-size) * 0.35);\n line-height: 1;\n }\n\n .comment-avatar__content::slotted(img) {\n -webkit-user-drag: none;\n align-self: stretch;\n flex: 1 0 0;\n height: var(--comment-avatar-size);\n object-fit: cover;\n pointer-events: none;\n position: absolute;\n user-select: none;\n width: var(--comment-avatar-size);\n }\n\n .comment-avatar__deleted-mark {\n -webkit-user-drag: none;\n bottom: -3px;\n height: auto;\n left: 0;\n object-fit: cover;\n pointer-events: none;\n position: absolute;\n user-select: none;\n width: 100%;\n transform: scale(0.57);\n }\n`);\n\nexport class PopCommentAvatar extends BaseElement {\n private _backgroundColor: string;\n\n constructor() {\n super();\n this._backgroundColor = sampleColor() ?? \"#e5e7eb\";\n }\n\n static get observedAttributes() {\n return [\"size\", \"data-color-key\", \"deleted\"];\n }\n\n onSizeChanged() {\n this.render();\n }\n\n onDataColorKeyChanged() {\n this.render();\n }\n\n onDeletedChanged() {\n this.render();\n }\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n get size(): string {\n return this.getAttribute(\"size\") || \"md\";\n }\n\n set size(value: string) {\n this.setAttribute(\"size\", value);\n }\n\n get deleted(): boolean {\n return this.hasAttribute(\"deleted\");\n }\n\n set deleted(value: boolean) {\n if (value) {\n this.setAttribute(\"deleted\", \"\");\n } else {\n this.removeAttribute(\"deleted\");\n }\n }\n\n protected getTemplate(): string {\n const size = this.size;\n const deleted = this.deleted;\n const key = this.getAttribute(\"data-color-key\");\n const bg = deleted\n ? \"var(--pop-muted-foreground, #e5e7eb)\"\n : key\n ? backgroundColor(key)\n : this._backgroundColor;\n\n const content = deleted\n ? `<div\n class=\"comment-avatar__content mask mask-squircle\"\n part=\"content\"\n style=\"background-color: ${bg}; opacity: 0.15\"\n ><img class=\"comment-avatar__deleted-mark\" src=\"${deletedUserMarkSrc}\" alt=\"Deleted user\" /></div>`\n : `<slot\n class=\"comment-avatar__content mask mask-squircle\"\n part=\"content\"\n style=\"background-color: ${bg};\"\n ></slot>`;\n\n return /* html */ `\n <div class=\"comment-avatar comment-avatar--size-${size}\" part=\"base\">\n <div class=\"comment-avatar__background mask mask-squircle\" part=\"background\"></div>\n ${content}\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-avatar\")) {\n customElements.define(\"pop-comment-avatar\", PopCommentAvatar);\n}\n","import { computed, signal } from \"@preact/signals-core\";\nimport { reconnectDelayMs } from \"../lib/backoff.js\";\nimport type { Comment, CommentAuthor, Grid } from \"../types/models.js\";\nimport type { EmbedAuthStore } from \"./embed-auth-store.js\";\n\nconst MAX_RECONNECT_DELAY_MS = 30_000;\nconst DEFAULT_PREVIEW_COUNT = 3;\n/** The preview count the Composer calls \"Counter only\": the count and icon, no avatars. */\nconst COUNTER_ONLY_PREVIEW_COUNT = 1;\n\nconst commentRecency = (comment: Comment) => {\n const createdAt =\n typeof comment.createdAt === \"number\"\n ? comment.createdAt\n : Date.parse(String(comment.createdAt));\n\n return Number.isFinite(createdAt) ? createdAt : 0;\n};\n\nconst resolvePreviewCount = (grid: Grid | null, fallback: number) => {\n const value = grid?.previewCount ?? fallback;\n\n return value > 0 ? value : DEFAULT_PREVIEW_COUNT;\n};\n\n/**\n * The five visual settings a `<pop-grid>` can override live via\n * `data-align`/`data-layout`/`data-position`/`data-icon`/`data-preview-count`\n * — see pop-grid.ts's observedAttributes. Never includes `undefined`-valued\n * keys: an absent/invalid attribute is simply omitted, not set to\n * `undefined`, so `mergeOverrides` can fall back to the fetched grid's value\n * for that field with a plain spread.\n */\nexport type GridOverrides = Partial<\n Pick<Grid, \"align\" | \"layout\" | \"position\" | \"icon\" | \"previewCount\">\n>;\n\n/** What a `<pop-grid data-demo>` shows in place of a fetched grid — see pop-grid.ts's `demo`. */\nexport interface DemoData {\n grid: Grid;\n comments: Comment[];\n}\n\nconst mergeOverrides = (fetched: Grid | null, overrides: GridOverrides): Grid | null => {\n if (!fetched) {\n return fetched;\n }\n\n return { ...fetched, ...overrides };\n};\n\nexport class GridStore {\n readonly apiUrl: string;\n readonly publicKey: string;\n readonly pageUrl: string;\n readonly externalId: string | null;\n /** Shows host-supplied data (`showDemo`) and never touches the network. */\n readonly demo: boolean;\n readonly previewCount = DEFAULT_PREVIEW_COUNT;\n private readonly authStore: EmbedAuthStore;\n\n /** The grid last fetched from the API — never read directly outside this\n * class; `grid` (below) is the override-aware value every consumer uses. */\n private _fetchedGrid = signal<Grid | null>(null);\n /** The override attributes currently set on the `<pop-grid>` element. */\n private _overrides = signal<GridOverrides>({});\n\n /** Fetched grid config with any live override attributes layered on top.\n * Read-only from the outside — set via `load()` (fetched) or\n * `setOverrides()` (overrides). */\n grid = computed(() => mergeOverrides(this._fetchedGrid.value, this._overrides.value));\n comments = signal<Comment[]>([]);\n loading = signal(true);\n error = signal<string | null>(null);\n open = signal(false);\n replyingTo = signal<string | null>(null);\n editingCommentId = signal<string | null>(null);\n scrollingCommentId = signal<string | null>(null);\n\n private socket: WebSocket | null = null;\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n\n topLevelComments = computed(() =>\n this.comments.value\n .filter((c) => c.parentCommentId === null)\n .sort((a, b) => String(a.sortKey).localeCompare(String(b.sortKey))),\n );\n\n /** Size of the comment avatars inside the open panel, set by the grid's Layout: 56px for \"lg\", otherwise 32px. */\n commentSize = computed(() => (this.grid.value?.layout === \"lg\" ? \"lg\" : \"sm\"));\n\n replyingToComment = computed(() => {\n const id = this.replyingTo.value;\n if (!id) return null;\n return this.comments.value.find((c) => c.id === id) ?? null;\n });\n\n editingComment = computed(() => {\n const id = this.editingCommentId.value;\n if (!id) return null;\n return this.comments.value.find((c) => c.id === id) ?? null;\n });\n\n previewComments = computed(() =>\n this.topLevelComments.value.slice(0, resolvePreviewCount(this.grid.value, this.previewCount)),\n );\n\n previewAvatars = computed((): CommentAuthor[] => {\n const limit = resolvePreviewCount(this.grid.value, this.previewCount);\n if (limit <= COUNTER_ONLY_PREVIEW_COUNT) return [];\n\n const seen = new Set<string>();\n const uniqueNewestFirst: CommentAuthor[] = [];\n\n const sorted = [...this.comments.value].sort((a, b) => commentRecency(b) - commentRecency(a));\n\n for (const comment of sorted) {\n const author = comment.author;\n\n if (!author?.id || seen.has(author.id)) {\n continue;\n }\n\n seen.add(author.id);\n uniqueNewestFirst.push(author);\n\n if (uniqueNewestFirst.length >= limit) {\n break;\n }\n }\n\n return uniqueNewestFirst.reverse();\n });\n\n constructor(opts: {\n apiUrl: string;\n publicKey: string;\n pageUrl: string;\n externalId?: string | null;\n demo?: boolean;\n authStore: EmbedAuthStore;\n }) {\n this.apiUrl = opts.apiUrl;\n this.publicKey = opts.publicKey;\n this.pageUrl = opts.pageUrl;\n this.externalId = opts.externalId?.trim() || null;\n this.demo = opts.demo ?? false;\n this.authStore = opts.authStore;\n }\n\n /** Stands in for `load()` in demo mode: shows the given data as if it had been fetched. */\n showDemo({ grid, comments }: DemoData): void {\n this._fetchedGrid.value = grid;\n this.comments.value = comments;\n this.error.value = null;\n this.loading.value = false;\n }\n\n /** Replaces the current override set wholesale (not a per-key merge) —\n * called with every override attribute `<pop-grid>` currently has set, so\n * removing an attribute correctly falls back to the fetched grid's value\n * for that field instead of leaving a stale override in place. */\n setOverrides(overrides: GridOverrides): void {\n this._overrides.value = overrides;\n }\n\n /** pageUrl + optional externalId — the params that identify the discussion. */\n private identityParams(): string {\n const params = new URLSearchParams({ pageUrl: this.pageUrl });\n if (this.externalId) {\n params.set(\"externalId\", this.externalId);\n }\n return params.toString();\n }\n\n repliesFor(parentId: string): Comment[] {\n const parent = this.comments.value.find((c) => c.id === parentId);\n if (!parent) return [];\n return this.comments.value\n .filter(\n (c) =>\n c.id !== parentId &&\n (c.sortKey === parent.sortKey || c.sortKey.startsWith(parent.sortKey + \"/\")),\n )\n .sort((a, b) => String(a.sortKey).localeCompare(String(b.sortKey)));\n }\n\n async load(): Promise<boolean> {\n this.loading.value = true;\n this.error.value = null;\n try {\n const gridRes = await this.authStore.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}`,\n );\n\n if (!gridRes.ok) {\n this.error.value = \"There was a problem loading the PopGrid\";\n return false;\n }\n\n const data = (await gridRes.json()) as { grid: Grid };\n this._fetchedGrid.value = data.grid;\n void this.connectRealtime();\n\n const commentsRes = await this.authStore.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/comments?${this.identityParams()}`,\n );\n\n if (commentsRes.ok) {\n const commentsData = (await commentsRes.json()) as { comments: Comment[] };\n this.comments.value = commentsData.comments;\n }\n\n return true;\n } catch {\n console.error(\"Failed to load PopGrid\");\n this.error.value = \"There was a problem loading the PopGrid\";\n return false;\n } finally {\n this.loading.value = false;\n }\n }\n\n async postComment(body: string, parentCommentId?: string): Promise<Comment | null> {\n const res = await this.authStore.authorizedFetch(\n `/api/v1/embed/grids/${this.publicKey}/comments`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n body,\n pageUrl: this.pageUrl,\n externalId: this.externalId ?? undefined,\n parentCommentId,\n }),\n },\n );\n\n if (!res.ok) {\n return null;\n }\n\n const data = (await res.json()) as { comment: Comment };\n this.upsertComment(data.comment);\n\n if (data.comment.author && !this.authStore.currentUser.value) {\n this.authStore.currentUser.value = {\n id: data.comment.author.id,\n name: data.comment.author.name ?? \"\",\n email: \"\",\n image: data.comment.author.image,\n };\n }\n\n return data.comment;\n }\n\n destroy(): void {\n this.disposed = true;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onclose = null;\n this.socket.onerror = null;\n this.socket.close();\n this.socket = null;\n }\n }\n\n private async connectRealtime(): Promise<void> {\n const connectUrl = this.grid.value?.connectUrl;\n\n if (!connectUrl || this.disposed) {\n return;\n }\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onclose = null;\n this.socket.onerror = null;\n this.socket.close();\n this.socket = null;\n }\n\n // Mint a short-lived, single-use ticket for this connection attempt\n // rather than sending the long-lived embed token in the WS URL, where it\n // could land in access logs. Works for signed-out visitors too — an\n // anonymous ticket still gets broadcast updates for public comments.\n let ticket: string | null = null;\n try {\n const ticketRes = await this.authStore.fetchWithToken(\n `/api/v1/embed/grids/${this.publicKey}/connect-ticket`,\n { method: \"POST\" },\n );\n if (ticketRes.ok) {\n const ticketData = (await ticketRes.json()) as { ticket: string };\n ticket = ticketData.ticket;\n }\n } catch {\n // No realtime this attempt — scheduleReconnect will try again.\n }\n\n if (!ticket || this.disposed) {\n this.scheduleReconnect();\n return;\n }\n\n const wsUrl = new URL(connectUrl, this.apiUrl);\n wsUrl.protocol = wsUrl.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n wsUrl.searchParams.set(\"ticket\", ticket);\n wsUrl.searchParams.set(\"pageUrl\", this.pageUrl);\n if (this.externalId) {\n wsUrl.searchParams.set(\"externalId\", this.externalId);\n }\n\n const socket = new WebSocket(wsUrl.toString());\n this.socket = socket;\n\n socket.onopen = () => {\n this.reconnectAttempt = 0;\n };\n\n socket.onmessage = (event) => {\n try {\n const payload = JSON.parse(String(event.data)) as {\n type?: string;\n comment?: Comment;\n };\n\n if (payload.type === \"comment.created\" && payload.comment) {\n this.upsertComment(payload.comment);\n } else if (payload.type === \"comment.updated\" && payload.comment) {\n this.updateCommentInList(payload.comment);\n }\n } catch {\n // Ignore malformed realtime payloads.\n }\n };\n\n socket.onclose = () => {\n if (this.disposed) {\n return;\n }\n\n this.scheduleReconnect();\n };\n\n socket.onerror = () => {\n socket.close();\n };\n }\n\n private scheduleReconnect(): void {\n if (this.disposed || this.reconnectTimer) {\n return;\n }\n\n const delay = reconnectDelayMs(this.reconnectAttempt, 1000, MAX_RECONNECT_DELAY_MS);\n this.reconnectAttempt += 1;\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n void this.connectRealtime();\n }, delay);\n }\n\n private upsertComment(comment: Comment): void {\n const existing = this.comments.value.some((entry) => entry.id === comment.id);\n\n if (existing) {\n return;\n }\n\n this.comments.value = [...this.comments.value, comment];\n }\n\n async editComment(commentId: string, body: string): Promise<Comment | null> {\n const res = await this.authStore.authorizedFetch(\n `/api/v1/embed/grids/${this.publicKey}/comments/${commentId}`,\n {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n body,\n pageUrl: this.pageUrl,\n externalId: this.externalId ?? undefined,\n }),\n },\n );\n\n if (!res.ok) {\n return null;\n }\n\n const data = (await res.json()) as { comment: Comment };\n this.updateCommentInList(data.comment);\n return data.comment;\n }\n\n async deleteComment(commentId: string): Promise<Comment | null> {\n const res = await this.authStore.authorizedFetch(\n `/api/v1/embed/grids/${this.publicKey}/comments/${commentId}?${this.identityParams()}`,\n { method: \"DELETE\" },\n );\n\n if (!res.ok) {\n return null;\n }\n\n const data = (await res.json()) as { comment: Comment };\n this.updateCommentInList(data.comment);\n return data.comment;\n }\n\n async flagComment(commentId: string): Promise<boolean> {\n const res = await this.authStore.authorizedFetch(\n `/api/v1/embed/grids/${this.publicKey}/comments/${commentId}/flag?${this.identityParams()}`,\n { method: \"POST\" },\n );\n\n return res.ok;\n }\n\n private updateCommentInList(comment: Comment): void {\n this.comments.value = this.comments.value.map((c) => (c.id === comment.id ? comment : c));\n }\n}\n","import { getInitials } from \"../helpers/author.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\nimport type { PopCommentInput } from \"./pop-comment-input.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n background: var(--pop-background);\n border-top: 1px solid var(--pop-bar-input-bg);\n display: block;\n padding: 6px;\n position: relative;\n\n --pop-bar-avatar-bg: #e5e7eb;\n --pop-bar-avatar-color: #374151;\n --pop-bar-avatar-border: #ffffff;\n --pop-bar-input-bg: rgba(0, 0, 32, 0.04);\n --pop-bar-send-hover: rgba(0, 0, 32, 0.06);\n --pop-bar-send-color: #000000;\n --pop-bar-watermark: rgba(0, 0, 32, 0.1);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-bar-avatar-bg: #1f2937;\n --pop-bar-avatar-color: #d1d5db;\n --pop-bar-avatar-border: var(--pop-popover, #151d2a);\n --pop-bar-input-bg: rgba(255, 255, 255, 0.05);\n --pop-bar-send-hover: rgba(255, 255, 255, 0.08);\n --pop-bar-send-color: #ffffff;\n --pop-bar-watermark: rgba(255, 255, 255, 0.1);\n }\n }\n\n :host(.dark) {\n --pop-bar-avatar-bg: #1f2937;\n --pop-bar-avatar-color: #d1d5db;\n --pop-bar-avatar-border: var(--pop-popover, #151d2a);\n --pop-bar-input-bg: rgba(255, 255, 255, 0.05);\n --pop-bar-send-hover: rgba(255, 255, 255, 0.08);\n --pop-bar-send-color: #ffffff;\n --pop-bar-watermark: rgba(255, 255, 255, 0.1);\n }\n\n .bar {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .bar__user {\n display: flex;\n align-items: center;\n align-self: flex-start;\n flex-shrink: 0;\n padding-top: 2px;\n }\n\n .bar__avatar {\n flex-shrink: 0;\n --comment-avatar-border-size: 0px;\n }\n\n .bar__avatar--reply {\n margin-right: -4px;\n z-index: 1;\n }\n\n .bar__avatar--reply.hidden {\n display: none;\n }\n\n .bar__avatar--user {\n z-index: 2;\n }\n\n .bar__user.has-reply .bar__avatar--user {\n --comment-avatar-border-size: 2px;\n --comment-avatar-border-color: var(--pop-bar-avatar-border);\n }\n\n .bar__input-wrap {\n flex: 1;\n min-width: 0;\n background: var(--pop-bar-input-bg);\n border-radius: 18px;\n overflow: hidden;\n display: flex;\n align-items: flex-end;\n padding: 4px 8px 4px 12px;\n max-height: 280px;\n }\n\n .bar__send {\n align-items: center;\n align-self: flex-end;\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n justify-content: center;\n padding-bottom: 2px;\n }\n\n .logo-watermark {\n position: absolute;\n top: -16px;\n left: 8px;\n font-family: Inter, sans-serif;\n font-size: 8px;\n font-weight: 700;\n letter-spacing: 1px;\n color: var(--pop-bar-watermark);\n text-transform: uppercase;\n border-radius: 9999px;\n padding: 2px 6px;\n pointer-events: none;\n user-select: none;\n }\n`);\n\nconst LOGO_WATERMARK_SVG = `<svg width=\"64\" height=\"11\" viewBox=\"0 0 64 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M3.91111 0C0.892839 0 0 2.11357 0 4.77714C0 5.76321 0.0987654 6.73357 0.213333 7.70786C0.25679 8.08893 0.240988 8.50929 0.312099 8.89036C0.497778 9.89214 1.44593 10.3557 2.36642 10.3557C3.62667 10.3557 4.4642 9.56607 4.4642 8.30107C4.4642 7.57036 4.22321 7.09107 3.5279 6.80821C3.48444 6.7925 3.44099 6.78071 3.44099 6.72179C3.44099 6.62357 3.59901 6.55286 3.69778 6.55286C4.03753 6.55286 4.57481 6.89071 5.04494 6.89071C6.88593 6.89071 7.90519 5.13071 7.90519 3.48071C7.90519 1.08429 6.13136 0 3.91111 0ZM3.89531 5.18179C3.78074 5.18179 3.68198 5.08357 3.68198 4.96964C3.68198 4.81643 3.89531 4.7025 3.96642 4.57679C4.12049 4.29393 4.16395 3.81464 4.16395 3.4925C4.16395 3.11143 4.06519 2.40821 3.8242 2.12536C3.75309 2.04286 3.65432 1.99964 3.65432 1.88571C3.65432 1.77179 3.76889 1.67357 3.87951 1.67357C4.36148 1.67357 4.60247 3.08393 4.60247 3.44929C4.60247 3.84214 4.47605 5.18179 3.89531 5.18179Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M12.7368 0.239637C9.73433 0.239637 7.93285 2.35321 7.93285 5.25249C7.93285 8.15178 9.73038 10.2654 12.7368 10.2654C15.7432 10.2654 17.5249 8.12428 17.5249 5.25249C17.5249 2.38071 15.7116 0.239637 12.7368 0.239637ZM12.8672 8.83142C12.8198 8.89035 12.7249 9.00035 12.6104 9.00035C12.4958 9.00035 12.3852 8.90214 12.3852 8.78821C12.3852 8.74499 12.7526 8.19499 12.8119 8.02607C13.037 7.36214 13.0805 6.64321 13.0805 5.93999C13.0805 4.99714 12.9106 3.78321 12.3299 3.00928C12.2153 2.86785 11.8637 2.60071 11.8637 2.44749C11.8637 2.33357 11.9625 2.23535 12.077 2.23535C12.1758 2.23535 12.2746 2.32178 12.3457 2.37678C13.2504 3.12321 13.523 4.82821 13.523 5.93999C13.523 6.81214 13.4874 8.08499 12.8711 8.82749L12.8672 8.83142Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M21.6533 0C18.6351 0 17.7422 2.11357 17.7422 4.77714C17.7422 5.76321 17.841 6.73357 17.9555 7.70786C17.999 8.08893 17.9832 8.50929 18.0543 8.89036C18.24 9.89214 19.1881 10.3557 20.1086 10.3557C21.3689 10.3557 22.2064 9.56607 22.2064 8.30107C22.2064 7.57036 21.9654 7.09107 21.2701 6.80821C21.2267 6.7925 21.1832 6.78071 21.1832 6.72179C21.1832 6.62357 21.3412 6.55286 21.44 6.55286C21.7797 6.55286 22.317 6.89071 22.7871 6.89071C24.6281 6.89071 25.6474 5.13071 25.6474 3.48071C25.6474 1.08429 23.8775 0 21.6533 0ZM21.6415 5.18179C21.5269 5.18179 21.4281 5.08357 21.4281 4.96964C21.4281 4.81643 21.6415 4.7025 21.7126 4.57679C21.8667 4.29393 21.9101 3.81464 21.9101 3.4925C21.9101 3.11143 21.8113 2.40821 21.5704 2.12536C21.4992 2.04286 21.4005 1.99964 21.4005 1.88571C21.4005 1.77179 21.5151 1.67357 21.6257 1.67357C22.1076 1.67357 22.3486 3.08393 22.3486 3.44929C22.3486 3.84214 22.2222 5.18179 21.6415 5.18179Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M31.9012 4.16822C30.882 4.16822 29.4637 4.6318 29.4637 5.84572C29.4637 6.53715 29.9733 7.56251 30.7832 7.56251C31.2929 7.56251 31.6208 7.16965 31.7906 7.16965C31.8341 7.16965 31.8736 7.19715 31.8736 7.24037C31.8736 7.64894 31.0795 7.83358 30.7674 7.83358C29.677 7.83358 29.0963 6.90251 29.0963 5.91644C29.0963 4.70644 30.242 3.77537 31.4035 3.77537C31.7432 3.77537 32.0988 3.87358 32.4385 3.87358C33.4459 3.87358 34.165 2.97394 34.165 2.01537C34.165 0.424295 32.2687 0.0589382 31.0045 0.0589382C27.6464 0.0589382 25.6909 2.22751 25.6909 5.52358C25.6909 8.56822 27.279 10.5089 30.4237 10.5089C32.4622 10.5089 34.6864 9.6368 34.6864 7.26787C34.6864 5.6493 33.6237 4.16822 31.8973 4.16822H31.9012Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M41.2681 6.56464C41.0113 6.56464 40.802 6.66286 40.5886 6.66286C40.5452 6.66286 40.5333 6.61964 40.5333 6.59214C40.5333 6.49393 40.5768 6.45071 40.6479 6.42321C40.8889 6.34071 41.1457 6.28179 41.3827 6.16786C42.4612 5.66107 43.0973 4.7575 43.0973 3.56321C43.0973 1.40643 41.2405 0.0982143 39.202 0.0982143C38.4632 0.0982143 37.7442 0.310357 37.12 0.648214C35.4212 1.56357 35.0933 2.87571 34.9946 4.66321C34.9511 5.36643 34.9511 6.07357 34.9511 6.77679V8.48179C34.9511 9.55036 35.6583 10.4107 36.7763 10.4107C37.5822 10.4107 38.3052 9.83321 38.4909 9.07107C38.5896 8.61929 38.5343 8.085 38.5343 7.64893C38.5343 7.60571 38.5501 7.59393 38.5896 7.59393C38.6291 7.59393 38.6765 7.62143 38.7042 7.63714C39.202 8.83536 39.8815 10.3557 41.4222 10.3557C42.4849 10.3557 43.362 9.60929 43.362 8.525C43.362 7.44071 42.3427 6.56857 41.2642 6.56857L41.2681 6.56464ZM38.961 5.18179C38.8464 5.18179 38.7476 5.08357 38.7476 4.96964C38.7476 4.81643 38.961 4.7025 39.0321 4.57679C39.1862 4.29393 39.2296 3.81464 39.2296 3.4925C39.2296 3.11143 39.1309 2.40821 38.8899 2.12536C38.8188 2.04286 38.7358 1.99964 38.7358 1.88571C38.7358 1.77179 38.8346 1.67357 38.9491 1.67357C39.4311 1.67357 39.6721 3.08393 39.6721 3.44929C39.6721 3.84214 39.5575 5.18179 38.9649 5.18179H38.961Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M46.7674 0.549991C46.4277 0.326063 45.9457 0.212134 45.5348 0.212134C44.642 0.212134 43.8756 0.915349 43.7768 1.79142C43.7491 2.04678 43.761 2.28642 43.761 2.55356V4.94606L43.7175 7.46821V8.72142C43.7175 9.70749 44.5669 10.4814 45.5467 10.4814C46.2696 10.4814 47.0637 10.0296 47.3324 9.35392C47.4864 8.97285 47.5022 8.43856 47.5022 8.02999V6.92999L47.518 4.73392V2.53785C47.518 1.72071 47.5022 1.07249 46.7674 0.549991Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M50.2993 0.125713C48.8533 0.125713 48.1304 0.801428 48.1304 2.25107V2.82857L48.1462 3.96786V4.54536C48.1462 4.98143 48.1462 5.39 48.1304 5.82607C48.1027 6.34857 48.0316 6.86714 48.0316 7.40536C48.0316 9.3775 49.0509 10.3361 51.0222 10.3361C54.0523 10.3361 56.1067 9.03964 56.1067 5.81429C56.1067 1.925 54.2222 0.121785 50.2993 0.121785V0.125713ZM51.6583 7.91607C51.5437 7.91607 51.4449 7.81786 51.4449 7.70393C51.4449 7.66071 51.4608 7.83352 51.4884 7.59C51.8558 6.985 51.9546 6.14036 51.9546 5.44893C51.9546 4.80071 51.8835 3.84214 51.4726 3.33536C51.4015 3.22143 51.2593 3.13893 51.2593 2.9975C51.2593 2.88357 51.358 2.78536 51.4726 2.78536C51.6859 2.78536 51.9822 3.31964 52.0691 3.50428C52.3378 4.125 52.3812 4.80071 52.3812 5.46071C52.3812 5.86928 52.1679 7.91214 51.6583 7.91214V7.91607Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n<path d=\"M62.7239 5.1268C61.9022 5.05608 60.7249 4.77322 60.0889 4.23894C60.0059 4.16822 59.8637 4.07001 59.8637 3.9443C59.8637 3.90108 59.8795 3.83037 59.9348 3.83037C60.0889 3.83037 61.0805 4.62001 61.9338 4.62001C63.0123 4.62001 64 3.78715 64 2.69108C64 0.887867 61.5941 0.157152 60.1324 0.157152C57.9635 0.157152 56.3516 1.5518 56.3516 3.76358C56.3516 4.24287 56.4227 4.90287 56.7783 5.27215C56.9482 5.4568 57.2326 5.4568 57.4578 5.4568C58.3072 5.4568 59.3857 5.72394 59.836 6.49787C59.8795 6.56858 59.919 6.68251 59.919 6.76501C59.919 6.79251 59.919 6.83572 59.8914 6.82001C59.8084 6.79251 59.7373 6.7218 59.678 6.6668C59.1802 6.18751 58.5007 5.70822 57.7817 5.70822C56.7032 5.70822 56.324 6.73751 56.324 7.63715C56.324 9.45215 57.9674 10.4539 59.6385 10.4539C61.6217 10.4539 64 9.15751 64 6.94572C64 6.12858 63.6444 5.21322 62.7239 5.13072V5.1268Z\" fill=\"#000020\" fill-opacity=\"0.1\"/>\n</svg>`;\n\nexport class PopCommentBar extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: MouseEvent) {\n if (!(event.target as HTMLElement).closest(ref(\"send\"))) return;\n void this.handleSend();\n }\n\n protected setupEffects() {\n let lastReplyingTo: string | null = null;\n let lastEditingCommentId: string | null = null;\n\n this.addEffect(() => {\n const parentCommentId = this.gridStore.replyingTo.value;\n\n if (parentCommentId && parentCommentId !== lastReplyingTo) {\n const input = this.getElement<PopCommentInput>(\"pop-comment-input\");\n if (input) {\n setTimeout(() => input.focus(), 0);\n }\n }\n lastReplyingTo = parentCommentId;\n });\n\n this.addEffect(() => {\n const editingComment = this.gridStore.editingComment.value;\n if (editingComment && editingComment.id !== lastEditingCommentId) {\n const input = this.getElement<PopCommentInput>(\"pop-comment-input\");\n if (input) {\n input.setValue(editingComment.body);\n setTimeout(() => input.focus(), 0);\n }\n } else if (!editingComment && lastEditingCommentId) {\n const input = this.getElement<PopCommentInput>(\"pop-comment-input\");\n if (input) {\n input.clear();\n }\n }\n lastEditingCommentId = editingComment?.id ?? null;\n });\n\n // The user's own avatar is pop-account-switcher (getTemplate below) —\n // it manages its own avatar content by consuming EmbedAuthStore\n // directly, so this effect only needs to handle the reply-context\n // avatar shown alongside it. Left as a static, always-present node\n // (rather than rebuilt via innerHTML like before) so the switcher's\n // dropdown/floating-ui state never gets torn down by an unrelated\n // reply/editing state change.\n this.addEffect(() => {\n const barUser = this.getElement<HTMLDivElement>(ref(\"user\"));\n const replyAvatar = this.getElement<HTMLElement>(ref(\"avatar-reply\"));\n if (!barUser || !replyAvatar) return;\n\n const editingComment = this.gridStore.editingComment.value;\n const parentAuthor = editingComment ? null : this.gridStore.replyingToComment.value?.author;\n\n barUser.classList.toggle(\"has-reply\", Boolean(parentAuthor));\n replyAvatar.classList.toggle(\"hidden\", !parentAuthor);\n\n if (parentAuthor) {\n const parentColorKey = parentAuthor.id ?? parentAuthor.name ?? \"\";\n replyAvatar.setAttribute(\"data-color-key\", parentColorKey);\n replyAvatar.innerHTML = parentAuthor.image\n ? `<img src=\"${parentAuthor.image}\" alt=\"${parentAuthor.name ?? \"User\"}'s avatar\">`\n : getInitials(parentAuthor.name);\n }\n });\n }\n\n private async handleSend(): Promise<void> {\n const input = this.getElement<PopCommentInput>(\"pop-comment-input\");\n if (!input) return;\n\n const body = input.getValue().trim();\n if (!body) return;\n\n const editingId = this.gridStore.editingCommentId.value;\n if (editingId) {\n input.clear();\n this.gridStore.editingCommentId.value = null;\n await this.gridStore.editComment(editingId, body);\n } else {\n input.clear();\n const comment = await this.gridStore.postComment(\n body,\n this.gridStore.replyingTo.value ?? undefined,\n );\n this.gridStore.replyingTo.value = null;\n\n if (comment) {\n this.gridStore.scrollingCommentId.value = comment.id;\n }\n }\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"logo-watermark\">${LOGO_WATERMARK_SVG}</div>\n <div class=\"bar\">\n <div class=\"bar__user\" data-ref=\"user\">\n <pop-comment-avatar\n size=\"xs\"\n class=\"bar__avatar bar__avatar--reply hidden\"\n data-ref=\"avatar-reply\"\n ></pop-comment-avatar>\n <pop-account-switcher class=\"bar__avatar bar__avatar--user\"></pop-account-switcher>\n </div>\n <div class=\"bar__input-wrap\">\n <pop-comment-input></pop-comment-input>\n </div>\n <pop-comment-icon\n class=\"bar__send\"\n data-ref=\"send\"\n theme=\"neutral\"\n variant=\"send\"\n aria-label=\"Send comment\"\n ></pop-comment-icon>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-bar\")) {\n customElements.define(\"pop-comment-bar\", PopCommentBar);\n}\n","import { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n /* Mode-level theme colors (defaults for light mode) */\n --pop-comment-color-black: #000000;\n --pop-comment-color-white: #ffffff;\n --pop-comment-color-default: #000000;\n --pop-comment-color-reversed: #ffffff;\n --pop-comment-bg-singular-resting: #121926;\n --pop-comment-bg-singular-hover: rgba(0, 0, 32, 0.08);\n --pop-comment-bg-reversed: #121926;\n --pop-comment-bg-blank-resting: #ffffff;\n\n display: flex;\n\n --pop-comment-icon-scale: 1;\n --pop-comment-icon-scale-hover: 1.1875;\n --pop-comment-icon-scale-active: 0.9375;\n --pop-comment-icon-size: 32px;\n --pop-comment-icon-color: var(--pop-foreground, #000000);\n --pop-comment-icon-color-hover: var(--pop-foreground, #000000);\n --pop-comment-icon-color-active: var(--pop-foreground, #000000);\n --pop-comment-icon-color-focused: var(--pop-foreground, #000000);\n --pop-comment-icon-background: var(\n --color-surface-buttons-singular-bg-launch-icon-hover,\n rgba(0, 0, 32, 0.08)\n );\n --pop-comment-icon-background-hover: var(\n --color-surface-buttons-singular-bg-launch-icon-hover,\n rgba(0, 0, 32, 0.08)\n );\n --pop-comment-icon-background-active: var(\n --color-surface-buttons-singular-bg-launch-icon-hover,\n rgba(0, 0, 32, 0.08)\n );\n --pop-comment-icon-background-focused: var(\n --color-surface-buttons-singular-bg-launch-icon-hover,\n rgba(0, 0, 32, 0.08)\n );\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n /* Overrides for dark mode */\n --pop-comment-color-black: #ffffff;\n --pop-comment-color-white: #000000;\n --pop-comment-color-default: #ffffff;\n --pop-comment-color-reversed: #000000;\n --pop-comment-bg-singular-resting: #ffffff;\n --pop-comment-bg-singular-hover: rgba(255, 255, 255, 0.15);\n --pop-comment-bg-reversed: #ffffff;\n --pop-comment-bg-blank-resting: #121926;\n }\n }\n\n :host(.dark) {\n /* Overrides for dark mode (.dark class on host) */\n --pop-comment-color-black: #ffffff;\n --pop-comment-color-white: #000000;\n --pop-comment-color-default: #ffffff;\n --pop-comment-color-reversed: #000000;\n --pop-comment-bg-singular-resting: #ffffff;\n --pop-comment-bg-singular-hover: rgba(255, 255, 255, 0.15);\n --pop-comment-bg-reversed: #ffffff;\n --pop-comment-bg-blank-resting: #121926;\n }\n\n .comment-icon {\n align-items: center;\n background: transparent;\n border: none;\n display: inline-flex;\n height: var(--pop-comment-icon-size);\n justify-content: center;\n padding: 0;\n position: relative;\n transform-origin: center;\n width: var(--pop-comment-icon-size);\n }\n\n .comment-icon--size-sm {\n --pop-comment-icon-size: 24px;\n }\n\n .comment-icon:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .comment-icon__focus-indicator {\n background-color: var(--pop-ring);\n display: none;\n position: absolute;\n inset: -3px;\n pointer-events: none;\n transform-origin: center;\n transform: scale(var(--pop-comment-icon-scale));\n transition: all 200ms ease-out;\n width: calc(100% + 6px);\n }\n\n .comment-icon:focus-visible .comment-icon__focus-indicator {\n display: flex;\n }\n\n .comment-icon:focus-visible {\n outline: none;\n }\n\n .comment-icon__inner {\n align-items: center;\n background: var(--pop-comment-icon-background);\n color: var(--pop-comment-icon-color);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n height: var(--pop-comment-icon-size);\n justify-content: center;\n position: absolute;\n transform-origin: center;\n transition: all 200ms ease-out;\n transform: scale(var(--pop-comment-icon-scale));\n width: var(--pop-comment-icon-size);\n }\n\n .comment-icon__icon-container {\n align-items: center;\n display: flex;\n height: 100%;\n justify-content: center;\n transition: transform ease-out 150ms;\n width: 100%;\n }\n\n .comment-icon__icon-container svg {\n width: calc(var(--pop-comment-icon-size) * 0.6875);\n height: calc(var(--pop-comment-icon-size) * 0.6875);\n }\n\n .comment-icon--variant-close.comment-icon--theme-neutral .comment-icon__icon-container svg {\n width: var(--pop-comment-icon-size);\n height: var(--pop-comment-icon-size);\n }\n\n .comment-icon__icon-image {\n display: flex;\n width: var(--pop-comment-icon-size);\n height: var(--pop-comment-icon-size);\n }\n\n .comment-icon__icon {\n display: flex;\n }\n\n .comment-icon__icon-image + .comment-icon__icon {\n display: none;\n }\n\n .comment-icon .comment-icon__inner {\n transition: transform var(--pop-ease-pop-hover) var(--pop-duration-pop-hover);\n }\n\n @media (hover: hover) and (pointer: fine) {\n .comment-icon:hover .comment-icon__inner {\n background: var(--pop-comment-icon-background-hover);\n color: var(--pop-comment-icon-color-hover);\n transform: scale(var(--pop-comment-icon-scale-hover));\n }\n\n .comment-icon:hover .comment-icon__icon-image {\n display: none;\n }\n\n .comment-icon:hover .comment-icon__icon-image + .comment-icon__icon {\n display: flex;\n }\n }\n\n .comment-icon:active .comment-icon__inner {\n background: var(--pop-comment-icon-background-active);\n color: var(--pop-comment-icon-color-active);\n transform: scale(var(--pop-comment-icon-scale-active));\n transition-duration: 200ms;\n }\n\n .comment-icon:is(:focus-visible) .comment-icon__inner {\n background: var(--pop-comment-icon-background-focused);\n color: var(--pop-comment-icon-color-focused);\n }\n\n /* Brand / Add */\n .comment-icon--theme-brand.comment-icon--variant-add {\n --pop-comment-icon-color: var(--pop-comment-color-black);\n --pop-comment-icon-color-hover: var(--pop-comment-color-black);\n --pop-comment-icon-color-active: var(--pop-comment-color-black);\n --pop-comment-icon-color-focused: var(--pop-comment-color-black);\n --pop-comment-icon-background: transparent;\n --pop-comment-icon-background-hover: var(--pop-comment-bg-singular-hover);\n --pop-comment-icon-background-active: var(--pop-comment-bg-singular-hover);\n --pop-comment-icon-background-focused: transparent;\n }\n\n /* Brand / Close */\n .comment-icon--theme-brand.comment-icon--variant-close {\n --pop-comment-icon-color: var(--pop-comment-color-white);\n --pop-comment-icon-color-hover: var(--pop-comment-color-white);\n --pop-comment-icon-color-active: var(--pop-comment-color-white);\n --pop-comment-icon-color-focused: var(--pop-comment-color-white);\n --pop-comment-icon-background: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-active: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-singular-resting);\n }\n\n /* Neutral / Add */\n .comment-icon--theme-neutral.comment-icon--variant-add {\n --pop-comment-icon-color: var(--pop-comment-color-white);\n --pop-comment-icon-color-hover: var(--pop-comment-color-white);\n --pop-comment-icon-color-active: var(--pop-comment-color-white);\n --pop-comment-icon-color-focused: var(--pop-comment-color-white);\n --pop-comment-icon-background: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-active: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-singular-resting);\n }\n\n /* Neutral / Close */\n .comment-icon--theme-neutral.comment-icon--variant-close {\n --pop-comment-icon-color: var(--pop-comment-color-white);\n --pop-comment-icon-color-hover: var(--pop-comment-color-white);\n --pop-comment-icon-color-active: var(--pop-comment-color-white);\n --pop-comment-icon-color-focused: var(--pop-comment-color-white);\n --pop-comment-icon-background: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-active: var(--pop-comment-bg-singular-resting);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-singular-resting);\n }\n\n /* Neutral / Send */\n .comment-icon--theme-neutral.comment-icon--variant-send {\n --pop-comment-icon-color: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-hover: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-active: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-focused: var(--pop-comment-color-reversed);\n --pop-comment-icon-background: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-active: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-reversed);\n }\n\n /* Neutral / More */\n .comment-icon--theme-neutral.comment-icon--variant-more {\n --pop-comment-icon-color: var(--pop-comment-color-default);\n --pop-comment-icon-color-hover: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-active: var(--pop-comment-color-default);\n --pop-comment-icon-color-focused: var(--pop-comment-color-default);\n --pop-comment-icon-background: var(--pop-comment-bg-blank-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-active: var(--pop-comment-bg-blank-resting);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-blank-resting);\n }\n\n /* Neutral / Cancel */\n .comment-icon--theme-neutral.comment-icon--variant-cancel {\n --pop-comment-icon-color: var(--pop-comment-color-default);\n --pop-comment-icon-color-hover: var(--pop-comment-color-default);\n --pop-comment-icon-color-active: var(--pop-comment-color-reversed);\n --pop-comment-icon-color-focused: var(--pop-comment-color-default);\n --pop-comment-icon-background: var(--pop-comment-bg-blank-resting);\n --pop-comment-icon-background-hover: var(--pop-comment-bg-blank-resting);\n --pop-comment-icon-background-active: var(--pop-comment-bg-reversed);\n --pop-comment-icon-background-focused: var(--pop-comment-bg-blank-resting);\n }\n`);\n\nexport class PopCommentIcon extends BaseElement {\n protected get styleSheets() {\n return [localSheet];\n }\n\n static get observedAttributes() {\n return [\"counter\", \"icon-url\", \"size\", \"theme\", \"variant\", \"type\", \"disabled\", \"aria-label\"];\n }\n\n onAriaLabelChanged() {\n this.render();\n }\n\n onCounterChanged() {\n this.render();\n }\n\n onIconUrlChanged() {\n this.render();\n }\n\n onSizeChanged() {\n this.render();\n }\n\n onThemeChanged() {\n this.render();\n }\n\n onVariantChanged() {\n this.render();\n }\n\n onTypeChanged() {\n this.render();\n }\n\n onDisabledChanged() {\n this.render();\n }\n\n get counter(): number {\n return Number(this.getAttribute(\"counter\") || \"0\");\n }\n\n set counter(value: number) {\n this.setAttribute(\"counter\", String(value));\n }\n\n get iconUrl(): string | undefined {\n return this.getAttribute(\"icon-url\") || undefined;\n }\n\n set iconUrl(value: string | undefined) {\n if (value === undefined) {\n this.removeAttribute(\"icon-url\");\n } else {\n this.setAttribute(\"icon-url\", value);\n }\n }\n\n get size(): string {\n return this.getAttribute(\"size\") || \"md\";\n }\n\n set size(value: string) {\n this.setAttribute(\"size\", value);\n }\n\n get theme(): \"brand\" | \"neutral\" {\n return (this.getAttribute(\"theme\") as \"brand\" | \"neutral\") || \"brand\";\n }\n\n set theme(value: \"brand\" | \"neutral\") {\n this.setAttribute(\"theme\", value);\n }\n\n get variant(): \"add\" | \"close\" | \"filter\" | \"more\" | \"send\" | \"cancel\" {\n return (this.getAttribute(\"variant\") as any) || \"add\";\n }\n\n set variant(value: \"add\" | \"close\" | \"filter\" | \"more\" | \"send\" | \"cancel\") {\n this.setAttribute(\"variant\", value);\n }\n\n get type(): \"button\" | \"submit\" | \"reset\" | \"menu\" {\n return (this.getAttribute(\"type\") as any) || \"button\";\n }\n\n set type(value: \"button\" | \"submit\" | \"reset\" | \"menu\") {\n this.setAttribute(\"type\", value);\n }\n\n get disabled(): boolean {\n return this.hasAttribute(\"disabled\");\n }\n\n set disabled(value: boolean) {\n if (value) {\n this.setAttribute(\"disabled\", \"\");\n } else {\n this.removeAttribute(\"disabled\");\n }\n }\n\n get ariaLabel(): string | null {\n return this.getAttribute(\"aria-label\");\n }\n\n set ariaLabel(value: string | null) {\n if (value === null) {\n this.removeAttribute(\"aria-label\");\n } else {\n this.setAttribute(\"aria-label\", value);\n }\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: Event) {\n if (this.disabled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return;\n }\n this.emit(\"pop-click\");\n }\n\n get icon(): string {\n let icon = \"\";\n\n if (this.theme === \"brand\") {\n if (this.variant === \"add\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11 4.58331V17.4166M4.58333 11H17.4167\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n } else if (this.variant === \"close\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M16.5 5.5L5.5 16.5M5.5 5.5L16.5 16.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n }\n } else if (this.theme === \"neutral\") {\n if (this.variant === \"add\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.0002 4.58301V17.4163M4.5835 10.9997H17.4168\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n } else if (this.variant === \"close\") {\n icon = `\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.4628 11.4627L20.5373 20.5373M11.4628 20.5373L20.5373 11.4627\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n } else if (this.variant === \"more\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12.8335 16.5L7.3335 11L12.8335 5.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n } else if (this.variant === \"send\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M18.0394 3.68048C18.2139 3.61601 18.3837 3.78583 18.3193 3.96036L12.3858 20.0241C12.314 20.2185 12.0369 20.2123 11.9739 20.0149L9.89172 13.4908C9.86908 13.4199 9.88424 13.3423 9.93191 13.2851L14.4838 7.82287C14.6536 7.61906 14.3807 7.34616 14.1769 7.516L8.71467 12.0678C8.65746 12.1155 8.57987 12.1307 8.50893 12.108L1.98489 10.0259C1.78743 9.96287 1.78121 9.68575 1.97565 9.61393L18.0394 3.68048Z\"\n fill=\"currentColor\"\n />\n </svg>\n `;\n } else if (this.variant === \"cancel\") {\n icon = `\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M16.5 5.5L5.5 16.5M5.5 5.5L16.5 16.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n `;\n }\n }\n return icon;\n }\n\n protected getTemplate(): string {\n const disabledAttr = this.disabled ? \"disabled\" : \"\";\n const classes = [\n \"comment-icon\",\n this.size ? `comment-icon--size-${this.size}` : \"\",\n this.theme ? `comment-icon--theme-${this.theme}` : \"\",\n this.variant ? `comment-icon--variant-${this.variant}` : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const iconHtml = this.iconUrl\n ? `<img src=\"${this.iconUrl}\" alt=\"\" class=\"comment-icon__icon-image\" />\n <slot class=\"comment-icon__icon\" name=\"icon\">${this.icon}</slot>`\n : `<slot class=\"comment-icon__icon\" name=\"icon\">${this.icon}</slot>`;\n\n const ariaLabelAttr = this.ariaLabel ? `aria-label=\"${this.ariaLabel}\"` : \"\";\n\n return /* html */ `\n <button\n class=\"${classes}\"\n part=\"base\"\n type=\"${this.type}\"\n ${disabledAttr}\n ${ariaLabelAttr}\n >\n <pop-focus-indicator\n class=\"comment-icon__focus-indicator mask mask-squircle\"\n ></pop-focus-indicator>\n <div class=\"comment-icon__inner mask mask-squircle\">\n <div class=\"comment-icon__icon-container\" part=\"icon\">${iconHtml}</div>\n </div>\n </button>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-icon\")) {\n customElements.define(\"pop-comment-icon\", PopCommentIcon);\n}\n","import { consume } from \"../store/registry.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: flex;\n flex: 1;\n min-width: 0;\n align-items: flex-end;\n }\n\n textarea {\n flex: 1;\n min-width: 0;\n background: none;\n border: none;\n outline: none;\n resize: none;\n font-family: Inter, sans-serif;\n font-size: 13px;\n color: black;\n line-height: 18px;\n padding: 5px 0;\n max-height: 200px;\n overflow-y: auto;\n width: 100%;\n letter-spacing: -0.08px;\n }\n\n textarea::placeholder {\n color: #697586;\n }\n`);\n\nexport class PopCommentInput extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n input: \"onInput\",\n keydown: \"onKeyDown\",\n };\n\n protected onInput(event: Event) {\n const textarea = event.target as HTMLTextAreaElement;\n textarea.style.height = \"auto\";\n textarea.style.height = `${textarea.scrollHeight}px`;\n }\n\n protected onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n if (this.gridStore.editingCommentId.value || this.gridStore.replyingTo.value) {\n event.stopPropagation();\n this.gridStore.editingCommentId.value = null;\n this.gridStore.replyingTo.value = null;\n }\n }\n }\n\n getValue(): string {\n return this.getElement<HTMLTextAreaElement>(\"textarea\")?.value ?? \"\";\n }\n\n setValue(val: string): void {\n const textarea = this.getElement<HTMLTextAreaElement>(\"textarea\");\n if (!textarea) return;\n\n textarea.value = val;\n textarea.style.height = \"auto\";\n textarea.style.height = `${textarea.scrollHeight}px`;\n }\n\n clear(): void {\n const textarea = this.getElement<HTMLTextAreaElement>(\"textarea\");\n if (!textarea) return;\n\n textarea.value = \"\";\n textarea.style.height = \"auto\";\n }\n\n focus(): void {\n this.getElement<HTMLTextAreaElement>(\"textarea\")?.focus();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const parent = this.gridStore.replyingToComment.value;\n const editing = this.gridStore.editingComment.value;\n\n let placeholder = \"Comment\";\n if (editing) {\n placeholder = \"Edit comment...\";\n } else if (parent?.author?.name) {\n placeholder = `Reply to ${parent.author.name}`;\n }\n\n this.setAttr(\"textarea\", \"placeholder\", placeholder);\n });\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <textarea rows=\"1\" placeholder=\"Comment\"></textarea>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-input\")) {\n customElements.define(\"pop-comment-input\", PopCommentInput);\n}\n","import { consume } from \"../store/registry.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n /* Width of a comment's avatar column: pop-comment's avatar plus its gap. */\n --pop-thread-avatar-column: 40px;\n\n --pop-thread-link: rgba(0, 0, 32, 0.5);\n --pop-thread-link-hover: rgba(0, 0, 32, 0.8);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-thread-link: rgba(255, 255, 255, 0.5);\n --pop-thread-link-hover: rgba(255, 255, 255, 0.8);\n }\n }\n\n :host(.dark) {\n --pop-thread-link: rgba(255, 255, 255, 0.5);\n --pop-thread-link-hover: rgba(255, 255, 255, 0.8);\n }\n\n .thread {\n align-items: stretch;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .thread__replies {\n align-items: center;\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding-left: 24px;\n }\n\n .thread__more {\n display: flex;\n align-items: center;\n font-size: 13px;\n gap: 6px;\n /* Starts the count's text where the replies' text starts: the 4px dot and 6px gap sit in the avatar column. */\n padding-left: calc(var(--pop-thread-avatar-column) - 10px);\n transition: opacity 0.15s ease;\n width: 100%;\n }\n\n :host([data-size=\"lg\"]) {\n --pop-thread-avatar-column: 68px;\n }\n\n .thread__more:hover {\n opacity: 1;\n }\n\n .thread__more-dot {\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--pop-muted-foreground);\n flex-shrink: 0;\n opacity: 0.1;\n }\n`);\n\nconst COLLAPSED_REPLY_LIMIT = 2;\n\nexport class PopCommentThread extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n\n private _showAll = false;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: MouseEvent) {\n if (!(event.target as HTMLElement).closest(ref(\"more\"))) return;\n this._showAll = true;\n this.render();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n this.setAttribute(\"data-size\", this.gridStore.commentSize.value);\n });\n\n this.addEffect(() => {\n const commentId = this.getAttribute(\"comment-id\");\n const targetId = this.gridStore.scrollingCommentId.value;\n if (commentId && targetId) {\n const replies = this.gridStore.repliesFor(commentId);\n if (replies.some((r) => r.id === targetId)) {\n this._showAll = true;\n }\n }\n\n this.gridStore.comments.value;\n this.render();\n });\n }\n\n protected getTemplate(): string {\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return \"\";\n\n const replies = this.gridStore.repliesFor(commentId);\n const visibleReplies =\n this._showAll || replies.length <= COLLAPSED_REPLY_LIMIT\n ? replies\n : replies.slice(0, COLLAPSED_REPLY_LIMIT);\n const hiddenCount = replies.length - visibleReplies.length;\n\n const moreHtml =\n hiddenCount > 0\n ? `<div class=\"thread__more\">\n <div class=\"thread__more-dot\"></div>\n <pop-button-link data-ref=\"more\" size=\"sm\" theme=\"default\">\n Show ${hiddenCount} more ${hiddenCount === 1 ? \"reply\" : \"replies\"}\n </pop-button-link>\n </div>`\n : \"\";\n\n const repliesHtml =\n replies.length > 0\n ? `<div class=\"thread__replies\">\n ${visibleReplies\n .map((reply) => `<pop-comment comment-id=\"${reply.id}\"></pop-comment>`)\n .join(\"\")}\n ${moreHtml}\n </div>`\n : \"\";\n\n return /* html */ `\n <div class=\"thread\">\n <pop-comment comment-id=\"${commentId}\"></pop-comment>\n ${repliesHtml}\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment-thread\")) {\n customElements.define(\"pop-comment-thread\", PopCommentThread);\n}\n","export function timeAgo(date: Date | string | number): string {\n const d = date instanceof Date ? date : new Date(date);\n const seconds = (Date.now() - d.getTime()) / 1000;\n\n if (seconds < 1) return \"now\";\n if (seconds < 60) return `${Math.floor(seconds)}s`;\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;\n if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;\n if (seconds < 604800) return `${Math.floor(seconds / 86400)}d`;\n return `${Math.floor(seconds / 604800)}w`;\n}\n","import { getInitials } from \"../helpers/author.js\";\nimport { timeAgo } from \"../helpers/time.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\nimport { computePosition, autoUpdate, flip, offset, shift } from \"@floating-ui/dom\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n width: 100%;\n --pop-comment-hover: rgba(0, 0, 32, 0.04);\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --pop-comment-hover: rgba(255, 255, 255, 0.04);\n }\n }\n\n .comment {\n display: flex;\n width: 100%;\n gap: 8px;\n align-items: center;\n background-color: transparent;\n border: none;\n padding: 0;\n border-radius: var(--pop-radius-md);\n outline: 6px solid transparent;\n text-align: left;\n transition:\n background-color 150ms ease,\n outline-color 150ms ease;\n }\n\n :host([data-size=\"sm\"]) .comment,\n :host:not([data-size]) .comment {\n --avatar-size: 32px;\n --width: 32px;\n gap: 8px;\n }\n\n :host([data-size=\"lg\"]) .comment {\n --avatar-size: 56px;\n --width: 56px;\n gap: 12px;\n }\n\n .comment--is-selected {\n background-color: var(--pop-muted);\n outline-color: var(--pop-muted);\n }\n\n :host(.is-signed-in) .comment {\n cursor: pointer;\n }\n\n @media (hover: hover) and (pointer: fine) {\n .comment:hover .comment__avatar {\n --avatar-translate-x: 2px;\n }\n\n .comment__avatar:hover {\n /* --avatar-scale: 1.06; */\n }\n\n .comment .comment__menu {\n display: none;\n }\n\n .comment:hover .comment__menu {\n display: flex;\n }\n }\n\n .comment--is-selected .comment__avatar {\n --avatar-translate-x: 2px;\n }\n\n .comment__avatar {\n --comment-avatar-border-size: 0;\n --avatar-translate-x: 0px;\n --avatar-scale: 1;\n width: var(--avatar-size);\n height: var(--avatar-size);\n transform: translateX(var(--avatar-translate-x)) scale(var(--avatar-scale));\n transition: transform var(--pop-duration-quick) var(--pop-ease-quick);\n }\n\n .comment__user {\n display: flex;\n width: var(--width);\n align-items: flex-start;\n gap: 10px;\n flex-shrink: 0;\n align-self: stretch;\n }\n\n .comment__content {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n flex: 1 0 0;\n align-self: stretch;\n }\n\n .comment__info {\n display: flex;\n align-items: flex-start;\n align-self: stretch;\n }\n\n .comment__menu {\n display: flex;\n justify-self: flex-end;\n }\n\n .comment__menu-trigger {\n background: none;\n border: none;\n cursor: pointer;\n border-radius: 9999px;\n aspect-ratio: 1;\n position: relative;\n }\n\n .comment__menu-trigger:before {\n content: \"\";\n height: 40px;\n left: 50%;\n position: absolute;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 40px;\n }\n\n .comment__user-meta {\n display: flex;\n align-items: flex-start;\n gap: 4px;\n flex-shrink: 0;\n align-self: stretch;\n flex-grow: 1;\n }\n\n .comment__user-name {\n color: var(--pop-foreground);\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-family: Inter, sans-serif;\n font-size: var(--text-widget-base, 13px);\n font-style: normal;\n font-weight: 500;\n line-height: var(--text-widget-base--line-height, 18px);\n letter-spacing: -0.08px;\n }\n\n .comment__timestamp {\n color: var(--pop-muted-foreground);\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-family: Inter, sans-serif;\n font-size: var(--text-widget-base, 13px);\n font-style: normal;\n font-weight: 400;\n line-height: var(--text-widget-base--line-height, 18px);\n letter-spacing: -0.08px;\n opacity: 0.5;\n }\n\n .comment__text {\n align-self: stretch;\n color: var(--pop-foreground);\n font-feature-settings:\n \"liga\" off,\n \"clig\" off;\n font-family: Inter, sans-serif;\n font-size: 13px;\n font-style: normal;\n font-weight: 400;\n line-height: 18px;\n letter-spacing: -0.08px;\n text-align: left;\n\n /* Clamping when not expanded */\n display: -webkit-box;\n -webkit-line-clamp: 4;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .comment__text.expanded,\n .comment--is-selected .comment__text {\n -webkit-line-clamp: initial;\n display: block;\n }\n\n .comment__mention {\n color: #155eef;\n font-weight: 500;\n }\n\n .comment__menu {\n position: relative;\n }\n\n .comment__dropdown {\n background-color: var(--pop-background);\n border-radius: 6px;\n box-shadow: var(--pop-shadow-xl);\n display: none;\n flex-direction: column;\n gap: 6px;\n padding: 6px;\n pointer-events: auto;\n position: fixed;\n width: 120px;\n z-index: 1000;\n }\n\n .comment__dropdown.is-open {\n display: flex;\n }\n\n .comment__dropdown-item {\n align-items: center;\n background: none;\n border-radius: 4px;\n border: none;\n color: var(--pop-foreground);\n cursor: pointer;\n display: flex;\n flex: 1 0 0;\n font-family: Inter, sans-serif;\n font-size: 14px;\n font-weight: 500;\n justify-content: center;\n min-height: 40px;\n padding: 0 12px;\n text-align: left;\n transition: background-color 100ms ease;\n width: 100%;\n }\n\n .comment__dropdown-item:hover {\n background-color: var(--pop-comment-hover, rgba(0, 0, 0, 0.04));\n }\n\n .comment__dropdown-item--danger {\n color: #ef4444;\n }\n\n .comment__edit-form {\n display: flex;\n flex-direction: column;\n width: 100%;\n gap: 8px;\n margin-top: 4px;\n }\n\n .comment__edit-input {\n width: 100%;\n background: var(--pop-background, #ffffff);\n color: var(--pop-foreground, #000000);\n border: 1px solid var(--pop-border, #e4e4e7);\n border-radius: var(--pop-radius-sm, 4px);\n padding: 6px 8px;\n font-family: Inter, sans-serif;\n font-size: 13px;\n line-height: 18px;\n resize: vertical;\n outline: none;\n }\n\n .comment__edit-input:focus {\n border-color: var(--pop-ring, #000020);\n }\n\n .comment__edit-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n .comment__edit-save,\n .comment__edit-cancel {\n font-size: 12px;\n padding: 4px 8px;\n cursor: pointer;\n }\n\n .comment--deleted .comment__text {\n color: var(--pop-muted-foreground, #697586);\n font-style: italic;\n opacity: 0.8;\n }\n`);\n\nexport class PopComment extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n static get observedAttributes() {\n return [\"data-size\", \"comment-id\"];\n }\n\n onDataSizeChanged() {\n this.render();\n }\n\n onCommentIdChanged() {\n this.render();\n }\n\n get size(): \"sm\" | \"lg\" {\n return (this.getAttribute(\"data-size\") as \"sm\" | \"lg\") || \"sm\";\n }\n\n get commentAvatarSize(): \"xs\" | \"sm\" {\n return this.size === \"sm\" ? \"xs\" : \"sm\";\n }\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n private _expanded = false;\n private _dropdownOpen = false;\n private _floatingCleanup?: () => void;\n\n private _onOutsideClick = (event: MouseEvent) => {\n const path = event.composedPath();\n const dropdown = this.getElement(ref(\"dropdown\"));\n const trigger = this.getElement(ref(\"menu-trigger\"));\n\n if (dropdown && trigger && !path.includes(dropdown) && !path.includes(trigger)) {\n this.closeDropdown();\n }\n };\n\n private toggleDropdown() {\n if (this._dropdownOpen) {\n this.closeDropdown();\n } else {\n this.openDropdown();\n }\n }\n\n private openDropdown() {\n this._dropdownOpen = true;\n const dropdown = this.getElement<HTMLElement>(ref(\"dropdown\"));\n const trigger = this.getElement<HTMLElement>(ref(\"menu-trigger\"));\n\n if (dropdown && trigger) {\n dropdown.classList.add(\"is-open\");\n\n const update = () => {\n computePosition(trigger, dropdown, {\n placement: \"bottom-end\",\n middleware: [offset(4), flip(), shift({ padding: 8 })],\n strategy: \"fixed\",\n }).then(({ x, y }) => {\n Object.assign(dropdown.style, {\n left: `${x}px`,\n top: `${y}px`,\n position: \"fixed\",\n });\n });\n };\n\n this._floatingCleanup = autoUpdate(trigger, dropdown, update);\n document.addEventListener(\"mousedown\", this._onOutsideClick);\n }\n }\n\n private closeDropdown() {\n this._dropdownOpen = false;\n const dropdown = this.getElement(ref(\"dropdown\"));\n if (dropdown) {\n dropdown.classList.remove(\"is-open\");\n }\n if (this._floatingCleanup) {\n this._floatingCleanup();\n this._floatingCleanup = undefined;\n }\n document.removeEventListener(\"mousedown\", this._onOutsideClick);\n }\n\n private async deleteComment() {\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return;\n\n if (confirm(\"Are you sure you want to delete this comment?\")) {\n await this.gridStore.deleteComment(commentId);\n }\n }\n\n private async flagComment() {\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return;\n\n const success = await this.gridStore.flagComment(commentId);\n if (success) {\n alert(\"Comment flagged successfully.\");\n } else {\n alert(\"Failed to flag comment.\");\n }\n }\n\n protected onClick(event: Event) {\n const target = event.target as HTMLElement;\n\n // Handle menu trigger click\n if (target.closest(ref(\"menu-trigger\"))) {\n event.stopPropagation();\n this.toggleDropdown();\n return;\n }\n\n // Handle dropdown item click\n const dropdownItem = target.closest(ref(\"dropdown-item\")) as HTMLElement;\n if (dropdownItem) {\n event.stopPropagation();\n const action = dropdownItem.getAttribute(\"data-action\");\n const commentId = this.getAttribute(\"comment-id\");\n if (action === \"edit\" && commentId) {\n this.gridStore.replyingTo.value = null;\n this.gridStore.editingCommentId.value = commentId;\n } else if (action === \"delete\") {\n this.deleteComment();\n } else if (action === \"flag\") {\n this.flagComment();\n }\n this.closeDropdown();\n return;\n }\n\n // Don't trigger reply if clicking inside the dropdown\n if (target.closest(ref(\"dropdown\"))) {\n event.stopPropagation();\n return;\n }\n\n // Default reply action\n if (!this.authStore.currentUser.value) return;\n\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return;\n\n const comment = this.gridStore.comments.value.find((c) => c.id === commentId);\n if (comment?.status === \"deleted\") return;\n\n if (this.gridStore.replyingTo.value === commentId) {\n this.gridStore.replyingTo.value = null;\n } else {\n this.gridStore.replyingTo.value = commentId;\n }\n\n this.expandText();\n }\n\n private expandText() {\n const textEl = this.getElement<HTMLElement>(ref(\"text\"));\n if (!this._expanded && textEl) {\n const startHeight = textEl.offsetHeight;\n this._expanded = true;\n this.render();\n\n const newTextEl = this.getElement<HTMLElement>(ref(\"text\"));\n if (newTextEl) {\n const endHeight = newTextEl.scrollHeight;\n\n newTextEl.style.height = `${startHeight}px`;\n newTextEl.style.overflow = \"hidden\";\n\n // Force a reflow\n void newTextEl.offsetHeight;\n\n newTextEl.style.transition = \"height var(--pop-duration-quick) var(--pop-ease-quick)\";\n newTextEl.style.height = `${endHeight}px`;\n\n setTimeout(() => {\n newTextEl.style.height = \"\";\n newTextEl.style.overflow = \"\";\n }, 300);\n }\n }\n }\n\n private _timeUpdateTimer: ReturnType<typeof setTimeout> | null = null;\n\n disconnectedCallback() {\n this.closeDropdown();\n this.stopTimeUpdates();\n super.disconnectedCallback();\n }\n\n private startTimeUpdates() {\n this.stopTimeUpdates();\n\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return;\n\n const comment = this.gridStore.comments.value.find((c) => c.id === commentId);\n if (!comment) return;\n\n const update = () => {\n const timeSpan = this.getElement<HTMLSpanElement>(ref(\"timestamp\"));\n if (timeSpan) {\n timeSpan.textContent = timeAgo(comment.createdAt);\n }\n\n const ageMs =\n Date.now() -\n (typeof comment.createdAt === \"number\"\n ? comment.createdAt\n : Date.parse(String(comment.createdAt)));\n let delay = 60000;\n\n if (ageMs < 60000) {\n delay = 5000;\n } else if (ageMs < 3600000) {\n delay = 60000;\n } else {\n delay = 1800000;\n }\n\n this._timeUpdateTimer = setTimeout(update, delay);\n };\n\n const ageMs =\n Date.now() -\n (typeof comment.createdAt === \"number\"\n ? comment.createdAt\n : Date.parse(String(comment.createdAt)));\n const initialDelay = ageMs < 60000 ? 5000 : 60000;\n this._timeUpdateTimer = setTimeout(update, initialDelay);\n }\n\n private stopTimeUpdates() {\n if (this._timeUpdateTimer) {\n clearTimeout(this._timeUpdateTimer);\n this._timeUpdateTimer = null;\n }\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n this.setAttribute(\"data-size\", this.gridStore.commentSize.value);\n });\n\n this.addEffect(() => {\n const commentId = this.getAttribute(\"comment-id\");\n const user = this.authStore.currentUser.value;\n const replyingToId = this.gridStore.replyingTo.value;\n const editingId = this.gridStore.editingCommentId.value;\n const targetId = this.gridStore.scrollingCommentId.value;\n\n this.classList.toggle(\"is-signed-in\", user !== null);\n this.classList.toggle(\"is-replying\", commentId !== null && replyingToId === commentId);\n this.classList.toggle(\"is-editing\", commentId !== null && editingId === commentId);\n\n this.gridStore.comments.value;\n this.render();\n this.startTimeUpdates();\n\n if (commentId && targetId === commentId) {\n setTimeout(() => {\n const innerComment = this.shadowRoot?.querySelector(`#comment-${commentId}`);\n if (innerComment) {\n innerComment.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n } else {\n this.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n this.gridStore.scrollingCommentId.value = null;\n }, 50);\n }\n });\n }\n\n protected getTemplate(): string {\n const commentId = this.getAttribute(\"comment-id\");\n if (!commentId) return \"\";\n\n const comment = this.gridStore.comments.value.find((c) => c.id === commentId);\n if (!comment) return \"\";\n\n const isDeleted = comment.status === \"deleted\";\n const isAuthorDeleted = comment.authorDeleted === true;\n const showDeletedAvatar = isDeleted || isAuthorDeleted;\n\n const avatarContent = showDeletedAvatar\n ? \"\"\n : comment.author?.image\n ? `<img src=\"${comment.author.image}\" alt=\"${comment.author.name ?? \"User avatar\"}\" />`\n : getInitials(comment.author?.name);\n\n const replyingToId = this.gridStore.replyingTo.value;\n const isReplying = commentId !== null && replyingToId === commentId;\n const size = this.size;\n\n // Determine if signed-in user is the author\n const user = this.authStore.currentUser.value;\n const isAuthor = user && comment.author && user.id === comment.author.id;\n\n // Dropdown HTML (only if signed in and comment is not deleted)\n const menuHtml =\n user && !isDeleted\n ? `<div class=\"comment__menu\">\n <button class=\"comment__menu-trigger\" data-ref=\"menu-trigger\" type=\"button\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M9 9.5C9.27614 9.5 9.5 9.27614 9.5 9C9.5 8.72386 9.27614 8.5 9 8.5C8.72386 8.5 8.5 8.72386 8.5 9C8.5 9.27614 8.72386 9.5 9 9.5Z\"\n fill=\"white\"\n />\n <path\n d=\"M12.5 9.5C12.7761 9.5 13 9.27614 13 9C13 8.72386 12.7761 8.5 12.5 8.5C12.2239 8.5 12 8.72386 12 9C12 9.27614 12.2239 9.5 12.5 9.5Z\"\n fill=\"white\"\n />\n <path\n d=\"M5.5 9.5C5.77614 9.5 6 9.27614 6 9C6 8.72386 5.77614 8.5 5.5 8.5C5.22386 8.5 5 8.72386 5 9C5 9.27614 5.22386 9.5 5.5 9.5Z\"\n fill=\"white\"\n />\n <path\n d=\"M9 9.5C9.27614 9.5 9.5 9.27614 9.5 9C9.5 8.72386 9.27614 8.5 9 8.5C8.72386 8.5 8.5 8.72386 8.5 9C8.5 9.27614 8.72386 9.5 9 9.5Z\"\n stroke=\"#000020\"\n stroke-opacity=\"0.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M12.5 9.5C12.7761 9.5 13 9.27614 13 9C13 8.72386 12.7761 8.5 12.5 8.5C12.2239 8.5 12 8.72386 12 9C12 9.27614 12.2239 9.5 12.5 9.5Z\"\n stroke=\"#000020\"\n stroke-opacity=\"0.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M5.5 9.5C5.77614 9.5 6 9.27614 6 9C6 8.72386 5.77614 8.5 5.5 8.5C5.22386 8.5 5 8.72386 5 9C5 9.27614 5.22386 9.5 5.5 9.5Z\"\n stroke=\"#000020\"\n stroke-opacity=\"0.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <div class=\"comment__dropdown\" data-ref=\"dropdown\">\n ${\n isAuthor\n ? `<button class=\"comment__dropdown-item\" data-ref=\"dropdown-item\" type=\"button\" data-action=\"edit\">Edit</button>\n <button class=\"comment__dropdown-item comment__dropdown-item--danger\" data-ref=\"dropdown-item\" type=\"button\" data-action=\"delete\">Delete</button>`\n : \"\"\n }\n <button class=\"comment__dropdown-item\" data-ref=\"dropdown-item\" type=\"button\" data-action=\"flag\">Flag</button>\n </div>\n </div>`\n : \"\";\n\n return /* html */ `\n <div\n class=\"comment comment--size-${size}${isReplying ? \" comment--is-selected\" : \"\"}${isDeleted\n ? \" comment--deleted\"\n : \"\"}\"\n id=\"comment-${commentId}\"\n >\n <div class=\"comment__user\">\n <pop-comment-avatar\n class=\"comment__avatar\"\n size=\"${this.commentAvatarSize}\"\n data-color-key=\"${comment.author?.id ?? comment.author?.name ?? \"\"}\"\n ${showDeletedAvatar ? \"deleted\" : \"\"}\n >\n ${avatarContent}\n </pop-comment-avatar>\n </div>\n <div class=\"comment__content\">\n <div class=\"comment__info\">\n <div class=\"comment__user-meta\">\n <div class=\"comment__user-name\">\n ${isDeleted ? \"[Deleted]\" : isAuthorDeleted ? \"[Deleted user]\" : (comment.author?.name ?? \"\")}\n </div>\n <div class=\"comment__timestamp\" data-ref=\"timestamp\">${timeAgo(comment.createdAt)}</div>\n </div>\n ${menuHtml}\n </div>\n <div class=\"comment__text${this._expanded ? \" expanded\" : \"\"}\" data-ref=\"text\">${comment.body}</div>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-comment\")) {\n customElements.define(\"pop-comment\", PopComment);\n}\n","import { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: flex;\n background: var(--pop-background);\n border-radius: var(--pop-radius-2xl);\n /* border: 1px solid var(--pop-background); */\n box-shadow: var(--pop-shadow-3xl);\n display: block;\n left: 0;\n max-height: 340px;\n max-width: 400px;\n min-width: 343px;\n opacity: 0;\n overflow: hidden;\n padding: 0;\n pointer-events: none;\n position: fixed;\n top: 0;\n width: 100%;\n z-index: 9999;\n transform: scale(0.94);\n transition:\n opacity var(--pop-duration-quick) var(--pop-ease-quick),\n transform var(--pop-duration-quick) var(--pop-ease-quick),\n display var(--pop-duration-quick) allow-discrete;\n }\n\n :host([data-current-placement=\"top-start\"]) {\n transform-origin: left bottom;\n }\n\n :host([data-current-placement=\"bottom-start\"]) {\n transform-origin: left top;\n }\n\n :host([data-current-placement=\"top-end\"]) {\n transform-origin: right bottom;\n }\n\n :host([data-current-placement=\"bottom-end\"]) {\n transform-origin: right top;\n }\n\n :host([data-current-placement=\"top\"]) {\n transform-origin: bottom;\n }\n\n :host([data-current-placement=\"bottom\"]) {\n transform-origin: top;\n }\n\n :host([open]) {\n opacity: 1;\n pointer-events: auto;\n transform: scale(1);\n\n @starting-style {\n display: flex;\n opacity: 0;\n transform: scale(0.94);\n }\n }\n\n /* .feed__content and .feed__footer are stacked in the same grid cell\n (see grid-area below) rather than laid out as flex siblings, so the\n footer can grow taller (email/code/no-code states) and overlay the\n comment list instead of pushing it — the grid row auto-sizes to\n whichever of the two is taller, which a manual absolute-position +\n fixed-height-reservation approach can't do without clipping against\n :host's overflow:hidden when the footer is the tall one. */\n .feed {\n display: grid;\n grid-template-columns: 1fr;\n grid-template-rows: 1fr;\n /* height (not just max-height) gives the grid row a definite size to\n shrink to — otherwise an auto-height grid container sizes its 1fr\n row to content's max-content height regardless of max-height,\n clipping instead of scrolling. */\n height: fit-content(340px);\n max-height: 340px;\n }\n\n .feed__content {\n align-items: flex-start;\n /* stretch (not start) so .feed__main inherits a bounded height to\n scroll within, instead of growing to fit all comments. */\n align-self: stretch;\n display: flex;\n gap: 8px;\n grid-area: 1 / 1;\n min-height: 0;\n width: 100%;\n }\n\n .feed__empty {\n padding: 24px 16px 24px 8px;\n text-align: center;\n font-family: Inter, sans-serif;\n font-size: 13px;\n color: var(--pop-muted-foreground);\n line-height: 18px;\n }\n\n .feed__footer {\n align-self: end;\n grid-area: 1 / 1;\n width: 100%;\n z-index: 1;\n }\n\n /* Full-widget scrim for auth errors (e.g. \"You were signed out\"). Sits in\n the same grid cell as the content and footer, above both, so the message\n never takes layout space from the join bar. Click to dismiss. */\n .feed__notice {\n align-items: center;\n background: color-mix(in srgb, var(--pop-background) 80%, transparent);\n color: var(--pop-foreground);\n cursor: pointer;\n display: flex;\n font-family: Inter, sans-serif;\n font-size: 13px;\n grid-area: 1 / 1;\n justify-content: center;\n line-height: 18px;\n padding: 24px;\n text-align: center;\n z-index: 2;\n }\n\n .feed__notice-box {\n align-items: center;\n background: var(--pop-background);\n border: 1px solid var(--pop-border);\n border-radius: var(--pop-radius-sm);\n cursor: default;\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n }\n\n .feed__notice-box:focus {\n outline: none;\n }\n\n .feed__notice[hidden] {\n display: none;\n }\n\n .feed__notice-dismiss {\n background: var(--pop-foreground);\n border: none;\n border-radius: var(--pop-radius-xs);\n color: var(--pop-background);\n cursor: pointer;\n font: inherit;\n font-weight: 600;\n padding: 6px 12px;\n }\n\n .feed__notice-dismiss:focus-visible {\n outline: 2px solid var(--pop-ring);\n outline-offset: 2px;\n }\n\n .feed__main {\n align-items: stretch;\n align-self: stretch;\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n gap: 16px;\n min-height: 0;\n overflow: hidden auto;\n /* Bottom padding reserves space for the idle \"Join the Conversation\"\n bar (~50px) so comments end above it, same as before this became an\n overlay — a taller auth-panel state then naturally covers more. */\n padding: 8px 10px 58px 8px;\n }\n\n .feed__main::-webkit-scrollbar {\n width: 4px;\n }\n\n .feed__main::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .feed__main::-webkit-scrollbar-thumb {\n background: var(--pop-border);\n border-radius: 100px;\n }\n`);\n\nexport class PopFeed extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n @consume(EmbedAuthStore) authStore!: EmbedAuthStore;\n\n private _footerChild: string | null = null;\n private _wasOpen = false;\n private _noticeTimer: number | undefined;\n private _noticeRetryAt: number | null = null;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick(event: MouseEvent) {\n if (!(event.target as HTMLElement).closest(ref(\"notice\"))) return;\n // A rate-limit wait dismisses itself when the countdown ends.\n if (this.authStore.authErrorRetryAt.value !== null) return;\n this.authStore.dismissAuthError();\n }\n\n connectedCallback() {\n super.connectedCallback();\n document.addEventListener(\"mousedown\", this);\n document.addEventListener(\"keydown\", this);\n }\n\n disconnectedCallback() {\n document.removeEventListener(\"mousedown\", this);\n document.removeEventListener(\"keydown\", this);\n window.clearInterval(this._noticeTimer);\n super.disconnectedCallback();\n }\n\n handleEvent(event: Event): void {\n if (event.type === \"mousedown\") {\n this.onOutsideClick(event as MouseEvent);\n return;\n }\n\n if (event.type === \"keydown\") {\n this.onKeyDown(event as KeyboardEvent);\n return;\n }\n\n super.handleEvent(event);\n }\n\n private onOutsideClick(event: MouseEvent) {\n if (!this.gridStore.open.value) return;\n\n const path = event.composedPath();\n const root = this.getRootNode();\n const host = root instanceof ShadowRoot ? root.host : null;\n if (!path.includes(this) && (!host || !path.includes(host))) {\n if (this.authStore.authView.value !== \"idle\") {\n this.authStore.backToIdle();\n return;\n }\n this.gridStore.open.value = false;\n }\n }\n\n private onKeyDown(event: KeyboardEvent) {\n if (event.key !== \"Escape\") return;\n\n if (this.authStore.authError.value) {\n this.authStore.clearAuthError();\n return;\n }\n\n if (this.authStore.authView.value !== \"idle\") {\n this.authStore.backToIdle();\n return;\n }\n this.gridStore.open.value = false;\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const open = this.gridStore.open.value;\n\n if (open && !this._wasOpen && this.gridStore.grid.value) {\n // First real moment the widget needs to know anything about auth\n // beyond what's cached locally — the collapsed pill never shows the\n // current visitor's own identity, only other commenters. See\n // EmbedAuthStore.connectAuthChannel's own comment.\n void this.authStore.connectAuthChannel();\n }\n\n // A notice is only meant to be seen once: don't let it linger and\n // reappear the next time the panel opens.\n if (!open && this._wasOpen) {\n this.authStore.clearAuthError();\n }\n\n this._wasOpen = open;\n this.update();\n });\n }\n\n /**\n * For a rate-limit notice, swaps the dismiss button for a plain countdown\n * (there's nothing for the visitor to do but wait) and dismisses the notice\n * when it reaches zero. Keyed on the target time so the unrelated\n * re-renders that call update() don't restart the timer.\n */\n private syncNoticeCountdown(retryAt: number | null): void {\n if (retryAt === this._noticeRetryAt) return;\n this._noticeRetryAt = retryAt;\n window.clearInterval(this._noticeTimer);\n\n const dismiss = this.getElement<HTMLButtonElement>(ref(\"notice-dismiss\"));\n if (dismiss) dismiss.hidden = retryAt !== null;\n const countdown = this.getElement<HTMLElement>(ref(\"notice-countdown\"));\n if (countdown) countdown.hidden = retryAt === null;\n if (!countdown || retryAt === null) return;\n\n const render = (): boolean => {\n const remaining = Math.max(0, Math.ceil((retryAt - Date.now()) / 1000));\n const minutes = Math.floor(remaining / 60);\n countdown.textContent = `Try again in ${minutes}:${String(remaining % 60).padStart(2, \"0\")}`;\n return remaining === 0;\n };\n\n render();\n this._noticeTimer = window.setInterval(() => {\n if (!render()) return;\n window.clearInterval(this._noticeTimer);\n this.authStore.dismissAuthError();\n }, 1000);\n }\n\n private update(): void {\n if (this.gridStore.open.value) {\n this.setAttribute(\"open\", \"\");\n } else {\n this.removeAttribute(\"open\");\n }\n\n const content = this.getElement<HTMLDivElement>(ref(\"main\"));\n if (content) {\n const threads = this.gridStore.topLevelComments.value;\n\n if (threads.length === 0) {\n const isEmpty = content.querySelector(ref(\"empty\"));\n if (!isEmpty) {\n content.innerHTML = `<div class=\"feed__empty\" data-ref=\"empty\">Waiting for your thoughts…</div>`;\n }\n } else {\n const existingIds = Array.from(content.querySelectorAll(\"pop-comment-thread\")).map((el) =>\n el.getAttribute(\"comment-id\"),\n );\n\n const newIds = threads.map((c) => c.id);\n const needsRebuild =\n existingIds.length !== newIds.length || existingIds.some((id, i) => id !== newIds[i]);\n\n if (needsRebuild) {\n content.innerHTML = threads\n .map(\n (comment) => `<pop-comment-thread comment-id=\"${comment.id}\"></pop-comment-thread>`,\n )\n .join(\"\");\n }\n }\n }\n\n const error = this.authStore.authError.value;\n const notice = this.getElement<HTMLDivElement>(ref(\"notice\"));\n if (notice) {\n const wasHidden = notice.hidden;\n notice.hidden = !error;\n this.setText(ref(\"notice-message\"), error ?? \"\");\n const retryAt = error ? this.authStore.authErrorRetryAt.value : null;\n if (error) this.setText(ref(\"notice-dismiss\"), this.authStore.authErrorAction.value);\n this.syncNoticeCountdown(retryAt);\n // Keep keyboard/AT focus out of what the scrim visually covers.\n this.getElement(ref(\"content\"))?.toggleAttribute(\"inert\", Boolean(error));\n // Demo mode shows the sign-in footer but can't sign anyone in.\n this.getElement(ref(\"footer\"))?.toggleAttribute(\n \"inert\",\n Boolean(error) || this.gridStore.demo,\n );\n if (error && wasHidden && this.gridStore.open.value) {\n // A countdown has no control to focus, so focus the box itself.\n this.getElement<HTMLElement>(\n ref(retryAt === null ? \"notice-dismiss\" : \"notice-box\"),\n )?.focus();\n }\n }\n\n const footer = this.getElement<HTMLDivElement>(ref(\"footer\"));\n\n if (footer) {\n const authed = this.authStore.currentUser.value !== null;\n const desired = authed ? \"pop-comment-bar\" : \"pop-auth-panel\";\n if (this._footerChild !== desired) {\n this._footerChild = desired;\n footer.innerHTML = `<${desired}></${desired}>`;\n }\n }\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"feed\">\n <div class=\"feed__content\" data-ref=\"content\">\n <div class=\"feed__main\" data-ref=\"main\"></div>\n </div>\n <div class=\"feed__footer\" data-ref=\"footer\"></div>\n <div class=\"feed__notice\" data-ref=\"notice\" role=\"alert\" hidden>\n <div class=\"feed__notice-box\" data-ref=\"notice-box\" tabindex=\"-1\">\n <span data-ref=\"notice-message\"></span>\n <span data-ref=\"notice-countdown\" role=\"timer\" hidden></span>\n <button class=\"feed__notice-dismiss\" data-ref=\"notice-dismiss\" type=\"button\">\n Dismiss\n </button>\n </div>\n </div>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-feed\")) {\n customElements.define(\"pop-feed\", PopFeed);\n}\n","function hasWindow() {\n return typeof window !== 'undefined';\n}\nfunction getNodeName(node) {\n if (isNode(node)) {\n return (node.nodeName || '').toLowerCase();\n }\n // Mocked nodes in testing environments may not be instances of Node. By\n // returning `#document` an infinite loop won't occur.\n // https://github.com/floating-ui/floating-ui/issues/2317\n return '#document';\n}\nfunction getWindow(node) {\n var _node$ownerDocument;\n return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;\n}\nfunction getDocumentElement(node) {\n var _ref;\n return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;\n}\nfunction isNode(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof Node || value instanceof getWindow(value).Node;\n}\nfunction isElement(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof Element || value instanceof getWindow(value).Element;\n}\nfunction isHTMLElement(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;\n}\nfunction isShadowRoot(value) {\n if (!hasWindow() || typeof ShadowRoot === 'undefined') {\n return false;\n }\n return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;\n}\nfunction isOverflowElement(element) {\n const {\n overflow,\n overflowX,\n overflowY,\n display\n } = getComputedStyle(element);\n return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';\n}\nfunction isTableElement(element) {\n return /^(table|td|th)$/.test(getNodeName(element));\n}\nfunction isTopLayer(element) {\n try {\n if (element.matches(':popover-open')) {\n return true;\n }\n } catch (_e) {\n // no-op\n }\n try {\n return element.matches(':modal');\n } catch (_e) {\n return false;\n }\n}\nconst willChangeRe = /transform|translate|scale|rotate|perspective|filter/;\nconst containRe = /paint|layout|strict|content/;\nconst isNotNone = value => !!value && value !== 'none';\nlet isWebKitValue;\nfunction isContainingBlock(elementOrCss) {\n const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n // https://drafts.csswg.org/css-transforms-2/#individual-transforms\n return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');\n}\nfunction getContainingBlock(element) {\n let currentNode = getParentNode(element);\n while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {\n if (isContainingBlock(currentNode)) {\n return currentNode;\n } else if (isTopLayer(currentNode)) {\n return null;\n }\n currentNode = getParentNode(currentNode);\n }\n return null;\n}\nfunction isWebKit() {\n if (isWebKitValue == null) {\n isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');\n }\n return isWebKitValue;\n}\nfunction isLastTraversableNode(node) {\n return /^(html|body|#document)$/.test(getNodeName(node));\n}\nfunction getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}\nfunction getNodeScroll(element) {\n if (isElement(element)) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n }\n return {\n scrollLeft: element.scrollX,\n scrollTop: element.scrollY\n };\n}\nfunction getParentNode(node) {\n if (getNodeName(node) === 'html') {\n return node;\n }\n const result =\n // Step into the shadow DOM of the parent of a slotted node.\n node.assignedSlot ||\n // DOM Element detected.\n node.parentNode ||\n // ShadowRoot detected.\n isShadowRoot(node) && node.host ||\n // Fallback.\n getDocumentElement(node);\n return isShadowRoot(result) ? result.host : result;\n}\nfunction getNearestOverflowAncestor(node) {\n const parentNode = getParentNode(node);\n if (isLastTraversableNode(parentNode)) {\n return (node.ownerDocument || node).body;\n }\n if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {\n return parentNode;\n }\n return getNearestOverflowAncestor(parentNode);\n}\nfunction getOverflowAncestors(node, list, traverseIframes) {\n var _node$ownerDocument2;\n if (list === void 0) {\n list = [];\n }\n if (traverseIframes === void 0) {\n traverseIframes = true;\n }\n const scrollableAncestor = getNearestOverflowAncestor(node);\n const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);\n const win = getWindow(scrollableAncestor);\n if (isBody) {\n const frameElement = getFrameElement(win);\n return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);\n } else {\n return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));\n }\n}\nfunction getFrameElement(win) {\n return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;\n}\n\nexport { getComputedStyle, getContainingBlock, getDocumentElement, getFrameElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isTopLayer, isWebKit };\n","import{isContainingBlock as t}from\"@floating-ui/utils/dom\";function e(t){return i(t)}function n(t){return f(t,\"offsetTop\")}function o(t){return f(t,\"offsetLeft\")}function r(t){return t.assignedSlot?t.assignedSlot:t.parentNode instanceof ShadowRoot?t.parentNode.host:t.parentNode}function i(e){for(let t=e;t;t=r(t))if(t instanceof Element&&\"none\"===getComputedStyle(t).display)return null;for(let n=r(e);n;n=r(n)){if(!(n instanceof Element))continue;const e=getComputedStyle(n);if(\"contents\"!==e.display){if(\"static\"!==e.position||t(e))return n;if(\"BODY\"===n.tagName)return n}}return null}function f(t,e){let n=t[e],o=i(t);const r=function(t){const e=new Set;let n=t.getRootNode();for(;n;)e.add(n),n=n.parentNode?n.parentNode.getRootNode():null;return e}(t);for(;o&&!r.has(o.getRootNode());)n-=o[e],o=i(o);return n}export{o as offsetLeft,e as offsetParent,n as offsetTop};\n","import {\n type Middleware,\n autoUpdate,\n computePosition,\n flip,\n offset,\n platform,\n shift,\n} from \"@floating-ui/dom\";\nimport { offsetParent } from \"composed-offset-position\";\nimport type { Grid } from \"../types/models.js\";\n\n/** Minimum space between the panel and the viewport's edges. */\nconst VIEWPORT_PADDING = 16;\n\nconst getOffsetParent = (element: Element) => platform.getOffsetParent(element, offsetParent);\n\n/**\n * Keeps the open panel (`feed`) placed against the collapsed widget per the\n * grid's Position — \"up\", \"down\", or \"auto\" (flips to whichever side fits) —\n * and at least 16px inside the viewport. Returns the cleanup that stops\n * tracking.\n */\nexport function positionFeed(\n widget: HTMLElement,\n feed: HTMLElement,\n position: Grid[\"position\"],\n): () => void {\n const middleware: Middleware[] = [\n offset({\n mainAxis: position === \"down\" ? -16 : -54,\n crossAxis: -18,\n }),\n ];\n\n if (!position || position === \"auto\") {\n middleware.push(\n flip({\n fallbackPlacements: [\"bottom-start\", \"top-start\"],\n fallbackStrategy: \"bestFit\",\n padding: VIEWPORT_PADDING,\n }),\n );\n }\n\n // Both axes: sideways for alignment, and up or down when a fixed Position can't flip.\n middleware.push(shift({ padding: VIEWPORT_PADDING, crossAxis: true }));\n\n const update = () => {\n void computePosition(widget, feed, {\n placement: position === \"down\" ? \"bottom-start\" : \"top-start\",\n middleware,\n strategy: \"fixed\",\n platform: { ...platform, getOffsetParent },\n }).then(({ x, y, placement }) => {\n feed.setAttribute(\"data-current-placement\", placement);\n Object.assign(feed.style, { left: `${x}px`, top: `${y}px` });\n });\n };\n\n return autoUpdate(widget, feed, update);\n}\n","import { positionFeed } from \"../lib/position-feed.js\";\nimport { EmbedAuthStore } from \"../store/embed-auth-store.js\";\nimport { GridStore, type DemoData, type GridOverrides } from \"../store/grid-store.js\";\nimport { registerStore, unregisterStore } from \"../store/registry.js\";\nimport type { Grid } from \"../types/models.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\nimport { ref } from \"./refs.js\";\n\nconst DEFAULT_API_URL = \"https://www.popgrids.io\";\n\nconst ALIGN_VALUES = new Set<string>([\"start\", \"center\", \"end\"] satisfies Grid[\"align\"][]);\nconst LAYOUT_VALUES = new Set<string>([\"sm\", \"lg\"] satisfies Grid[\"layout\"][]);\nconst POSITION_VALUES = new Set<string>([\"auto\", \"up\", \"down\"] satisfies Grid[\"position\"][]);\n\nconst localSheet = createSheet(/* css */ `\n :host {\n display: block;\n position: relative;\n }\n\n .grid {\n display: flex;\n height: 100%;\n position: relative;\n width: 100%;\n }\n\n .grid--align-start {\n justify-content: flex-start;\n }\n\n .grid--align-center {\n justify-content: center;\n }\n\n .grid--align-end {\n justify-content: flex-end;\n }\n`);\n\nexport class PopGrid extends BaseElement {\n private _initialized = false;\n private _floatingCleanup?: () => void;\n private _store!: GridStore;\n private _authStore!: EmbedAuthStore;\n private _demo?: DemoData;\n\n /**\n * The grid and comments a `data-demo` grid shows instead of fetching its\n * own — the host page supplies them, so no sample data ships in the bundle.\n * Shows the loading skeleton until it's set.\n */\n get demo(): DemoData | undefined {\n return this._demo;\n }\n\n set demo(data: DemoData) {\n this._demo = data;\n if (this._store?.demo) this._store.showDemo(data);\n }\n\n /** Whether the panel is open. Setting it opens or closes the panel; the visitor can still toggle it as usual. */\n get open(): boolean {\n return this._store?.open.value ?? false;\n }\n\n set open(value: boolean) {\n if (this._store) this._store.open.value = value;\n }\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n // Only the five visual-override attributes are observed/reactive.\n // data-key/data-api-url/data-page-url/data-id/data-demo stay connect-once —\n // changing them would mean tearing down and re-establishing the\n // fetch/websocket, which is out of scope here.\n static get observedAttributes() {\n return [\"data-align\", \"data-layout\", \"data-position\", \"data-icon\", \"data-preview-count\"];\n }\n\n connectedCallback() {\n if (this._initialized) return;\n this._initialized = true;\n\n const publicKey = this.getAttribute(\"data-key\") ?? this.getAttribute(\"public-key\") ?? \"\";\n\n const apiUrl =\n this.getAttribute(\"data-api-url\") ??\n this.getAttribute(\"api-url\") ??\n DEFAULT_API_URL;\n\n const pageUrl =\n this.getAttribute(\"data-page-url\") ?? this.getAttribute(\"page-url\") ?? location.href;\n\n // Names the discussion thread (Disqus-style identifier): embeds sharing a\n // data-id share one thread across pages; without it the thread is keyed\n // by the page's canonical URL.\n const externalId = this.getAttribute(\"data-id\");\n\n const demo = this.hasAttribute(\"data-demo\");\n\n this._authStore = new EmbedAuthStore({ apiUrl, publicKey, demo });\n registerStore(this, this._authStore);\n\n this._store = new GridStore({\n apiUrl,\n publicKey,\n pageUrl,\n externalId,\n demo,\n authStore: this._authStore,\n });\n registerStore(this, this._store);\n\n super.connectedCallback();\n\n // Picks up any override attributes already present at connect time —\n // attributeChangedCallback can fire for these before _store exists (the\n // browser calls it for observed attributes present at upgrade, ahead of\n // connectedCallback), so each onData*Changed handler below no-ops until\n // this runs.\n this._store.setOverrides(this._readOverridesFromAttributes());\n\n if (this._store.demo) {\n if (this._demo) this._store.showDemo(this._demo);\n return;\n }\n\n // Auth is intentionally not verified here — pop-feed.ts's effect calls\n // authStore.connectAuthChannel() once the panel actually opens, the\n // first moment the widget needs to know anything about it beyond\n // what's already cached locally in currentUser.\n void this._store.load();\n }\n\n private _readOverridesFromAttributes(): GridOverrides {\n const overrides: GridOverrides = {};\n\n const align = this.getAttribute(\"data-align\");\n if (align && ALIGN_VALUES.has(align)) {\n overrides.align = align as Grid[\"align\"];\n }\n\n const layout = this.getAttribute(\"data-layout\");\n if (layout && LAYOUT_VALUES.has(layout)) {\n overrides.layout = layout as Grid[\"layout\"];\n }\n\n const position = this.getAttribute(\"data-position\");\n if (position && POSITION_VALUES.has(position)) {\n overrides.position = position as Grid[\"position\"];\n }\n\n const icon = this.getAttribute(\"data-icon\");\n if (icon) {\n overrides.icon = icon;\n }\n\n const previewCountAttr = this.getAttribute(\"data-preview-count\");\n if (previewCountAttr !== null) {\n const previewCount = Number(previewCountAttr);\n if (Number.isInteger(previewCount) && previewCount > 0) {\n overrides.previewCount = previewCount;\n }\n }\n\n return overrides;\n }\n\n private _applyOverridesFromAttributes(): void {\n // Attributes present at upgrade can trigger this before connectedCallback\n // constructs _store — connectedCallback re-reads everything once it does.\n if (!this._store) return;\n this._store.setOverrides(this._readOverridesFromAttributes());\n }\n\n onDataAlignChanged() {\n this._applyOverridesFromAttributes();\n }\n\n onDataLayoutChanged() {\n this._applyOverridesFromAttributes();\n }\n\n onDataPositionChanged() {\n this._applyOverridesFromAttributes();\n }\n\n onDataIconChanged() {\n this._applyOverridesFromAttributes();\n }\n\n onDataPreviewCountChanged() {\n this._applyOverridesFromAttributes();\n }\n\n disconnectedCallback() {\n this._floatingCleanup?.();\n this._store.destroy();\n this._authStore.destroy();\n unregisterStore(this);\n super.disconnectedCallback();\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n const grid = this._store.grid.value;\n const gridEl = this.getElement(ref(\"grid\"));\n if (!gridEl) return;\n\n // Remove any existing grid-- classes\n const toRemove = Array.from(gridEl.classList).filter((cls) => cls.startsWith(\"grid--\"));\n if (toRemove.length > 0) {\n gridEl.classList.remove(...toRemove);\n }\n\n if (grid) {\n if (grid.align) gridEl.classList.add(`grid--align-${grid.align}`);\n if (grid.appearance) gridEl.classList.add(`grid--appearance-${grid.appearance}`);\n if (grid.icon) gridEl.classList.add(`grid--icon-${grid.icon}`);\n if (grid.layout) gridEl.classList.add(`grid--layout-${grid.layout}`);\n if (grid.position) gridEl.classList.add(`grid--position-${grid.position}`);\n\n const previewVal = grid.previewCount ?? this._store.previewCount;\n gridEl.classList.add(`grid--preview-${previewVal}`);\n }\n });\n\n this.addEffect(() => {\n const open = this._store.open.value;\n\n if (this._floatingCleanup) {\n this._floatingCleanup();\n this._floatingCleanup = undefined;\n }\n\n if (!open) return;\n\n const widget = this.getElement(\"pop-widget\");\n const feed = this.getElement(\"pop-feed\");\n if (!widget || !feed) return;\n\n const grid = this._store.grid.value;\n if (!grid) return;\n\n this._floatingCleanup = positionFeed(widget, feed, grid.position);\n });\n }\n\n protected getTemplate(): string {\n return /* html */ `\n <div class=\"grid\" data-ref=\"grid\">\n <pop-widget></pop-widget>\n <pop-feed></pop-feed>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-grid\")) {\n customElements.define(\"pop-grid\", PopGrid);\n}\n","import { getInitials } from \"../helpers/author.js\";\nimport { GridStore } from \"../store/grid-store.js\";\nimport { consume } from \"../store/registry.js\";\nimport { BaseElement, createSheet } from \"./base-element.js\";\n\nconst localSheet = createSheet(/* css */ `\n :host {\n --error-badge-bg: #fef2f2;\n --error-badge-text: #991b1b;\n --error-badge-border: #fecaca;\n\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n }\n\n @media (prefers-color-scheme: dark) {\n :host {\n --error-badge-bg: #450a0a;\n --error-badge-text: #fca5a5;\n --error-badge-border: #7f1d1d;\n }\n }\n\n :host(.dark) {\n --error-badge-bg: #450a0a;\n --error-badge-text: #fca5a5;\n --error-badge-border: #7f1d1d;\n }\n\n :host([data-error]) {\n cursor: default;\n }\n\n .error-badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: var(--pop-radius-full);\n border: 1px solid var(--error-badge-border);\n background: var(--error-badge-bg);\n color: var(--error-badge-text);\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n white-space: nowrap;\n }\n\n .widget {\n display: inline-flex;\n align-items: flex-start;\n }\n\n .widget > :not([hidden]) ~ :not([hidden]) {\n margin-left: -6px;\n }\n\n .skeleton {\n width: 32px;\n height: 32px;\n background: var(--pop-muted);\n animation: pulse 1.5s ease-in-out infinite;\n }\n\n @keyframes pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n }\n\n .count {\n --count-size: calc(32px + var(--count-border-size));\n --count-background: var(--pop-background);\n --count-border-color: rgba(0 0 32 / 16%);\n --count-border-size: 1px;\n --count-color: var(--pop-foreground);\n\n align-items: center;\n background-color: var(--pop-background);\n display: flex;\n flex-shrink: 0;\n justify-content: center;\n padding: calc(var(--count-border-size) / 2);\n position: relative;\n z-index: 10;\n\n width: calc(var(--count-size) + (calc(var(--count-border-size))));\n height: calc(var(--count-size) + (calc(var(--count-border-size))));\n }\n\n .count__background {\n background-color: var(--count-border-color);\n position: absolute;\n top: 0;\n left: 0;\n z-index: 10;\n width: 100%;\n height: 100%;\n }\n\n .count__content {\n align-items: center;\n background: var(--count-background);\n display: flex;\n justify-content: center;\n overflow: hidden;\n height: var(--count-size);\n width: var(--count-size);\n }\n\n .count__label {\n color: var(--count-color);\n font-size: 16px;\n font-style: normal;\n font-weight: 500;\n letter-spacing: -0.96px;\n line-height: 28px;\n text-align: center;\n user-select: none;\n }\n\n .count__label-container {\n align-items: center;\n background: var(--pop-background);\n display: flex;\n height: calc(100% - calc(var(--count-border-size) * 2));\n justify-content: center;\n position: relative;\n text-indent: calc(calc(var(--count-border-size) * 2) * -1);\n width: calc(100% - calc(var(--count-border-size) * 2));\n z-index: 20;\n }\n\n /* Above .count (z-index: 10) — otherwise it paints underneath despite\n * coming later in the widget's facepile, since z-index only applies to\n * positioned elements and this one had neither. */\n .widget pop-comment-icon {\n position: relative;\n z-index: 20;\n top: 1px;\n }\n`);\n\nexport class PopWidget extends BaseElement {\n @consume(GridStore) gridStore!: GridStore;\n\n protected get styleSheets() {\n return [localSheet];\n }\n\n protected events = {\n click: \"onClick\",\n };\n\n protected onClick() {\n if (this.gridStore.error.value) {\n return;\n }\n\n this.gridStore.open.value = !this.gridStore.open.value;\n }\n\n protected setupEffects() {\n this.addEffect(() => {\n this.gridStore.loading.value;\n this.gridStore.error.value;\n this.gridStore.previewAvatars.value;\n this.gridStore.comments.value;\n this.gridStore.grid.value;\n\n const hasError = Boolean(this.gridStore.error.value);\n this.toggleAttribute(\"data-error\", hasError);\n\n if (hasError && this.gridStore.open.value) {\n this.gridStore.open.value = false;\n }\n\n this.render();\n });\n }\n\n protected getTemplate(): string {\n if (this.gridStore.loading.value) {\n return `<div class=\"widget\"><div class=\"skeleton mask mask-squircle\"></div></div>`;\n }\n\n if (this.gridStore.error.value) {\n return `<div class=\"error-badge\">Error: there was a problem loading the PopGrid</div>`;\n }\n\n const avatars = this.gridStore.previewAvatars.value;\n const totalCount = this.gridStore.comments.value.length;\n const grid = this.gridStore.grid.value;\n\n const iconTheme = grid?.icon === \"brand\" ? \"brand\" : \"neutral\";\n\n const avatarsHtml = avatars\n .map((author, idx) => {\n const zIndex = avatars.length + idx;\n const colorKey = author?.id ?? author?.name ?? \"\";\n\n if (author?.image) {\n return `<pop-comment-avatar size=\"xs\" style=\"z-index: ${zIndex}\" data-color-key=\"${colorKey}\">\n <img src=\"${author.image}\" alt=\"${author.name ?? \"User\"}\" />\n </pop-comment-avatar>`;\n }\n\n return `<pop-comment-avatar size=\"xs\" style=\"z-index: ${zIndex}\" data-color-key=\"${colorKey}\">\n ${getInitials(author?.name)}\n </pop-comment-avatar>`;\n })\n .join(\"\");\n\n return /* html */ `\n <div class=\"widget\">\n ${avatarsHtml}\n <div class=\"count mask mask-squircle\">\n <span class=\"count__content mask mask-squircle\">\n <div class=\"count__background mask mask-squircle\"></div>\n <div class=\"count__label-container mask mask-squircle\">\n <div class=\"count__label\">${totalCount}</div>\n </div>\n </span>\n </div>\n <pop-comment-icon variant=\"add\" theme=\"${iconTheme}\" size=\"xs\"></pop-comment-icon>\n </div>\n `;\n }\n}\n\nif (!customElements.get(\"pop-widget\")) {\n customElements.define(\"pop-widget\", PopWidget);\n}\n","if (typeof document !== \"undefined\") {\n const fontUrl = \"https://rsms.me/inter/inter.css\";\n if (!document.querySelector(`link[href=\"${fontUrl}\"]`)) {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = fontUrl;\n document.head.appendChild(link);\n }\n}\n\nimport \"./components/pop-account-switcher.js\";\nimport \"./components/pop-auth-code.js\";\nimport \"./components/pop-auth-email.js\";\nimport \"./components/pop-auth-join.js\";\nimport \"./components/pop-auth-no-code.js\";\nimport \"./components/pop-auth-panel.js\";\nimport \"./components/pop-button-link.js\";\nimport \"./components/pop-comment-avatar.js\";\nimport \"./components/pop-comment-bar.js\";\nimport \"./components/pop-comment-icon.js\";\nimport \"./components/pop-comment-input.js\";\nimport \"./components/pop-comment-thread.js\";\nimport \"./components/pop-comment.js\";\nimport \"./components/pop-feed.js\";\nimport \"./components/pop-grid.js\";\nimport \"./components/pop-widget.js\";\n\nexport type { AuthUser, Comment, CommentAuthor, Grid, OrgOption } from \"./types/models.js\";\nexport type { PopGrid } from \"./components/pop-grid.js\";\nexport type { DemoData } from \"./store/grid-store.js\";\n"],"x_google_ignoreList":[34,35],"mappings":"oEAAA,SAAgB,EAAY,EAAyC,CAEnE,OADK,EACE,EACJ,MAAM,GAAG,CAAC,CACV,IAAK,GAAM,EAAE,IAAM,EAAE,CAAC,CACtB,KAAK,EAAE,CAAC,CACR,YAAY,CAAC,CACb,MAAM,EAAG,CAAC,EANK,GAOpB,CCCA,SAAgB,EAAiB,EAAiB,EAAgB,EAAuB,CACvF,IAAM,EAAU,KAAK,IAAI,EAAS,GAAK,EAAS,CAAK,EACrD,OAAO,KAAK,MAAM,KAAK,OAAO,EAAI,CAAO,CAC3C,CCNA,IAAa,EAAwB,oBACxB,EAAa,gBACb,EAAiB,6BACjB,EAAkB,IAAS,IAOlC,EAAuB,IAEhB,EAAb,cAAoC,KAAM,CACxC,YAAY,EAAiB,CAC3B,MAAM,CAAO,EACb,KAAK,KAAO,gBACd,CACF,EAGa,EAAb,cAA6C,CAAe,CAC1D,YAAY,EAAU,wBAAyB,CAC7C,MAAM,CAAO,EACb,KAAK,KAAO,yBACd,CACF,EAQa,GAAsB,EAAgB,EAAmB,IAAyB,CAC7F,IAAM,EAAM,IAAI,IAAI,EAAuB,CAAM,EAGjD,OAFA,EAAI,aAAa,IAAI,YAAa,CAAS,EAC3C,EAAI,aAAa,IAAI,eAAgB,CAAY,EAC1C,EAAI,SAAS,CACtB,EAEa,GAA0B,EAAgB,IAAsB,CAC3E,IAAM,EAAQ,OAAO,KACnB,EAAmB,EAAQ,EAAW,OAAO,SAAS,MAAM,EAC5D,EACA,CACF,EAEA,GAAI,CAAC,EACH,MAAM,IAAI,EAAe,0DAA0D,EAGrF,OAAO,CACT,EAEM,IAAiB,EAAe,IACpC,OAAO,GAAS,YAChB,GACA,SAAU,GACV,WAAY,GACX,EAA0C,OAAS,GACnD,EAA0C,SAAA,iBAEvC,GAAmB,GAA2C,CAClE,GAAI,OAAO,GAAS,WAAY,GAAiB,EAAE,SAAU,GAC3D,OAAO,KAGT,IAAM,EAAS,EACT,EAAO,EAAO,KAEpB,GAAI,OAAO,GAAS,WAAY,GAAiB,EAAE,OAAQ,GACzD,OAAO,KAGT,IAAM,EAAa,EAenB,OARI,OAAO,EAAW,IAAO,UAIzB,OAAO,EAAO,OAAU,UAAY,OAAO,EAAO,WAAc,SAC3D,KAGF,CACL,KAAM,CACJ,GAAI,EAAW,GACf,KAAM,OAAO,EAAW,MAAS,SAAW,EAAW,KAAO,GAC9D,MAAO,OAAO,EAAW,OAAU,SAAW,EAAW,MAAQ,GACjE,MAAO,OAAO,EAAW,OAAU,SAAW,EAAW,MAAQ,IACnE,EACA,MAAO,EAAO,MACd,UAAW,EAAO,SACpB,CACF,EAEa,GACX,EACA,EACA,IAIA,IAAI,SAAe,EAAS,IAAW,CACrC,IAAM,EAAiB,IAAI,IAAI,CAAM,CAAC,CAAC,OACnC,EAAU,GAER,GAAU,EAA8B,IAA2B,CACnE,MAKJ,IAFA,EAAU,GACV,GAAQ,EACJ,IAAW,UAAW,CACxB,EAAQ,EACR,MACF,CACA,EAAO,GAAS,IAAI,EAAe,gBAAgB,CAAC,CADpD,CAEF,EAEM,EAAa,GAAwB,CACrC,KAAM,SAAW,EAIrB,IAAI,GAAc,EAAM,KAAA,uBAAwB,EAAG,CACjD,IAAM,EAAS,GAAgB,EAAM,IAAI,EACzC,GAAI,CAAC,EAAQ,CACX,EAAO,SAAU,IAAI,EAAe,gBAAgB,CAAC,EACrD,MACF,CACA,GAAS,gBAAgB,CAAM,EAC/B,EAAO,SAAS,EAChB,MACF,CAEA,GAAI,GAAc,EAAM,KAAA,qBAAsB,EAAG,CAC/C,IAAM,EACJ,OAAO,EAAM,MAAS,UACtB,EAAM,OAAS,MACf,UAAW,EAAM,MACjB,OAAQ,EAAM,KAA6B,OAAU,SAChD,EAAM,KAA2B,MAClC,iBACN,EAAO,SAAU,IAAI,EAAe,CAAO,CAAC,CAC9C,CAXA,CAYF,EAEM,EAAW,OAAO,gBAAkB,CACpC,CAAC,EAAM,QAAU,IAIrB,cAAc,CAAQ,EAEtB,OAAO,eAAiB,CAClB,GACJ,EAAO,SAAU,IAAI,CAAyB,CAChD,EAAG,CAAoB,EACzB,EAAG,GAAG,EAEA,EAAU,OAAO,eAAiB,CACtC,GAAI,CACF,EAAM,MAAM,CACd,MAAQ,CAER,CACA,EAAO,SAAU,IAAI,EAAe,mBAAmB,CAAC,CAC1D,EAAG,CAAe,EAEZ,OAAgB,CACpB,OAAO,oBAAoB,UAAW,CAAS,EAC/C,cAAc,CAAQ,EACtB,aAAa,CAAO,CACtB,EAEA,OAAO,iBAAiB,UAAW,CAAS,CAC9C,CAAC,EAEU,EAAkB,MAC7B,EACA,EACA,IAGG,CAEH,MAAM,EAAoB,EADZ,EAAuB,EAAQ,CACX,EAAO,CAAO,CAClD,EClMM,GAAe,yBACf,GAAiB,IAAS,IAG1B,GAAmB,cACnB,GAA6B,oBAC7B,GAAmB,cACnB,EAAwB,UAExB,GAAwB,GACxB,EAAwB,6DAIxB,GAA8B,IAU9B,EAAc,GAAsB,0BAA0B,IAE9D,EAAkB,GACtB,OAAO,GAAU,YACjB,GACA,OAAQ,EAAgC,OAAU,UAClD,OAAQ,EAAgC,WAAc,UACtD,CAAC,CAAE,EAAgC,KASxB,EAAb,MAAa,CAAe,uBA2EC,IAAI,wBACN,GAGzB,oBAA4B,EAA+B,CACzD,GAAI,IAAa,KAAM,CAKjB,KAAK,YAAY,OACnB,KAAK,gBAAgB,EAEvB,MACF,CAEA,GAAI,CACF,IAAM,EAAkB,KAAK,MAAM,CAAQ,EACvC,EAAe,CAAM,GAAK,EAAO,UAAY,KAAK,IAAI,GACxD,KAAK,mBAAmB,CAAM,CAElC,MAAQ,CAER,CACF,CAGA,eAAuB,EAA+B,CAChD,MAAe,QAEnB,GAAe,QAAU,GACzB,GAAI,CACF,IAAK,IAAM,KAAS,EAAe,UAC7B,IAAU,MAAQ,EAAM,YAAc,KAAK,WAC7C,EAAM,oBAAoB,CAAQ,CAGxC,QAAU,CACR,EAAe,QAAU,EAC3B,CATyB,CAU3B,CAEA,YAAY,EAA6D,+BA/GnC,IAAI,8BACR,IAAI,oCAEb,CAAqB,yCAMhB,CAAC,qCAKU,IAAI,gCACxB,EAAK,kCASU,CAAC,CAAC,yCAER,EAAK,6BAOF,MAAM,6BACb,EAAE,+BACR,EAAK,6BACQ,IAAI,iCACA,IAAI,eAEF,qBAQA,+BACR,0BACoC,oBAC/C,uBAKM,GAA8B,CAClD,EAAM,cAAgB,OAAO,cAAgB,EAAM,MAAQ,EAAW,KAAK,SAAS,GAIxF,KAAK,oBAAoB,EAAM,QAAQ,CACzC,2BAgamE,8BACZ,KA9WrD,KAAK,OAAS,EAAK,OACnB,KAAK,UAAY,EAAK,UACtB,KAAK,KAAO,EAAK,MAAQ,GACrB,MAAK,OAET,KAAK,QAAU,KAAK,kBAAkB,EACtC,KAAK,YAAY,MAAQ,KAAK,SAAS,MAAQ,KAE/C,OAAO,iBAAiB,UAAW,KAAK,cAAc,EACtD,EAAe,UAAU,IAAI,IAAI,EAKnC,CAGA,SAAgB,CACd,KAAK,UAAY,GACjB,KAAK,iBAAiB,EACtB,OAAO,oBAAoB,UAAW,KAAK,cAAc,EACzD,EAAe,UAAU,OAAO,IAAI,CACtC,CAEA,mBAAiD,CAC/C,GAAI,CACF,IAAM,EAAM,OAAO,aAAa,QAAQ,EAAW,KAAK,SAAS,CAAC,EAClE,GAAI,CAAC,EAAK,OAAO,KAEjB,IAAM,EAAkB,KAAK,MAAM,CAAG,EAUtC,OATK,EAAe,CAAM,EAItB,EAAO,WAAa,KAAK,IAAI,GAC/B,KAAK,mBAAmB,EACjB,MAGF,EARE,IASX,MAAQ,CACN,OAAO,IACT,CACF,CAUA,eAAuB,EAA6B,CAClD,KAAK,QAAU,EACf,GAAI,CACF,OAAO,aAAa,QAAQ,EAAW,KAAK,SAAS,EAAG,KAAK,UAAU,CAAO,CAAC,CACjF,MAAQ,CAGR,CACA,KAAK,eAAe,KAAK,UAAU,CAAO,CAAC,CAC7C,CAEA,mBAA2B,EAA6B,CACtD,KAAK,eAAe,CAAO,EAI3B,KAAK,YAAY,MAAQ,EAAQ,KAGjC,KAAK,UAAU,MAAQ,KAOvB,KAAK,cAAc,MAAQ,CAAC,EAgB5B,IAAM,EAAa,KAAK,aAAe,MAAQ,KAAK,qBAAuB,KAC3E,KAAK,iBAAiB,EAClB,GACF,KAAU,mBAAmB,CAEjC,CAEA,oBAAmC,CACjC,KAAK,QAAU,KACf,GAAI,CACF,OAAO,aAAa,WAAW,EAAW,KAAK,SAAS,CAAC,CAC3D,MAAQ,CAER,CACA,KAAK,eAAe,IAAI,EACxB,KAAK,cAAc,MAAQ,CAAC,EAC5B,KAAK,iBAAiB,CACxB,CAaA,IAAY,OAAuB,CAQjC,OAPK,KAAK,QAEN,KAAK,QAAQ,WAAa,KAAK,IAAI,GACrC,KAAK,gBAAgB,EACd,MAGF,KAAK,QAAQ,MAPM,IAQ5B,CASA,MAAM,eAAe,EAAc,EAAoB,CAAC,EAAsB,CAC5E,GAAI,KAAK,KAAM,MAAU,MAAM,oCAAoC,EAEnE,IAAM,EAAU,IAAI,QAAQ,EAAK,OAAO,EAClC,EAAQ,KAAK,MAInB,OAHI,GACF,EAAQ,IAAI,GAAc,CAAK,EAE1B,MAAM,IAAI,IAAI,EAAM,KAAK,MAAM,EAAG,CAAE,GAAG,EAAM,SAAQ,CAAC,CAC/D,CAgBA,MAAM,gBAAgB,EAAc,EAAoB,CAAC,EAAsB,CAC7E,IAAI,EAAM,MAAM,KAAK,eAAe,EAAM,CAAI,EAE9C,GAAI,EAAI,SAAW,IAAK,CAEtB,GAAI,CAAC,MADkB,KAAK,oBAAoB,EAE9C,OAAO,EAET,EAAM,MAAM,KAAK,eAAe,EAAM,CAAI,CAC5C,CAEA,OAAO,CACT,CAEA,MAAc,UACZ,EACkE,CAClE,GAAI,CACF,IAAM,EAAQ,MAAM,EAAI,KAAK,EAC7B,MAAO,CACL,QACE,OAAO,EAAK,OAAU,UAAY,EAAK,MACnC,EAAK,MACL,0CACN,KAAM,OAAO,EAAK,MAAS,SAAW,EAAK,KAAO,IAAA,GAClD,WAAY,OAAO,EAAK,YAAe,SAAW,EAAK,WAAa,IAAA,EACtE,CACF,MAAQ,CAER,CACA,MAAO,CAAE,QAAS,yCAA0C,CAC9D,CAGA,kBAAyB,CACvB,KAAK,SAAS,MAAQ,KACtB,KAAK,SAAS,MAAQ,OACxB,CAEA,YAAmB,CACjB,KAAK,SAAS,MAAQ,KACtB,KAAK,SAAS,MAAQ,GACtB,KAAK,aAAa,MAAQ,KAC1B,KAAK,SAAS,MAAQ,OAItB,KAAK,sBAAsB,EAAK,CAClC,CAEA,aAAoB,CAClB,KAAK,SAAS,MAAQ,KACtB,KAAK,SAAS,MAAQ,OACxB,CAOA,WAAkB,CAChB,KAAK,SAAS,MAAQ,QACtB,KAAK,aAAa,MAAQ,KAC1B,KAAK,SAAS,MAAQ,IACxB,CAGA,YAAmB,CACjB,KAAK,SAAS,MAAQ,MACxB,CAEA,YAAmB,CACjB,KAAK,SAAS,MAAQ,SACxB,CAGA,MAAM,QAAQ,EAAiC,CAC7C,KAAK,WAAW,MAAQ,GACxB,KAAK,SAAS,MAAQ,KAEtB,GAAI,CACF,IAAM,EAAM,MAAM,MAChB,IAAI,IAAI,uBAAuB,KAAK,UAAU,gBAAiB,KAAK,MAAM,EAC1E,CACE,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CAAE,OAAM,CAAC,CAChC,CACF,EAEA,GAAI,CAAC,EAAI,GAAI,CACX,GAAM,CAAE,UAAS,cAAe,MAAM,KAAK,UAAU,CAAG,EAMxD,OALI,EAAI,SAAW,IACjB,KAAK,gBAAgB,CAAU,EAE/B,KAAK,SAAS,MAAQ,EAEjB,EACT,CAKA,MAHA,MAAK,SAAS,MAAQ,EACtB,KAAK,aAAa,MAAQ,KAAK,IAAI,EAAI,GACvC,KAAK,SAAS,MAAQ,OACf,EACT,MAAQ,CAEN,OADA,KAAK,cAAc,CAAqB,EACjC,EACT,QAAU,CACR,KAAK,WAAW,MAAQ,EAC1B,CACF,CAEA,MAAM,WAA8B,CAElC,OADK,KAAK,SAAS,MACZ,KAAK,QAAQ,KAAK,SAAS,KAAK,EADN,EAEnC,CAGA,MAAM,UAAU,EAAgC,CAC9C,KAAK,WAAW,MAAQ,GACxB,KAAK,SAAS,MAAQ,KAEtB,GAAI,CACF,IAAM,EAAM,MAAM,MAChB,IAAI,IAAI,uBAAuB,KAAK,UAAU,kBAAmB,KAAK,MAAM,EAC5E,CACE,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CAAE,MAAO,KAAK,SAAS,MAAO,IAAK,CAAK,CAAC,CAChE,CACF,EAEA,GAAI,CAAC,EAAI,GAAI,CACX,GAAM,CAAE,UAAS,OAAM,cAAe,MAAM,KAAK,UAAU,CAAG,EAkB9D,OAjBI,EAAI,SAAW,IACjB,KAAK,gBAAgB,CAAU,EACtB,IAAS,IAGlB,KAAK,UAAU,EACf,KAAK,cAAc,qBAAsB,oBAAoB,GACpD,IAAS,GAGlB,KAAK,UAAU,EACN,IAAS,GAElB,KAAK,SAAS,MAAQ,eAEtB,KAAK,SAAS,MAAQ,EAEjB,EACT,CAEA,IAAM,EAAQ,MAAM,EAAI,KAAK,EAM7B,OALA,KAAK,mBAAmB,CAAI,EAC5B,KAAK,SAAS,MAAQ,OACtB,KAAK,SAAS,MAAQ,GACtB,KAAK,aAAa,MAAQ,KAC1B,KAAK,sBAAsB,EAAI,EACxB,EACT,MAAQ,CAEN,OADA,KAAK,cAAc,CAAqB,EACjC,EACT,QAAU,CACR,KAAK,WAAW,MAAQ,EAC1B,CACF,CAEA,MAAM,eAAkC,CACtC,KAAK,UAAU,MAAQ,KACvB,KAAK,YAAY,MAAQ,GAEzB,GAAI,CAOF,OANA,MAAM,EAAgB,KAAK,OAAQ,KAAK,UAAW,CACjD,eAAgB,CAAE,OAAM,QAAO,eAAgB,CAC7C,KAAK,mBAAmB,CAAE,QAAO,YAAW,MAAK,CAAC,CACpD,CACF,CAAC,EAEM,KAAK,YAAY,QAAU,IACpC,OAAS,EAAO,CAId,OAHM,aAAiB,GACrB,KAAK,cAAc,aAAiB,MAAQ,EAAM,QAAU,gBAAgB,EAEvE,EACT,QAAU,CACR,KAAK,YAAY,MAAQ,EAC3B,CACF,CAmBA,qBAAwC,CAatC,OAZI,KAAK,oBACA,KAAK,qBAGd,KAAK,iBAAiB,EACtB,KAAK,oBAAsB,IAAI,QAAkB,GAAY,CAC3D,KAAK,oBAAuB,GAAY,CACtC,KAAK,oBAAsB,KAC3B,KAAK,oBAAsB,KAC3B,EAAQ,CAAO,CACjB,CACF,CAAC,EACM,KAAK,oBACd,CAEA,cACE,EACA,EAAS,EACT,EACM,CACN,KAAK,gBAAgB,MAAQ,EAC7B,KAAK,iBAAiB,MACpB,IAAsB,IAAA,GAAY,KAAO,KAAK,IAAI,EAAI,EAAoB,IAC5E,KAAK,UAAU,MAAQ,CACzB,CAGA,gBAAwB,EAAsC,CAC5D,KAAK,cACH,qBACA,EACA,GAAc,EAChB,CACF,CAEA,kBAAyB,CACvB,KAAK,eAAe,EACpB,KAAK,qBAAqB,OAAS,CACrC,CAEA,gBAAuB,CACrB,KAAK,UAAU,MAAQ,IACzB,CAYA,MAAM,mBAAmC,CACvC,GAAI,CAAC,KAAK,YAAY,MAAO,CAC3B,KAAK,cAAc,MAAQ,CAAC,EAC5B,MACF,CAEI,SAAK,qBAAqB,MAI9B,MAAK,qBAAqB,MAAQ,GAClC,GAAI,CACF,IAAM,EAAM,MAAM,KAAK,eACrB,uBAAuB,KAAK,UAAU,oBACxC,EACA,GAAI,CAAC,EAAI,GAAI,OAEb,IAAM,EAAQ,MAAM,EAAI,KAAK,EAC7B,KAAK,cAAc,MAAQ,EAAK,aAClC,MAAQ,CAIR,QAAU,CACR,KAAK,qBAAqB,MAAQ,EACpC,CAfkC,CAgBpC,CAaA,MAAM,mBAAmB,EAA0C,CACjE,IAAM,EAAM,MAAM,KAAK,eACrB,uBAAuB,KAAK,UAAU,sBAAsB,IAC5D,CAAE,OAAQ,MAAO,CACnB,EAEA,GAAI,CAAC,EAAI,GAIP,OAHI,EAAI,SAAW,KACjB,KAAK,gBAAgB,EAEhB,GAGT,IAAM,EAAQ,MAAM,EAAI,KAAK,EAK7B,MAJA,MAAK,YAAY,MAAQ,EAAK,KAC1B,KAAK,SACP,KAAK,eAAe,CAAE,GAAG,KAAK,QAAS,KAAM,EAAK,IAAK,CAAC,EAEnD,EACT,CAGA,MAAM,mBAAsC,CAC1C,IAAM,EAAM,MAAM,KAAK,eAAe,uBAAuB,KAAK,UAAU,gBAAiB,CAC3F,OAAQ,MACV,CAAC,EASD,OAPI,EAAI,IAIN,KAAK,gBAAgB,CAAE,OAAQ,EAAK,CAAC,EAGhC,EAAI,EACb,CAGA,gBAAwB,EAAsC,CAC5D,IAAM,EAAc,KAAK,YAAY,QAAU,KAC/C,KAAK,mBAAmB,EACxB,KAAK,YAAY,MAAQ,KACzB,KAAK,SAAS,MAAQ,OAElB,GAAe,CAAC,GAAS,QAC3B,KAAK,cAAc,wDAAwD,CAE/E,CAYA,MAAM,oBAAoC,CACxC,GAAI,KAAK,MAAQ,KAAK,WAAa,KAAK,YAAc,CAAC,KAAK,YAAY,MACtE,OAGF,IAAI,EAAwB,KACxB,EAAe,GACnB,GAAI,CACF,IAAM,EAAY,MAAM,KAAK,eAC3B,uBAAuB,KAAK,UAAU,sBACtC,CAAE,OAAQ,MAAO,CACnB,EACA,GAAI,EAAU,GAAI,CAKhB,IAAM,EAAc,MAAM,EAAU,KAAK,EAKzC,EAAS,EAAW,OACpB,KAAK,YAAY,MAAQ,EAAW,KAElC,KAAK,SACL,EAAW,WACX,EAAW,YAAc,KAAK,QAAQ,WAEtC,KAAK,eAAe,CAClB,GAAG,KAAK,QACR,KAAM,EAAW,KACjB,UAAW,EAAW,SACxB,CAAC,CAEL,MAAW,EAAU,SAAW,MAI9B,EAAe,GAEnB,MAAQ,CAER,CAEA,GAAI,EAAc,CAChB,KAAK,gBAAgB,EACrB,MACF,CAEA,GAAI,CAAC,GAAU,KAAK,WAAa,CAAC,KAAK,YAAY,MAAO,CACxD,KAAK,sBAAsB,EAC3B,MACF,CAEA,IAAM,EAAQ,IAAI,IAAI,uBAAuB,KAAK,UAAU,eAAgB,KAAK,MAAM,EACvF,EAAM,SAAW,EAAM,WAAa,SAAW,OAAS,MACxD,EAAM,aAAa,IAAI,SAAU,CAAM,EAEvC,IAAM,EAAS,IAAI,UAAU,EAAM,SAAS,CAAC,EAC7C,KAAK,WAAa,EAElB,EAAO,WAAe,CACpB,KAAK,qBAAuB,CAC9B,EAEA,EAAO,UAAa,GAAU,CAC5B,GAAI,CACc,KAAK,MAAM,OAAO,EAAM,IAAI,CACxC,CAAA,CAAQ,OAAS,mBACnB,KAAK,gBAAgB,CAEzB,MAAQ,CAER,CACF,EAEA,EAAO,YAAgB,CACrB,KAAK,WAAa,KACd,OAAK,WAAa,CAAC,KAAK,YAAY,QAGxC,KAAK,sBAAsB,CAC7B,EAEA,EAAO,YAAgB,CACrB,EAAO,MAAM,CACf,CACF,CAEA,uBAAsC,CACpC,GAAI,KAAK,WAAa,KAAK,oBAAsB,CAAC,KAAK,YAAY,MACjE,OAGF,IAAM,EAAQ,EAAiB,KAAK,qBAAsB,IAAM,EAA2B,EAC3F,KAAK,sBAAwB,EAE7B,KAAK,mBAAqB,eAAiB,CACzC,KAAK,mBAAqB,KAC1B,KAAU,mBAAmB,CAC/B,EAAG,CAAK,CACV,CAEA,kBAAiC,CAC/B,AAEE,KAAK,sBADL,aAAa,KAAK,kBAAkB,EACV,MAG5B,AAME,KAAK,cALL,KAAK,WAAW,OAAS,KACzB,KAAK,WAAW,UAAY,KAC5B,KAAK,WAAW,QAAU,KAC1B,KAAK,WAAW,QAAU,KAC1B,KAAK,WAAW,MAAM,EACJ,KAEtB,CACF,EC3yBM,EAAY,IAAI,QAET,IAAiB,EAAa,EAAY,EAAW,EAAM,cAAsB,CAC5F,IAAI,EAAS,EAAU,IAAI,CAAE,EACxB,IACH,EAAS,IAAI,IACb,EAAU,IAAI,EAAI,CAAM,GAE1B,EAAO,IAAI,EAAK,CAAK,CACvB,EAEa,GAAmB,GAAsB,CACpD,EAAU,OAAO,CAAE,CACrB,EAEa,IAAmB,EAAa,IAAuB,CAClE,IAAI,EAAuB,EAC3B,KAAO,GAAM,CAEX,IAAM,EADS,EAAU,IAAI,CACf,CAAA,EAAQ,IAAI,CAAG,EAC7B,GAAI,EAAO,OAAO,EAElB,IAAM,EAAO,EAAK,YAAY,EAC9B,GAAI,EAAE,aAAgB,YAAa,MACnC,EAAO,EAAK,IACd,CACA,OAAO,IACT,EAEA,SAAgB,EAAQ,EAAe,CACrC,OAAO,SAAU,EAAa,EAAqB,CACjD,IAAM,EAAW,OAAO,YAAc,EAAS,MAAQ,QAAQ,EAC/D,OAAO,eAAe,EAAQ,EAAa,CACzC,KAAe,CACb,GAAI,KAAK,GAAW,OAAO,KAAK,GAChC,IAAM,EAAW,GAAa,KAAM,CAAQ,EAC5C,GAAI,CAAC,EAEH,MADA,QAAQ,MAAM,+CAA+C,KAAK,cAAe,IAAI,EAC3E,MACR,4BAA4B,EAAS,MAAQ,EAAS,qBAAqB,KAAK,UAAU,GAC5F,EAGF,MADA,MAAK,GAAY,EACV,CACT,EACA,WAAY,GACZ,aAAc,EAChB,CAAC,CACH,CACF,8+RIjDI,EAAe,GACb,EAAiB,IAAI,IACvB,EAA0C,KAC1C,EAAoC,KAExC,SAAS,GAA2B,CAClC,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IAAa,MAAO,GAE7E,IAAM,EACJ,SAAS,gBAAgB,UAAU,SAAS,MAAM,GAClD,SAAS,KAAK,UAAU,SAAS,MAAM,EACnC,EACJ,SAAS,gBAAgB,UAAU,SAAS,OAAO,GACnD,SAAS,KAAK,UAAU,SAAS,OAAO,EAQ1C,OANI,EAAqB,GACrB,EAAsB,IAE1B,AACE,IAAa,OAAO,WAAW,8BAA8B,EAExD,EAAW,QACpB,CAEA,SAAS,GAAmB,CAC1B,IAAM,EAAU,EAAgB,EAC5B,IAAY,IACd,EAAe,EACf,EAAe,QAAS,GAAO,CAC7B,IAAM,EAAS,GAAgB,CAAC,CAAC,EAAG,QAAQ,OAAO,EACnD,EAAG,UAAU,OAAO,OAAQ,CAAM,CACpC,CAAC,EAEL,CAEA,IAAM,OAAsB,CAC1B,EAAiB,CACnB,EAEA,SAAgB,GAAsB,EAAiB,CACrD,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IAAa,OAElE,EAAe,OAAS,IAC1B,EAAe,EAAgB,EAC/B,EAAiB,IAAI,qBAAuB,CAC1C,EAAiB,CACnB,CAAC,EACD,EAAe,QAAQ,SAAS,gBAAiB,CAC/C,WAAY,GACZ,gBAAiB,CAAC,OAAO,CAC3B,CAAC,EACD,EAAe,QAAQ,SAAS,KAAM,CACpC,WAAY,GACZ,gBAAiB,CAAC,OAAO,CAC3B,CAAC,EAED,EAAa,OAAO,WAAW,8BAA8B,EAC7D,EAAW,iBAAiB,SAAU,EAAa,GAGrD,EAAe,IAAI,CAAE,EAErB,IAAM,EAAS,GAAgB,CAAC,CAAC,EAAG,QAAQ,OAAO,EACnD,EAAG,UAAU,OAAO,OAAQ,CAAM,CACpC,CAEA,SAAgB,GAAwB,EAAiB,CACvD,EAAe,OAAO,CAAE,EACpB,EAAe,OAAS,IAC1B,AAEE,KADA,EAAe,WAAW,EACT,MAEnB,AAEE,KADA,EAAW,oBAAoB,SAAU,EAAa,EACzC,MAGnB,CCxEA,SAAgB,EAAY,EAAgC,CAC1D,IAAM,EAAQ,IAAI,cAElB,OADA,EAAM,YAAY,CAAO,EAClB,CACT,CAEA,IAAa,GAAkB,EAAY,EAAU,EACxC,GAAW,EAAY,EAAS,EAChC,GAAa,EAAY,EAAW,EAI3B,EAAtB,cAA0C,WAA2C,CAEnF,IAAc,aAA+B,CAC3C,MAAO,CAAC,CACV,CAMA,aAAc,CACZ,MAAM,uBAVqC,CAAC,GAAiB,GAAU,EAAU,oBAK5D,qBAEmB,CAAC,cAgDA,CAAC,EA5C1C,KAAK,aAAa,CAAE,KAAM,MAAO,CAAC,EAC9B,KAAK,aACP,KAAK,WAAW,mBAAqB,KAAK,OAE9C,CAEA,yBAAyB,EAAc,EAAyB,EAAyB,CACvF,GAAI,IAAa,EAAU,OAM3B,IAAM,EAAa,KAJA,EAChB,MAAM,GAAG,CAAC,CACV,IAAK,GAAS,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAK,MAAM,CAAC,CAAC,CAAC,CAC3D,KAAK,EACgB,EAAW,SAE/B,OAAQ,KAAa,IAAgB,YACvC,KAAc,EAAW,CAAC,EAAU,CAAQ,CAEhD,CAMA,UAAoB,EAAsB,CACxC,KAAK,aAAa,MAAA,EAAA,EAAA,OAAA,CAAY,CAAQ,CAAC,CACzC,CAEA,mBAAoB,CAClB,GAAsB,IAAI,GAC1B,EAAA,EAAA,UAAA,KAAgB,CACd,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,CACpB,CAAC,CACH,CAEA,sBAAuB,CACrB,GAAwB,IAAI,EAE5B,KAAK,aAAa,QAAS,GAAY,EAAQ,CAAC,EAChD,KAAK,aAAe,CAAC,CACvB,CAIA,aAAsB,CACpB,IAAM,EAAa,KAAK,WACnB,GAGL,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,QAAS,GAAQ,CACxC,EAAW,iBAAiB,EAAK,IAAI,CACvC,CAAC,CACH,CAEA,YAAY,EAAoB,CAC9B,IAAM,EAAa,KAAK,OAAO,EAAM,MAEjC,GAAc,OAAQ,KAAa,IAAgB,YACrD,KAAc,EAAW,CAAC,CAAK,CAEnC,CAEA,KAA4B,EAAmB,EAA8B,CAAC,EAAG,CAC/E,KAAK,cACH,IAAI,YAAe,EAAW,CAC5B,QAAS,GACT,SAAU,GACV,GAAG,CACL,CAAC,CACH,CACF,CAKA,IAAc,QAA0B,CACtC,MAAO,CAAC,GAAG,KAAK,gBAAiB,GAAG,KAAK,WAAW,CACtD,CAEA,cAA+B,CAAC,CAEhC,QAAmB,CACZ,KAAK,aACV,KAAK,WAAW,UAAY,KAAK,YAAY,EAC7C,KAAK,aAAe,GACtB,CAEA,YAAsB,EAAkB,EAAqB,EAAiB,GAAM,CAClF,GAAI,CAAC,KAAK,YAAc,CAAC,KAAK,aAC5B,OAGF,IAAM,EAAK,KAAK,WAAW,cAAc,CAAQ,EACjD,GAAI,CAAC,EAAI,CACP,QAAQ,KAAK,mCAAmC,GAAU,EAC1D,MACF,CAEI,EACF,EAAG,UAAU,OAAO,SAAU,CAAU,EAExC,EAAG,UAAU,OAAO,YAAa,CAAU,CAE/C,CAEA,QAAkB,EAAkB,EAAuB,CACzD,IAAM,EAAK,KAAK,YAAY,cAAc,CAAQ,EAC9C,GAAM,EAAG,cAAgB,OAAO,CAAI,IACtC,EAAG,YAAc,OAAO,CAAI,EAEhC,CAEA,QAAkB,EAAkB,EAAc,EAAsB,CACtE,IAAM,EAAK,KAAK,YAAY,cAAc,CAAQ,EAC7C,IAED,IAAU,KACZ,EAAG,gBAAgB,CAAI,EACd,EAAG,aAAa,CAAI,IAAM,GACnC,EAAG,aAAa,EAAM,CAAK,EAE/B,CAEA,YAAsB,EAAkB,EAAmB,EAAiB,CAC1E,IAAM,EAAK,KAAK,YAAY,cAAc,CAAQ,EAC7C,GAEL,EAAG,UAAU,OAAO,EAAW,CAAK,CACtC,CAEA,WAAsD,EAA4B,CAChF,OAAO,KAAK,YAAY,cAAc,CAAQ,GAAK,IACrD,CACF,EC/Ja,EAAO,GAAyB,cAAc,EAAK,yUCChE,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoIxC,EAaY,EAAb,cAAwC,CAAY,2CAO/B,CACjB,MAAO,SACT,qBAEwB,wBAGG,GAAsB,CAC/C,IAAM,EAAO,EAAM,aAAa,EAC1B,EAAW,KAAK,WAAW,EAAI,UAAU,CAAC,EAC1C,EAAU,KAAK,WAAW,EAAI,SAAS,CAAC,EAE1C,GAAY,GAAW,CAAC,EAAK,SAAS,CAAQ,GAAK,CAAC,EAAK,SAAS,CAAO,GAC3E,KAAK,cAAc,CAEvB,EAnBA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAmBA,sBAAuB,CACrB,KAAK,cAAc,EACnB,MAAM,qBAAqB,CAC7B,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,IAAM,EAAO,KAAK,UAAU,YAAY,MAClC,EAAgB,KAAK,UAAU,cAAc,MAK7C,EAAS,KAAK,WAAwB,EAAI,QAAQ,CAAC,EAQzD,GAPI,IACF,EAAO,aAAa,iBAAkB,GAAM,IAAM,GAAM,MAAQ,EAAE,EAClE,EAAO,UAAY,GAAM,MACrB,aAAa,EAAK,MAAM,SAAS,EAAK,MAAQ,OAAO,aACrD,EAAY,GAAM,IAAI,GAGxB,CAAC,EAAM,CACT,KAAK,cAAc,EACnB,MACF,CAEA,IAAM,EAAU,KAAK,UAAU,qBAAqB,MAE9C,EAAW,KAAK,WAAW,EAAI,UAAU,CAAC,EAC5C,IAcF,EAAS,UAAY;YAZnB,EAAc,SAAW,GAAK,EAC1B,gGACA,EACG,IACE,GAAQ;mDACwB,EAAI,KAAO,EAAK,GAAK,aAAe,GAAG,+CAA+C,EAAI,GAAG;wBACxH,EAAI,KAAK;;mBAGjB,CAAC,CACA,KAAK,EAAE,EAGH;YACT,EAAc,OAAS,EAAI,wCAA0C,GAAG;;UAIhF,CAAC,CACH,CAEA,gBAAyB,CACnB,KAAK,cACP,KAAK,cAAc,EAEnB,KAAK,aAAa,CAEtB,CAEA,cAAuB,CACrB,GAAI,CAAC,KAAK,UAAU,YAAY,MAAO,OAKnC,KAAK,UAAU,cAAc,MAAM,SAAW,GAChD,KAAU,UAAU,kBAAkB,EAGxC,KAAK,cAAgB,GACrB,IAAM,EAAW,KAAK,WAAwB,EAAI,UAAU,CAAC,EACvD,EAAU,KAAK,WAAwB,EAAI,SAAS,CAAC,EAE3D,GAAI,GAAY,EAAS,CACvB,EAAS,UAAU,IAAI,SAAS,EAEhC,IAAM,MAAe,EACnB,EAAA,EAAA,gBAAA,CAAqB,EAAS,EAAU,CACtC,UAAW,eACX,WAAY,cAAQ,CAAC,aAAQ,cAAS,CAAE,QAAS,CAAE,CAAC,CAAC,EACrD,SAAU,OACZ,CAAC,CAAC,CAAC,MAAM,CAAE,IAAG,IAAG,eAAgB,CAC/B,OAAO,OAAO,EAAS,MAAO,CAAE,KAAM,GAAG,EAAE,IAAK,IAAK,GAAG,EAAE,IAAK,SAAU,OAAQ,CAAC,EAMlF,IAAM,EAAc,EAAU,WAAW,KAAK,EAC9C,EAAS,MAAM,YAAY,oBAAqB,EAAc,cAAgB,UAAU,EACxF,EAAS,MAAM,YAAY,qBAAsB,EAAc,MAAQ,MAAM,CAC/E,CAAC,CACH,EAEA,KAAK,kBAAA,EAAA,EAAA,WAAA,CAA8B,EAAS,EAAU,CAAM,EAC5D,SAAS,iBAAiB,YAAa,KAAK,eAAe,CAC7D,CACF,CAEA,eAAwB,CACtB,KAAK,cAAgB,GACrB,IAAM,EAAW,KAAK,WAAW,EAAI,UAAU,CAAC,EAC5C,GACF,EAAS,UAAU,OAAO,SAAS,EAErC,AAEE,KAAK,oBADL,KAAK,iBAAiB,EACE,IAAA,IAE1B,SAAS,oBAAoB,YAAa,KAAK,eAAe,CAChE,CAEA,QAAkB,EAAc,CAC9B,IAAM,EAAS,EAAM,OAErB,GAAI,EAAO,QAAQ,EAAI,SAAS,CAAC,EAAG,CAClC,EAAM,gBAAgB,EACtB,KAAK,eAAe,EACpB,MACF,CAEA,IAAM,EAAO,EAAO,QAAQ,EAAI,MAAM,CAAC,EACvC,GAAI,EAAM,CAIR,GAHA,EAAM,gBAAgB,EACtB,KAAK,cAAc,EAEf,EAAK,aAAa,aAAa,IAAM,WAAY,CACnD,KAAU,UAAU,kBAAkB,EACtC,MACF,CAEA,IAAM,EAAiB,EAAK,aAAa,aAAa,EAClD,GACF,KAAU,UAAU,mBAAmB,CAAc,CAEzD,CACF,CAEA,aAAgC,CAC9B,MAAkB;;;;;;;;;;;;KAapB,CACF,KAjLG,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EAmLpB,eAAe,IAAI,sBAAsB,GAC5C,eAAe,OAAO,uBAAwB,CAAkB,ECxUlE,IAAM,EAAc,EAEd,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkGxC,EAEY,EAAb,cAAiC,CAAY,2CAOxB,CACjB,MAAO,UACP,QAAS,YACT,MAAO,SACT,EARA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAQA,mBAAoB,CAClB,MAAM,kBAAkB,EACxB,KAAK,eAAe,CAAC,CAAC,EAAE,EAAE,MAAM,CAClC,CAEA,gBAA6C,CAC3C,OAAO,MAAM,KAAK,KAAK,YAAY,iBAAmC,EAAI,OAAO,CAAC,GAAK,CAAC,CAAC,CAC3F,CAEA,QAAkB,EAAc,CAC9B,IAAM,EAAS,EAAM,OAChB,EAAO,QAAQ,EAAI,OAAO,CAAC,IAEhC,EAAO,MAAQ,EAAO,MAAM,QAAQ,UAAW,EAAE,CAAC,CAAC,MAAM,EAAG,CAAC,EAEzD,EAAO,OAET,EADoB,oBACd,MAAM,EAGd,KAAK,YAAY,EACnB,CAEA,UAAoB,EAAsB,CACxC,IAAM,EAAS,EAAM,OAChB,EAAO,QAAQ,EAAI,OAAO,CAAC,GAE5B,EAAM,MAAQ,aAAe,CAAC,EAAO,OAEvC,EADoB,wBACd,MAAM,CAEhB,CAEA,QAAkB,EAAmB,CACnC,IAAM,EAAS,EAAM,OAErB,GAAI,EAAO,QAAQ,EAAI,SAAS,CAAC,EAAG,CAClC,KAAK,UAAU,WAAW,EAC1B,MACF,CAEA,GAAI,EAAO,QAAQ,EAAI,MAAM,CAAC,EAAG,CAC/B,KAAK,UAAU,YAAY,EAC3B,MACF,CACF,CAEA,aAA4B,CAC1B,IAAM,EAAS,KAAK,eAAe,CAAC,CAAC,IAAK,GAAU,EAAM,KAAK,EAC3D,EAAO,KAAM,GAAU,CAAC,CAAK,GACjC,KAAU,UAAU,UAAU,EAAO,KAAK,EAAE,CAAC,CAC/C,CAGA,gBAAwB,EAA4B,CAClD,IAAM,EAAc,EAAY,KAAK,IAAI,EACzC,GAAI,GAAe,EAAG,MAAO,GAE7B,IAAM,EAAK,KAAK,WAAiC,EAAI,QAAQ,CAAC,EAC9D,GAAI,CAAC,EAAI,MAAO,GAEhB,IAAM,EAAe,KAAK,KAAK,EAAc,GAAI,EAC3C,EAAU,KAAK,MAAM,EAAe,EAAE,EACtC,EAAU,EAAe,GAE/B,MADA,GAAG,UAAY,2BAA2B,EAAQ,GAAG,OAAO,CAAO,CAAC,CAAC,SAAS,EAAG,GAAG,EAAE,WAC/E,EACT,CAEA,cAAyB,CACvB,IAAI,EAAa,KAAK,UAAU,qBAAqB,KAAK,EAC1D,KAAK,cAAgB,CACnB,IAAM,EAAO,KAAK,UAAU,qBAAqB,MAC7C,IAAS,IACb,EAAa,EAGb,mBAAqB,CACnB,IAAM,EAAS,KAAK,eAAe,GAClC,EAAO,KAAM,GAAU,CAAC,EAAM,KAAK,GAAK,EAAO,GAAA,EAAK,MAAM,CAAE,cAAe,EAAK,CAAC,CACpF,CAAC,EACH,CAAC,EAED,KAAK,cAAgB,CACnB,IAAM,EAAY,KAAK,UAAU,aAAa,MAC9C,GAAI,CAAC,EAAW,OAEhB,KAAK,gBAAgB,CAAS,EAI9B,IAAM,EAAW,OAAO,gBAAkB,CACnC,KAAK,gBAAgB,CAAS,IACnC,OAAO,cAAc,CAAQ,EAC7B,KAAK,UAAU,UAAU,EAC3B,EAAG,GAAI,EACP,UAAa,OAAO,cAAc,CAAQ,CAC5C,CAAC,EAED,KAAK,cAAgB,CACnB,IAAM,EAAU,KAAK,UAAU,WAAW,MACpC,EAAS,KAAK,eAAe,EACnC,EAAO,QAAS,GAAU,CACxB,EAAM,SAAW,CACnB,CAAC,EAQG,CAAC,GAAW,CAAC,KAAK,YAAY,gBAC/B,EAAO,KAAM,GAAU,CAAC,EAAM,KAAK,GAAK,EAAO,GAAA,EAAK,MAAM,CAAE,cAAe,EAAK,CAAC,CAEtF,CAAC,EAED,KAAK,cAAgB,CACnB,IAAM,EAAQ,KAAK,UAAU,SAAS,MAEhC,EAAU,KAAK,WAA2B,EAAI,OAAO,CAAC,EAM5D,GALI,IACF,EAAQ,OAAS,CAAC,EAClB,EAAQ,YAAc,GAAS,IAG7B,EAAO,CACT,IAAM,EAAS,KAAK,eAAe,EACnC,EAAO,QAAS,GAAU,CACxB,EAAM,MAAQ,EAChB,CAAC,EACD,EAAO,EAAE,EAAE,MAAM,CACnB,CACF,CAAC,CACH,CAEA,aAAgC,CAQ9B,MAAkB;;;8EAPH,MAAM,KAAK,CAAE,OAAQ,CAAY,CAAC,CAAC,CAC/C,KACE,EAAG,IACF,4IAA4I,EAAQ,EAAE,MAAM,EAAY,KAC5K,CAAC,CACA,KAAK,EAKkE,EAAO;;;;;;;;;;;;;;;KAgBnF,CACF,KA/KG,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EAiLpB,eAAe,IAAI,eAAe,GACrC,eAAe,OAAO,gBAAiB,CAAW,EC9RpD,IAAA,GAAe,6vECAf,GAAe,6sECKF,EAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QCG/B,GAAgB,6BAEhB,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoGxC,EAEY,EAAb,cAAkC,CAAY,2CAOzB,CACjB,MAAO,UACP,OAAQ,UACV,EAPA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAOA,mBAAoB,CAClB,MAAM,kBAAkB,EAGxB,IAAM,EAAQ,KAAK,WAA6B,EAAI,OAAO,CAAC,EACxD,IAAO,EAAM,MAAQ,KAAK,UAAU,SAAS,OACjD,KAAK,2BAA2B,CAClC,CAEA,4BAA2C,CACzC,IAAM,EAAQ,KAAK,WAA6B,EAAI,OAAO,CAAC,EAC5D,GAAI,CAAC,EAAO,OAKZ,IAAM,MAAc,CACd,EAAM,aAAa,EAAM,MAAM,CAAE,cAAe,EAAK,CAAC,CAC5D,EASM,EADO,KAAK,QAAQ,cACV,CAAA,EAAM,cAAc,GAAK,CAAC,EAC1C,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAM,EACN,MACF,CAEA,QAAa,WAAW,EAAQ,IAAK,GAAc,EAAU,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAK,CACpF,CAEA,QAAkB,EAAmB,CACnC,IAAM,EAAS,EAAM,OAErB,GAAI,EAAO,QAAQ,EAAI,QAAQ,CAAC,EAAG,CACjC,KAAU,UAAU,cAAc,EAClC,MACF,CAEA,GAAI,EAAO,QAAQ,EAAI,OAAO,CAAC,EAAG,CAChC,KAAU,UAAU,cAAc,EAClC,MACF,CACF,CAEA,SAAmB,EAAc,CAC/B,EAAM,eAAe,EACrB,KAAU,eAAe,CAC3B,CAEA,MAAc,gBAAgC,CAC5C,IAAM,EAAQ,KAAK,WAA6B,EAAI,OAAO,CAAC,EAC5D,GAAI,CAAC,EAAO,OAEZ,IAAM,EAAQ,EAAM,MAAM,KAAK,EAC/B,GAAI,CAAC,GAAc,KAAK,CAAK,EAAG,CAC9B,KAAK,UAAU,SAAS,MAAQ,+BAChC,MACF,CAEA,MAAM,KAAK,UAAU,QAAQ,CAAK,CACpC,CAEA,cAAyB,CACvB,IAAI,EAAa,KAAK,UAAU,qBAAqB,KAAK,EAC1D,KAAK,cAAgB,CACnB,IAAM,EAAO,KAAK,UAAU,qBAAqB,MAC7C,IAAS,IACb,EAAa,EAGb,mBAAqB,CACnB,KAAK,WAA6B,EAAI,OAAO,CAAC,CAAC,EAAE,MAAM,CAAE,cAAe,EAAK,CAAC,CAChF,CAAC,EACH,CAAC,EAED,KAAK,cAAgB,CACnB,IAAM,EAAU,KAAK,UAAU,WAAW,MACpC,EAAQ,KAAK,UAAU,SAAS,MAEhC,EAAS,KAAK,WAA8B,EAAI,QAAQ,CAAC,EAC3D,IACF,EAAO,SAAW,EAClB,EAAO,YAAc,EAAU,gBAAkB,YAGnD,IAAM,EAAU,KAAK,WAA2B,EAAI,OAAO,CAAC,EACxD,IACF,EAAQ,OAAS,CAAC,EAClB,EAAQ,YAAc,GAAS,GAEnC,CAAC,CACH,CAEA,aAAgC,CAC9B,MAAkB;;oEAE8C,EAAsB;;;;;;;;;;;;;;;;;;;;wBAoBlE,GAAa;;;;;;;;wBAQb,GAAc;;;;;;;KAQpC,CACF,KAtJG,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EAwJpB,eAAe,IAAI,gBAAgB,GACtC,eAAe,OAAO,iBAAkB,CAAY,EEnQtD,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuExC,EAEY,EAAb,cAAiC,CAAY,2CAOxB,CACjB,MAAO,UACP,QAAS,YACT,SAAU,YACZ,EARA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CASA,cAAqB,CACnB,KAAK,aAAa,gBAAiB,EAAE,EACrC,KAAK,WAA8B,EAAI,MAAM,CAAC,CAAC,EAAE,MAAM,CAAE,cAAe,EAAK,CAAC,CAChF,CAIA,WAAsB,CACpB,KAAK,gBAAgB,eAAe,CACtC,CAEA,YAAuB,CACrB,KAAK,gBAAgB,eAAe,CACtC,CAEA,QAAkB,EAAmB,CAC7B,EAAM,OAAuB,QAAQ,EAAI,MAAM,CAAC,GACtD,KAAK,WAAW,CAClB,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,IAAM,EAAU,KAAK,UAAU,YAAY,MAErC,EAAU,KAAK,WAA8B,EAAI,MAAM,CAAC,EAC1D,IACF,EAAQ,SAAW,GAErB,KAAK,QAAQ,EAAI,OAAO,EAAG,EAAU,cAAqB,uBAAuB,CACnF,CAAC,CACH,CAEA,YAA2B,CACzB,KAAK,UAAU,eAAe,EAC9B,KAAK,UAAU,iBAAiB,CAClC,CAEA,aAAgC,CAC9B,MAAkB;;;;6DAIuC,EAAsB;;;KAIjF,CACF,KA5DG,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EA8DpB,eAAe,IAAI,eAAe,GACrC,eAAe,OAAO,gBAAiB,CAAW,EC3IpD,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCxC,EAEY,EAAb,cAAmC,CAAY,2CAO1B,CACjB,MAAO,SACT,EANA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CASA,mBAAoB,CAClB,MAAM,kBAAkB,EACxB,KAAK,WAAwB,gBAAgB,CAAC,EAAE,MAAM,CACxD,CAIA,cAAyB,CACvB,IAAI,EAAa,KAAK,UAAU,qBAAqB,KAAK,EAC1D,KAAK,cAAgB,CACnB,IAAM,EAAO,KAAK,UAAU,qBAAqB,MAC7C,IAAS,IACb,EAAa,EACb,mBACE,KAAK,WAAwB,gBAAgB,CAAC,EAAE,MAAM,CAAE,cAAe,EAAK,CAAC,CAC/E,EACF,CAAC,CACH,CAEA,QAAkB,EAAmB,CACnC,IAAM,EAAS,EAAM,OAErB,GAAI,EAAO,QAAQ,EAAI,QAAQ,CAAC,EAAG,CACjC,KAAU,UAAU,UAAU,EAC9B,MACF,CAEA,GAAI,EAAO,QAAQ,EAAI,MAAM,CAAC,EAAG,CAC/B,KAAK,UAAU,WAAW,EAC1B,MACF,CACF,CAEA,aAAgC,CAC9B,MAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+BpB,CACF,KA/EG,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EAiFpB,eAAe,IAAI,kBAAkB,GACxC,eAAe,OAAO,mBAAoB,CAAa,EChIzD,IAAA,GAAe,iwICOT,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmJxC,EAUY,EAAb,cAAkC,CAAY,2CAGZ,oBACG,kCACY,+BAC2B,KAE1E,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAEA,sBAAuB,CACrB,KAAK,0BAA0B,EAC/B,MAAM,qBAAqB,CAC7B,CAEA,2BAA0C,CACpC,KAAK,wBAA0B,OACjC,OAAO,qBAAqB,KAAK,qBAAqB,EACtD,KAAK,sBAAwB,MAG/B,IAAM,EAAO,KAAK,WAA2B,EAAI,MAAM,CAAC,EACxD,AAEE,KAAK,wBADL,GAAM,oBAAoB,gBAAiB,KAAK,oBAAoB,EACxC,KAEhC,CAEA,gBAAwB,EAAsB,EAAuB,EAAqB,CACxF,KAAK,0BAA0B,EAE/B,IAAM,EAAiB,EAAK,sBAAsB,CAAC,CAAC,OACpD,EAAK,MAAM,OAAS,GAAG,EAAe,IACtC,EAAM,UAAY,IAAI,EAAM,KAAK,EAAM,GAEvC,KAAK,sBAAwB,OAAO,0BAA4B,CAC9D,KAAK,sBAAwB,KAK7B,IAAM,EAAa,EAAM,sBAAsB,CAAC,CAAC,OAEjD,GAAI,KAAK,IAAI,EAAa,CAAc,EAAI,EAAG,CAC7C,EAAK,MAAM,OAAS,GACpB,MACF,CAEA,KAAK,qBAAwB,GAA2B,CAClD,EAAM,SAAW,GAAQ,EAAM,eAAiB,WACpD,EAAK,MAAM,OAAS,GACpB,EAAK,oBAAoB,gBAAiB,KAAK,oBAAqB,EACpE,KAAK,qBAAuB,KAC9B,EACA,EAAK,iBAAiB,gBAAiB,KAAK,oBAAoB,EAChE,EAAK,MAAM,OAAS,GAAG,EAAW,GACpC,CAAC,CACH,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,IAAM,EAAO,KAAK,UAAU,SAAS,MAC/B,EACJ,IAAS,QACL,iBACA,IAAS,OACP,gBACA,IAAS,UACP,mBACA,KAMJ,EACJ,IAAS,QACT,KAAK,YAAc,QACnB,KAAK,WAAW,EAAI,MAAM,CAAC,CAAC,EAAE,QAAQ,eAAe,EAEvD,KAAK,YAAY,EAAI,OAAO,EAAG,cAAe,IAAY,IAAI,EAE1D,GACF,KAAK,WAAwB,eAAe,CAAC,EAAE,aAAa,EAS9D,IAAM,EAAmB,KAAK,YAAc,QAAU,IAAS,OACzD,EAAQ,KAAK,WAA2B,EAAI,cAAc,CAAC,EACjE,GAAI,GAAS,IAAY,KAAK,SAAW,GAAW,GAAmB,CACrE,IAAM,EAAO,KAAK,WAA2B,EAAI,MAAM,CAAC,EACxD,KAAK,OAAS,EACV,GAAQ,KAAK,YAAc,OAC7B,KAAK,gBAAgB,EAAM,EAAO,CAAO,EAEzC,EAAM,UAAY,IAAI,EAAQ,KAAK,EAAQ,EAE/C,CAEA,KAAK,UAAY,CACnB,CAAC,CACH,CAEA,aAAgC,CAC9B,MAAkB;;;;;0BAKI,GAAa;;;;;;;;;KAUrC,CACF,KA9HG,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EAgIpB,eAAe,IAAI,gBAAgB,GACtC,eAAe,OAAO,iBAAkB,CAAY,ECpStD,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuHxC,EAEK,GAAQ,IAAI,IAAI,CAAC,KAAM,KAAM,IAAI,CAAC,EAClC,GAAS,IAAI,IAAI,CAAC,UAAW,QAAS,OAAO,CAAC,EAWvC,GAAb,cAAmC,CAAY,2CAwG1B,CACjB,MAAO,SACT,EAzGA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAEA,WAAW,oBAAqB,CAC9B,MAAO,CAAC,OAAQ,OAAQ,QAAS,UAAW,WAAY,OAAQ,SAAU,KAAK,CACjF,CAEA,eAAgB,CACd,KAAK,OAAO,CACd,CAEA,eAAgB,CACd,KAAK,OAAO,CACd,CAEA,gBAAiB,CACf,KAAK,OAAO,CACd,CAEA,kBAAmB,CACjB,KAAK,OAAO,CACd,CAEA,mBAAoB,CAClB,KAAK,OAAO,CACd,CAEA,eAAgB,CACd,KAAK,OAAO,CACd,CAEA,iBAAkB,CAChB,KAAK,OAAO,CACd,CAEA,cAAe,CACb,KAAK,OAAO,CACd,CAEA,IAAI,MAAsB,CACxB,OAAO,KAAK,aAAa,MAAM,CACjC,CAEA,IAAI,KAAK,EAAsB,CACzB,IAAU,KACZ,KAAK,gBAAgB,MAAM,EAE3B,KAAK,aAAa,OAAQ,CAAK,CAEnC,CAEA,IAAI,MAA2B,CAC7B,IAAM,EAAQ,KAAK,aAAa,MAAM,EACtC,OAAO,GAAS,GAAM,IAAI,CAAK,EAAK,EAA+B,IACrE,CAEA,IAAI,KAAK,EAA2B,CAClC,KAAK,aAAa,OAAQ,CAAK,CACjC,CAEA,IAAI,OAAuC,CACzC,IAAM,EAAQ,KAAK,aAAa,OAAO,EACvC,OAAO,GAAS,GAAO,IAAI,CAAK,EAAK,EAA0C,SACjF,CAEA,IAAI,MAAM,EAAsC,CAC9C,KAAK,aAAa,QAAS,CAAK,CAClC,CAEA,IAAI,SAAmB,CACrB,OAAO,KAAK,aAAa,SAAS,CACpC,CAEA,IAAI,QAAQ,EAAgB,CACtB,EACF,KAAK,aAAa,UAAW,EAAE,EAE/B,KAAK,gBAAgB,SAAS,CAElC,CAEA,IAAI,UAAoB,CACtB,OAAO,KAAK,aAAa,UAAU,CACrC,CAEA,IAAI,SAAS,EAAgB,CACvB,EACF,KAAK,aAAa,WAAY,EAAE,EAEhC,KAAK,gBAAgB,UAAU,CAEnC,CAEA,IAAI,MAAsC,CACxC,IAAM,EAAQ,KAAK,aAAa,MAAM,EACtC,OAAO,IAAU,UAAY,IAAU,QAAU,EAAQ,QAC3D,CAEA,IAAI,KAAK,EAAsC,CAC7C,KAAK,aAAa,OAAQ,CAAK,CACjC,CAMA,QAAkB,EAAmB,CAC9B,KAAK,WACV,EAAM,eAAe,EACrB,EAAM,yBAAyB,EACjC,CAEA,WAAmB,EAAuB,CACxC,OAAO,KAAK,cAAc,mBAAmB,EAAK,GAAG,IAAM,IAC7D,CAGA,UAA4B,CAC1B,OAAO,MAAM,KAAK,KAAK,UAAU,CAAC,CAAC,KAAM,GACnC,EAAK,WAAa,KAAK,aAClB,CAAE,EAAiB,aAAa,MAAM,EAExC,EAAK,WAAa,KAAK,WAAa,CAAC,CAAC,EAAK,aAAa,KAAK,CACrE,CACH,CAEA,aAAgC,CAC9B,IAAM,EAAU,CACd,WACA,kBAAkB,KAAK,OACvB,mBAAmB,KAAK,QACxB,KAAK,QAAU,oBAAsB,GACrC,KAAK,SAAW,cAAgB,EAClC,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,EAEL,EAAU,KAAK,WAAW,SAAS,EACrC,mEACA,GACE,EAAW,KAAK,WAAW,UAAU,EACvC,oEACA,GAEE,EAAQ,GAAG,IADH,KAAK,SAAS,EAAI,qDAAuD,KACpD,IAEnC,GAAI,KAAK,OAAS,KAAM,CACtB,IAAM,EAAgB,KAAK,SAAW,qCAAuC,GACvE,EAAS,KAAK,aAAa,QAAQ,EACnC,EAAM,KAAK,aAAa,KAAK,EACnC,MAAkB;;mBAEL,EAAQ;;kBAET,KAAK,KAAK;YAChB,EAAS,WAAW,EAAO,GAAK,GAAG;YACnC,EAAM,QAAQ,EAAI,GAAK,GAAG;YAC1B,EAAc;aACb,EAAM;;OAGf,CAEA,MAAkB;;iBAEL,EAAQ;;gBAET,KAAK,KAAK;UAChB,KAAK,SAAW,WAAa,GAAG;;UAEhC,EAAM;;KAGd,CACF,EAEK,eAAe,IAAI,iBAAiB,GACvC,eAAe,OAAO,kBAAmB,EAAa,EC1TxD,IAAA,GAAe,i5DCAF,EAAS,mSAoCtB,EAEa,GAAe,GACtB,OAAO,GAAU,SACZ,EAAO,EAAQ,EAAO,SAAW,UAEnC,EAAO,KAAK,MAAM,KAAK,OAAO,EAAI,EAAO,MAAM,GAIxD,SAAgB,GAAQ,EAAsB,CAC5C,IAAM,EAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,EACvC,EAAI,WACR,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACrC,IAAM,EAAO,EAAM,IAAM,EACzB,GAAK,EACL,EAAI,KAAK,KAAK,EAAG,QAAU,CAC7B,CACA,OAAO,IAAM,CACf,CAGA,SAAgB,GAAgB,EAAoB,CAClD,OAAO,EAAO,GAAQ,CAAE,EAAI,EAAO,SAAW,SAChD,CCxDA,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiGxC,EAEY,GAAb,cAAsC,CAAY,CAGhD,aAAc,CACZ,MAAM,EACN,KAAK,iBAAmB,GAAY,GAAK,SAC3C,CAEA,WAAW,oBAAqB,CAC9B,MAAO,CAAC,OAAQ,iBAAkB,SAAS,CAC7C,CAEA,eAAgB,CACd,KAAK,OAAO,CACd,CAEA,uBAAwB,CACtB,KAAK,OAAO,CACd,CAEA,kBAAmB,CACjB,KAAK,OAAO,CACd,CAEA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAEA,IAAI,MAAe,CACjB,OAAO,KAAK,aAAa,MAAM,GAAK,IACtC,CAEA,IAAI,KAAK,EAAe,CACtB,KAAK,aAAa,OAAQ,CAAK,CACjC,CAEA,IAAI,SAAmB,CACrB,OAAO,KAAK,aAAa,SAAS,CACpC,CAEA,IAAI,QAAQ,EAAgB,CACtB,EACF,KAAK,aAAa,UAAW,EAAE,EAE/B,KAAK,gBAAgB,SAAS,CAElC,CAEA,aAAgC,CAC9B,IAAM,EAAO,KAAK,KACZ,EAAU,KAAK,QACf,EAAM,KAAK,aAAa,gBAAgB,EACxC,EAAK,EACP,uCACA,EACE,GAAgB,CAAG,EACnB,KAAK,iBAcX,MAAkB;wDACkC,EAAK;;UAbzC,EACZ;;;qCAG6B,EAAG;0DACkB,GAAmB,+BACrE;;;qCAG6B,EAAG;kBAMtB;;KAGhB,CACF,EAEK,eAAe,IAAI,oBAAoB,GAC1C,eAAe,OAAO,qBAAsB,EAAgB,EClL9D,IAAM,GAAyB,IACzB,EAAwB,EAExB,GAA6B,EAE7B,EAAkB,GAAqB,CAC3C,IAAM,EACJ,OAAO,EAAQ,WAAc,SACzB,EAAQ,UACR,KAAK,MAAM,OAAO,EAAQ,SAAS,CAAC,EAE1C,OAAO,OAAO,SAAS,CAAS,EAAI,EAAY,CAClD,EAEM,GAAuB,EAAmB,IAAqB,CACnE,IAAM,EAAQ,GAAM,cAAgB,EAEpC,OAAO,EAAQ,EAAI,EAAQ,CAC7B,EAoBM,IAAkB,EAAsB,IACvC,GAIE,CAAE,GAAG,EAAS,GAAG,CAAU,EAGvB,EAAb,KAAuB,CAqFrB,YAAY,EAOT,mBArFqB,iCAKmB,IAAI,+BAEJ,CAAC,CAAC,+BAKvB,GAAe,KAAK,aAAa,MAAO,KAAK,WAAW,KAAK,CAAC,6BACvD,CAAC,CAAC,4BACd,EAAI,0BACS,IAAI,yBACpB,EAAK,+BACgB,IAAI,qCACE,IAAI,uCACF,IAAI,cAEZ,2BACR,sBACoC,mBAC5C,4CAGjB,KAAK,SAAS,MACX,OAAQ,GAAM,EAAE,kBAAoB,IAAI,CAAC,CACzC,MAAM,EAAG,IAAM,OAAO,EAAE,OAAO,CAAC,CAAC,cAAc,OAAO,EAAE,OAAO,CAAC,CAAC,CACtE,sCAG8B,KAAK,KAAK,OAAO,SAAW,KAAO,KAAO,IAAK,4CAE1C,CACjC,IAAM,EAAK,KAAK,WAAW,MAE3B,OADK,EACE,KAAK,SAAS,MAAM,KAAM,GAAM,EAAE,KAAO,CAAE,GAAK,KADvC,IAElB,CAAC,yCAE+B,CAC9B,IAAM,EAAK,KAAK,iBAAiB,MAEjC,OADK,EACE,KAAK,SAAS,MAAM,KAAM,GAAM,EAAE,KAAO,CAAE,GAAK,KADvC,IAElB,CAAC,0CAGC,KAAK,iBAAiB,MAAM,MAAM,EAAG,EAAoB,KAAK,KAAK,MAAO,KAAK,YAAY,CAAC,CAC9F,yCAEiD,CAC/C,IAAM,EAAQ,EAAoB,KAAK,KAAK,MAAO,KAAK,YAAY,EACpE,GAAI,GAAS,GAA4B,MAAO,CAAC,EAEjD,IAAM,EAAO,IAAI,IACX,EAAqC,CAAC,EAEtC,EAAS,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC,CAAC,MAAM,EAAG,IAAM,EAAe,CAAC,EAAI,EAAe,CAAC,CAAC,EAE5F,IAAK,IAAM,KAAW,EAAQ,CAC5B,IAAM,EAAS,EAAQ,OAEnB,MAAC,GAAQ,IAAM,EAAK,IAAI,EAAO,EAAE,KAIrC,EAAK,IAAI,EAAO,EAAE,EAClB,EAAkB,KAAK,CAAM,EAEzB,EAAkB,QAAU,GAC9B,KAEJ,CAEA,OAAO,EAAkB,QAAQ,CACnC,CAAC,EAUC,KAAK,OAAS,EAAK,OACnB,KAAK,UAAY,EAAK,UACtB,KAAK,QAAU,EAAK,QACpB,KAAK,WAAa,EAAK,YAAY,KAAK,GAAK,KAC7C,KAAK,KAAO,EAAK,MAAQ,GACzB,KAAK,UAAY,EAAK,SACxB,CAGA,SAAS,CAAE,OAAM,YAA4B,CAC3C,KAAK,aAAa,MAAQ,EAC1B,KAAK,SAAS,MAAQ,EACtB,KAAK,MAAM,MAAQ,KACnB,KAAK,QAAQ,MAAQ,EACvB,CAMA,aAAa,EAAgC,CAC3C,KAAK,WAAW,MAAQ,CAC1B,CAGA,gBAAiC,CAC/B,IAAM,EAAS,IAAI,gBAAgB,CAAE,QAAS,KAAK,OAAQ,CAAC,EAI5D,OAHI,KAAK,YACP,EAAO,IAAI,aAAc,KAAK,UAAU,EAEnC,EAAO,SAAS,CACzB,CAEA,WAAW,EAA6B,CACtC,IAAM,EAAS,KAAK,SAAS,MAAM,KAAM,GAAM,EAAE,KAAO,CAAQ,EAEhE,OADK,EACE,KAAK,SAAS,MAClB,OACE,GACC,EAAE,KAAO,IACR,EAAE,UAAY,EAAO,SAAW,EAAE,QAAQ,WAAW,EAAO,QAAU,GAAG,EAC9E,CAAC,CACA,MAAM,EAAG,IAAM,OAAO,EAAE,OAAO,CAAC,CAAC,cAAc,OAAO,EAAE,OAAO,CAAC,CAAC,EAPhD,CAAC,CAQvB,CAEA,MAAM,MAAyB,CAC7B,KAAK,QAAQ,MAAQ,GACrB,KAAK,MAAM,MAAQ,KACnB,GAAI,CACF,IAAM,EAAU,MAAM,KAAK,UAAU,eACnC,uBAAuB,KAAK,WAC9B,EAEA,GAAI,CAAC,EAAQ,GAEX,MADA,MAAK,MAAM,MAAQ,0CACZ,GAGT,IAAM,EAAQ,MAAM,EAAQ,KAAK,EACjC,KAAK,aAAa,MAAQ,EAAK,KAC/B,KAAU,gBAAgB,EAE1B,IAAM,EAAc,MAAM,KAAK,UAAU,eACvC,uBAAuB,KAAK,UAAU,YAAY,KAAK,eAAe,GACxE,EAEA,GAAI,EAAY,GAAI,CAClB,IAAM,EAAgB,MAAM,EAAY,KAAK,EAC7C,KAAK,SAAS,MAAQ,EAAa,QACrC,CAEA,MAAO,EACT,MAAQ,CAGN,OAFA,QAAQ,MAAM,wBAAwB,EACtC,KAAK,MAAM,MAAQ,0CACZ,EACT,QAAU,CACR,KAAK,QAAQ,MAAQ,EACvB,CACF,CAEA,MAAM,YAAY,EAAc,EAAmD,CACjF,IAAM,EAAM,MAAM,KAAK,UAAU,gBAC/B,uBAAuB,KAAK,UAAU,WACtC,CACE,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CACnB,OACA,QAAS,KAAK,QACd,WAAY,KAAK,YAAc,IAAA,GAC/B,iBACF,CAAC,CACH,CACF,EAEA,GAAI,CAAC,EAAI,GACP,OAAO,KAGT,IAAM,EAAQ,MAAM,EAAI,KAAK,EAY7B,OAXA,KAAK,cAAc,EAAK,OAAO,EAE3B,EAAK,QAAQ,QAAU,CAAC,KAAK,UAAU,YAAY,QACrD,KAAK,UAAU,YAAY,MAAQ,CACjC,GAAI,EAAK,QAAQ,OAAO,GACxB,KAAM,EAAK,QAAQ,OAAO,MAAQ,GAClC,MAAO,GACP,MAAO,EAAK,QAAQ,OAAO,KAC7B,GAGK,EAAK,OACd,CAEA,SAAgB,CACd,KAAK,SAAW,GAEhB,AAEE,KAAK,kBADL,aAAa,KAAK,cAAc,EACV,MAGxB,AAME,KAAK,UALL,KAAK,OAAO,OAAS,KACrB,KAAK,OAAO,UAAY,KACxB,KAAK,OAAO,QAAU,KACtB,KAAK,OAAO,QAAU,KACtB,KAAK,OAAO,MAAM,EACJ,KAElB,CAEA,MAAc,iBAAiC,CAC7C,IAAM,EAAa,KAAK,KAAK,OAAO,WAEpC,GAAI,CAAC,GAAc,KAAK,SACtB,OAGF,AAME,KAAK,UALL,KAAK,OAAO,OAAS,KACrB,KAAK,OAAO,UAAY,KACxB,KAAK,OAAO,QAAU,KACtB,KAAK,OAAO,QAAU,KACtB,KAAK,OAAO,MAAM,EACJ,MAOhB,IAAI,EAAwB,KAC5B,GAAI,CACF,IAAM,EAAY,MAAM,KAAK,UAAU,eACrC,uBAAuB,KAAK,UAAU,iBACtC,CAAE,OAAQ,MAAO,CACnB,EACI,EAAU,KAEZ,GAAS,MADiB,EAAU,KAAK,EAAA,CACrB,OAExB,MAAQ,CAER,CAEA,GAAI,CAAC,GAAU,KAAK,SAAU,CAC5B,KAAK,kBAAkB,EACvB,MACF,CAEA,IAAM,EAAQ,IAAI,IAAI,EAAY,KAAK,MAAM,EAC7C,EAAM,SAAW,EAAM,WAAa,SAAW,OAAS,MACxD,EAAM,aAAa,IAAI,SAAU,CAAM,EACvC,EAAM,aAAa,IAAI,UAAW,KAAK,OAAO,EAC1C,KAAK,YACP,EAAM,aAAa,IAAI,aAAc,KAAK,UAAU,EAGtD,IAAM,EAAS,IAAI,UAAU,EAAM,SAAS,CAAC,EAC7C,KAAK,OAAS,EAEd,EAAO,WAAe,CACpB,KAAK,iBAAmB,CAC1B,EAEA,EAAO,UAAa,GAAU,CAC5B,GAAI,CACF,IAAM,EAAU,KAAK,MAAM,OAAO,EAAM,IAAI,CAAC,EAKzC,EAAQ,OAAS,mBAAqB,EAAQ,QAChD,KAAK,cAAc,EAAQ,OAAO,EACzB,EAAQ,OAAS,mBAAqB,EAAQ,SACvD,KAAK,oBAAoB,EAAQ,OAAO,CAE5C,MAAQ,CAER,CACF,EAEA,EAAO,YAAgB,CACjB,KAAK,UAIT,KAAK,kBAAkB,CACzB,EAEA,EAAO,YAAgB,CACrB,EAAO,MAAM,CACf,CACF,CAEA,mBAAkC,CAChC,GAAI,KAAK,UAAY,KAAK,eACxB,OAGF,IAAM,EAAQ,EAAiB,KAAK,iBAAkB,IAAM,EAAsB,EAClF,KAAK,kBAAoB,EAEzB,KAAK,eAAiB,eAAiB,CACrC,KAAK,eAAiB,KACtB,KAAU,gBAAgB,CAC5B,EAAG,CAAK,CACV,CAEA,cAAsB,EAAwB,CAC3B,KAAK,SAAS,MAAM,KAAM,GAAU,EAAM,KAAO,EAAQ,EAEtE,IAIJ,KAAK,SAAS,MAAQ,CAAC,GAAG,KAAK,SAAS,MAAO,CAAO,EACxD,CAEA,MAAM,YAAY,EAAmB,EAAuC,CAC1E,IAAM,EAAM,MAAM,KAAK,UAAU,gBAC/B,uBAAuB,KAAK,UAAU,YAAY,IAClD,CACE,OAAQ,QACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CACnB,OACA,QAAS,KAAK,QACd,WAAY,KAAK,YAAc,IAAA,EACjC,CAAC,CACH,CACF,EAEA,GAAI,CAAC,EAAI,GACP,OAAO,KAGT,IAAM,EAAQ,MAAM,EAAI,KAAK,EAE7B,OADA,KAAK,oBAAoB,EAAK,OAAO,EAC9B,EAAK,OACd,CAEA,MAAM,cAAc,EAA4C,CAC9D,IAAM,EAAM,MAAM,KAAK,UAAU,gBAC/B,uBAAuB,KAAK,UAAU,YAAY,EAAU,GAAG,KAAK,eAAe,IACnF,CAAE,OAAQ,QAAS,CACrB,EAEA,GAAI,CAAC,EAAI,GACP,OAAO,KAGT,IAAM,EAAQ,MAAM,EAAI,KAAK,EAE7B,OADA,KAAK,oBAAoB,EAAK,OAAO,EAC9B,EAAK,OACd,CAEA,MAAM,YAAY,EAAqC,CAMrD,OAAO,MALW,KAAK,UAAU,gBAC/B,uBAAuB,KAAK,UAAU,YAAY,EAAU,QAAQ,KAAK,eAAe,IACxF,CAAE,OAAQ,MAAO,CACnB,EAAA,CAEW,EACb,CAEA,oBAA4B,EAAwB,CAClD,KAAK,SAAS,MAAQ,KAAK,SAAS,MAAM,IAAK,GAAO,EAAE,KAAO,EAAQ,GAAK,EAAU,CAAE,CAC1F,CACF,EC3aM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkHxC,EAEK,GAAqB;;;;;;;;;QAWd,EAAb,cAAmC,CAAY,2CAQ1B,CACjB,MAAO,SACT,EANA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAMA,QAAkB,EAAmB,CAC7B,EAAM,OAAuB,QAAQ,EAAI,MAAM,CAAC,GACtD,KAAU,WAAW,CACvB,CAEA,cAAyB,CACvB,IAAI,EAAgC,KAChC,EAAsC,KAE1C,KAAK,cAAgB,CACnB,IAAM,EAAkB,KAAK,UAAU,WAAW,MAElD,GAAI,GAAmB,IAAoB,EAAgB,CACzD,IAAM,EAAQ,KAAK,WAA4B,mBAAmB,EAC9D,GACF,eAAiB,EAAM,MAAM,EAAG,CAAC,CAErC,CACA,EAAiB,CACnB,CAAC,EAED,KAAK,cAAgB,CACnB,IAAM,EAAiB,KAAK,UAAU,eAAe,MACrD,GAAI,GAAkB,EAAe,KAAO,EAAsB,CAChE,IAAM,EAAQ,KAAK,WAA4B,mBAAmB,EAC9D,IACF,EAAM,SAAS,EAAe,IAAI,EAClC,eAAiB,EAAM,MAAM,EAAG,CAAC,EAErC,MAAO,GAAI,CAAC,GAAkB,EAAsB,CAClD,IAAM,EAAQ,KAAK,WAA4B,mBAAmB,EAC9D,GACF,EAAM,MAAM,CAEhB,CACA,EAAuB,GAAgB,IAAM,IAC/C,CAAC,EASD,KAAK,cAAgB,CACnB,IAAM,EAAU,KAAK,WAA2B,EAAI,MAAM,CAAC,EACrD,EAAc,KAAK,WAAwB,EAAI,cAAc,CAAC,EACpE,GAAI,CAAC,GAAW,CAAC,EAAa,OAG9B,IAAM,EADiB,KAAK,UAAU,eAAe,MACf,KAAO,KAAK,UAAU,kBAAkB,OAAO,OAKrF,GAHA,EAAQ,UAAU,OAAO,YAAa,EAAQ,CAAa,EAC3D,EAAY,UAAU,OAAO,SAAU,CAAC,CAAY,EAEhD,EAAc,CAChB,IAAM,EAAiB,EAAa,IAAM,EAAa,MAAQ,GAC/D,EAAY,aAAa,iBAAkB,CAAc,EACzD,EAAY,UAAY,EAAa,MACjC,aAAa,EAAa,MAAM,SAAS,EAAa,MAAQ,OAAO,aACrE,EAAY,EAAa,IAAI,CACnC,CACF,CAAC,CACH,CAEA,MAAc,YAA4B,CACxC,IAAM,EAAQ,KAAK,WAA4B,mBAAmB,EAClE,GAAI,CAAC,EAAO,OAEZ,IAAM,EAAO,EAAM,SAAS,CAAC,CAAC,KAAK,EACnC,GAAI,CAAC,EAAM,OAEX,IAAM,EAAY,KAAK,UAAU,iBAAiB,MAClD,GAAI,EACF,EAAM,MAAM,EACZ,KAAK,UAAU,iBAAiB,MAAQ,KACxC,MAAM,KAAK,UAAU,YAAY,EAAW,CAAI,MAC3C,CACL,EAAM,MAAM,EACZ,IAAM,EAAU,MAAM,KAAK,UAAU,YACnC,EACA,KAAK,UAAU,WAAW,OAAS,IAAA,EACrC,EACA,KAAK,UAAU,WAAW,MAAQ,KAE9B,IACF,KAAK,UAAU,mBAAmB,MAAQ,EAAQ,GAEtD,CACF,CAEA,aAAgC,CAC9B,MAAkB;oCACc,GAAmB;;;;;;;;;;;;;;;;;;;;;KAsBrD,CACF,KAhIG,EAAQ,CAAS,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,KACjB,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EAiIpB,eAAe,IAAI,iBAAiB,GACvC,eAAe,OAAO,kBAAmB,CAAa,ECzQxD,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgRxC,EAEY,GAAb,cAAoC,CAAY,2CAqH3B,CACjB,MAAO,SACT,EAtHA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAEA,WAAW,oBAAqB,CAC9B,MAAO,CAAC,UAAW,WAAY,OAAQ,QAAS,UAAW,OAAQ,WAAY,YAAY,CAC7F,CAEA,oBAAqB,CACnB,KAAK,OAAO,CACd,CAEA,kBAAmB,CACjB,KAAK,OAAO,CACd,CAEA,kBAAmB,CACjB,KAAK,OAAO,CACd,CAEA,eAAgB,CACd,KAAK,OAAO,CACd,CAEA,gBAAiB,CACf,KAAK,OAAO,CACd,CAEA,kBAAmB,CACjB,KAAK,OAAO,CACd,CAEA,eAAgB,CACd,KAAK,OAAO,CACd,CAEA,mBAAoB,CAClB,KAAK,OAAO,CACd,CAEA,IAAI,SAAkB,CACpB,OAAO,OAAO,KAAK,aAAa,SAAS,GAAK,GAAG,CACnD,CAEA,IAAI,QAAQ,EAAe,CACzB,KAAK,aAAa,UAAW,OAAO,CAAK,CAAC,CAC5C,CAEA,IAAI,SAA8B,CAChC,OAAO,KAAK,aAAa,UAAU,GAAK,IAAA,EAC1C,CAEA,IAAI,QAAQ,EAA2B,CACjC,IAAU,IAAA,GACZ,KAAK,gBAAgB,UAAU,EAE/B,KAAK,aAAa,WAAY,CAAK,CAEvC,CAEA,IAAI,MAAe,CACjB,OAAO,KAAK,aAAa,MAAM,GAAK,IACtC,CAEA,IAAI,KAAK,EAAe,CACtB,KAAK,aAAa,OAAQ,CAAK,CACjC,CAEA,IAAI,OAA6B,CAC/B,OAAQ,KAAK,aAAa,OAAO,GAA6B,OAChE,CAEA,IAAI,MAAM,EAA4B,CACpC,KAAK,aAAa,QAAS,CAAK,CAClC,CAEA,IAAI,SAAmE,CACrE,OAAQ,KAAK,aAAa,SAAS,GAAa,KAClD,CAEA,IAAI,QAAQ,EAAgE,CAC1E,KAAK,aAAa,UAAW,CAAK,CACpC,CAEA,IAAI,MAA+C,CACjD,OAAQ,KAAK,aAAa,MAAM,GAAa,QAC/C,CAEA,IAAI,KAAK,EAA+C,CACtD,KAAK,aAAa,OAAQ,CAAK,CACjC,CAEA,IAAI,UAAoB,CACtB,OAAO,KAAK,aAAa,UAAU,CACrC,CAEA,IAAI,SAAS,EAAgB,CACvB,EACF,KAAK,aAAa,WAAY,EAAE,EAEhC,KAAK,gBAAgB,UAAU,CAEnC,CAEA,IAAI,WAA2B,CAC7B,OAAO,KAAK,aAAa,YAAY,CACvC,CAEA,IAAI,UAAU,EAAsB,CAC9B,IAAU,KACZ,KAAK,gBAAgB,YAAY,EAEjC,KAAK,aAAa,aAAc,CAAK,CAEzC,CAMA,QAAkB,EAAc,CAC9B,GAAI,KAAK,SAAU,CACjB,EAAM,eAAe,EACrB,EAAM,yBAAyB,EAC/B,MACF,CACA,KAAK,KAAK,WAAW,CACvB,CAEA,IAAI,MAAe,CACjB,IAAI,EAAO,GAwFX,OAtFI,KAAK,QAAU,QACb,KAAK,UAAY,MACnB,EAAO;;;;;;;;;;UAWE,KAAK,UAAY,UAC1B,EAAO;;;;;;;;;;WAYA,KAAK,QAAU,YACpB,KAAK,UAAY,MACnB,EAAO;;;;;;;;;;UAWE,KAAK,UAAY,QAC1B,EAAO;;;;;;;;;;UAWE,KAAK,UAAY,OAC1B,EAAO;;;;;;;;;;UAWE,KAAK,UAAY,OAC1B,EAAO;;;;;;;UAQE,KAAK,UAAY,WAC1B,EAAO;;;;;;;;;;YAaJ,CACT,CAEA,aAAgC,CAC9B,IAAM,EAAe,KAAK,SAAW,WAAa,GAC5C,EAAU,CACd,eACA,KAAK,KAAO,sBAAsB,KAAK,OAAS,GAChD,KAAK,MAAQ,uBAAuB,KAAK,QAAU,GACnD,KAAK,QAAU,yBAAyB,KAAK,UAAY,EAC3D,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,EAEL,EAAW,KAAK,QAClB,aAAa,KAAK,QAAQ;wDACsB,KAAK,KAAK,SAC1D,gDAAgD,KAAK,KAAK,SAExD,EAAgB,KAAK,UAAY,eAAe,KAAK,UAAU,GAAK,GAE1E,MAAkB;;iBAEL,EAAQ;;gBAET,KAAK,KAAK;UAChB,EAAa;UACb,EAAc;;;;;;kEAM0C,EAAS;;;KAIzE,CACF,EAEK,eAAe,IAAI,kBAAkB,GACxC,eAAe,OAAO,mBAAoB,EAAc,ECphB1D,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BxC,EAEY,EAAb,cAAqC,CAAY,2CAO5B,CACjB,MAAO,UACP,QAAS,WACX,EAPA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAOA,QAAkB,EAAc,CAC9B,IAAM,EAAW,EAAM,OACvB,EAAS,MAAM,OAAS,OACxB,EAAS,MAAM,OAAS,GAAG,EAAS,aAAa,GACnD,CAEA,UAAoB,EAAsB,CACpC,EAAM,MAAQ,WACZ,KAAK,UAAU,iBAAiB,OAAS,KAAK,UAAU,WAAW,SACrE,EAAM,gBAAgB,EACtB,KAAK,UAAU,iBAAiB,MAAQ,KACxC,KAAK,UAAU,WAAW,MAAQ,KAGxC,CAEA,UAAmB,CACjB,OAAO,KAAK,WAAgC,UAAU,CAAC,EAAE,OAAS,EACpE,CAEA,SAAS,EAAmB,CAC1B,IAAM,EAAW,KAAK,WAAgC,UAAU,EAC3D,IAEL,EAAS,MAAQ,EACjB,EAAS,MAAM,OAAS,OACxB,EAAS,MAAM,OAAS,GAAG,EAAS,aAAa,IACnD,CAEA,OAAc,CACZ,IAAM,EAAW,KAAK,WAAgC,UAAU,EAC3D,IAEL,EAAS,MAAQ,GACjB,EAAS,MAAM,OAAS,OAC1B,CAEA,OAAc,CACZ,KAAK,WAAgC,UAAU,CAAC,EAAE,MAAM,CAC1D,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,IAAM,EAAS,KAAK,UAAU,kBAAkB,MAC1C,EAAU,KAAK,UAAU,eAAe,MAE1C,EAAc,UACd,EACF,EAAc,kBACL,GAAQ,QAAQ,OACzB,EAAc,YAAY,EAAO,OAAO,QAG1C,KAAK,QAAQ,WAAY,cAAe,CAAW,CACrD,CAAC,CACH,CAEA,aAAgC,CAC9B,MAAkB;;KAGpB,CACF,KAzEG,EAAQ,CAAS,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EA2Ef,eAAe,IAAI,mBAAmB,GACzC,eAAe,OAAO,oBAAqB,CAAe,EC3G5D,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgExC,EAEK,EAAwB,EAEjB,EAAb,cAAsC,CAAY,6CAG7B,eAMA,CACjB,MAAO,SACT,EANA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAMA,QAAkB,EAAmB,CAC7B,EAAM,OAAuB,QAAQ,EAAI,MAAM,CAAC,IACtD,KAAK,SAAW,GAChB,KAAK,OAAO,EACd,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,KAAK,aAAa,YAAa,KAAK,UAAU,YAAY,KAAK,CACjE,CAAC,EAED,KAAK,cAAgB,CACnB,IAAM,EAAY,KAAK,aAAa,YAAY,EAC1C,EAAW,KAAK,UAAU,mBAAmB,MAC/C,GAAa,GACC,KAAK,UAAU,WAAW,CACtC,CAAA,CAAQ,KAAM,GAAM,EAAE,KAAO,CAAQ,IACvC,KAAK,SAAW,IAIpB,KAAK,UAAU,SAAS,MACxB,KAAK,OAAO,CACd,CAAC,CACH,CAEA,aAAgC,CAC9B,IAAM,EAAY,KAAK,aAAa,YAAY,EAChD,GAAI,CAAC,EAAW,MAAO,GAEvB,IAAM,EAAU,KAAK,UAAU,WAAW,CAAS,EAC7C,EACJ,KAAK,UAAY,EAAQ,QAAU,EAC/B,EACA,EAAQ,MAAM,EAAG,CAAqB,EACtC,EAAc,EAAQ,OAAS,EAAe,OAE9C,EACJ,EAAc,EACV;;;qBAGW,EAAY,QAAQ,IAAgB,EAAI,QAAU,UAAU;;kBAGvE,GAYN,MAAkB;;mCAEa,EAAU;UAXvC,EAAQ,OAAS,EACb;cACI,EACC,IAAK,GAAU,4BAA4B,EAAM,GAAG,iBAAiB,CAAC,CACtE,KAAK,EAAE,EAAE;cACV,EAAS;kBAEb,GAKY;;KAGpB,CACF,KA5EG,EAAQ,CAAS,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EA8Ef,eAAe,IAAI,oBAAoB,GAC1C,eAAe,OAAO,qBAAsB,CAAgB,ECzJ9D,SAAgB,EAAQ,EAAsC,CAC5D,IAAM,EAAI,aAAgB,KAAO,EAAO,IAAI,KAAK,CAAI,EAC/C,GAAW,KAAK,IAAI,EAAI,EAAE,QAAQ,GAAK,IAO7C,OALI,EAAU,EAAU,MACpB,EAAU,GAAW,GAAG,KAAK,MAAM,CAAO,EAAE,GAC5C,EAAU,KAAa,GAAG,KAAK,MAAM,EAAU,EAAE,EAAE,GACnD,EAAU,MAAc,GAAG,KAAK,MAAM,EAAU,IAAI,EAAE,GACtD,EAAU,OAAe,GAAG,KAAK,MAAM,EAAU,KAAK,EAAE,GACrD,GAAG,KAAK,MAAM,EAAU,MAAM,EAAE,EACzC,CCDA,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoSxC,EAEY,EAAb,cAAgC,CAAY,2CA4BvB,CACjB,MAAO,SACT,iBAEoB,sBACI,wBAGG,GAAsB,CAC/C,IAAM,EAAO,EAAM,aAAa,EAC1B,EAAW,KAAK,WAAW,EAAI,UAAU,CAAC,EAC1C,EAAU,KAAK,WAAW,EAAI,cAAc,CAAC,EAE/C,GAAY,GAAW,CAAC,EAAK,SAAS,CAAQ,GAAK,CAAC,EAAK,SAAS,CAAO,GAC3E,KAAK,cAAc,CAEvB,wBAuJiE,KA/LjE,WAAW,oBAAqB,CAC9B,MAAO,CAAC,YAAa,YAAY,CACnC,CAEA,mBAAoB,CAClB,KAAK,OAAO,CACd,CAEA,oBAAqB,CACnB,KAAK,OAAO,CACd,CAEA,IAAI,MAAoB,CACtB,OAAQ,KAAK,aAAa,WAAW,GAAqB,IAC5D,CAEA,IAAI,mBAAiC,CACnC,OAAO,KAAK,OAAS,KAAO,KAAO,IACrC,CAEA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAoBA,gBAAyB,CACnB,KAAK,cACP,KAAK,cAAc,EAEnB,KAAK,aAAa,CAEtB,CAEA,cAAuB,CACrB,KAAK,cAAgB,GACrB,IAAM,EAAW,KAAK,WAAwB,EAAI,UAAU,CAAC,EACvD,EAAU,KAAK,WAAwB,EAAI,cAAc,CAAC,EAEhE,GAAI,GAAY,EAAS,CACvB,EAAS,UAAU,IAAI,SAAS,EAEhC,IAAM,MAAe,EACnB,EAAA,EAAA,gBAAA,CAAgB,EAAS,EAAU,CACjC,UAAW,aACX,WAAY,cAAQ,CAAC,aAAQ,cAAS,CAAE,QAAS,CAAE,CAAC,CAAC,EACrD,SAAU,OACZ,CAAC,CAAC,CAAC,MAAM,CAAE,IAAG,OAAQ,CACpB,OAAO,OAAO,EAAS,MAAO,CAC5B,KAAM,GAAG,EAAE,IACX,IAAK,GAAG,EAAE,IACV,SAAU,OACZ,CAAC,CACH,CAAC,CACH,EAEA,KAAK,kBAAA,EAAA,EAAA,WAAA,CAA8B,EAAS,EAAU,CAAM,EAC5D,SAAS,iBAAiB,YAAa,KAAK,eAAe,CAC7D,CACF,CAEA,eAAwB,CACtB,KAAK,cAAgB,GACrB,IAAM,EAAW,KAAK,WAAW,EAAI,UAAU,CAAC,EAC5C,GACF,EAAS,UAAU,OAAO,SAAS,EAErC,AAEE,KAAK,oBADL,KAAK,iBAAiB,EACE,IAAA,IAE1B,SAAS,oBAAoB,YAAa,KAAK,eAAe,CAChE,CAEA,MAAc,eAAgB,CAC5B,IAAM,EAAY,KAAK,aAAa,YAAY,EAC3C,GAED,QAAQ,+CAA+C,GACzD,MAAM,KAAK,UAAU,cAAc,CAAS,CAEhD,CAEA,MAAc,aAAc,CAC1B,IAAM,EAAY,KAAK,aAAa,YAAY,EAC3C,IAGD,MADkB,KAAK,UAAU,YAAY,CAAS,EAExD,MAAM,+BAA+B,EAErC,MAAM,yBAAyB,EAEnC,CAEA,QAAkB,EAAc,CAC9B,IAAM,EAAS,EAAM,OAGrB,GAAI,EAAO,QAAQ,EAAI,cAAc,CAAC,EAAG,CACvC,EAAM,gBAAgB,EACtB,KAAK,eAAe,EACpB,MACF,CAGA,IAAM,EAAe,EAAO,QAAQ,EAAI,eAAe,CAAC,EACxD,GAAI,EAAc,CAChB,EAAM,gBAAgB,EACtB,IAAM,EAAS,EAAa,aAAa,aAAa,EAChD,EAAY,KAAK,aAAa,YAAY,EAC5C,IAAW,QAAU,GACvB,KAAK,UAAU,WAAW,MAAQ,KAClC,KAAK,UAAU,iBAAiB,MAAQ,GAC/B,IAAW,SACpB,KAAK,cAAc,EACV,IAAW,QACpB,KAAK,YAAY,EAEnB,KAAK,cAAc,EACnB,MACF,CAGA,GAAI,EAAO,QAAQ,EAAI,UAAU,CAAC,EAAG,CACnC,EAAM,gBAAgB,EACtB,MACF,CAGA,GAAI,CAAC,KAAK,UAAU,YAAY,MAAO,OAEvC,IAAM,EAAY,KAAK,aAAa,YAAY,EAC3C,GAEW,KAAK,UAAU,SAAS,MAAM,KAAM,GAAM,EAAE,KAAO,CAC/D,CAAA,EAAS,SAAW,YAEpB,KAAK,UAAU,WAAW,QAAU,EACtC,KAAK,UAAU,WAAW,MAAQ,KAElC,KAAK,UAAU,WAAW,MAAQ,EAGpC,KAAK,WAAW,EAClB,CAEA,YAAqB,CACnB,IAAM,EAAS,KAAK,WAAwB,EAAI,MAAM,CAAC,EACvD,GAAI,CAAC,KAAK,WAAa,EAAQ,CAC7B,IAAM,EAAc,EAAO,aAC3B,KAAK,UAAY,GACjB,KAAK,OAAO,EAEZ,IAAM,EAAY,KAAK,WAAwB,EAAI,MAAM,CAAC,EAC1D,GAAI,EAAW,CACb,IAAM,EAAY,EAAU,aAE5B,EAAU,MAAM,OAAS,GAAG,EAAY,IACxC,EAAU,MAAM,SAAW,SAG3B,EAAe,aAEf,EAAU,MAAM,WAAa,yDAC7B,EAAU,MAAM,OAAS,GAAG,EAAU,IAEtC,eAAiB,CACf,EAAU,MAAM,OAAS,GACzB,EAAU,MAAM,SAAW,EAC7B,EAAG,GAAG,CACR,CACF,CACF,CAIA,sBAAuB,CACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,MAAM,qBAAqB,CAC7B,CAEA,kBAA2B,CACzB,KAAK,gBAAgB,EAErB,IAAM,EAAY,KAAK,aAAa,YAAY,EAChD,GAAI,CAAC,EAAW,OAEhB,IAAM,EAAU,KAAK,UAAU,SAAS,MAAM,KAAM,GAAM,EAAE,KAAO,CAAS,EAC5E,GAAI,CAAC,EAAS,OAEd,IAAM,MAAe,CACnB,IAAM,EAAW,KAAK,WAA4B,EAAI,WAAW,CAAC,EAC9D,IACF,EAAS,YAAc,EAAQ,EAAQ,SAAS,GAGlD,IAAM,EACJ,KAAK,IAAI,GACR,OAAO,EAAQ,WAAc,SAC1B,EAAQ,UACR,KAAK,MAAM,OAAO,EAAQ,SAAS,CAAC,GACtC,EAAQ,IAEZ,AAKE,EALE,EAAQ,IACF,IACC,EAAQ,KACT,IAEA,KAGV,KAAK,iBAAmB,WAAW,EAAQ,CAAK,CAClD,EAOM,EAJJ,KAAK,IAAI,GACR,OAAO,EAAQ,WAAc,SAC1B,EAAQ,UACR,KAAK,MAAM,OAAO,EAAQ,SAAS,CAAC,GACb,IAAQ,IAAO,IAC5C,KAAK,iBAAmB,WAAW,EAAQ,CAAY,CACzD,CAEA,iBAA0B,CACxB,AAEE,KAAK,oBADL,aAAa,KAAK,gBAAgB,EACV,KAE5B,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,KAAK,aAAa,YAAa,KAAK,UAAU,YAAY,KAAK,CACjE,CAAC,EAED,KAAK,cAAgB,CACnB,IAAM,EAAY,KAAK,aAAa,YAAY,EAC1C,EAAO,KAAK,UAAU,YAAY,MAClC,EAAe,KAAK,UAAU,WAAW,MACzC,EAAY,KAAK,UAAU,iBAAiB,MAC5C,EAAW,KAAK,UAAU,mBAAmB,MAEnD,KAAK,UAAU,OAAO,eAAgB,IAAS,IAAI,EACnD,KAAK,UAAU,OAAO,cAAe,IAAc,MAAQ,IAAiB,CAAS,EACrF,KAAK,UAAU,OAAO,aAAc,IAAc,MAAQ,IAAc,CAAS,EAEjF,KAAK,UAAU,SAAS,MACxB,KAAK,OAAO,EACZ,KAAK,iBAAiB,EAElB,GAAa,IAAa,GAC5B,eAAiB,CACf,IAAM,EAAe,KAAK,YAAY,cAAc,YAAY,GAAW,EACvE,EACF,EAAa,eAAe,CAAE,SAAU,SAAU,MAAO,QAAS,CAAC,EAEnE,KAAK,eAAe,CAAE,SAAU,SAAU,MAAO,QAAS,CAAC,EAE7D,KAAK,UAAU,mBAAmB,MAAQ,IAC5C,EAAG,EAAE,CAET,CAAC,CACH,CAEA,aAAgC,CAC9B,IAAM,EAAY,KAAK,aAAa,YAAY,EAChD,GAAI,CAAC,EAAW,MAAO,GAEvB,IAAM,EAAU,KAAK,UAAU,SAAS,MAAM,KAAM,GAAM,EAAE,KAAO,CAAS,EAC5E,GAAI,CAAC,EAAS,MAAO,GAErB,IAAM,EAAY,EAAQ,SAAW,UAC/B,EAAkB,EAAQ,gBAAkB,GAC5C,EAAoB,GAAa,EAEjC,EAAgB,EAClB,GACA,EAAQ,QAAQ,MACd,aAAa,EAAQ,OAAO,MAAM,SAAS,EAAQ,OAAO,MAAQ,cAAc,MAChF,EAAY,EAAQ,QAAQ,IAAI,EAEhC,EAAe,KAAK,UAAU,WAAW,MACzC,EAAa,IAAc,MAAQ,IAAiB,EACpD,EAAO,KAAK,KAGZ,EAAO,KAAK,UAAU,YAAY,MAClC,EAAW,GAAQ,EAAQ,QAAU,EAAK,KAAO,EAAQ,OAAO,GAGhE,EACJ,GAAQ,CAAC,EACL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA8CM,EACI;wKAEA,GACL;;;kBAIL,GAEN,MAAkB;;uCAEiB,IAAO,EAAa,wBAA0B,KAAK,EAC9E,oBACA,GAAG;sBACO,EAAU;;;;;oBAKZ,KAAK,kBAAkB;8BACb,EAAQ,QAAQ,IAAM,EAAQ,QAAQ,MAAQ,GAAG;cACjE,EAAoB,UAAY,GAAG;;cAEnC,EAAc;;;;;;;kBAOV,EAAY,YAAc,EAAkB,iBAAoB,EAAQ,QAAQ,MAAQ,GAAI;;qEAEzC,EAAQ,EAAQ,SAAS,EAAE;;cAElF,EAAS;;qCAEc,KAAK,UAAY,YAAc,GAAG,oBAAoB,EAAQ,KAAK;;;KAItG,CACF,KAjZG,EAAQ,CAAS,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,KACjB,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EAkZpB,eAAe,IAAI,aAAa,GACnC,eAAe,OAAO,cAAe,CAAU,EC9rBjD,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgMxC,EAEY,EAAb,cAA6B,CAAY,iDAID,mBACnB,uBAEqB,iBAMrB,CACjB,MAAO,SACT,EANA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAMA,QAAkB,EAAmB,CAC7B,EAAM,OAAuB,QAAQ,EAAI,QAAQ,CAAC,GAEpD,KAAK,UAAU,iBAAiB,QAAU,MAC9C,KAAK,UAAU,iBAAiB,CAClC,CAEA,mBAAoB,CAClB,MAAM,kBAAkB,EACxB,SAAS,iBAAiB,YAAa,IAAI,EAC3C,SAAS,iBAAiB,UAAW,IAAI,CAC3C,CAEA,sBAAuB,CACrB,SAAS,oBAAoB,YAAa,IAAI,EAC9C,SAAS,oBAAoB,UAAW,IAAI,EAC5C,OAAO,cAAc,KAAK,YAAY,EACtC,MAAM,qBAAqB,CAC7B,CAEA,YAAY,EAAoB,CAC9B,GAAI,EAAM,OAAS,YAAa,CAC9B,KAAK,eAAe,CAAmB,EACvC,MACF,CAEA,GAAI,EAAM,OAAS,UAAW,CAC5B,KAAK,UAAU,CAAsB,EACrC,MACF,CAEA,MAAM,YAAY,CAAK,CACzB,CAEA,eAAuB,EAAmB,CACxC,GAAI,CAAC,KAAK,UAAU,KAAK,MAAO,OAEhC,IAAM,EAAO,EAAM,aAAa,EAC1B,EAAO,KAAK,YAAY,EACxB,EAAO,aAAgB,WAAa,EAAK,KAAO,KACtD,GAAI,CAAC,EAAK,SAAS,IAAI,IAAM,CAAC,GAAQ,CAAC,EAAK,SAAS,CAAI,GAAI,CAC3D,GAAI,KAAK,UAAU,SAAS,QAAU,OAAQ,CAC5C,KAAK,UAAU,WAAW,EAC1B,MACF,CACA,KAAK,UAAU,KAAK,MAAQ,EAC9B,CACF,CAEA,UAAkB,EAAsB,CAClC,KAAM,MAAQ,SAElB,IAAI,KAAK,UAAU,UAAU,MAAO,CAClC,KAAK,UAAU,eAAe,EAC9B,MACF,CAEA,GAAI,KAAK,UAAU,SAAS,QAAU,OAAQ,CAC5C,KAAK,UAAU,WAAW,EAC1B,MACF,CACA,KAAK,UAAU,KAAK,MAAQ,EAN5B,CAOF,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,IAAM,EAAO,KAAK,UAAU,KAAK,MAE7B,GAAQ,CAAC,KAAK,UAAY,KAAK,UAAU,KAAK,OAKhD,KAAU,UAAU,mBAAmB,EAKrC,CAAC,GAAQ,KAAK,UAChB,KAAK,UAAU,eAAe,EAGhC,KAAK,SAAW,EAChB,KAAK,OAAO,CACd,CAAC,CACH,CAQA,oBAA4B,EAA8B,CACxD,GAAI,IAAY,KAAK,eAAgB,OACrC,KAAK,eAAiB,EACtB,OAAO,cAAc,KAAK,YAAY,EAEtC,IAAM,EAAU,KAAK,WAA8B,EAAI,gBAAgB,CAAC,EACpE,IAAS,EAAQ,OAAS,IAAY,MAC1C,IAAM,EAAY,KAAK,WAAwB,EAAI,kBAAkB,CAAC,EAEtE,GADI,IAAW,EAAU,OAAS,IAAY,MAC1C,CAAC,GAAa,IAAY,KAAM,OAEpC,IAAM,MAAwB,CAC5B,IAAM,EAAY,KAAK,IAAI,EAAG,KAAK,MAAM,EAAU,KAAK,IAAI,GAAK,GAAI,CAAC,EAChE,EAAU,KAAK,MAAM,EAAY,EAAE,EAEzC,MADA,GAAU,YAAc,gBAAgB,EAAQ,GAAG,OAAO,EAAY,EAAE,CAAC,CAAC,SAAS,EAAG,GAAG,IAClF,IAAc,CACvB,EAEA,EAAO,EACP,KAAK,aAAe,OAAO,gBAAkB,CACtC,EAAO,IACZ,OAAO,cAAc,KAAK,YAAY,EACtC,KAAK,UAAU,iBAAiB,EAClC,EAAG,GAAI,CACT,CAEA,QAAuB,CACjB,KAAK,UAAU,KAAK,MACtB,KAAK,aAAa,OAAQ,EAAE,EAE5B,KAAK,gBAAgB,MAAM,EAG7B,IAAM,EAAU,KAAK,WAA2B,EAAI,MAAM,CAAC,EAC3D,GAAI,EAAS,CACX,IAAM,EAAU,KAAK,UAAU,iBAAiB,MAEhD,GAAI,EAAQ,SAAW,EACL,EAAQ,cAAc,EAAI,OAAO,CAC5C,IACH,EAAQ,UAAY,kFAEjB,CACL,IAAM,EAAc,MAAM,KAAK,EAAQ,iBAAiB,oBAAoB,CAAC,CAAC,CAAC,IAAK,GAClF,EAAG,aAAa,YAAY,CAC9B,EAEM,EAAS,EAAQ,IAAK,GAAM,EAAE,EAAE,GAEpC,EAAY,SAAW,EAAO,QAAU,EAAY,MAAM,EAAI,IAAM,IAAO,EAAO,EAAE,KAGpF,EAAQ,UAAY,EACjB,IACE,GAAY,mCAAmC,EAAQ,GAAG,wBAC7D,CAAC,CACA,KAAK,EAAE,EAEd,CACF,CAEA,IAAM,EAAQ,KAAK,UAAU,UAAU,MACjC,EAAS,KAAK,WAA2B,EAAI,QAAQ,CAAC,EAC5D,GAAI,EAAQ,CACV,IAAM,EAAY,EAAO,OACzB,EAAO,OAAS,CAAC,EACjB,KAAK,QAAQ,EAAI,gBAAgB,EAAG,GAAS,EAAE,EAC/C,IAAM,EAAU,EAAQ,KAAK,UAAU,iBAAiB,MAAQ,KAC5D,GAAO,KAAK,QAAQ,EAAI,gBAAgB,EAAG,KAAK,UAAU,gBAAgB,KAAK,EACnF,KAAK,oBAAoB,CAAO,EAEhC,KAAK,WAAW,EAAI,SAAS,CAAC,CAAC,EAAE,gBAAgB,QAAS,EAAQ,CAAM,EAExE,KAAK,WAAW,EAAI,QAAQ,CAAC,CAAC,EAAE,gBAC9B,QACA,EAAQ,GAAU,KAAK,UAAU,IACnC,EACI,GAAS,GAAa,KAAK,UAAU,KAAK,OAE5C,KAAK,WACH,EAAI,IAAY,KAAO,iBAAmB,YAAY,CACxD,CAAC,EAAE,MAAM,CAEb,CAEA,IAAM,EAAS,KAAK,WAA2B,EAAI,QAAQ,CAAC,EAE5D,GAAI,EAAQ,CAEV,IAAM,EADS,KAAK,UAAU,YAAY,QAAU,KACP,iBAApB,kBACrB,KAAK,eAAiB,IACxB,KAAK,aAAe,EACpB,EAAO,UAAY,IAAI,EAAQ,KAAK,EAAQ,GAEhD,CACF,CAEA,aAAgC,CAC9B,MAAkB;;;;;;;;;;;;;;;;KAiBpB,CACF,KAjOG,EAAQ,CAAS,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,KACjB,EAAQ,CAAc,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA,EAkOpB,eAAe,IAAI,UAAU,GAChC,eAAe,OAAO,WAAY,CAAO,EC7a3C,SAAS,IAAY,CACnB,OAAO,OAAO,OAAW,GAC3B,CAUA,SAAS,GAAU,EAAM,CACvB,IAAI,EACJ,OAAQ,GAAQ,OAAS,EAAsB,EAAK,gBAAkB,KAAO,IAAK,GAAI,EAAoB,cAAgB,MAC5H,CAWA,SAAS,GAAU,EAAO,CAIxB,OAHK,GAAU,EAGR,aAAiB,SAAW,aAAiB,GAAU,CAAK,CAAC,CAAC,QAF5D,EAGX,CAuCA,IAAM,GAAe,sDACf,GAAY,8BACZ,EAAY,GAAS,CAAC,CAAC,GAAS,IAAU,OAC5C,GACJ,SAAS,GAAkB,EAAc,CACvC,IAAM,EAAM,GAAU,CAAY,EAAIA,GAAiB,CAAY,EAAI,EAIvE,OAAO,EAAU,EAAI,SAAS,GAAK,EAAU,EAAI,SAAS,GAAK,EAAU,EAAI,KAAK,GAAK,EAAU,EAAI,MAAM,GAAK,EAAU,EAAI,WAAW,GAAK,CAAC,GAAS,IAAM,EAAU,EAAI,cAAc,GAAK,EAAU,EAAI,MAAM,IAAM,GAAa,KAAK,EAAI,YAAc,EAAE,GAAK,GAAU,KAAK,EAAI,SAAW,EAAE,CACtS,CAaA,SAAS,IAAW,CAIlB,MAHA,CACE,KAAgB,OAAO,IAAQ,KAAe,IAAI,UAAY,IAAI,SAAS,0BAA2B,MAAM,EAEvG,EACT,CAIA,SAASA,GAAiB,EAAS,CACjC,OAAO,GAAU,CAAO,CAAC,CAAC,iBAAiB,CAAO,CACpD,CCxG2D,SAAS,GAAE,EAAE,CAAC,OAAO,GAAE,CAAC,CAAC,CAA8E,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,sBAAsB,WAAW,EAAE,WAAW,KAAK,EAAE,UAAU,CAAC,SAAS,GAAE,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,aAAa,SAAkB,iBAAiB,CAAC,CAAC,CAAC,UAA7B,OAAqC,OAAO,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,SAAS,SAAS,IAAM,EAAE,iBAAiB,CAAC,EAAE,GAAgB,EAAE,UAAf,aAAsC,EAAE,WAAb,UAAuBC,GAAE,CAAC,GAAuB,EAAE,UAAX,QAAmB,OAAO,CAAE,CAAC,OAAO,IAAI,CCa3kB,IAAM,GAAmB,GAEnB,GAAmB,GAAqB,EAAA,SAAS,gBAAgB,EAAS,EAAY,EAQ5F,SAAgB,GACd,EACA,EACA,EACY,CACZ,IAAM,EAA2B,EAAA,EAAA,EAAA,OAAA,CACxB,CACL,SAAU,IAAa,OAAS,IAAM,IACtC,UAAW,GACb,CAAC,CACH,EA2BA,OAzBI,CAAC,GAAY,IAAa,SAC5B,EAAW,MAAA,EAAA,EAAA,KAAA,CACJ,CACH,mBAAoB,CAAC,eAAgB,WAAW,EAChD,iBAAkB,UAClB,QAAS,EACX,CAAC,CACH,EAIF,EAAW,MAAA,EAAA,EAAA,MAAA,CAAW,CAAE,QAAS,GAAkB,UAAW,EAAK,CAAC,CAAC,GAcrE,EAAA,EAAA,WAAA,CAAkB,EAAQ,MAZL,EACnB,EAAA,EAAA,gBAAA,CAAqB,EAAQ,EAAM,CACjC,UAAW,IAAa,OAAS,eAAiB,YAClD,aACA,SAAU,QACV,SAAU,CAAE,GAAG,EAAA,SAAU,kBAAgB,CAC3C,CAAC,CAAC,CAAC,MAAM,CAAE,IAAG,IAAG,eAAgB,CAC/B,EAAK,aAAa,yBAA0B,CAAS,EACrD,OAAO,OAAO,EAAK,MAAO,CAAE,KAAM,GAAG,EAAE,IAAK,IAAK,GAAG,EAAE,GAAI,CAAC,CAC7D,CAAC,CACH,CAEsC,CACxC,CCrDA,IAAM,GAAkB,0BAElB,GAAe,IAAI,IAAY,CAAC,QAAS,SAAU,KAAK,CAA2B,EACnF,GAAgB,IAAI,IAAY,CAAC,KAAM,IAAI,CAA4B,EACvE,GAAkB,IAAI,IAAY,CAAC,OAAQ,KAAM,MAAM,CAA8B,EAErF,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;CAwBxC,EAEY,GAAb,cAA6B,CAAY,iDAChB,GAWvB,IAAI,MAA6B,CAC/B,OAAO,KAAK,KACd,CAEA,IAAI,KAAK,EAAgB,CACvB,KAAK,MAAQ,EACT,KAAK,QAAQ,MAAM,KAAK,OAAO,SAAS,CAAI,CAClD,CAGA,IAAI,MAAgB,CAClB,OAAO,KAAK,QAAQ,KAAK,OAAS,EACpC,CAEA,IAAI,KAAK,EAAgB,CACnB,KAAK,SAAQ,KAAK,OAAO,KAAK,MAAQ,EAC5C,CAEA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAMA,WAAW,oBAAqB,CAC9B,MAAO,CAAC,aAAc,cAAe,gBAAiB,YAAa,oBAAoB,CACzF,CAEA,mBAAoB,CAClB,GAAI,KAAK,aAAc,OACvB,KAAK,aAAe,GAEpB,IAAM,EAAY,KAAK,aAAa,UAAU,GAAK,KAAK,aAAa,YAAY,GAAK,GAEhF,EACJ,KAAK,aAAa,cAAc,GAChC,KAAK,aAAa,SAAS,GAC3B,GAEI,EACJ,KAAK,aAAa,eAAe,GAAK,KAAK,aAAa,UAAU,GAAK,SAAS,KAK5E,EAAa,KAAK,aAAa,SAAS,EAExC,EAAO,KAAK,aAAa,WAAW,EAwB1C,GAtBA,KAAK,WAAa,IAAI,EAAe,CAAE,SAAQ,YAAW,MAAK,CAAC,EAChE,GAAc,KAAM,KAAK,UAAU,EAEnC,KAAK,OAAS,IAAI,EAAU,CAC1B,SACA,YACA,UACA,aACA,OACA,UAAW,KAAK,UAClB,CAAC,EACD,GAAc,KAAM,KAAK,MAAM,EAE/B,MAAM,kBAAkB,EAOxB,KAAK,OAAO,aAAa,KAAK,6BAA6B,CAAC,EAExD,KAAK,OAAO,KAAM,CAChB,KAAK,OAAO,KAAK,OAAO,SAAS,KAAK,KAAK,EAC/C,MACF,CAMA,KAAU,OAAO,KAAK,CACxB,CAEA,8BAAsD,CACpD,IAAM,EAA2B,CAAC,EAE5B,EAAQ,KAAK,aAAa,YAAY,EACxC,GAAS,GAAa,IAAI,CAAK,IACjC,EAAU,MAAQ,GAGpB,IAAM,EAAS,KAAK,aAAa,aAAa,EAC1C,GAAU,GAAc,IAAI,CAAM,IACpC,EAAU,OAAS,GAGrB,IAAM,EAAW,KAAK,aAAa,eAAe,EAC9C,GAAY,GAAgB,IAAI,CAAQ,IAC1C,EAAU,SAAW,GAGvB,IAAM,EAAO,KAAK,aAAa,WAAW,EACtC,IACF,EAAU,KAAO,GAGnB,IAAM,EAAmB,KAAK,aAAa,oBAAoB,EAC/D,GAAI,IAAqB,KAAM,CAC7B,IAAM,EAAe,OAAO,CAAgB,EACxC,OAAO,UAAU,CAAY,GAAK,EAAe,IACnD,EAAU,aAAe,EAE7B,CAEA,OAAO,CACT,CAEA,+BAA8C,CAGvC,KAAK,QACV,KAAK,OAAO,aAAa,KAAK,6BAA6B,CAAC,CAC9D,CAEA,oBAAqB,CACnB,KAAK,8BAA8B,CACrC,CAEA,qBAAsB,CACpB,KAAK,8BAA8B,CACrC,CAEA,uBAAwB,CACtB,KAAK,8BAA8B,CACrC,CAEA,mBAAoB,CAClB,KAAK,8BAA8B,CACrC,CAEA,2BAA4B,CAC1B,KAAK,8BAA8B,CACrC,CAEA,sBAAuB,CACrB,KAAK,mBAAmB,EACxB,KAAK,OAAO,QAAQ,EACpB,KAAK,WAAW,QAAQ,EACxB,GAAgB,IAAI,EACpB,MAAM,qBAAqB,CAC7B,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,IAAM,EAAO,KAAK,OAAO,KAAK,MACxB,EAAS,KAAK,WAAW,EAAI,MAAM,CAAC,EAC1C,GAAI,CAAC,EAAQ,OAGb,IAAM,EAAW,MAAM,KAAK,EAAO,SAAS,CAAC,CAAC,OAAQ,GAAQ,EAAI,WAAW,QAAQ,CAAC,EAKtF,GAJI,EAAS,OAAS,GACpB,EAAO,UAAU,OAAO,GAAG,CAAQ,EAGjC,EAAM,CACJ,EAAK,OAAO,EAAO,UAAU,IAAI,eAAe,EAAK,OAAO,EAC5D,EAAK,YAAY,EAAO,UAAU,IAAI,oBAAoB,EAAK,YAAY,EAC3E,EAAK,MAAM,EAAO,UAAU,IAAI,cAAc,EAAK,MAAM,EACzD,EAAK,QAAQ,EAAO,UAAU,IAAI,gBAAgB,EAAK,QAAQ,EAC/D,EAAK,UAAU,EAAO,UAAU,IAAI,kBAAkB,EAAK,UAAU,EAEzE,IAAM,EAAa,EAAK,cAAgB,KAAK,OAAO,aACpD,EAAO,UAAU,IAAI,iBAAiB,GAAY,CACpD,CACF,CAAC,EAED,KAAK,cAAgB,CACnB,IAAM,EAAO,KAAK,OAAO,KAAK,MAO9B,GALA,AAEE,KAAK,oBADL,KAAK,iBAAiB,EACE,IAAA,IAGtB,CAAC,EAAM,OAEX,IAAM,EAAS,KAAK,WAAW,YAAY,EACrC,EAAO,KAAK,WAAW,UAAU,EACvC,GAAI,CAAC,GAAU,CAAC,EAAM,OAEtB,IAAM,EAAO,KAAK,OAAO,KAAK,MACzB,IAEL,KAAK,iBAAmB,GAAa,EAAQ,EAAM,EAAK,QAAQ,EAClE,CAAC,CACH,CAEA,aAAgC,CAC9B,MAAkB;;;;;KAMpB,CACF,EAEK,eAAe,IAAI,UAAU,GAChC,eAAe,OAAO,WAAY,EAAO,ECjQ3C,IAAM,GAAa,EAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8IxC,EAEY,GAAb,cAA+B,CAAY,2CAOtB,CACjB,MAAO,SACT,EANA,IAAc,aAAc,CAC1B,MAAO,CAAC,EAAU,CACpB,CAMA,SAAoB,CACd,KAAK,UAAU,MAAM,QAIzB,KAAK,UAAU,KAAK,MAAQ,CAAC,KAAK,UAAU,KAAK,MACnD,CAEA,cAAyB,CACvB,KAAK,cAAgB,CACnB,KAAK,UAAU,QAAQ,MACvB,KAAK,UAAU,MAAM,MACrB,KAAK,UAAU,eAAe,MAC9B,KAAK,UAAU,SAAS,MACxB,KAAK,UAAU,KAAK,MAEpB,IAAM,EAAW,EAAQ,KAAK,UAAU,MAAM,MAC9C,KAAK,gBAAgB,aAAc,CAAQ,EAEvC,GAAY,KAAK,UAAU,KAAK,QAClC,KAAK,UAAU,KAAK,MAAQ,IAG9B,KAAK,OAAO,CACd,CAAC,CACH,CAEA,aAAgC,CAC9B,GAAI,KAAK,UAAU,QAAQ,MACzB,MAAO,4EAGT,GAAI,KAAK,UAAU,MAAM,MACvB,MAAO,gFAGT,IAAM,EAAU,KAAK,UAAU,eAAe,MACxC,EAAa,KAAK,UAAU,SAAS,MAAM,OAG3C,EAFO,KAAK,UAAU,KAAK,OAET,OAAS,QAAU,QAAU,UAmBrD,MAAkB;;UAjBE,EACjB,KAAK,EAAQ,IAAQ,CACpB,IAAM,EAAS,EAAQ,OAAS,EAC1B,EAAW,GAAQ,IAAM,GAAQ,MAAQ,GAQ/C,OANI,GAAQ,MACH,iDAAiD,EAAO,oBAAoB,EAAS;wBAC9E,EAAO,MAAM,SAAS,EAAO,MAAQ,OAAO;iCAIrD,iDAAiD,EAAO,oBAAoB,EAAS;YACxF,EAAY,GAAQ,IAAI,EAAE;8BAEhC,CAAC,CAAC,CACD,KAAK,EAIF,EAAY;;;;;0CAKoB,EAAW;;;;iDAIJ,EAAU;;KAGzD,CACF,EC1OA,MDsJG,EAAQ,CAAS,CAAA,EAAA,GAAA,UAAA,YAAA,IAAA,EAAA,EAsFf,eAAe,IAAI,YAAY,GAClC,eAAe,OAAO,aAAc,EAAS,EC7O3C,OAAO,SAAa,IAAa,CACnC,IAAM,EAAU,kCAChB,GAAI,CAAC,SAAS,cAAc,cAAc,EAAQ,GAAG,EAAG,CACtD,IAAM,EAAO,SAAS,cAAc,MAAM,EAC1C,EAAK,IAAM,aACX,EAAK,KAAO,EACZ,SAAS,KAAK,YAAY,CAAI,CAChC,CACF"}