@xtandard/webhooks 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/cli.cjs +4 -4
  2. package/dist/cli.mjs +4 -4
  3. package/dist/{core-CMpnmI5Q.mjs → core-B1JzRitF.mjs} +20 -3
  4. package/dist/core-B1JzRitF.mjs.map +1 -0
  5. package/dist/{core-ZGhH6Vs2.cjs → core-DuHD0Rdg.cjs} +20 -3
  6. package/dist/core-DuHD0Rdg.cjs.map +1 -0
  7. package/dist/core.cjs +1 -1
  8. package/dist/core.mjs +1 -1
  9. package/dist/{create-fetch-handler-jy3hy5nZ.d.mts → create-fetch-handler-BN9vXbgW.d.mts} +7 -3
  10. package/dist/{create-fetch-handler-CmooujQo.cjs → create-fetch-handler-BNsNcspj.cjs} +6 -5
  11. package/dist/{create-fetch-handler-CmooujQo.cjs.map → create-fetch-handler-BNsNcspj.cjs.map} +1 -1
  12. package/dist/{create-fetch-handler-BIdk9P30.mjs → create-fetch-handler-C6BqzdsN.mjs} +6 -5
  13. package/dist/{create-fetch-handler-BIdk9P30.mjs.map → create-fetch-handler-C6BqzdsN.mjs.map} +1 -1
  14. package/dist/{create-fetch-handler-Dlkhustu.d.cts → create-fetch-handler-D9ZRfrY6.d.cts} +7 -3
  15. package/dist/{dispatcher-Coubwrka.mjs → dispatcher-CFfWo-fN.mjs} +3 -3
  16. package/dist/{dispatcher-Coubwrka.mjs.map → dispatcher-CFfWo-fN.mjs.map} +1 -1
  17. package/dist/{dispatcher-B0xTEHt1.cjs → dispatcher-COdWV6hM.cjs} +3 -3
  18. package/dist/{dispatcher-B0xTEHt1.cjs.map → dispatcher-COdWV6hM.cjs.map} +1 -1
  19. package/dist/entry-bun.cjs +1 -1
  20. package/dist/entry-bun.d.cts +1 -1
  21. package/dist/entry-bun.d.mts +1 -1
  22. package/dist/entry-bun.mjs +1 -1
  23. package/dist/entry-elysia.cjs +1 -1
  24. package/dist/entry-elysia.d.cts +1 -1
  25. package/dist/entry-elysia.d.mts +1 -1
  26. package/dist/entry-elysia.mjs +1 -1
  27. package/dist/entry-express.cjs +1 -1
  28. package/dist/entry-express.d.cts +1 -1
  29. package/dist/entry-express.d.mts +1 -1
  30. package/dist/entry-express.mjs +1 -1
  31. package/dist/entry-hono.cjs +1 -1
  32. package/dist/entry-hono.d.cts +1 -1
  33. package/dist/entry-hono.d.mts +1 -1
  34. package/dist/entry-hono.mjs +1 -1
  35. package/dist/index.cjs +3 -3
  36. package/dist/index.d.cts +2 -2
  37. package/dist/index.d.mts +2 -2
  38. package/dist/index.mjs +3 -3
  39. package/dist/react.css +1 -1
  40. package/dist/react.js +2522 -2506
  41. package/dist/testing.cjs +2 -2
  42. package/dist/testing.mjs +2 -2
  43. package/dist/types-react/ui/lib/portal-container.d.ts +24 -0
  44. package/dist/ui/assets/{index-S5t_CLOe.js → index-BgyX_njf.js} +44 -44
  45. package/dist/ui/assets/index-mJCJq_EB.css +1 -0
  46. package/dist/ui/index.html +2 -2
  47. package/package.json +4 -2
  48. package/dist/core-CMpnmI5Q.mjs.map +0 -1
  49. package/dist/core-ZGhH6Vs2.cjs.map +0 -1
  50. package/dist/ui/assets/index-B0eoQX2U.css +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher-Coubwrka.mjs","names":[],"sources":["../src/dispatcher.ts"],"sourcesContent":["/**\n * The delivery engine. Polls the due index, claims deliveries (lease-based,\n * multi-instance safe when storage supports CAS or the `deliveryQueue`\n * capability), performs the signed HTTP attempts, and drives each delivery's\n * state machine through the retry schedule into success or dead-letter.\n *\n * Runs in-process: the panel starts one by default, a split worker runs one\n * via the CLI (`xtandard-webhooks dispatch`), and tests drive {@link Dispatcher.tick}\n * manually. All timers are `unref()`ed so a dispatcher never keeps a process\n * alive on its own. Semantics are **at-least-once**: a crashed process loses\n * nothing (leases expire, the next tick reclaims); receivers dedupe on\n * `webhook-id`.\n *\n * @module\n */\n\nimport { attemptDelivery, type AttemptOutcome } from \"./deliver.ts\";\nimport type { WebhooksCore } from \"./core.ts\";\nimport { durationToMs } from \"./duration.ts\";\nimport { deliveryKey, dueKey, type DueEntry } from \"./keys.ts\";\nimport type { Delivery, WebhookDuration } from \"./schema.ts\";\nimport { VERSION } from \"./version.ts\";\n\n/** Options for {@link createDispatcher} (also accepted on panels and the core). */\nexport interface DispatcherOptions {\n /** How often to poll for due deliveries. Default `1000`. */\n pollIntervalMs?: number;\n /** Max deliveries claimed per tick. Default `20`. */\n batchSize?: number;\n /** Max in-flight HTTP attempts. Default `8`. */\n concurrency?: number;\n /** Per-attempt timeout (AbortController). Default `20_000`. */\n timeoutMs?: number;\n /** Claim lease duration; an expired lease makes a claim reclaimable. Default `60_000`. */\n leaseMs?: number;\n /**\n * Delay before attempt N+1 after attempt N fails (index 0 = the initial\n * attempt's delay). Exhausting the schedule dead-letters the delivery.\n * Default `[\"0s\", \"5s\", \"5m\", \"30m\", \"2h\", \"5h\", \"10h\"]` (Svix-compatible).\n */\n retrySchedule?: WebhookDuration[];\n /**\n * Auto-disable endpoints whose every attempt has failed for this many\n * consecutive days. `false` disables the policy. Default `{ failingForDays: 5 }`.\n */\n autoDisable?: { failingForDays?: number } | false;\n /** Cap on stored response-body characters per attempt. Default `4096`. */\n responseBodyLimit?: number;\n /** Injectable fetch (tests, instrumentation). Default: global fetch. */\n fetch?: typeof fetch;\n /** `user-agent` header. Default `\"xtandard-webhooks/<version>\"`. */\n userAgent?: string;\n}\n\n/** The delivery engine handle. */\nexport interface Dispatcher {\n /** Begin polling. Idempotent. */\n start(): void;\n /** Stop polling and wait for in-flight attempts to finish. */\n stop(): Promise<void>;\n /**\n * Run one manual pass: claim due deliveries, attempt them, record outcomes.\n * Returns the number of attempts made — the unit-test surface (tests never\n * assert on timers).\n */\n tick(): Promise<number>;\n readonly running: boolean;\n}\n\n/** The default retry schedule (Svix-compatible). */\nexport const DEFAULT_RETRY_SCHEDULE: WebhookDuration[] = [\n \"0s\",\n \"5s\",\n \"5m\",\n \"30m\",\n \"2h\",\n \"5h\",\n \"10h\",\n];\n\n/** Fractional jitter applied to every retry delay (±10%). */\nconst JITTER = 0.1;\n\n/**\n * Create a dispatcher over a core. Not started — call\n * {@link Dispatcher.start}, or drive {@link Dispatcher.tick} manually.\n *\n * @example\n * ```ts\n * import { createWebhooksCore, createDispatcher } from \"@xtandard/webhooks\";\n * import { createMemoryStorage } from \"@xtandard/webhooks/storage/memory\";\n *\n * const core = createWebhooksCore({ storage: createMemoryStorage() });\n * const dispatcher = createDispatcher(core);\n * dispatcher.start();\n * ```\n */\nexport function createDispatcher(core: WebhooksCore, options: DispatcherOptions = {}): Dispatcher {\n const merged = { ...core.options.dispatcher, ...options };\n const pollIntervalMs = merged.pollIntervalMs ?? 1000;\n const batchSize = merged.batchSize ?? 20;\n const concurrency = merged.concurrency ?? 8;\n const timeoutMs = merged.timeoutMs ?? 20_000;\n // The lease must outlast a single attempt, or a slow-but-alive attempt runs\n // past its lease and a second dispatcher reclaims and re-sends it. Enforce\n // lease > timeout with headroom for recording the outcome.\n const configuredLeaseMs = merged.leaseMs ?? 60_000;\n const leaseMs = Math.max(configuredLeaseMs, timeoutMs + 10_000);\n const schedule = merged.retrySchedule ?? DEFAULT_RETRY_SCHEDULE;\n const autoDisable = merged.autoDisable ?? { failingForDays: 5 };\n const responseBodyLimit = merged.responseBodyLimit ?? 4096;\n const userAgent = merged.userAgent ?? `xtandard-webhooks/${VERSION}`;\n const doFetch = merged.fetch;\n const now = core.options.now;\n\n let timer: ReturnType<typeof setInterval> | null = null;\n let inFlight: Promise<number> | null = null;\n\n /** Delay before the next attempt, per schedule position, with ±10% jitter. */\n function nextDelayMs(attemptsMade: number): number | null {\n if (attemptsMade >= schedule.length) return null; // exhausted\n const nominal = durationToMs(schedule[attemptsMade] as WebhookDuration);\n const jitter = 1 + (Math.random() * 2 - 1) * JITTER;\n return Math.round(nominal * jitter);\n }\n\n async function processClaim(delivery: Delivery): Promise<boolean> {\n const app = delivery.applicationKey;\n const trigger = delivery.pendingTrigger ?? \"schedule\";\n\n const failTerminal = async (error: string, eventType: string): Promise<boolean> => {\n const outcome: AttemptOutcome = {\n ok: false,\n error,\n durationMs: 0,\n at: new Date(now()).toISOString(),\n };\n await core.recordAttempt({ delivery, outcome, trigger, nextAttemptAt: null, eventType });\n return true;\n };\n\n const message = await core.getMessage(app, delivery.messageId);\n if (!message) return failTerminal(\"Message no longer exists\", \"unknown\");\n\n const endpoint = await core.getEndpoint(app, delivery.endpointId);\n if (!endpoint) return failTerminal(\"Endpoint no longer exists\", message.eventType);\n\n if (endpoint.disabled) {\n // Held, not failed: release the claim and re-check after the lease\n // window. Re-enabling the endpoint resumes delivery automatically.\n const queue = core.options.queueStorage;\n const recheckAt = now() + leaseMs;\n const released: Delivery = {\n ...delivery,\n status: \"pending\",\n nextAttemptAt: new Date(recheckAt).toISOString(),\n leaseUntil: null,\n updatedAt: new Date(now()).toISOString(),\n };\n // Remove the lease-position due entry the claim created, then park the\n // delivery at the recheck time.\n if (delivery.leaseUntil) {\n await queue.removeItem(dueKey(app, Date.parse(delivery.leaseUntil), delivery.id));\n }\n await queue.setItem(deliveryKey(app, delivery.id), released);\n await queue.setItem<DueEntry>(dueKey(app, recheckAt, delivery.id), {\n app,\n deliveryId: delivery.id,\n });\n return false; // no attempt made\n }\n\n const outcome = await attemptDelivery({\n endpoint,\n messageId: delivery.messageId,\n body: message.envelope,\n timeoutMs,\n responseBodyLimit,\n userAgent,\n ...(doFetch ? { fetch: doFetch } : {}),\n nowMs: now(),\n });\n\n const attemptsMade = delivery.attemptCount + 1;\n const delay = outcome.ok ? null : nextDelayMs(attemptsMade);\n await core.recordAttempt({\n delivery,\n outcome,\n trigger,\n nextAttemptAt: delay === null ? null : new Date(now() + delay).toISOString(),\n eventType: message.eventType,\n });\n await core.noteEndpointOutcome(app, endpoint.id, outcome.ok, autoDisable);\n return true;\n }\n\n async function runTick(): Promise<number> {\n const claimed = await core.claimDueDeliveries({ limit: batchSize, leaseMs });\n if (claimed.length === 0) return 0;\n\n let attempts = 0;\n let cursor = 0;\n const workers = Array.from({ length: Math.min(concurrency, claimed.length) }, async () => {\n while (cursor < claimed.length) {\n const delivery = claimed[cursor++] as Delivery;\n try {\n if (await processClaim(delivery)) attempts++;\n } catch (error) {\n // A storage failure mid-claim: leave the delivery leased; the lease\n // expiry re-exposes it. Never let one claim kill the tick.\n // eslint-disable-next-line no-console\n console.warn(`[@xtandard/webhooks] delivery ${delivery.id} processing failed:`, error);\n }\n }\n });\n await Promise.all(workers);\n return attempts;\n }\n\n const dispatcher: Dispatcher = {\n start() {\n if (timer) return;\n timer = setInterval(() => {\n if (inFlight) return; // never overlap ticks\n inFlight = runTick()\n .catch((error) => {\n // eslint-disable-next-line no-console\n console.warn(\"[@xtandard/webhooks] dispatcher tick failed:\", error);\n return 0;\n })\n .finally(() => {\n inFlight = null;\n });\n }, pollIntervalMs);\n // Never keep the host process alive just to poll.\n (timer as unknown as { unref?: () => void }).unref?.();\n },\n\n async stop() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n if (inFlight) await inFlight;\n },\n\n async tick() {\n // Manual ticks also serialize against the poller.\n while (inFlight) await inFlight;\n inFlight = runTick().finally(() => {\n inFlight = null;\n });\n return inFlight;\n },\n\n get running() {\n return timer !== null;\n },\n };\n\n return dispatcher;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dispatcher-CFfWo-fN.mjs","names":[],"sources":["../src/dispatcher.ts"],"sourcesContent":["/**\n * The delivery engine. Polls the due index, claims deliveries (lease-based,\n * multi-instance safe when storage supports CAS or the `deliveryQueue`\n * capability), performs the signed HTTP attempts, and drives each delivery's\n * state machine through the retry schedule into success or dead-letter.\n *\n * Runs in-process: the panel starts one by default, a split worker runs one\n * via the CLI (`xtandard-webhooks dispatch`), and tests drive {@link Dispatcher.tick}\n * manually. All timers are `unref()`ed so a dispatcher never keeps a process\n * alive on its own. Semantics are **at-least-once**: a crashed process loses\n * nothing (leases expire, the next tick reclaims); receivers dedupe on\n * `webhook-id`.\n *\n * @module\n */\n\nimport { attemptDelivery, type AttemptOutcome } from \"./deliver.ts\";\nimport type { WebhooksCore } from \"./core.ts\";\nimport { durationToMs } from \"./duration.ts\";\nimport { deliveryKey, dueKey, type DueEntry } from \"./keys.ts\";\nimport type { Delivery, WebhookDuration } from \"./schema.ts\";\nimport { VERSION } from \"./version.ts\";\n\n/** Options for {@link createDispatcher} (also accepted on panels and the core). */\nexport interface DispatcherOptions {\n /** How often to poll for due deliveries. Default `1000`. */\n pollIntervalMs?: number;\n /** Max deliveries claimed per tick. Default `20`. */\n batchSize?: number;\n /** Max in-flight HTTP attempts. Default `8`. */\n concurrency?: number;\n /** Per-attempt timeout (AbortController). Default `20_000`. */\n timeoutMs?: number;\n /** Claim lease duration; an expired lease makes a claim reclaimable. Default `60_000`. */\n leaseMs?: number;\n /**\n * Delay before attempt N+1 after attempt N fails (index 0 = the initial\n * attempt's delay). Exhausting the schedule dead-letters the delivery.\n * Default `[\"0s\", \"5s\", \"5m\", \"30m\", \"2h\", \"5h\", \"10h\"]` (Svix-compatible).\n */\n retrySchedule?: WebhookDuration[];\n /**\n * Auto-disable endpoints whose every attempt has failed for this many\n * consecutive days. `false` disables the policy. Default `{ failingForDays: 5 }`.\n */\n autoDisable?: { failingForDays?: number } | false;\n /** Cap on stored response-body characters per attempt. Default `4096`. */\n responseBodyLimit?: number;\n /** Injectable fetch (tests, instrumentation). Default: global fetch. */\n fetch?: typeof fetch;\n /** `user-agent` header. Default `\"xtandard-webhooks/<version>\"`. */\n userAgent?: string;\n}\n\n/** The delivery engine handle. */\nexport interface Dispatcher {\n /** Begin polling. Idempotent. */\n start(): void;\n /** Stop polling and wait for in-flight attempts to finish. */\n stop(): Promise<void>;\n /**\n * Run one manual pass: claim due deliveries, attempt them, record outcomes.\n * Returns the number of attempts made — the unit-test surface (tests never\n * assert on timers).\n */\n tick(): Promise<number>;\n readonly running: boolean;\n}\n\n/** The default retry schedule (Svix-compatible). */\nexport const DEFAULT_RETRY_SCHEDULE: WebhookDuration[] = [\n \"0s\",\n \"5s\",\n \"5m\",\n \"30m\",\n \"2h\",\n \"5h\",\n \"10h\",\n];\n\n/** Fractional jitter applied to every retry delay (±10%). */\nconst JITTER = 0.1;\n\n/**\n * Create a dispatcher over a core. Not started — call\n * {@link Dispatcher.start}, or drive {@link Dispatcher.tick} manually.\n *\n * @example\n * ```ts\n * import { createWebhooksCore, createDispatcher } from \"@xtandard/webhooks\";\n * import { createMemoryStorage } from \"@xtandard/webhooks/storage/memory\";\n *\n * const core = createWebhooksCore({ storage: createMemoryStorage() });\n * const dispatcher = createDispatcher(core);\n * dispatcher.start();\n * ```\n */\nexport function createDispatcher(core: WebhooksCore, options: DispatcherOptions = {}): Dispatcher {\n const merged = { ...core.options.dispatcher, ...options };\n const pollIntervalMs = merged.pollIntervalMs ?? 1000;\n const batchSize = merged.batchSize ?? 20;\n const concurrency = merged.concurrency ?? 8;\n const timeoutMs = merged.timeoutMs ?? 20_000;\n // The lease must outlast a single attempt, or a slow-but-alive attempt runs\n // past its lease and a second dispatcher reclaims and re-sends it. Enforce\n // lease > timeout with headroom for recording the outcome.\n const configuredLeaseMs = merged.leaseMs ?? 60_000;\n const leaseMs = Math.max(configuredLeaseMs, timeoutMs + 10_000);\n const schedule = merged.retrySchedule ?? DEFAULT_RETRY_SCHEDULE;\n const autoDisable = merged.autoDisable ?? { failingForDays: 5 };\n const responseBodyLimit = merged.responseBodyLimit ?? 4096;\n const userAgent = merged.userAgent ?? `xtandard-webhooks/${VERSION}`;\n const doFetch = merged.fetch;\n const now = core.options.now;\n\n let timer: ReturnType<typeof setInterval> | null = null;\n let inFlight: Promise<number> | null = null;\n\n /** Delay before the next attempt, per schedule position, with ±10% jitter. */\n function nextDelayMs(attemptsMade: number): number | null {\n if (attemptsMade >= schedule.length) return null; // exhausted\n const nominal = durationToMs(schedule[attemptsMade] as WebhookDuration);\n const jitter = 1 + (Math.random() * 2 - 1) * JITTER;\n return Math.round(nominal * jitter);\n }\n\n async function processClaim(delivery: Delivery): Promise<boolean> {\n const app = delivery.applicationKey;\n const trigger = delivery.pendingTrigger ?? \"schedule\";\n\n const failTerminal = async (error: string, eventType: string): Promise<boolean> => {\n const outcome: AttemptOutcome = {\n ok: false,\n error,\n durationMs: 0,\n at: new Date(now()).toISOString(),\n };\n await core.recordAttempt({ delivery, outcome, trigger, nextAttemptAt: null, eventType });\n return true;\n };\n\n const message = await core.getMessage(app, delivery.messageId);\n if (!message) return failTerminal(\"Message no longer exists\", \"unknown\");\n\n const endpoint = await core.getEndpoint(app, delivery.endpointId);\n if (!endpoint) return failTerminal(\"Endpoint no longer exists\", message.eventType);\n\n if (endpoint.disabled) {\n // Held, not failed: release the claim and re-check after the lease\n // window. Re-enabling the endpoint resumes delivery automatically.\n const queue = core.options.queueStorage;\n const recheckAt = now() + leaseMs;\n const released: Delivery = {\n ...delivery,\n status: \"pending\",\n nextAttemptAt: new Date(recheckAt).toISOString(),\n leaseUntil: null,\n updatedAt: new Date(now()).toISOString(),\n };\n // Remove the lease-position due entry the claim created, then park the\n // delivery at the recheck time.\n if (delivery.leaseUntil) {\n await queue.removeItem(dueKey(app, Date.parse(delivery.leaseUntil), delivery.id));\n }\n await queue.setItem(deliveryKey(app, delivery.id), released);\n await queue.setItem<DueEntry>(dueKey(app, recheckAt, delivery.id), {\n app,\n deliveryId: delivery.id,\n });\n return false; // no attempt made\n }\n\n const outcome = await attemptDelivery({\n endpoint,\n messageId: delivery.messageId,\n body: message.envelope,\n timeoutMs,\n responseBodyLimit,\n userAgent,\n ...(doFetch ? { fetch: doFetch } : {}),\n nowMs: now(),\n });\n\n const attemptsMade = delivery.attemptCount + 1;\n const delay = outcome.ok ? null : nextDelayMs(attemptsMade);\n await core.recordAttempt({\n delivery,\n outcome,\n trigger,\n nextAttemptAt: delay === null ? null : new Date(now() + delay).toISOString(),\n eventType: message.eventType,\n });\n await core.noteEndpointOutcome(app, endpoint.id, outcome.ok, autoDisable);\n return true;\n }\n\n async function runTick(): Promise<number> {\n const claimed = await core.claimDueDeliveries({ limit: batchSize, leaseMs });\n if (claimed.length === 0) return 0;\n\n let attempts = 0;\n let cursor = 0;\n const workers = Array.from({ length: Math.min(concurrency, claimed.length) }, async () => {\n while (cursor < claimed.length) {\n const delivery = claimed[cursor++] as Delivery;\n try {\n if (await processClaim(delivery)) attempts++;\n } catch (error) {\n // A storage failure mid-claim: leave the delivery leased; the lease\n // expiry re-exposes it. Never let one claim kill the tick.\n // eslint-disable-next-line no-console\n console.warn(`[@xtandard/webhooks] delivery ${delivery.id} processing failed:`, error);\n }\n }\n });\n await Promise.all(workers);\n return attempts;\n }\n\n const dispatcher: Dispatcher = {\n start() {\n if (timer) return;\n timer = setInterval(() => {\n if (inFlight) return; // never overlap ticks\n inFlight = runTick()\n .catch((error) => {\n // eslint-disable-next-line no-console\n console.warn(\"[@xtandard/webhooks] dispatcher tick failed:\", error);\n return 0;\n })\n .finally(() => {\n inFlight = null;\n });\n }, pollIntervalMs);\n // Never keep the host process alive just to poll.\n (timer as unknown as { unref?: () => void }).unref?.();\n },\n\n async stop() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n if (inFlight) await inFlight;\n },\n\n async tick() {\n // Manual ticks also serialize against the poller.\n while (inFlight) await inFlight;\n inFlight = runTick().finally(() => {\n inFlight = null;\n });\n return inFlight;\n },\n\n get running() {\n return timer !== null;\n },\n };\n\n return dispatcher;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_keys = require("./keys-FiKpaVHX.cjs");
2
- const require_core = require("./core-ZGhH6Vs2.cjs");
2
+ const require_core = require("./core-DuHD0Rdg.cjs");
3
3
  //#region src/dispatcher.ts
4
4
  /**
5
5
  * The delivery engine. Polls the due index, claims deliveries (lease-based,
@@ -60,7 +60,7 @@ function createDispatcher(core, options = {}) {
60
60
  const schedule = merged.retrySchedule ?? DEFAULT_RETRY_SCHEDULE;
61
61
  const autoDisable = merged.autoDisable ?? { failingForDays: 5 };
62
62
  const responseBodyLimit = merged.responseBodyLimit ?? 4096;
63
- const userAgent = merged.userAgent ?? `xtandard-webhooks/0.1.0`;
63
+ const userAgent = merged.userAgent ?? `xtandard-webhooks/0.1.2`;
64
64
  const doFetch = merged.fetch;
65
65
  const now = core.options.now;
66
66
  let timer = null;
@@ -209,4 +209,4 @@ Object.defineProperty(exports, "dispatcher_exports", {
209
209
  }
210
210
  });
211
211
 
212
- //# sourceMappingURL=dispatcher-B0xTEHt1.cjs.map
212
+ //# sourceMappingURL=dispatcher-COdWV6hM.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher-B0xTEHt1.cjs","names":["durationToMs","dueKey","deliveryKey","attemptDelivery"],"sources":["../src/dispatcher.ts"],"sourcesContent":["/**\n * The delivery engine. Polls the due index, claims deliveries (lease-based,\n * multi-instance safe when storage supports CAS or the `deliveryQueue`\n * capability), performs the signed HTTP attempts, and drives each delivery's\n * state machine through the retry schedule into success or dead-letter.\n *\n * Runs in-process: the panel starts one by default, a split worker runs one\n * via the CLI (`xtandard-webhooks dispatch`), and tests drive {@link Dispatcher.tick}\n * manually. All timers are `unref()`ed so a dispatcher never keeps a process\n * alive on its own. Semantics are **at-least-once**: a crashed process loses\n * nothing (leases expire, the next tick reclaims); receivers dedupe on\n * `webhook-id`.\n *\n * @module\n */\n\nimport { attemptDelivery, type AttemptOutcome } from \"./deliver.ts\";\nimport type { WebhooksCore } from \"./core.ts\";\nimport { durationToMs } from \"./duration.ts\";\nimport { deliveryKey, dueKey, type DueEntry } from \"./keys.ts\";\nimport type { Delivery, WebhookDuration } from \"./schema.ts\";\nimport { VERSION } from \"./version.ts\";\n\n/** Options for {@link createDispatcher} (also accepted on panels and the core). */\nexport interface DispatcherOptions {\n /** How often to poll for due deliveries. Default `1000`. */\n pollIntervalMs?: number;\n /** Max deliveries claimed per tick. Default `20`. */\n batchSize?: number;\n /** Max in-flight HTTP attempts. Default `8`. */\n concurrency?: number;\n /** Per-attempt timeout (AbortController). Default `20_000`. */\n timeoutMs?: number;\n /** Claim lease duration; an expired lease makes a claim reclaimable. Default `60_000`. */\n leaseMs?: number;\n /**\n * Delay before attempt N+1 after attempt N fails (index 0 = the initial\n * attempt's delay). Exhausting the schedule dead-letters the delivery.\n * Default `[\"0s\", \"5s\", \"5m\", \"30m\", \"2h\", \"5h\", \"10h\"]` (Svix-compatible).\n */\n retrySchedule?: WebhookDuration[];\n /**\n * Auto-disable endpoints whose every attempt has failed for this many\n * consecutive days. `false` disables the policy. Default `{ failingForDays: 5 }`.\n */\n autoDisable?: { failingForDays?: number } | false;\n /** Cap on stored response-body characters per attempt. Default `4096`. */\n responseBodyLimit?: number;\n /** Injectable fetch (tests, instrumentation). Default: global fetch. */\n fetch?: typeof fetch;\n /** `user-agent` header. Default `\"xtandard-webhooks/<version>\"`. */\n userAgent?: string;\n}\n\n/** The delivery engine handle. */\nexport interface Dispatcher {\n /** Begin polling. Idempotent. */\n start(): void;\n /** Stop polling and wait for in-flight attempts to finish. */\n stop(): Promise<void>;\n /**\n * Run one manual pass: claim due deliveries, attempt them, record outcomes.\n * Returns the number of attempts made — the unit-test surface (tests never\n * assert on timers).\n */\n tick(): Promise<number>;\n readonly running: boolean;\n}\n\n/** The default retry schedule (Svix-compatible). */\nexport const DEFAULT_RETRY_SCHEDULE: WebhookDuration[] = [\n \"0s\",\n \"5s\",\n \"5m\",\n \"30m\",\n \"2h\",\n \"5h\",\n \"10h\",\n];\n\n/** Fractional jitter applied to every retry delay (±10%). */\nconst JITTER = 0.1;\n\n/**\n * Create a dispatcher over a core. Not started — call\n * {@link Dispatcher.start}, or drive {@link Dispatcher.tick} manually.\n *\n * @example\n * ```ts\n * import { createWebhooksCore, createDispatcher } from \"@xtandard/webhooks\";\n * import { createMemoryStorage } from \"@xtandard/webhooks/storage/memory\";\n *\n * const core = createWebhooksCore({ storage: createMemoryStorage() });\n * const dispatcher = createDispatcher(core);\n * dispatcher.start();\n * ```\n */\nexport function createDispatcher(core: WebhooksCore, options: DispatcherOptions = {}): Dispatcher {\n const merged = { ...core.options.dispatcher, ...options };\n const pollIntervalMs = merged.pollIntervalMs ?? 1000;\n const batchSize = merged.batchSize ?? 20;\n const concurrency = merged.concurrency ?? 8;\n const timeoutMs = merged.timeoutMs ?? 20_000;\n // The lease must outlast a single attempt, or a slow-but-alive attempt runs\n // past its lease and a second dispatcher reclaims and re-sends it. Enforce\n // lease > timeout with headroom for recording the outcome.\n const configuredLeaseMs = merged.leaseMs ?? 60_000;\n const leaseMs = Math.max(configuredLeaseMs, timeoutMs + 10_000);\n const schedule = merged.retrySchedule ?? DEFAULT_RETRY_SCHEDULE;\n const autoDisable = merged.autoDisable ?? { failingForDays: 5 };\n const responseBodyLimit = merged.responseBodyLimit ?? 4096;\n const userAgent = merged.userAgent ?? `xtandard-webhooks/${VERSION}`;\n const doFetch = merged.fetch;\n const now = core.options.now;\n\n let timer: ReturnType<typeof setInterval> | null = null;\n let inFlight: Promise<number> | null = null;\n\n /** Delay before the next attempt, per schedule position, with ±10% jitter. */\n function nextDelayMs(attemptsMade: number): number | null {\n if (attemptsMade >= schedule.length) return null; // exhausted\n const nominal = durationToMs(schedule[attemptsMade] as WebhookDuration);\n const jitter = 1 + (Math.random() * 2 - 1) * JITTER;\n return Math.round(nominal * jitter);\n }\n\n async function processClaim(delivery: Delivery): Promise<boolean> {\n const app = delivery.applicationKey;\n const trigger = delivery.pendingTrigger ?? \"schedule\";\n\n const failTerminal = async (error: string, eventType: string): Promise<boolean> => {\n const outcome: AttemptOutcome = {\n ok: false,\n error,\n durationMs: 0,\n at: new Date(now()).toISOString(),\n };\n await core.recordAttempt({ delivery, outcome, trigger, nextAttemptAt: null, eventType });\n return true;\n };\n\n const message = await core.getMessage(app, delivery.messageId);\n if (!message) return failTerminal(\"Message no longer exists\", \"unknown\");\n\n const endpoint = await core.getEndpoint(app, delivery.endpointId);\n if (!endpoint) return failTerminal(\"Endpoint no longer exists\", message.eventType);\n\n if (endpoint.disabled) {\n // Held, not failed: release the claim and re-check after the lease\n // window. Re-enabling the endpoint resumes delivery automatically.\n const queue = core.options.queueStorage;\n const recheckAt = now() + leaseMs;\n const released: Delivery = {\n ...delivery,\n status: \"pending\",\n nextAttemptAt: new Date(recheckAt).toISOString(),\n leaseUntil: null,\n updatedAt: new Date(now()).toISOString(),\n };\n // Remove the lease-position due entry the claim created, then park the\n // delivery at the recheck time.\n if (delivery.leaseUntil) {\n await queue.removeItem(dueKey(app, Date.parse(delivery.leaseUntil), delivery.id));\n }\n await queue.setItem(deliveryKey(app, delivery.id), released);\n await queue.setItem<DueEntry>(dueKey(app, recheckAt, delivery.id), {\n app,\n deliveryId: delivery.id,\n });\n return false; // no attempt made\n }\n\n const outcome = await attemptDelivery({\n endpoint,\n messageId: delivery.messageId,\n body: message.envelope,\n timeoutMs,\n responseBodyLimit,\n userAgent,\n ...(doFetch ? { fetch: doFetch } : {}),\n nowMs: now(),\n });\n\n const attemptsMade = delivery.attemptCount + 1;\n const delay = outcome.ok ? null : nextDelayMs(attemptsMade);\n await core.recordAttempt({\n delivery,\n outcome,\n trigger,\n nextAttemptAt: delay === null ? null : new Date(now() + delay).toISOString(),\n eventType: message.eventType,\n });\n await core.noteEndpointOutcome(app, endpoint.id, outcome.ok, autoDisable);\n return true;\n }\n\n async function runTick(): Promise<number> {\n const claimed = await core.claimDueDeliveries({ limit: batchSize, leaseMs });\n if (claimed.length === 0) return 0;\n\n let attempts = 0;\n let cursor = 0;\n const workers = Array.from({ length: Math.min(concurrency, claimed.length) }, async () => {\n while (cursor < claimed.length) {\n const delivery = claimed[cursor++] as Delivery;\n try {\n if (await processClaim(delivery)) attempts++;\n } catch (error) {\n // A storage failure mid-claim: leave the delivery leased; the lease\n // expiry re-exposes it. Never let one claim kill the tick.\n // eslint-disable-next-line no-console\n console.warn(`[@xtandard/webhooks] delivery ${delivery.id} processing failed:`, error);\n }\n }\n });\n await Promise.all(workers);\n return attempts;\n }\n\n const dispatcher: Dispatcher = {\n start() {\n if (timer) return;\n timer = setInterval(() => {\n if (inFlight) return; // never overlap ticks\n inFlight = runTick()\n .catch((error) => {\n // eslint-disable-next-line no-console\n console.warn(\"[@xtandard/webhooks] dispatcher tick failed:\", error);\n return 0;\n })\n .finally(() => {\n inFlight = null;\n });\n }, pollIntervalMs);\n // Never keep the host process alive just to poll.\n (timer as unknown as { unref?: () => void }).unref?.();\n },\n\n async stop() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n if (inFlight) await inFlight;\n },\n\n async tick() {\n // Manual ticks also serialize against the poller.\n while (inFlight) await inFlight;\n inFlight = runTick().finally(() => {\n inFlight = null;\n });\n return inFlight;\n },\n\n get running() {\n return timer !== null;\n },\n };\n\n return dispatcher;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dispatcher-COdWV6hM.cjs","names":["durationToMs","dueKey","deliveryKey","attemptDelivery"],"sources":["../src/dispatcher.ts"],"sourcesContent":["/**\n * The delivery engine. Polls the due index, claims deliveries (lease-based,\n * multi-instance safe when storage supports CAS or the `deliveryQueue`\n * capability), performs the signed HTTP attempts, and drives each delivery's\n * state machine through the retry schedule into success or dead-letter.\n *\n * Runs in-process: the panel starts one by default, a split worker runs one\n * via the CLI (`xtandard-webhooks dispatch`), and tests drive {@link Dispatcher.tick}\n * manually. All timers are `unref()`ed so a dispatcher never keeps a process\n * alive on its own. Semantics are **at-least-once**: a crashed process loses\n * nothing (leases expire, the next tick reclaims); receivers dedupe on\n * `webhook-id`.\n *\n * @module\n */\n\nimport { attemptDelivery, type AttemptOutcome } from \"./deliver.ts\";\nimport type { WebhooksCore } from \"./core.ts\";\nimport { durationToMs } from \"./duration.ts\";\nimport { deliveryKey, dueKey, type DueEntry } from \"./keys.ts\";\nimport type { Delivery, WebhookDuration } from \"./schema.ts\";\nimport { VERSION } from \"./version.ts\";\n\n/** Options for {@link createDispatcher} (also accepted on panels and the core). */\nexport interface DispatcherOptions {\n /** How often to poll for due deliveries. Default `1000`. */\n pollIntervalMs?: number;\n /** Max deliveries claimed per tick. Default `20`. */\n batchSize?: number;\n /** Max in-flight HTTP attempts. Default `8`. */\n concurrency?: number;\n /** Per-attempt timeout (AbortController). Default `20_000`. */\n timeoutMs?: number;\n /** Claim lease duration; an expired lease makes a claim reclaimable. Default `60_000`. */\n leaseMs?: number;\n /**\n * Delay before attempt N+1 after attempt N fails (index 0 = the initial\n * attempt's delay). Exhausting the schedule dead-letters the delivery.\n * Default `[\"0s\", \"5s\", \"5m\", \"30m\", \"2h\", \"5h\", \"10h\"]` (Svix-compatible).\n */\n retrySchedule?: WebhookDuration[];\n /**\n * Auto-disable endpoints whose every attempt has failed for this many\n * consecutive days. `false` disables the policy. Default `{ failingForDays: 5 }`.\n */\n autoDisable?: { failingForDays?: number } | false;\n /** Cap on stored response-body characters per attempt. Default `4096`. */\n responseBodyLimit?: number;\n /** Injectable fetch (tests, instrumentation). Default: global fetch. */\n fetch?: typeof fetch;\n /** `user-agent` header. Default `\"xtandard-webhooks/<version>\"`. */\n userAgent?: string;\n}\n\n/** The delivery engine handle. */\nexport interface Dispatcher {\n /** Begin polling. Idempotent. */\n start(): void;\n /** Stop polling and wait for in-flight attempts to finish. */\n stop(): Promise<void>;\n /**\n * Run one manual pass: claim due deliveries, attempt them, record outcomes.\n * Returns the number of attempts made — the unit-test surface (tests never\n * assert on timers).\n */\n tick(): Promise<number>;\n readonly running: boolean;\n}\n\n/** The default retry schedule (Svix-compatible). */\nexport const DEFAULT_RETRY_SCHEDULE: WebhookDuration[] = [\n \"0s\",\n \"5s\",\n \"5m\",\n \"30m\",\n \"2h\",\n \"5h\",\n \"10h\",\n];\n\n/** Fractional jitter applied to every retry delay (±10%). */\nconst JITTER = 0.1;\n\n/**\n * Create a dispatcher over a core. Not started — call\n * {@link Dispatcher.start}, or drive {@link Dispatcher.tick} manually.\n *\n * @example\n * ```ts\n * import { createWebhooksCore, createDispatcher } from \"@xtandard/webhooks\";\n * import { createMemoryStorage } from \"@xtandard/webhooks/storage/memory\";\n *\n * const core = createWebhooksCore({ storage: createMemoryStorage() });\n * const dispatcher = createDispatcher(core);\n * dispatcher.start();\n * ```\n */\nexport function createDispatcher(core: WebhooksCore, options: DispatcherOptions = {}): Dispatcher {\n const merged = { ...core.options.dispatcher, ...options };\n const pollIntervalMs = merged.pollIntervalMs ?? 1000;\n const batchSize = merged.batchSize ?? 20;\n const concurrency = merged.concurrency ?? 8;\n const timeoutMs = merged.timeoutMs ?? 20_000;\n // The lease must outlast a single attempt, or a slow-but-alive attempt runs\n // past its lease and a second dispatcher reclaims and re-sends it. Enforce\n // lease > timeout with headroom for recording the outcome.\n const configuredLeaseMs = merged.leaseMs ?? 60_000;\n const leaseMs = Math.max(configuredLeaseMs, timeoutMs + 10_000);\n const schedule = merged.retrySchedule ?? DEFAULT_RETRY_SCHEDULE;\n const autoDisable = merged.autoDisable ?? { failingForDays: 5 };\n const responseBodyLimit = merged.responseBodyLimit ?? 4096;\n const userAgent = merged.userAgent ?? `xtandard-webhooks/${VERSION}`;\n const doFetch = merged.fetch;\n const now = core.options.now;\n\n let timer: ReturnType<typeof setInterval> | null = null;\n let inFlight: Promise<number> | null = null;\n\n /** Delay before the next attempt, per schedule position, with ±10% jitter. */\n function nextDelayMs(attemptsMade: number): number | null {\n if (attemptsMade >= schedule.length) return null; // exhausted\n const nominal = durationToMs(schedule[attemptsMade] as WebhookDuration);\n const jitter = 1 + (Math.random() * 2 - 1) * JITTER;\n return Math.round(nominal * jitter);\n }\n\n async function processClaim(delivery: Delivery): Promise<boolean> {\n const app = delivery.applicationKey;\n const trigger = delivery.pendingTrigger ?? \"schedule\";\n\n const failTerminal = async (error: string, eventType: string): Promise<boolean> => {\n const outcome: AttemptOutcome = {\n ok: false,\n error,\n durationMs: 0,\n at: new Date(now()).toISOString(),\n };\n await core.recordAttempt({ delivery, outcome, trigger, nextAttemptAt: null, eventType });\n return true;\n };\n\n const message = await core.getMessage(app, delivery.messageId);\n if (!message) return failTerminal(\"Message no longer exists\", \"unknown\");\n\n const endpoint = await core.getEndpoint(app, delivery.endpointId);\n if (!endpoint) return failTerminal(\"Endpoint no longer exists\", message.eventType);\n\n if (endpoint.disabled) {\n // Held, not failed: release the claim and re-check after the lease\n // window. Re-enabling the endpoint resumes delivery automatically.\n const queue = core.options.queueStorage;\n const recheckAt = now() + leaseMs;\n const released: Delivery = {\n ...delivery,\n status: \"pending\",\n nextAttemptAt: new Date(recheckAt).toISOString(),\n leaseUntil: null,\n updatedAt: new Date(now()).toISOString(),\n };\n // Remove the lease-position due entry the claim created, then park the\n // delivery at the recheck time.\n if (delivery.leaseUntil) {\n await queue.removeItem(dueKey(app, Date.parse(delivery.leaseUntil), delivery.id));\n }\n await queue.setItem(deliveryKey(app, delivery.id), released);\n await queue.setItem<DueEntry>(dueKey(app, recheckAt, delivery.id), {\n app,\n deliveryId: delivery.id,\n });\n return false; // no attempt made\n }\n\n const outcome = await attemptDelivery({\n endpoint,\n messageId: delivery.messageId,\n body: message.envelope,\n timeoutMs,\n responseBodyLimit,\n userAgent,\n ...(doFetch ? { fetch: doFetch } : {}),\n nowMs: now(),\n });\n\n const attemptsMade = delivery.attemptCount + 1;\n const delay = outcome.ok ? null : nextDelayMs(attemptsMade);\n await core.recordAttempt({\n delivery,\n outcome,\n trigger,\n nextAttemptAt: delay === null ? null : new Date(now() + delay).toISOString(),\n eventType: message.eventType,\n });\n await core.noteEndpointOutcome(app, endpoint.id, outcome.ok, autoDisable);\n return true;\n }\n\n async function runTick(): Promise<number> {\n const claimed = await core.claimDueDeliveries({ limit: batchSize, leaseMs });\n if (claimed.length === 0) return 0;\n\n let attempts = 0;\n let cursor = 0;\n const workers = Array.from({ length: Math.min(concurrency, claimed.length) }, async () => {\n while (cursor < claimed.length) {\n const delivery = claimed[cursor++] as Delivery;\n try {\n if (await processClaim(delivery)) attempts++;\n } catch (error) {\n // A storage failure mid-claim: leave the delivery leased; the lease\n // expiry re-exposes it. Never let one claim kill the tick.\n // eslint-disable-next-line no-console\n console.warn(`[@xtandard/webhooks] delivery ${delivery.id} processing failed:`, error);\n }\n }\n });\n await Promise.all(workers);\n return attempts;\n }\n\n const dispatcher: Dispatcher = {\n start() {\n if (timer) return;\n timer = setInterval(() => {\n if (inFlight) return; // never overlap ticks\n inFlight = runTick()\n .catch((error) => {\n // eslint-disable-next-line no-console\n console.warn(\"[@xtandard/webhooks] dispatcher tick failed:\", error);\n return 0;\n })\n .finally(() => {\n inFlight = null;\n });\n }, pollIntervalMs);\n // Never keep the host process alive just to poll.\n (timer as unknown as { unref?: () => void }).unref?.();\n },\n\n async stop() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n if (inFlight) await inFlight;\n },\n\n async tick() {\n // Manual ticks also serialize against the poller.\n while (inFlight) await inFlight;\n inFlight = runTick().finally(() => {\n inFlight = null;\n });\n return inFlight;\n },\n\n get running() {\n return timer !== null;\n },\n };\n\n return dispatcher;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_create_fetch_handler = require("./create-fetch-handler-CmooujQo.cjs");
2
+ const require_create_fetch_handler = require("./create-fetch-handler-BNsNcspj.cjs");
3
3
  //#region src/adapters/bun.ts
4
4
  /**
5
5
  * Bun adapter. The handler is already web-standard, so this is a passthrough you
@@ -1,4 +1,4 @@
1
- import { n as WebhooksPanelOptions, t as CreateFetchHandlerResult } from "./create-fetch-handler-Dlkhustu.cjs";
1
+ import { n as WebhooksPanelOptions, t as CreateFetchHandlerResult } from "./create-fetch-handler-D9ZRfrY6.cjs";
2
2
 
3
3
  //#region src/adapters/bun.d.ts
4
4
  /** Create a Bun-ready panel handler (`fetch` + `core` + `dispatcher` + `openapi`). */
@@ -1,4 +1,4 @@
1
- import { n as WebhooksPanelOptions, t as CreateFetchHandlerResult } from "./create-fetch-handler-jy3hy5nZ.mjs";
1
+ import { n as WebhooksPanelOptions, t as CreateFetchHandlerResult } from "./create-fetch-handler-BN9vXbgW.mjs";
2
2
 
3
3
  //#region src/adapters/bun.d.ts
4
4
  /** Create a Bun-ready panel handler (`fetch` + `core` + `dispatcher` + `openapi`). */
@@ -1,4 +1,4 @@
1
- import { t as createFetchHandler } from "./create-fetch-handler-BIdk9P30.mjs";
1
+ import { t as createFetchHandler } from "./create-fetch-handler-C6BqzdsN.mjs";
2
2
  //#region src/adapters/bun.ts
3
3
  /**
4
4
  * Bun adapter. The handler is already web-standard, so this is a passthrough you
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_create_fetch_handler = require("./create-fetch-handler-CmooujQo.cjs");
2
+ const require_create_fetch_handler = require("./create-fetch-handler-BNsNcspj.cjs");
3
3
  let elysia = require("elysia");
4
4
  //#region src/adapters/elysia.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-Dlkhustu.cjs";
1
+ import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-D9ZRfrY6.cjs";
2
2
  import { Elysia } from "elysia";
3
3
 
4
4
  //#region src/adapters/elysia.d.ts
@@ -1,4 +1,4 @@
1
- import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-jy3hy5nZ.mjs";
1
+ import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-BN9vXbgW.mjs";
2
2
  import { Elysia } from "elysia";
3
3
 
4
4
  //#region src/adapters/elysia.d.ts
@@ -1,4 +1,4 @@
1
- import { t as createFetchHandler } from "./create-fetch-handler-BIdk9P30.mjs";
1
+ import { t as createFetchHandler } from "./create-fetch-handler-C6BqzdsN.mjs";
2
2
  import { Elysia, t } from "elysia";
3
3
  //#region src/adapters/elysia.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_create_fetch_handler = require("./create-fetch-handler-CmooujQo.cjs");
2
+ const require_create_fetch_handler = require("./create-fetch-handler-BNsNcspj.cjs");
3
3
  //#region src/adapters/express.ts
4
4
  function headersFrom(req) {
5
5
  const headers = new Headers();
@@ -1,4 +1,4 @@
1
- import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-Dlkhustu.cjs";
1
+ import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-D9ZRfrY6.cjs";
2
2
  import { NextFunction, Request, Response } from "express";
3
3
 
4
4
  //#region src/adapters/express.d.ts
@@ -1,4 +1,4 @@
1
- import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-jy3hy5nZ.mjs";
1
+ import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-BN9vXbgW.mjs";
2
2
  import { NextFunction, Request, Response } from "express";
3
3
 
4
4
  //#region src/adapters/express.d.ts
@@ -1,4 +1,4 @@
1
- import { t as createFetchHandler } from "./create-fetch-handler-BIdk9P30.mjs";
1
+ import { t as createFetchHandler } from "./create-fetch-handler-C6BqzdsN.mjs";
2
2
  //#region src/adapters/express.ts
3
3
  function headersFrom(req) {
4
4
  const headers = new Headers();
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_create_fetch_handler = require("./create-fetch-handler-CmooujQo.cjs");
2
+ const require_create_fetch_handler = require("./create-fetch-handler-BNsNcspj.cjs");
3
3
  let hono = require("hono");
4
4
  //#region src/adapters/hono.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-Dlkhustu.cjs";
1
+ import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-D9ZRfrY6.cjs";
2
2
  import { Hono } from "hono";
3
3
 
4
4
  //#region src/adapters/hono.d.ts
@@ -1,4 +1,4 @@
1
- import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-jy3hy5nZ.mjs";
1
+ import { n as WebhooksPanelOptions, r as createFetchHandler } from "./create-fetch-handler-BN9vXbgW.mjs";
2
2
  import { Hono } from "hono";
3
3
 
4
4
  //#region src/adapters/hono.d.ts
@@ -1,4 +1,4 @@
1
- import { t as createFetchHandler } from "./create-fetch-handler-BIdk9P30.mjs";
1
+ import { t as createFetchHandler } from "./create-fetch-handler-C6BqzdsN.mjs";
2
2
  import { Hono } from "hono";
3
3
  //#region src/adapters/hono.ts
4
4
  /**
package/dist/index.cjs CHANGED
@@ -1,12 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_keys = require("./keys-FiKpaVHX.cjs");
3
3
  const require_schema = require("./schema.cjs");
4
+ const require_core = require("./core-DuHD0Rdg.cjs");
4
5
  const require_signing = require("./signing.cjs");
5
- const require_core = require("./core-ZGhH6Vs2.cjs");
6
6
  const require_contract = require("./contract-Bf1qguwt.cjs");
7
- const require_dispatcher = require("./dispatcher-B0xTEHt1.cjs");
7
+ const require_dispatcher = require("./dispatcher-COdWV6hM.cjs");
8
8
  const require_contract$1 = require("./contract-B2d5dNU3.cjs");
9
- const require_create_fetch_handler = require("./create-fetch-handler-CmooujQo.cjs");
9
+ const require_create_fetch_handler = require("./create-fetch-handler-BNsNcspj.cjs");
10
10
  //#region src/storage/watch.ts
11
11
  /**
12
12
  * Wrap a storage so it implements {@link WatchableWebhooksStorage} using
package/dist/index.d.cts CHANGED
@@ -4,7 +4,7 @@ import { a as WatchableWebhooksStorage, c as isCompareAndSwap, d as requirePeer,
4
4
  import { a as HookDeniedError, c as WebhooksHooksInput, d as runAfter, f as runBefore, i as BeforeEventType, l as defaultHookErrorReporter, n as AfterEventType, o as HookErrorReporter, r as BeforeEvent, s as WebhooksHooks, t as AfterEvent, u as normalizeHooks } from "./contract-Bnb3fgRJ.cjs";
5
5
  import { n as Principal, t as AuthProvider } from "./contract-lETlIuXo.cjs";
6
6
  import { a as WebhooksResource, i as WebhooksAction, n as AuthorizeInput, o as isMutatingAction, r as MUTATING_ACTIONS, t as AuthorizationProvider } from "./contract-CiPskNvS.cjs";
7
- import { a as WebhooksPortalOptions, i as DEFAULT_PORTAL_ACTIONS, n as WebhooksPanelOptions, o as WebhooksCorsOptions, r as createFetchHandler, t as CreateFetchHandlerResult } from "./create-fetch-handler-Dlkhustu.cjs";
7
+ import { a as WebhooksPortalOptions, i as DEFAULT_PORTAL_ACTIONS, n as WebhooksPanelOptions, o as WebhooksCorsOptions, r as createFetchHandler, t as CreateFetchHandlerResult } from "./create-fetch-handler-D9ZRfrY6.cjs";
8
8
  import { SECRET_PREFIX, VerifyInput, WebhookVerificationError, generateSecret, sign, signatureHeader, verify } from "./signing.cjs";
9
9
 
10
10
  //#region \0rolldown/runtime.js
@@ -17,7 +17,7 @@ import { SECRET_PREFIX, VerifyInput, WebhookVerificationError, generateSecret, s
17
17
  * @module
18
18
  */
19
19
  /** The published package version. */
20
- declare const VERSION = "0.1.0";
20
+ declare const VERSION = "0.1.2";
21
21
  declare namespace keys_d_exports {
22
22
  export { DueEntry, RESERVED_APPLICATION_KEYS, ROOT, applicationMetaKey, applicationPrefix, applicationsKey, attemptKey, attemptsPrefix, auditLogKey, byEndpointKey, byEndpointPrefix, byMessageKey, byMessagePrefix, deliveriesPrefix, deliveryKey, dueKey, duePrefix, endpointKey, endpointsKey, eventTypeKey, eventTypesKey, globalAuditLogKey, idempotencyKey, lastSegment, messageKey, messagesPrefix, parseDueKey };
23
23
  }
package/dist/index.d.mts CHANGED
@@ -4,7 +4,7 @@ import { a as WatchableWebhooksStorage, c as isCompareAndSwap, d as requirePeer,
4
4
  import { a as HookDeniedError, c as WebhooksHooksInput, d as runAfter, f as runBefore, i as BeforeEventType, l as defaultHookErrorReporter, n as AfterEventType, o as HookErrorReporter, r as BeforeEvent, s as WebhooksHooks, t as AfterEvent, u as normalizeHooks } from "./contract-T1kcZNdG.mjs";
5
5
  import { n as Principal, t as AuthProvider } from "./contract-lETlIuXo.mjs";
6
6
  import { a as WebhooksResource, i as WebhooksAction, n as AuthorizeInput, o as isMutatingAction, r as MUTATING_ACTIONS, t as AuthorizationProvider } from "./contract-C2r2Xzwp.mjs";
7
- import { a as WebhooksPortalOptions, i as DEFAULT_PORTAL_ACTIONS, n as WebhooksPanelOptions, o as WebhooksCorsOptions, r as createFetchHandler, t as CreateFetchHandlerResult } from "./create-fetch-handler-jy3hy5nZ.mjs";
7
+ import { a as WebhooksPortalOptions, i as DEFAULT_PORTAL_ACTIONS, n as WebhooksPanelOptions, o as WebhooksCorsOptions, r as createFetchHandler, t as CreateFetchHandlerResult } from "./create-fetch-handler-BN9vXbgW.mjs";
8
8
  import { SECRET_PREFIX, VerifyInput, WebhookVerificationError, generateSecret, sign, signatureHeader, verify } from "./signing.mjs";
9
9
 
10
10
  //#region src/version.d.ts
@@ -15,7 +15,7 @@ import { SECRET_PREFIX, VerifyInput, WebhookVerificationError, generateSecret, s
15
15
  * @module
16
16
  */
17
17
  /** The published package version. */
18
- declare const VERSION = "0.1.0";
18
+ declare const VERSION = "0.1.2";
19
19
  declare namespace keys_d_exports {
20
20
  export { DueEntry, RESERVED_APPLICATION_KEYS, ROOT, applicationMetaKey, applicationPrefix, applicationsKey, attemptKey, attemptsPrefix, auditLogKey, byEndpointKey, byEndpointPrefix, byMessageKey, byMessagePrefix, deliveriesPrefix, deliveryKey, dueKey, duePrefix, endpointKey, endpointsKey, eventTypeKey, eventTypesKey, globalAuditLogKey, idempotencyKey, lastSegment, messageKey, messagesPrefix, parseDueKey };
21
21
  }
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  import { SCHEMA_VERSION, isTerminalDeliveryStatus } from "./schema.mjs";
2
+ import { A as attemptDelivery, C as newId, D as DEFAULT_ATTEMPT_TIMEOUT_MS, E as emitDelivery, O as DEFAULT_RESPONSE_BODY_LIMIT, T as parseDurationList, _ as normalizeHooks, a as ReadonlyError, b as VERSION, c as RESERVED_HEADERS, d as validateApplication, f as validateEndpoint, g as defaultHookErrorReporter, h as HookDeniedError, i as PayloadTooLargeError, j as buildSignedRequest, k as activeSecrets, l as ValidationError, m as validateEventType, n as IdempotencyConflictError, o as createWebhooksCore, p as validateEndpointUrl, r as NotFoundError, s as KEY_REGEX, t as ConflictError, u as assertValid, v as runAfter, w as durationToMs, x as idPattern, y as runBefore } from "./core-B1JzRitF.mjs";
2
3
  import { SECRET_PREFIX, WebhookVerificationError, generateSecret, sign, signatureHeader, verify } from "./signing.mjs";
3
- import { A as attemptDelivery, C as newId, D as DEFAULT_ATTEMPT_TIMEOUT_MS, E as emitDelivery, O as DEFAULT_RESPONSE_BODY_LIMIT, T as parseDurationList, _ as normalizeHooks, a as ReadonlyError, b as VERSION, c as RESERVED_HEADERS, d as validateApplication, f as validateEndpoint, g as defaultHookErrorReporter, h as HookDeniedError, i as PayloadTooLargeError, j as buildSignedRequest, k as activeSecrets, l as ValidationError, m as validateEventType, n as IdempotencyConflictError, o as createWebhooksCore, p as validateEndpointUrl, r as NotFoundError, s as KEY_REGEX, t as ConflictError, u as assertValid, v as runAfter, w as durationToMs, x as idPattern, y as runBefore } from "./core-CMpnmI5Q.mjs";
4
4
  import { x as keys_exports } from "./keys-Byyj4quQ.mjs";
5
5
  import { a as requirePeer, i as isWatchable, n as isCompareAndSwap, r as isTransactional, t as hasDeliveryQueue } from "./contract-BEhDcd_5.mjs";
6
- import { n as createDispatcher, t as DEFAULT_RETRY_SCHEDULE } from "./dispatcher-Coubwrka.mjs";
6
+ import { n as createDispatcher, t as DEFAULT_RETRY_SCHEDULE } from "./dispatcher-CFfWo-fN.mjs";
7
7
  import { n as isMutatingAction, t as MUTATING_ACTIONS } from "./contract-9XpcwcCn.mjs";
8
- import { a as PORTAL_TOKEN_PREFIX, c as verifyPortalToken, i as buildOpenApiDocument, o as PortalTokenError, r as DEFAULT_PORTAL_ACTIONS, s as createPortalToken, t as createFetchHandler } from "./create-fetch-handler-BIdk9P30.mjs";
8
+ import { a as PORTAL_TOKEN_PREFIX, c as verifyPortalToken, i as buildOpenApiDocument, o as PortalTokenError, r as DEFAULT_PORTAL_ACTIONS, s as createPortalToken, t as createFetchHandler } from "./create-fetch-handler-C6BqzdsN.mjs";
9
9
  //#region src/storage/watch.ts
10
10
  /**
11
11
  * Wrap a storage so it implements {@link WatchableWebhooksStorage} using
package/dist/react.css CHANGED
@@ -1 +1 @@
1
- /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-ease:initial;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--color-black:#000;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-2xl:42rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-snug:1.375;--leading-relaxed:1.625;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--default-mono-font-family:"JetBrains Mono", "SFMono-Regular", "Cascadia Code", ui-monospace, monospace}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:before,:after{box-sizing:border-box;border-color:var(--border)}html,body,#root{height:100%;margin:0;padding:0}body{background-color:var(--background);color:var(--foreground);font-family:var(--font-sans);letter-spacing:-.006em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:14px;line-height:1.5}:focus-visible{outline:2px solid var(--ring);outline-offset:2px}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-1\/2{top:50%}.right-6{right:calc(var(--spacing) * 6)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.z-40{z-index:40}.z-50{z-index:50}.z-\[9999\]{z-index:9999}.order-42{order:42}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-14{height:calc(var(--spacing) * 14)}.h-screen{height:100vh}.max-h-32{max-height:calc(var(--spacing) * 32)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-\[85vh\]{max-height:85vh}.max-h-\[min\(20rem\,var\(--available-height\)\)\]{max-height:min(20rem,var(--available-height))}.min-h-0{min-height:0}.w-4{width:calc(var(--spacing) * 4)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-28{width:calc(var(--spacing) * 28)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-\[max\(var\(--anchor-width\)\,13rem\)\]{width:max(var(--anchor-width),13rem)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[240px\]{max-width:240px}.max-w-\[320px\]{max-width:320px}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:0}.min-w-\[280px\]{min-width:280px}.min-w-\[var\(--anchor-width\)\]{min-width:var(--anchor-width)}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.origin-\[var\(--transform-origin\)\]{transform-origin:var(--transform-origin)}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-x-8{column-gap:calc(var(--spacing) * 8)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--border)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[5px\]{border-radius:5px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-\[3px\]{border-left-style:var(--tw-border-style);border-left-width:3px}.border-accent,.border-accent\/20{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.border-accent\/20{border-color:color-mix(in oklab,var(--accent) 20%,transparent)}}.border-accent\/30{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.border-accent\/30{border-color:color-mix(in oklab,var(--accent) 30%,transparent)}}.border-accent\/40{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.border-accent\/40{border-color:color-mix(in oklab,var(--accent) 40%,transparent)}}.border-border{border-color:var(--border)}.border-card{border-color:var(--card)}.border-chart-2\/30{border-color:var(--chart-2)}@supports (color:color-mix(in lab,red,red)){.border-chart-2\/30{border-color:color-mix(in oklab,var(--chart-2) 30%,transparent)}}.border-destructive\/20{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/20{border-color:color-mix(in oklab,var(--destructive) 20%,transparent)}}.border-destructive\/30{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/30{border-color:color-mix(in oklab,var(--destructive) 30%,transparent)}}.border-input{border-color:var(--input)}.border-success\/20{border-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.border-success\/20{border-color:color-mix(in oklab,var(--success) 20%,transparent)}}.border-success\/30{border-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.border-success\/30{border-color:color-mix(in oklab,var(--success) 30%,transparent)}}.border-transparent{border-color:#0000}.border-warning\/20{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.border-warning\/20{border-color:color-mix(in oklab,var(--warning) 20%,transparent)}}.border-warning\/30{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.border-warning\/30{border-color:color-mix(in oklab,var(--warning) 30%,transparent)}}.border-l-\[var\(--accent\)\]{border-left-color:var(--accent)}.border-l-\[var\(--destructive\)\]{border-left-color:var(--destructive)}.border-l-\[var\(--success\)\]{border-left-color:var(--success)}.border-l-\[var\(--warning\)\]{border-left-color:var(--warning)}.bg-accent,.bg-accent\/10{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-accent\/10{background-color:color-mix(in oklab,var(--accent) 10%,transparent)}}.bg-accent\/\[0\.06\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-accent\/\[0\.06\]{background-color:color-mix(in oklab,var(--accent) 6%,transparent)}}.bg-background,.bg-background\/80{background-color:var(--background)}@supports (color:color-mix(in lab,red,red)){.bg-background\/80{background-color:color-mix(in oklab,var(--background) 80%,transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-card{background-color:var(--card)}.bg-chart-2\/10{background-color:var(--chart-2)}@supports (color:color-mix(in lab,red,red)){.bg-chart-2\/10{background-color:color-mix(in oklab,var(--chart-2) 10%,transparent)}}.bg-destructive,.bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.bg-destructive\/10{background-color:color-mix(in oklab,var(--destructive) 10%,transparent)}}.bg-input{background-color:var(--input)}.bg-muted-foreground\/40{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.bg-muted-foreground\/40{background-color:color-mix(in oklab,var(--muted-foreground) 40%,transparent)}}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-secondary,.bg-secondary\/30{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.bg-secondary\/30{background-color:color-mix(in oklab,var(--secondary) 30%,transparent)}}.bg-secondary\/40{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.bg-secondary\/40{background-color:color-mix(in oklab,var(--secondary) 40%,transparent)}}.bg-secondary\/50{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.bg-secondary\/50{background-color:color-mix(in oklab,var(--secondary) 50%,transparent)}}.bg-secondary\/60{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.bg-secondary\/60{background-color:color-mix(in oklab,var(--secondary) 60%,transparent)}}.bg-success,.bg-success\/10{background-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.bg-success\/10{background-color:color-mix(in oklab,var(--success) 10%,transparent)}}.bg-transparent{background-color:#0000}.bg-warning,.bg-warning\/10{background-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.bg-warning\/10{background-color:color-mix(in oklab,var(--warning) 10%,transparent)}}.object-contain{object-fit:contain}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:JetBrains Mono,SFMono-Regular,Cascadia Code,ui-monospace,monospace}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-all{word-break:break-all}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--accent)}.text-border{color:var(--border)}.text-chart-1{color:var(--chart-1)}.text-chart-2{color:var(--chart-2)}.text-destructive{color:var(--destructive)}.text-foreground{color:var(--foreground)}.text-muted-foreground,.text-muted-foreground\/50{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/50{color:color-mix(in oklab,var(--muted-foreground) 50%,transparent)}}.text-muted-foreground\/60{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/60{color:color-mix(in oklab,var(--muted-foreground) 60%,transparent)}}.text-muted-foreground\/70{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/70{color:color-mix(in oklab,var(--muted-foreground) 70%,transparent)}}.text-popover-foreground{color:var(--popover-foreground)}.text-primary-foreground{color:var(--primary-foreground)}.text-success{color:var(--success)}.text-warning{color:var(--warning)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.accent-\[var\(--accent\)\]{accent-color:var(--accent)}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-border{--tw-ring-color:var(--border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[transform\,opacity\]{transition-property:transform,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:translate-x-0\.5:is(:where(.group):hover *){--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.group-hover\:text-muted-foreground:is(:where(.group):hover *){color:var(--muted-foreground)}}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:top-2:before{content:var(--tw-content);top:calc(var(--spacing) * 2)}.before\:bottom-1:before{content:var(--tw-content);bottom:var(--spacing)}.before\:left-\[13px\]:before{content:var(--tw-content);left:13px}.before\:w-px:before{content:var(--tw-content);width:1px}.before\:bg-border:before{content:var(--tw-content);background-color:var(--border)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:inset-x-3:after{content:var(--tw-content);inset-inline:calc(var(--spacing) * 3)}.after\:-bottom-px:after{content:var(--tw-content);bottom:-1px}.after\:h-0\.5:after{content:var(--tw-content);height:calc(var(--spacing) * .5)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:bg-foreground:after{content:var(--tw-content);background-color:var(--foreground)}@media(hover:hover){.hover\:bg-destructive\/10:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/10:hover{background-color:color-mix(in oklab,var(--destructive) 10%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary) 90%,transparent)}}.hover\:bg-secondary:hover,.hover\:bg-secondary\/30:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/30:hover{background-color:color-mix(in oklab,var(--secondary) 30%,transparent)}}.hover\:bg-secondary\/60:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/60:hover{background-color:color-mix(in oklab,var(--secondary) 60%,transparent)}}.hover\:bg-secondary\/70:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/70:hover{background-color:color-mix(in oklab,var(--secondary) 70%,transparent)}}.hover\:text-destructive:hover{color:var(--destructive)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color:var(--background)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[checked\]\:translate-x-\[18px\][data-checked]{--tw-translate-x:18px;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[checked\]\:bg-success[data-checked]{background-color:var(--success)}.data-\[ending-style\]\:scale-95[data-ending-style]{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.data-\[ending-style\]\:opacity-0[data-ending-style]{opacity:0}.data-\[highlighted\]\:bg-accent\/15[data-highlighted]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[highlighted\]\:bg-accent\/15[data-highlighted]{background-color:color-mix(in oklab,var(--accent) 15%,transparent)}}.data-\[highlighted\]\:text-foreground[data-highlighted]{color:var(--foreground)}.data-\[popup-open\]\:border-ring[data-popup-open]{border-color:var(--ring)}.data-\[pressed\]\:bg-card[data-pressed]{background-color:var(--card)}.data-\[pressed\]\:text-foreground[data-pressed]{color:var(--foreground)}.data-\[pressed\]\:shadow-sm[data-pressed]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.data-\[starting-style\]\:scale-95[data-starting-style]{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.data-\[starting-style\]\:opacity-0[data-starting-style]{opacity:0}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:px-4{padding-inline:calc(var(--spacing) * 4)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media(min-width:64rem){.lg\:flex{display:flex}}}:root{color-scheme:light;--radius:.625rem;--background:oklch(99% .002 285);--foreground:oklch(21% .01 285);--card:oklch(100% 0 0);--card-foreground:oklch(21% .01 285);--popover:oklch(100% 0 0);--popover-foreground:oklch(21% .01 285);--primary:oklch(24% .01 285);--primary-foreground:oklch(98% 0 0);--secondary:oklch(96.5% .003 285);--secondary-foreground:oklch(24% .01 285);--muted:oklch(96.5% .003 285);--muted-foreground:oklch(50% .012 285);--accent:oklch(55% .2 256);--accent-foreground:oklch(99% 0 0);--success:oklch(60% .15 152);--warning:oklch(70% .15 78);--info:oklch(55% .2 256);--destructive:oklch(58% .21 24);--border:oklch(21% .01 285/.11);--input:oklch(21% .01 285/.14);--ring:oklch(55% .2 256);--chart-1:oklch(55% .2 256);--chart-2:oklch(60% .15 152);--chart-3:oklch(70% .15 78);--chart-4:oklch(60% .2 16);--chart-5:oklch(62% .16 300);--shadow-sm:0 1px 2px oklch(20% .02 285/.06);--shadow-md:0 2px 4px oklch(20% .02 285/.05), 0 8px 20px oklch(20% .02 285/.08);--shadow-lg:0 16px 40px oklch(20% .02 285/.16)}:root[data-theme=dark]{color-scheme:dark;--background:oklch(16% .004 285);--foreground:oklch(97% 0 0);--card:oklch(20.5% .004 285);--card-foreground:oklch(97% 0 0);--popover:oklch(22% .004 285);--popover-foreground:oklch(97% 0 0);--primary:oklch(97% 0 0);--primary-foreground:oklch(20% .01 285);--secondary:oklch(27% .004 285);--secondary-foreground:oklch(97% 0 0);--muted:oklch(27% .004 285);--muted-foreground:oklch(66% .005 285);--accent:oklch(62% .19 256);--accent-foreground:oklch(99% 0 0);--success:oklch(72% .18 152);--warning:oklch(78% .15 78);--info:oklch(62% .19 256);--destructive:oklch(62% .21 24);--border:oklch(100% 0 0/.11);--input:oklch(100% 0 0/.14);--ring:oklch(62% .19 256);--chart-1:oklch(62% .19 256);--chart-2:oklch(72% .18 152);--chart-3:oklch(78% .15 78);--chart-4:oklch(66% .2 16);--chart-5:oklch(70% .16 300);--shadow-sm:0 1px 2px oklch(0% 0 0/.3);--shadow-md:0 2px 4px oklch(0% 0 0/.3), 0 10px 28px oklch(0% 0 0/.45);--shadow-lg:0 18px 48px oklch(0% 0 0/.55)}*{scrollbar-width:thin;scrollbar-color:var(--border) transparent}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){::-webkit-scrollbar-thumb{background:color-mix(in oklab,var(--muted-foreground) 35%,transparent)}}::-webkit-scrollbar-thumb{background-clip:content-box;border:2px solid #0000;border-radius:4px}::-webkit-scrollbar-track{background:0 0}@media(prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}
1
+ /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){.xtandard-webhooks *,.xtandard-webhooks :before,.xtandard-webhooks :after,.xtandard-webhooks ::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-ease:initial;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{.xtandard-webhooks,.xtandard-webhooks{--font-sans:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--color-black:#000;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-2xl:42rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-snug:1.375;--leading-relaxed:1.625;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--default-mono-font-family:"JetBrains Mono", "SFMono-Regular", "Cascadia Code", ui-monospace, monospace}}@layer base{.xtandard-webhooks *,.xtandard-webhooks :after,.xtandard-webhooks :before,.xtandard-webhooks ::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}.xtandard-webhooks ::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}.xtandard-webhooks,.xtandard-webhooks{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}.xtandard-webhooks hr{height:0;color:inherit;border-top-width:1px}.xtandard-webhooks abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.xtandard-webhooks h1,.xtandard-webhooks h2,.xtandard-webhooks h3,.xtandard-webhooks h4,.xtandard-webhooks h5,.xtandard-webhooks h6{font-size:inherit;font-weight:inherit}.xtandard-webhooks a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}.xtandard-webhooks b,.xtandard-webhooks strong{font-weight:bolder}.xtandard-webhooks code,.xtandard-webhooks kbd,.xtandard-webhooks samp,.xtandard-webhooks pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}.xtandard-webhooks small{font-size:80%}.xtandard-webhooks sub,.xtandard-webhooks sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}.xtandard-webhooks sub{bottom:-.25em}.xtandard-webhooks sup{top:-.5em}.xtandard-webhooks table{text-indent:0;border-color:inherit;border-collapse:collapse}.xtandard-webhooks :-moz-focusring{outline:auto}.xtandard-webhooks progress{vertical-align:baseline}.xtandard-webhooks summary{display:list-item}.xtandard-webhooks ol,.xtandard-webhooks ul,.xtandard-webhooks menu{list-style:none}.xtandard-webhooks img,.xtandard-webhooks svg,.xtandard-webhooks video,.xtandard-webhooks canvas,.xtandard-webhooks audio,.xtandard-webhooks iframe,.xtandard-webhooks embed,.xtandard-webhooks object{vertical-align:middle;display:block}.xtandard-webhooks img,.xtandard-webhooks video{max-width:100%;height:auto}.xtandard-webhooks button,.xtandard-webhooks input,.xtandard-webhooks select,.xtandard-webhooks optgroup,.xtandard-webhooks textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}.xtandard-webhooks ::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}.xtandard-webhooks :where(select:is([multiple],[size])) optgroup{font-weight:bolder}.xtandard-webhooks :where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}.xtandard-webhooks ::file-selector-button{margin-inline-end:4px}.xtandard-webhooks ::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){.xtandard-webhooks ::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks ::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}.xtandard-webhooks textarea{resize:vertical}.xtandard-webhooks ::-webkit-search-decoration{-webkit-appearance:none}.xtandard-webhooks ::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}.xtandard-webhooks ::-webkit-datetime-edit{display:inline-flex}.xtandard-webhooks ::-webkit-datetime-edit-fields-wrapper{padding:0}.xtandard-webhooks ::-webkit-datetime-edit{padding-block:0}.xtandard-webhooks ::-webkit-datetime-edit-year-field{padding-block:0}.xtandard-webhooks ::-webkit-datetime-edit-month-field{padding-block:0}.xtandard-webhooks ::-webkit-datetime-edit-day-field{padding-block:0}.xtandard-webhooks ::-webkit-datetime-edit-hour-field{padding-block:0}.xtandard-webhooks ::-webkit-datetime-edit-minute-field{padding-block:0}.xtandard-webhooks ::-webkit-datetime-edit-second-field{padding-block:0}.xtandard-webhooks ::-webkit-datetime-edit-millisecond-field{padding-block:0}.xtandard-webhooks ::-webkit-datetime-edit-meridiem-field{padding-block:0}.xtandard-webhooks ::-webkit-calendar-picker-indicator{line-height:1}.xtandard-webhooks :-moz-ui-invalid{box-shadow:none}.xtandard-webhooks button,.xtandard-webhooks input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}.xtandard-webhooks ::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}.xtandard-webhooks ::-webkit-inner-spin-button{height:auto}.xtandard-webhooks ::-webkit-outer-spin-button{height:auto}.xtandard-webhooks [hidden]:where(:not([hidden=until-found])){display:none!important}.xtandard-webhooks *,.xtandard-webhooks :before,.xtandard-webhooks :after{box-sizing:border-box;border-color:var(--border)}.xtandard-webhooks,.xtandard-webhooks body,.xtandard-webhooks #root{height:100%;margin:0;padding:0}.xtandard-webhooks body{background-color:var(--background);color:var(--foreground);font-family:var(--font-sans);letter-spacing:-.006em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:14px;line-height:1.5}.xtandard-webhooks :focus-visible{outline:2px solid var(--ring);outline-offset:2px}}@layer components;@layer utilities{.xtandard-webhooks .visible{visibility:visible}.xtandard-webhooks .absolute{position:absolute}.xtandard-webhooks .fixed{position:fixed}.xtandard-webhooks .relative{position:relative}.xtandard-webhooks .static{position:static}.xtandard-webhooks .sticky{position:sticky}.xtandard-webhooks .inset-0{top:0;right:0;bottom:0;left:0}.xtandard-webhooks .top-0{top:0}.xtandard-webhooks .top-1\.5{top:calc(var(--spacing) * 1.5)}.xtandard-webhooks .top-1\/2{top:50%}.xtandard-webhooks .right-6{right:calc(var(--spacing) * 6)}.xtandard-webhooks .bottom-6{bottom:calc(var(--spacing) * 6)}.xtandard-webhooks .left-1\/2{left:50%}.xtandard-webhooks .left-2{left:calc(var(--spacing) * 2)}.xtandard-webhooks .z-40{z-index:40}.xtandard-webhooks .z-50{z-index:50}.xtandard-webhooks .z-\[9999\]{z-index:9999}.xtandard-webhooks .order-42{order:42}.xtandard-webhooks .container{width:100%}@media(min-width:40rem){.xtandard-webhooks .container{max-width:40rem}}@media(min-width:48rem){.xtandard-webhooks .container{max-width:48rem}}@media(min-width:64rem){.xtandard-webhooks .container{max-width:64rem}}@media(min-width:80rem){.xtandard-webhooks .container{max-width:80rem}}@media(min-width:96rem){.xtandard-webhooks .container{max-width:96rem}}.xtandard-webhooks .m-0{margin:0}.xtandard-webhooks .mx-auto{margin-inline:auto}.xtandard-webhooks .mt-0\.5{margin-top:calc(var(--spacing) * .5)}.xtandard-webhooks .mt-1{margin-top:var(--spacing)}.xtandard-webhooks .mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.xtandard-webhooks .mt-2{margin-top:calc(var(--spacing) * 2)}.xtandard-webhooks .mt-3{margin-top:calc(var(--spacing) * 3)}.xtandard-webhooks .mt-4{margin-top:calc(var(--spacing) * 4)}.xtandard-webhooks .mt-6{margin-top:calc(var(--spacing) * 6)}.xtandard-webhooks .mt-8{margin-top:calc(var(--spacing) * 8)}.xtandard-webhooks .mb-1{margin-bottom:var(--spacing)}.xtandard-webhooks .mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.xtandard-webhooks .mb-2{margin-bottom:calc(var(--spacing) * 2)}.xtandard-webhooks .mb-4{margin-bottom:calc(var(--spacing) * 4)}.xtandard-webhooks .ml-auto{margin-left:auto}.xtandard-webhooks .block{display:block}.xtandard-webhooks .contents{display:contents}.xtandard-webhooks .flex{display:flex}.xtandard-webhooks .grid{display:grid}.xtandard-webhooks .hidden{display:none}.xtandard-webhooks .inline-flex{display:inline-flex}.xtandard-webhooks .table{display:table}.xtandard-webhooks .size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.xtandard-webhooks .size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.xtandard-webhooks .size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.xtandard-webhooks .size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.xtandard-webhooks .size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.xtandard-webhooks .size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.xtandard-webhooks .h-5{height:calc(var(--spacing) * 5)}.xtandard-webhooks .h-6{height:calc(var(--spacing) * 6)}.xtandard-webhooks .h-7{height:calc(var(--spacing) * 7)}.xtandard-webhooks .h-8{height:calc(var(--spacing) * 8)}.xtandard-webhooks .h-9{height:calc(var(--spacing) * 9)}.xtandard-webhooks .h-14{height:calc(var(--spacing) * 14)}.xtandard-webhooks .h-screen{height:100vh}.xtandard-webhooks .max-h-32{max-height:calc(var(--spacing) * 32)}.xtandard-webhooks .max-h-64{max-height:calc(var(--spacing) * 64)}.xtandard-webhooks .max-h-\[85vh\]{max-height:85vh}.xtandard-webhooks .max-h-\[min\(20rem\,var\(--available-height\)\)\]{max-height:min(20rem,var(--available-height))}.xtandard-webhooks .min-h-0{min-height:0}.xtandard-webhooks .w-4{width:calc(var(--spacing) * 4)}.xtandard-webhooks .w-7{width:calc(var(--spacing) * 7)}.xtandard-webhooks .w-8{width:calc(var(--spacing) * 8)}.xtandard-webhooks .w-9{width:calc(var(--spacing) * 9)}.xtandard-webhooks .w-28{width:calc(var(--spacing) * 28)}.xtandard-webhooks .w-44{width:calc(var(--spacing) * 44)}.xtandard-webhooks .w-48{width:calc(var(--spacing) * 48)}.xtandard-webhooks .w-64{width:calc(var(--spacing) * 64)}.xtandard-webhooks .w-72{width:calc(var(--spacing) * 72)}.xtandard-webhooks .w-\[max\(var\(--anchor-width\)\,13rem\)\]{width:max(var(--anchor-width),13rem)}.xtandard-webhooks .w-full{width:100%}.xtandard-webhooks .max-w-2xl{max-width:var(--container-2xl)}.xtandard-webhooks .max-w-6xl{max-width:var(--container-6xl)}.xtandard-webhooks .max-w-\[240px\]{max-width:240px}.xtandard-webhooks .max-w-\[320px\]{max-width:320px}.xtandard-webhooks .max-w-md{max-width:var(--container-md)}.xtandard-webhooks .max-w-sm{max-width:var(--container-sm)}.xtandard-webhooks .min-w-0{min-width:0}.xtandard-webhooks .min-w-\[280px\]{min-width:280px}.xtandard-webhooks .min-w-\[var\(--anchor-width\)\]{min-width:var(--anchor-width)}.xtandard-webhooks .flex-1{flex:1}.xtandard-webhooks .shrink{flex-shrink:1}.xtandard-webhooks .shrink-0{flex-shrink:0}.xtandard-webhooks .grow{flex-grow:1}.xtandard-webhooks .border-collapse{border-collapse:collapse}.xtandard-webhooks .origin-\[var\(--transform-origin\)\]{transform-origin:var(--transform-origin)}.xtandard-webhooks .-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.xtandard-webhooks .translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.xtandard-webhooks .-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.xtandard-webhooks .transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.xtandard-webhooks .animate-spin{animation:var(--animate-spin)}.xtandard-webhooks .cursor-not-allowed{cursor:not-allowed}.xtandard-webhooks .cursor-pointer{cursor:pointer}.xtandard-webhooks .grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.xtandard-webhooks .flex-col{flex-direction:column}.xtandard-webhooks .flex-wrap{flex-wrap:wrap}.xtandard-webhooks .items-baseline{align-items:baseline}.xtandard-webhooks .items-center{align-items:center}.xtandard-webhooks .items-end{align-items:flex-end}.xtandard-webhooks .items-start{align-items:flex-start}.xtandard-webhooks .justify-between{justify-content:space-between}.xtandard-webhooks .justify-center{justify-content:center}.xtandard-webhooks .justify-end{justify-content:flex-end}.xtandard-webhooks .gap-0\.5{gap:calc(var(--spacing) * .5)}.xtandard-webhooks .gap-1{gap:var(--spacing)}.xtandard-webhooks .gap-1\.5{gap:calc(var(--spacing) * 1.5)}.xtandard-webhooks .gap-2{gap:calc(var(--spacing) * 2)}.xtandard-webhooks .gap-2\.5{gap:calc(var(--spacing) * 2.5)}.xtandard-webhooks .gap-3{gap:calc(var(--spacing) * 3)}.xtandard-webhooks .gap-4{gap:calc(var(--spacing) * 4)}.xtandard-webhooks .gap-5{gap:calc(var(--spacing) * 5)}.xtandard-webhooks .gap-6{gap:calc(var(--spacing) * 6)}.xtandard-webhooks .gap-x-8{column-gap:calc(var(--spacing) * 8)}.xtandard-webhooks .gap-y-2{row-gap:calc(var(--spacing) * 2)}.xtandard-webhooks :where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.xtandard-webhooks :where(.divide-border>:not(:last-child)){border-color:var(--border)}.xtandard-webhooks .truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.xtandard-webhooks .overflow-auto{overflow:auto}.xtandard-webhooks .overflow-hidden{overflow:hidden}.xtandard-webhooks .overflow-x-auto{overflow-x:auto}.xtandard-webhooks .overflow-x-hidden{overflow-x:hidden}.xtandard-webhooks .overflow-y-auto{overflow-y:auto}.xtandard-webhooks .rounded{border-radius:.25rem}.xtandard-webhooks .rounded-\[5px\]{border-radius:5px}.xtandard-webhooks .rounded-full{border-radius:3.40282e38px}.xtandard-webhooks .rounded-lg{border-radius:var(--radius)}.xtandard-webhooks .rounded-md{border-radius:calc(var(--radius) - 2px)}.xtandard-webhooks .rounded-sm{border-radius:calc(var(--radius) - 4px)}.xtandard-webhooks .rounded-xl{border-radius:calc(var(--radius) + 4px)}.xtandard-webhooks .border{border-style:var(--tw-border-style);border-width:1px}.xtandard-webhooks .border-2{border-style:var(--tw-border-style);border-width:2px}.xtandard-webhooks .border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.xtandard-webhooks .border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.xtandard-webhooks .border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.xtandard-webhooks .border-l-\[3px\]{border-left-style:var(--tw-border-style);border-left-width:3px}.xtandard-webhooks .border-accent,.xtandard-webhooks .border-accent\/20{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-accent\/20{border-color:color-mix(in oklab,var(--accent) 20%,transparent)}}.xtandard-webhooks .border-accent\/30{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-accent\/30{border-color:color-mix(in oklab,var(--accent) 30%,transparent)}}.xtandard-webhooks .border-accent\/40{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-accent\/40{border-color:color-mix(in oklab,var(--accent) 40%,transparent)}}.xtandard-webhooks .border-border{border-color:var(--border)}.xtandard-webhooks .border-card{border-color:var(--card)}.xtandard-webhooks .border-chart-2\/30{border-color:var(--chart-2)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-chart-2\/30{border-color:color-mix(in oklab,var(--chart-2) 30%,transparent)}}.xtandard-webhooks .border-destructive\/20{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-destructive\/20{border-color:color-mix(in oklab,var(--destructive) 20%,transparent)}}.xtandard-webhooks .border-destructive\/30{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-destructive\/30{border-color:color-mix(in oklab,var(--destructive) 30%,transparent)}}.xtandard-webhooks .border-input{border-color:var(--input)}.xtandard-webhooks .border-success\/20{border-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-success\/20{border-color:color-mix(in oklab,var(--success) 20%,transparent)}}.xtandard-webhooks .border-success\/30{border-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-success\/30{border-color:color-mix(in oklab,var(--success) 30%,transparent)}}.xtandard-webhooks .border-transparent{border-color:#0000}.xtandard-webhooks .border-warning\/20{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-warning\/20{border-color:color-mix(in oklab,var(--warning) 20%,transparent)}}.xtandard-webhooks .border-warning\/30{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .border-warning\/30{border-color:color-mix(in oklab,var(--warning) 30%,transparent)}}.xtandard-webhooks .border-l-\[var\(--accent\)\]{border-left-color:var(--accent)}.xtandard-webhooks .border-l-\[var\(--destructive\)\]{border-left-color:var(--destructive)}.xtandard-webhooks .border-l-\[var\(--success\)\]{border-left-color:var(--success)}.xtandard-webhooks .border-l-\[var\(--warning\)\]{border-left-color:var(--warning)}.xtandard-webhooks .bg-accent,.xtandard-webhooks .bg-accent\/10{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-accent\/10{background-color:color-mix(in oklab,var(--accent) 10%,transparent)}}.xtandard-webhooks .bg-accent\/\[0\.06\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-accent\/\[0\.06\]{background-color:color-mix(in oklab,var(--accent) 6%,transparent)}}.xtandard-webhooks .bg-background,.xtandard-webhooks .bg-background\/80{background-color:var(--background)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-background\/80{background-color:color-mix(in oklab,var(--background) 80%,transparent)}}.xtandard-webhooks .bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.xtandard-webhooks .bg-card{background-color:var(--card)}.xtandard-webhooks .bg-chart-2\/10{background-color:var(--chart-2)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-chart-2\/10{background-color:color-mix(in oklab,var(--chart-2) 10%,transparent)}}.xtandard-webhooks .bg-destructive,.xtandard-webhooks .bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-destructive\/10{background-color:color-mix(in oklab,var(--destructive) 10%,transparent)}}.xtandard-webhooks .bg-input{background-color:var(--input)}.xtandard-webhooks .bg-muted-foreground\/40{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-muted-foreground\/40{background-color:color-mix(in oklab,var(--muted-foreground) 40%,transparent)}}.xtandard-webhooks .bg-popover{background-color:var(--popover)}.xtandard-webhooks .bg-primary{background-color:var(--primary)}.xtandard-webhooks .bg-secondary,.xtandard-webhooks .bg-secondary\/30{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-secondary\/30{background-color:color-mix(in oklab,var(--secondary) 30%,transparent)}}.xtandard-webhooks .bg-secondary\/40{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-secondary\/40{background-color:color-mix(in oklab,var(--secondary) 40%,transparent)}}.xtandard-webhooks .bg-secondary\/50{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-secondary\/50{background-color:color-mix(in oklab,var(--secondary) 50%,transparent)}}.xtandard-webhooks .bg-secondary\/60{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-secondary\/60{background-color:color-mix(in oklab,var(--secondary) 60%,transparent)}}.xtandard-webhooks .bg-success,.xtandard-webhooks .bg-success\/10{background-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-success\/10{background-color:color-mix(in oklab,var(--success) 10%,transparent)}}.xtandard-webhooks .bg-transparent{background-color:#0000}.xtandard-webhooks .bg-warning,.xtandard-webhooks .bg-warning\/10{background-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .bg-warning\/10{background-color:color-mix(in oklab,var(--warning) 10%,transparent)}}.xtandard-webhooks .object-contain{object-fit:contain}.xtandard-webhooks .p-0\.5{padding:calc(var(--spacing) * .5)}.xtandard-webhooks .p-1{padding:var(--spacing)}.xtandard-webhooks .p-1\.5{padding:calc(var(--spacing) * 1.5)}.xtandard-webhooks .px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.xtandard-webhooks .px-2{padding-inline:calc(var(--spacing) * 2)}.xtandard-webhooks .px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.xtandard-webhooks .px-3{padding-inline:calc(var(--spacing) * 3)}.xtandard-webhooks .px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.xtandard-webhooks .px-4{padding-inline:calc(var(--spacing) * 4)}.xtandard-webhooks .px-5{padding-inline:calc(var(--spacing) * 5)}.xtandard-webhooks .py-0\.5{padding-block:calc(var(--spacing) * .5)}.xtandard-webhooks .py-1{padding-block:var(--spacing)}.xtandard-webhooks .py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.xtandard-webhooks .py-2{padding-block:calc(var(--spacing) * 2)}.xtandard-webhooks .py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.xtandard-webhooks .py-3{padding-block:calc(var(--spacing) * 3)}.xtandard-webhooks .py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.xtandard-webhooks .py-4{padding-block:calc(var(--spacing) * 4)}.xtandard-webhooks .py-5{padding-block:calc(var(--spacing) * 5)}.xtandard-webhooks .py-8{padding-block:calc(var(--spacing) * 8)}.xtandard-webhooks .py-16{padding-block:calc(var(--spacing) * 16)}.xtandard-webhooks .pt-0\.5{padding-top:calc(var(--spacing) * .5)}.xtandard-webhooks .pr-2{padding-right:calc(var(--spacing) * 2)}.xtandard-webhooks .pl-2{padding-left:calc(var(--spacing) * 2)}.xtandard-webhooks .pl-8{padding-left:calc(var(--spacing) * 8)}.xtandard-webhooks .text-center{text-align:center}.xtandard-webhooks .text-left{text-align:left}.xtandard-webhooks .font-mono{font-family:JetBrains Mono,SFMono-Regular,Cascadia Code,ui-monospace,monospace}.xtandard-webhooks .text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.xtandard-webhooks .text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.xtandard-webhooks .text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.xtandard-webhooks .text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.xtandard-webhooks .text-\[10px\]{font-size:10px}.xtandard-webhooks .text-\[11px\]{font-size:11px}.xtandard-webhooks .text-\[12px\]{font-size:12px}.xtandard-webhooks .text-\[13px\]{font-size:13px}.xtandard-webhooks .text-\[15px\]{font-size:15px}.xtandard-webhooks .leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.xtandard-webhooks .leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.xtandard-webhooks .font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.xtandard-webhooks .font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.xtandard-webhooks .tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.xtandard-webhooks .tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.xtandard-webhooks .tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.xtandard-webhooks .break-all{word-break:break-all}.xtandard-webhooks .text-ellipsis{text-overflow:ellipsis}.xtandard-webhooks .whitespace-nowrap{white-space:nowrap}.xtandard-webhooks .whitespace-pre-wrap{white-space:pre-wrap}.xtandard-webhooks .text-accent{color:var(--accent)}.xtandard-webhooks .text-border{color:var(--border)}.xtandard-webhooks .text-chart-1{color:var(--chart-1)}.xtandard-webhooks .text-chart-2{color:var(--chart-2)}.xtandard-webhooks .text-destructive{color:var(--destructive)}.xtandard-webhooks .text-foreground{color:var(--foreground)}.xtandard-webhooks .text-muted-foreground,.xtandard-webhooks .text-muted-foreground\/50{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .text-muted-foreground\/50{color:color-mix(in oklab,var(--muted-foreground) 50%,transparent)}}.xtandard-webhooks .text-muted-foreground\/60{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .text-muted-foreground\/60{color:color-mix(in oklab,var(--muted-foreground) 60%,transparent)}}.xtandard-webhooks .text-muted-foreground\/70{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .text-muted-foreground\/70{color:color-mix(in oklab,var(--muted-foreground) 70%,transparent)}}.xtandard-webhooks .text-popover-foreground{color:var(--popover-foreground)}.xtandard-webhooks .text-primary-foreground{color:var(--primary-foreground)}.xtandard-webhooks .text-success{color:var(--success)}.xtandard-webhooks .text-warning{color:var(--warning)}.xtandard-webhooks .lowercase{text-transform:lowercase}.xtandard-webhooks .uppercase{text-transform:uppercase}.xtandard-webhooks .ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.xtandard-webhooks .tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.xtandard-webhooks .accent-\[var\(--accent\)\]{accent-color:var(--accent)}.xtandard-webhooks .opacity-60{opacity:.6}.xtandard-webhooks .shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.xtandard-webhooks .shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.xtandard-webhooks .shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.xtandard-webhooks .shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.xtandard-webhooks .ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.xtandard-webhooks .ring-border{--tw-ring-color:var(--border)}.xtandard-webhooks .outline{outline-style:var(--tw-outline-style);outline-width:1px}.xtandard-webhooks .filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.xtandard-webhooks .backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.xtandard-webhooks .backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.xtandard-webhooks .transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.xtandard-webhooks .transition-\[transform\,opacity\]{transition-property:transform,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.xtandard-webhooks .transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.xtandard-webhooks .transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.xtandard-webhooks .ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.xtandard-webhooks .outline-none{--tw-outline-style:none;outline-style:none}.xtandard-webhooks .select-all{-webkit-user-select:all;user-select:all}.xtandard-webhooks .select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.xtandard-webhooks .group-hover\:translate-x-0\.5:is(:where(.group):hover *){--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.xtandard-webhooks .group-hover\:text-muted-foreground:is(:where(.group):hover *){color:var(--muted-foreground)}}.xtandard-webhooks .placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.xtandard-webhooks .before\:absolute:before{content:var(--tw-content);position:absolute}.xtandard-webhooks .before\:top-2:before{content:var(--tw-content);top:calc(var(--spacing) * 2)}.xtandard-webhooks .before\:bottom-1:before{content:var(--tw-content);bottom:var(--spacing)}.xtandard-webhooks .before\:left-\[13px\]:before{content:var(--tw-content);left:13px}.xtandard-webhooks .before\:w-px:before{content:var(--tw-content);width:1px}.xtandard-webhooks .before\:bg-border:before{content:var(--tw-content);background-color:var(--border)}.xtandard-webhooks .after\:absolute:after{content:var(--tw-content);position:absolute}.xtandard-webhooks .after\:inset-x-3:after{content:var(--tw-content);inset-inline:calc(var(--spacing) * 3)}.xtandard-webhooks .after\:-bottom-px:after{content:var(--tw-content);bottom:-1px}.xtandard-webhooks .after\:h-0\.5:after{content:var(--tw-content);height:calc(var(--spacing) * .5)}.xtandard-webhooks .after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.xtandard-webhooks .after\:bg-foreground:after{content:var(--tw-content);background-color:var(--foreground)}@media(hover:hover){.xtandard-webhooks .hover\:bg-destructive\/10:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .hover\:bg-destructive\/10:hover{background-color:color-mix(in oklab,var(--destructive) 10%,transparent)}}.xtandard-webhooks .hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary) 90%,transparent)}}.xtandard-webhooks .hover\:bg-secondary:hover,.xtandard-webhooks .hover\:bg-secondary\/30:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .hover\:bg-secondary\/30:hover{background-color:color-mix(in oklab,var(--secondary) 30%,transparent)}}.xtandard-webhooks .hover\:bg-secondary\/60:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .hover\:bg-secondary\/60:hover{background-color:color-mix(in oklab,var(--secondary) 60%,transparent)}}.xtandard-webhooks .hover\:bg-secondary\/70:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .hover\:bg-secondary\/70:hover{background-color:color-mix(in oklab,var(--secondary) 70%,transparent)}}.xtandard-webhooks .hover\:text-destructive:hover{color:var(--destructive)}.xtandard-webhooks .hover\:text-foreground:hover{color:var(--foreground)}.xtandard-webhooks .hover\:underline:hover{text-decoration-line:underline}}.xtandard-webhooks .focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.xtandard-webhooks .focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.xtandard-webhooks .focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.xtandard-webhooks .focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.xtandard-webhooks .focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color:var(--background)}.xtandard-webhooks .disabled\:pointer-events-none:disabled{pointer-events:none}.xtandard-webhooks .disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.xtandard-webhooks .disabled\:opacity-50:disabled{opacity:.5}.xtandard-webhooks .data-\[checked\]\:translate-x-\[18px\][data-checked]{--tw-translate-x:18px;translate:var(--tw-translate-x) var(--tw-translate-y)}.xtandard-webhooks .data-\[checked\]\:bg-success[data-checked]{background-color:var(--success)}.xtandard-webhooks .data-\[ending-style\]\:scale-95[data-ending-style]{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.xtandard-webhooks .data-\[ending-style\]\:opacity-0[data-ending-style]{opacity:0}.xtandard-webhooks .data-\[highlighted\]\:bg-accent\/15[data-highlighted]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks .data-\[highlighted\]\:bg-accent\/15[data-highlighted]{background-color:color-mix(in oklab,var(--accent) 15%,transparent)}}.xtandard-webhooks .data-\[highlighted\]\:text-foreground[data-highlighted]{color:var(--foreground)}.xtandard-webhooks .data-\[popup-open\]\:border-ring[data-popup-open]{border-color:var(--ring)}.xtandard-webhooks .data-\[pressed\]\:bg-card[data-pressed]{background-color:var(--card)}.xtandard-webhooks .data-\[pressed\]\:text-foreground[data-pressed]{color:var(--foreground)}.xtandard-webhooks .data-\[pressed\]\:shadow-sm[data-pressed]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.xtandard-webhooks .data-\[starting-style\]\:scale-95[data-starting-style]{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.xtandard-webhooks .data-\[starting-style\]\:opacity-0[data-starting-style]{opacity:0}@media(min-width:40rem){.xtandard-webhooks .sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xtandard-webhooks .sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xtandard-webhooks .sm\:px-4{padding-inline:calc(var(--spacing) * 4)}.xtandard-webhooks .sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media(min-width:64rem){.xtandard-webhooks .lg\:flex{display:flex}}}.xtandard-webhooks{color-scheme:light;--radius:.625rem;--background:oklch(99% .002 285);--foreground:oklch(21% .01 285);--card:oklch(100% 0 0);--card-foreground:oklch(21% .01 285);--popover:oklch(100% 0 0);--popover-foreground:oklch(21% .01 285);--primary:oklch(24% .01 285);--primary-foreground:oklch(98% 0 0);--secondary:oklch(96.5% .003 285);--secondary-foreground:oklch(24% .01 285);--muted:oklch(96.5% .003 285);--muted-foreground:oklch(50% .012 285);--accent:oklch(55% .2 256);--accent-foreground:oklch(99% 0 0);--success:oklch(60% .15 152);--warning:oklch(70% .15 78);--info:oklch(55% .2 256);--destructive:oklch(58% .21 24);--border:oklch(21% .01 285/.11);--input:oklch(21% .01 285/.14);--ring:oklch(55% .2 256);--chart-1:oklch(55% .2 256);--chart-2:oklch(60% .15 152);--chart-3:oklch(70% .15 78);--chart-4:oklch(60% .2 16);--chart-5:oklch(62% .16 300);--shadow-sm:0 1px 2px oklch(20% .02 285/.06);--shadow-md:0 2px 4px oklch(20% .02 285/.05), 0 8px 20px oklch(20% .02 285/.08);--shadow-lg:0 16px 40px oklch(20% .02 285/.16)}.xtandard-webhooks :root[data-theme=dark]{color-scheme:dark;--background:oklch(16% .004 285);--foreground:oklch(97% 0 0);--card:oklch(20.5% .004 285);--card-foreground:oklch(97% 0 0);--popover:oklch(22% .004 285);--popover-foreground:oklch(97% 0 0);--primary:oklch(97% 0 0);--primary-foreground:oklch(20% .01 285);--secondary:oklch(27% .004 285);--secondary-foreground:oklch(97% 0 0);--muted:oklch(27% .004 285);--muted-foreground:oklch(66% .005 285);--accent:oklch(62% .19 256);--accent-foreground:oklch(99% 0 0);--success:oklch(72% .18 152);--warning:oklch(78% .15 78);--info:oklch(62% .19 256);--destructive:oklch(62% .21 24);--border:oklch(100% 0 0/.11);--input:oklch(100% 0 0/.14);--ring:oklch(62% .19 256);--chart-1:oklch(62% .19 256);--chart-2:oklch(72% .18 152);--chart-3:oklch(78% .15 78);--chart-4:oklch(66% .2 16);--chart-5:oklch(70% .16 300);--shadow-sm:0 1px 2px oklch(0% 0 0/.3);--shadow-md:0 2px 4px oklch(0% 0 0/.3), 0 10px 28px oklch(0% 0 0/.45);--shadow-lg:0 18px 48px oklch(0% 0 0/.55)}.xtandard-webhooks *{scrollbar-width:thin;scrollbar-color:var(--border) transparent}.xtandard-webhooks ::-webkit-scrollbar{width:8px;height:8px}.xtandard-webhooks ::-webkit-scrollbar-thumb{background:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.xtandard-webhooks ::-webkit-scrollbar-thumb{background:color-mix(in oklab,var(--muted-foreground) 35%,transparent)}}.xtandard-webhooks ::-webkit-scrollbar-thumb{background-clip:content-box;border:2px solid #0000;border-radius:4px}.xtandard-webhooks ::-webkit-scrollbar-track{background:0 0}@media(prefers-reduced-motion:reduce){.xtandard-webhooks *,.xtandard-webhooks :before,.xtandard-webhooks :after{transition-duration:.01ms!important;animation-duration:.01ms!important}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}