@spooled/sdk 1.0.33 → 1.0.34
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.
- package/dist/{index-QIsnz4Bc.d.cts → index-CYEamGDj.d.cts} +25 -0
- package/dist/{index-QIsnz4Bc.d.ts → index-CYEamGDj.d.ts} +25 -0
- package/dist/index.cjs +8 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +8 -4
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +1 -1
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/index.js +8 -4
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/proto/spooled.proto +13 -0
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/utils/casing.ts","../src/utils/retry.ts","../src/utils/http.ts","../src/utils/circuit-breaker.ts","../src/resources/auth.ts","../src/resources/jobs.ts","../src/resources/queues.ts","../src/resources/workers.ts","../src/resources/schedules.ts","../src/resources/workflows.ts","../src/resources/webhooks.ts","../src/resources/api-keys.ts","../src/resources/organizations.ts","../src/resources/billing.ts","../src/resources/dashboard.ts","../src/resources/health.ts","../src/resources/metrics.ts","../src/resources/admin.ts","../src/resources/webhook-ingestion.ts","../src/realtime/event-map.ts","../src/realtime/websocket.ts","../src/realtime/sse.ts","../src/realtime/index.ts","../src/grpc/loader.ts","../src/grpc/streaming.ts","../src/grpc/client.ts","../src/client.ts","../src/types/common.ts","../src/grpc/types.ts","../src/worker/worker.ts"],"names":["CircuitState","Buffer","createHmac","fileURLToPath","__dirname","dirname","join","protoLoader","grpc","credentials","grpc2","GrpcJobStatus","osHostname"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * SDK Configuration\n *\n * Defines configuration types and defaults for the Spooled SDK.\n */\n\n/** Retry configuration options */\nexport interface RetryConfig {\n /** Maximum number of retry attempts (default: 3) */\n maxRetries: number;\n /** Base delay in milliseconds for exponential backoff (default: 1000) */\n baseDelay: number;\n /** Maximum delay in milliseconds (default: 30000) */\n maxDelay: number;\n /** Exponential backoff factor (default: 2) */\n factor: number;\n /** Whether to add jitter to delays (default: true) */\n jitter: boolean;\n /** Custom function to determine if an error is retryable */\n retryOn?: (error: Error, attempt: number) => boolean;\n}\n\n/** Circuit breaker configuration options */\nexport interface CircuitBreakerConfig {\n /** Whether circuit breaker is enabled (default: true) */\n enabled: boolean;\n /** Number of failures before opening the circuit (default: 5) */\n failureThreshold: number;\n /** Number of successes in half-open state to close circuit (default: 3) */\n successThreshold: number;\n /** Time in milliseconds to wait before trying again after opening (default: 30000) */\n timeout: number;\n}\n\n/** Debug logging function type */\nexport type DebugFn = (message: string, meta?: unknown) => void;\n\n/** Main SDK configuration options */\nexport interface SpooledClientConfig {\n /** API key for authentication (starts with sp_live_, sp_test_, sk_live_, or sk_test_) */\n apiKey?: string;\n /** JWT access token (alternative to API key) */\n accessToken?: string;\n /** JWT refresh token for automatic token renewal */\n refreshToken?: string;\n /** Admin API key (for /api/v1/admin/* endpoints; uses X-Admin-Key header) */\n adminKey?: string;\n /** Base URL for the REST API (default: https://api.spooled.cloud) */\n baseUrl?: string;\n /** WebSocket URL for realtime events (default: derived from baseUrl, e.g., wss://api.spooled.cloud) */\n wsUrl?: string;\n /** gRPC server address (default: grpc.spooled.cloud:443) */\n grpcAddress?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Number of retry attempts (shorthand for retry.maxRetries) */\n retries?: number;\n /** Base retry delay in milliseconds (shorthand for retry.baseDelay) */\n retryDelay?: number;\n /** Full retry configuration */\n retry?: Partial<RetryConfig>;\n /** Circuit breaker configuration */\n circuitBreaker?: Partial<CircuitBreakerConfig>;\n /** Additional headers to include in all requests */\n headers?: Record<string, string>;\n /** Custom fetch implementation (for testing or special runtimes) */\n fetch?: typeof fetch;\n /** Custom user agent string */\n userAgent?: string;\n /** Enable debug logging */\n debug?: boolean | DebugFn;\n /** Whether to automatically refresh tokens when they expire (default: true) */\n autoRefreshToken?: boolean;\n}\n\n/** Resolved configuration with all defaults applied */\nexport interface ResolvedConfig {\n apiKey?: string;\n accessToken?: string;\n refreshToken?: string;\n adminKey?: string;\n baseUrl: string;\n wsUrl: string;\n grpcAddress: string;\n timeout: number;\n retry: RetryConfig;\n circuitBreaker: CircuitBreakerConfig;\n headers: Record<string, string>;\n fetch: typeof fetch;\n userAgent: string;\n debug: DebugFn | null;\n autoRefreshToken: boolean;\n}\n\n/** Default configuration values */\nexport const DEFAULT_CONFIG = {\n baseUrl: 'https://api.spooled.cloud',\n wsUrl: 'wss://api.spooled.cloud',\n grpcAddress: 'grpc.spooled.cloud:443',\n timeout: 30000,\n retry: {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 30000,\n factor: 2,\n jitter: true,\n } satisfies RetryConfig,\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n successThreshold: 3,\n timeout: 30000,\n } satisfies CircuitBreakerConfig,\n userAgent: '@spooled/sdk-nodejs/1.0.33',\n autoRefreshToken: true,\n} as const;\n\n/** SDK version */\nexport const SDK_VERSION = '1.0.33';\n\n/** API version prefix */\nexport const API_VERSION = 'v1';\n\n/** API base path */\nexport const API_BASE_PATH = `/api/${API_VERSION}`;\n\n/**\n * Trim surrounding whitespace from a credential string and treat an\n * all-whitespace input as unset. Mirrors the trim policy in the Go, PHP,\n * and Python SDKs so behavior is consistent across languages.\n */\nfunction normalizeCredential(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed === '' ? undefined : trimmed;\n}\n\n/**\n * Resolve configuration by merging user options with defaults\n */\nexport function resolveConfig(options: SpooledClientConfig): ResolvedConfig {\n // Create debug function\n let debugFn: DebugFn | null = null;\n if (options.debug === true) {\n debugFn = (message: string, meta?: unknown) => {\n // eslint-disable-next-line no-console\n console.log(`[spooled-sdk] ${message}`, meta !== undefined ? meta : '');\n };\n } else if (typeof options.debug === 'function') {\n debugFn = options.debug;\n }\n\n // Merge retry config\n const retry: RetryConfig = {\n ...DEFAULT_CONFIG.retry,\n ...options.retry,\n // Allow shorthand overrides\n ...(options.retries !== undefined && { maxRetries: options.retries }),\n ...(options.retryDelay !== undefined && { baseDelay: options.retryDelay }),\n };\n\n // Merge circuit breaker config\n const circuitBreaker: CircuitBreakerConfig = {\n ...DEFAULT_CONFIG.circuitBreaker,\n ...options.circuitBreaker,\n };\n\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...options.headers,\n };\n\n // Resolve base URL first\n const baseUrl = options.baseUrl ?? DEFAULT_CONFIG.baseUrl;\n \n // Derive WebSocket URL from base URL if not explicitly set\n // Replace http(s):// with ws(s)://\n const derivedWsUrl = baseUrl.replace(/^http/, 'ws');\n const wsUrl = options.wsUrl ?? derivedWsUrl;\n\n // Trim whitespace (including a stray trailing '\\n') from every credential.\n // Node's `undici` fetch rejects `Authorization: Bearer <key>\\n` with an\n // opaque `TypeError: HeaderValue` and users routinely paste keys from\n // `.env` files that include a newline; normalizing here keeps behavior\n // consistent with the Go, PHP, and Python SDKs.\n return {\n apiKey: normalizeCredential(options.apiKey),\n accessToken: normalizeCredential(options.accessToken),\n refreshToken: normalizeCredential(options.refreshToken),\n adminKey: normalizeCredential(options.adminKey),\n baseUrl,\n wsUrl,\n grpcAddress: options.grpcAddress ?? DEFAULT_CONFIG.grpcAddress,\n timeout: options.timeout ?? DEFAULT_CONFIG.timeout,\n retry,\n circuitBreaker,\n headers,\n fetch: options.fetch ?? globalThis.fetch,\n userAgent: options.userAgent ?? DEFAULT_CONFIG.userAgent,\n debug: debugFn,\n autoRefreshToken: options.autoRefreshToken ?? DEFAULT_CONFIG.autoRefreshToken,\n };\n}\n\n/**\n * Validate configuration options\n * @throws Error if configuration is invalid\n */\nexport function validateConfig(config: ResolvedConfig): void {\n // Must have at least one auth method\n if (!config.apiKey && !config.accessToken) {\n throw new Error(\n 'SpooledClient requires either apiKey or accessToken for authentication'\n );\n }\n\n // Validate API key format if provided\n // Accept both sp_ (new standard) and sk_ (legacy) prefixes\n if (config.apiKey && !config.apiKey.startsWith('sp_') && !config.apiKey.startsWith('sk_')) {\n throw new Error(\n 'Invalid API key format. API keys should start with sp_live_, sp_test_, sk_live_, or sk_test_'\n );\n }\n\n // Validate baseUrl\n if (!config.baseUrl.startsWith('http://') && !config.baseUrl.startsWith('https://')) {\n throw new Error('baseUrl must start with http:// or https://');\n }\n\n // Validate timeout\n if (config.timeout <= 0) {\n throw new Error('timeout must be a positive number');\n }\n\n // Validate retry config\n if (config.retry.maxRetries < 0) {\n throw new Error('retry.maxRetries must be non-negative');\n }\n if (config.retry.baseDelay <= 0) {\n throw new Error('retry.baseDelay must be positive');\n }\n if (config.retry.maxDelay < config.retry.baseDelay) {\n throw new Error('retry.maxDelay must be >= retry.baseDelay');\n }\n if (config.retry.factor < 1) {\n throw new Error('retry.factor must be >= 1');\n }\n\n // Validate circuit breaker config\n if (config.circuitBreaker.enabled) {\n if (config.circuitBreaker.failureThreshold <= 0) {\n throw new Error('circuitBreaker.failureThreshold must be positive');\n }\n if (config.circuitBreaker.successThreshold <= 0) {\n throw new Error('circuitBreaker.successThreshold must be positive');\n }\n if (config.circuitBreaker.timeout <= 0) {\n throw new Error('circuitBreaker.timeout must be positive');\n }\n }\n}\n","/**\n * Custom Error Classes\n *\n * Provides a hierarchy of error types for the Spooled SDK.\n */\n\n/** Error response body from the API */\nexport interface ApiErrorBody {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\n/** Rate limit information parsed from headers */\nexport interface RateLimitInfo {\n /** Maximum requests per window */\n limit?: number;\n /** Remaining requests in current window */\n remaining?: number;\n /** Unix timestamp when the window resets */\n reset?: Date;\n /** Seconds to wait before retrying */\n retryAfter?: number;\n}\n\n/**\n * Base error class for all Spooled SDK errors\n */\nexport class SpooledError extends Error {\n /** HTTP status code (if applicable) */\n readonly statusCode: number;\n /** Error code from API response */\n readonly code: string;\n /** Additional error details */\n readonly details?: Record<string, unknown>;\n /** Request ID for debugging */\n readonly requestId?: string;\n /** Original cause of the error */\n readonly cause?: Error;\n\n constructor(\n message: string,\n statusCode: number = 0,\n code: string = 'UNKNOWN_ERROR',\n details?: Record<string, unknown>,\n requestId?: string,\n cause?: Error\n ) {\n super(message);\n this.name = 'SpooledError';\n this.statusCode = statusCode;\n this.code = code;\n this.details = details;\n this.requestId = requestId;\n this.cause = cause;\n\n // Maintain proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /** Whether this error is retryable */\n isRetryable(): boolean {\n return false;\n }\n\n /** Convert to plain object for logging */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n code: this.code,\n details: this.details,\n requestId: this.requestId,\n };\n }\n}\n\n/**\n * Authentication error (401)\n * Thrown when authentication fails (invalid/expired token or API key)\n */\nexport class AuthenticationError extends SpooledError {\n constructor(\n message: string = 'Authentication failed',\n code: string = 'AUTHENTICATION_FAILED',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 401, code, details, requestId);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Authorization error (403)\n * Thrown when the authenticated user lacks permission\n */\nexport class AuthorizationError extends SpooledError {\n constructor(\n message: string = 'Access denied',\n code: string = 'ACCESS_DENIED',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 403, code, details, requestId);\n this.name = 'AuthorizationError';\n }\n}\n\n/**\n * Not found error (404)\n * Thrown when a requested resource doesn't exist\n */\nexport class NotFoundError extends SpooledError {\n constructor(\n message: string = 'Resource not found',\n code: string = 'NOT_FOUND',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 404, code, details, requestId);\n this.name = 'NotFoundError';\n }\n}\n\n/**\n * Conflict error (409)\n * Thrown when there's a conflict (e.g., duplicate resource)\n */\nexport class ConflictError extends SpooledError {\n constructor(\n message: string = 'Conflict',\n code: string = 'CONFLICT',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 409, code, details, requestId);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Validation error (400)\n * Thrown when request validation fails\n */\nexport class ValidationError extends SpooledError {\n constructor(\n message: string = 'Validation failed',\n code: string = 'VALIDATION_ERROR',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 400, code, details, requestId);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Payload too large error (413)\n * Thrown when request body exceeds size limit\n */\nexport class PayloadTooLargeError extends SpooledError {\n constructor(\n message: string = 'Request payload too large',\n code: string = 'PAYLOAD_TOO_LARGE',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 413, code, details, requestId);\n this.name = 'PayloadTooLargeError';\n }\n}\n\n/**\n * Rate limit error (429)\n * Thrown when rate limit is exceeded\n */\nexport class RateLimitError extends SpooledError {\n /** Rate limit information */\n readonly rateLimitInfo: RateLimitInfo;\n\n constructor(\n message: string = 'Rate limit exceeded',\n code: string = 'RATE_LIMIT_EXCEEDED',\n rateLimitInfo: RateLimitInfo = {},\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 429, code, details, requestId);\n this.name = 'RateLimitError';\n this.rateLimitInfo = rateLimitInfo;\n }\n\n override isRetryable(): boolean {\n return true;\n }\n\n /** Get the number of seconds to wait before retrying */\n getRetryAfter(): number {\n if (this.rateLimitInfo.retryAfter !== undefined) {\n return this.rateLimitInfo.retryAfter;\n }\n if (this.rateLimitInfo.reset) {\n const now = Date.now();\n const resetTime = this.rateLimitInfo.reset.getTime();\n return Math.max(0, Math.ceil((resetTime - now) / 1000));\n }\n return 60; // Default to 60 seconds\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n rateLimitInfo: this.rateLimitInfo,\n };\n }\n}\n\n/**\n * Server error (5xx)\n * Thrown when the server encounters an error\n */\nexport class ServerError extends SpooledError {\n constructor(\n message: string = 'Server error',\n statusCode: number = 500,\n code: string = 'SERVER_ERROR',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, statusCode, code, details, requestId);\n this.name = 'ServerError';\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Network error\n * Thrown when a network request fails (no response received)\n */\nexport class NetworkError extends SpooledError {\n constructor(message: string = 'Network request failed', cause?: Error) {\n super(message, 0, 'NETWORK_ERROR', undefined, undefined, cause);\n this.name = 'NetworkError';\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Timeout error\n * Thrown when a request times out\n */\nexport class TimeoutError extends SpooledError {\n /** Timeout duration in milliseconds */\n readonly timeoutMs: number;\n\n constructor(message: string = 'Request timed out', timeoutMs: number = 0) {\n super(message, 0, 'TIMEOUT', { timeoutMs });\n this.name = 'TimeoutError';\n this.timeoutMs = timeoutMs;\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Circuit breaker open error\n * Thrown when the circuit breaker is open and rejecting requests\n */\nexport class CircuitBreakerOpenError extends SpooledError {\n constructor(message: string = 'Circuit breaker is open') {\n super(message, 0, 'CIRCUIT_BREAKER_OPEN');\n this.name = 'CircuitBreakerOpenError';\n }\n\n override isRetryable(): boolean {\n return false; // Should wait for circuit to close\n }\n}\n\n/**\n * Parse rate limit headers from a Response\n */\nexport function parseRateLimitHeaders(headers: Headers): RateLimitInfo {\n const info: RateLimitInfo = {};\n\n const retryAfter = headers.get('Retry-After');\n if (retryAfter) {\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n info.retryAfter = seconds;\n }\n }\n\n const limit = headers.get('X-RateLimit-Limit');\n if (limit) {\n const parsed = parseInt(limit, 10);\n if (!isNaN(parsed)) {\n info.limit = parsed;\n }\n }\n\n const remaining = headers.get('X-RateLimit-Remaining');\n if (remaining) {\n const parsed = parseInt(remaining, 10);\n if (!isNaN(parsed)) {\n info.remaining = parsed;\n }\n }\n\n const reset = headers.get('X-RateLimit-Reset');\n if (reset) {\n const timestamp = parseInt(reset, 10);\n if (!isNaN(timestamp)) {\n info.reset = new Date(timestamp * 1000);\n }\n }\n\n return info;\n}\n\n/** Cap a raw (non-JSON) error body so a stray HTML page can't become a huge message. */\nconst MAX_RAW_ERROR_BODY_CHARS = 500;\n\n/**\n * Parse an error response body.\n *\n * Reads the body once as text, then:\n * - if it parses as a JSON object, extracts `{code, message}` (falling back to\n * the `error` field when `message` is absent);\n * - otherwise (plain-text/HTML body, or malformed JSON) preserves the raw body\n * text as the message so a server's human-readable error — e.g. a proxy's\n * `502 Bad Gateway` page — is not silently discarded.\n */\nasync function parseErrorBody(response: Response): Promise<ApiErrorBody | null> {\n const contentType = response.headers.get('Content-Type') || '';\n\n let raw: string;\n try {\n raw = await response.text();\n } catch {\n return null;\n }\n\n if (contentType.includes('application/json')) {\n try {\n const body = JSON.parse(raw) as Record<string, unknown>;\n if (typeof body === 'object' && body !== null) {\n // Error bodies come in two shapes: {code, message} or {error, code, details}.\n // Fall back to `error` when `message` is absent so the server's\n // human-readable message is not lost.\n const message = ((body.message as string) ?? (body.error as string)) || response.statusText;\n return {\n code: (body.code as string) || 'UNKNOWN_ERROR',\n message,\n details: body.details as Record<string, unknown> | undefined,\n };\n }\n } catch {\n // Content-Type claimed JSON but the body did not parse — fall through and\n // preserve the raw text below instead of throwing it away.\n }\n }\n\n // Non-JSON body (or unparseable JSON): keep the raw text as the message.\n const trimmed = raw.trim();\n if (trimmed) {\n const message =\n trimmed.length > MAX_RAW_ERROR_BODY_CHARS\n ? `${trimmed.slice(0, MAX_RAW_ERROR_BODY_CHARS)}…`\n : trimmed;\n return { code: 'UNKNOWN_ERROR', message };\n }\n\n return null;\n}\n\n/**\n * Create an appropriate error from an HTTP response\n */\nexport async function createErrorFromResponse(response: Response): Promise<SpooledError> {\n const requestId = response.headers.get('X-Request-ID') ?? undefined;\n const body = await parseErrorBody(response);\n\n const message = body?.message || response.statusText || `HTTP ${response.status}`;\n const code = body?.code || 'UNKNOWN_ERROR';\n const details = body?.details;\n\n switch (response.status) {\n case 400:\n return new ValidationError(message, code, details, requestId);\n\n case 401:\n return new AuthenticationError(message, code, details, requestId);\n\n case 403:\n return new AuthorizationError(message, code, details, requestId);\n\n case 404:\n return new NotFoundError(message, code, details, requestId);\n\n case 409:\n return new ConflictError(message, code, details, requestId);\n\n case 413:\n return new PayloadTooLargeError(message, code, details, requestId);\n\n case 429: {\n const rateLimitInfo = parseRateLimitHeaders(response.headers);\n return new RateLimitError(message, code, rateLimitInfo, details, requestId);\n }\n\n default:\n if (response.status >= 500) {\n return new ServerError(message, response.status, code, details, requestId);\n }\n return new SpooledError(message, response.status, code, details, requestId);\n }\n}\n\n/**\n * Check if an error is a SpooledError instance\n */\nexport function isSpooledError(error: unknown): error is SpooledError {\n return error instanceof SpooledError;\n}\n\n/**\n * Check if an error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (error instanceof SpooledError) {\n return error.isRetryable();\n }\n // Network errors from fetch are typically retryable\n if (error instanceof TypeError) {\n return true;\n }\n return false;\n}\n","/**\n * Case Conversion Utilities\n *\n * Provides deep conversion between snake_case (API) and camelCase (SDK).\n * User-defined JSON blobs are preserved without conversion.\n */\n\n/**\n * Keys that should NOT have their values deeply converted.\n * These typically contain user-defined JSON that shouldn't be modified.\n */\nconst SKIP_CONVERSION_KEYS = new Set([\n 'payload',\n 'result',\n 'metadata',\n 'tags',\n 'settings',\n 'details',\n 'extra',\n 'payloadTemplate',\n 'payload_template',\n 'customLimits',\n 'custom_limits',\n]);\n\n/**\n * Check if a value is a plain object (not array, Date, null, etc.)\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !(value instanceof RegExp) &&\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\n/**\n * Convert a string from camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Convert a string from snake_case to camelCase\n */\nexport function snakeToCamel(str: string): string {\n // Handle numeric segments like `completed_24h` -> `completed24h`\n // and then standard `_x` -> `X` conversion.\n return str\n .replace(/_([0-9]+)/g, (_, digits) => digits)\n .replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Deep convert object keys from camelCase to snake_case.\n * Preserves values in SKIP_CONVERSION_KEYS without deep conversion.\n *\n * @param obj - Object to convert\n * @param skipDeepConversion - Whether current context should skip deep conversion of values\n * @returns Object with snake_case keys\n */\nexport function toSnakeCase<T = unknown>(obj: T, skipDeepConversion = false): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toSnakeCase(item, skipDeepConversion)) as T;\n }\n\n if (obj instanceof Date) {\n return obj.toISOString() as T;\n }\n\n if (!isPlainObject(obj)) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n\n // Check if this key's value should skip deep conversion\n const shouldSkip = skipDeepConversion || SKIP_CONVERSION_KEYS.has(key) || SKIP_CONVERSION_KEYS.has(snakeKey);\n\n if (shouldSkip) {\n // Don't convert the value, just preserve it as-is\n result[snakeKey] = value;\n } else {\n // Recursively convert the value\n result[snakeKey] = toSnakeCase(value, false);\n }\n }\n\n return result as T;\n}\n\n/**\n * Deep convert object keys from snake_case to camelCase.\n * Preserves values in SKIP_CONVERSION_KEYS without deep conversion.\n *\n * @param obj - Object to convert\n * @param skipDeepConversion - Whether current context should skip deep conversion of values\n * @returns Object with camelCase keys\n */\nexport function toCamelCase<T = unknown>(obj: T, skipDeepConversion = false): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toCamelCase(item, skipDeepConversion)) as T;\n }\n\n if (obj instanceof Date) {\n return obj as T;\n }\n\n if (!isPlainObject(obj)) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const camelKey = snakeToCamel(key);\n\n // Check if this key's value should skip deep conversion\n const shouldSkip = skipDeepConversion || SKIP_CONVERSION_KEYS.has(key) || SKIP_CONVERSION_KEYS.has(camelKey);\n\n if (shouldSkip) {\n // Don't convert the value, just preserve it as-is\n result[camelKey] = value;\n } else {\n // Recursively convert the value\n result[camelKey] = toCamelCase(value, false);\n }\n }\n\n return result as T;\n}\n\n/**\n * Convert request body from camelCase (SDK) to snake_case (API)\n */\nexport function convertRequest<T>(body: T): T {\n return toSnakeCase(body);\n}\n\n/**\n * Convert response body from snake_case (API) to camelCase (SDK)\n */\nexport function convertResponse<T>(body: T): T {\n return toCamelCase(body);\n}\n\n/**\n * Convert query parameters from camelCase to snake_case.\n * Only converts top-level keys, not nested objects.\n */\nexport function convertQueryParams(\n params: Record<string, string | number | boolean | undefined>\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = String(value);\n }\n }\n\n return result;\n}\n","/**\n * Retry Utility\n *\n * Implements exponential backoff with jitter for retrying failed requests.\n */\n\nimport type { RetryConfig } from '../config.js';\nimport { RateLimitError, isRetryableError } from '../errors.js';\n\n/** Options for a single retry operation */\nexport interface RetryOptions {\n /** Retry configuration */\n config: RetryConfig;\n /** Optional abort signal to cancel retries */\n signal?: AbortSignal;\n /** Callback for retry events (for logging/debugging) */\n onRetry?: (attempt: number, error: Error, delayMs: number) => void;\n}\n\n/**\n * Calculate delay for a given attempt using exponential backoff with optional jitter\n *\n * @param attempt - Current attempt number (1-based)\n * @param config - Retry configuration\n * @param retryAfterSeconds - Optional Retry-After header value\n * @returns Delay in milliseconds\n */\nexport function calculateDelay(\n attempt: number,\n config: RetryConfig,\n retryAfterSeconds?: number\n): number {\n // If we have a Retry-After value, use it (but respect maxDelay)\n if (retryAfterSeconds !== undefined && retryAfterSeconds > 0) {\n const retryAfterMs = retryAfterSeconds * 1000;\n return Math.min(retryAfterMs, config.maxDelay);\n }\n\n // Calculate exponential delay: baseDelay * factor^(attempt-1)\n const exponentialDelay = config.baseDelay * Math.pow(config.factor, attempt - 1);\n\n // Cap at maxDelay\n let delay = Math.min(exponentialDelay, config.maxDelay);\n\n // Add jitter if enabled (random value between 0 and 25% of delay)\n if (config.jitter) {\n const jitterRange = delay * 0.25;\n const jitter = Math.random() * jitterRange;\n delay = delay + jitter;\n }\n\n return Math.floor(delay);\n}\n\n/**\n * Check if an error should be retried\n *\n * @param error - The error to check\n * @param attempt - Current attempt number\n * @param config - Retry configuration\n * @returns Whether the error is retryable\n */\nexport function shouldRetry(error: Error, attempt: number, config: RetryConfig): boolean {\n // Don't retry if we've exhausted attempts\n // attempt is 1-based, so with maxRetries=2, we allow attempts 1, 2, 3 (initial + 2 retries)\n if (attempt > config.maxRetries) {\n return false;\n }\n\n // Use custom retry function if provided\n if (config.retryOn) {\n return config.retryOn(error, attempt);\n }\n\n // Default: retry on retryable errors\n return isRetryableError(error);\n}\n\n/**\n * Sleep for the specified duration\n *\n * @param ms - Duration in milliseconds\n * @param signal - Optional abort signal\n * @returns Promise that resolves after the delay or rejects if aborted\n */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException('Aborted', 'AbortError'));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n reject(new DOMException('Aborted', 'AbortError'));\n };\n\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\n/**\n * Execute a function with retry logic\n *\n * @param fn - Async function to execute\n * @param options - Retry options\n * @returns Promise resolving to the function result\n * @throws Last error if all retries fail\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): Promise<T> {\n const { config, signal, onRetry } = options;\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= config.maxRetries + 1; attempt++) {\n // Check if aborted before each attempt\n if (signal?.aborted) {\n throw new DOMException('Aborted', 'AbortError');\n }\n\n try {\n return await fn();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n lastError = err;\n\n // Check if we should retry\n if (!shouldRetry(err, attempt, config)) {\n throw err;\n }\n\n // Calculate delay\n let retryAfter: number | undefined;\n if (err instanceof RateLimitError) {\n retryAfter = err.getRetryAfter();\n }\n const delayMs = calculateDelay(attempt, config, retryAfter);\n\n // Notify about retry\n onRetry?.(attempt, err, delayMs);\n\n // Wait before retrying\n await sleep(delayMs, signal);\n }\n }\n\n // Should not reach here, but throw last error just in case\n throw lastError ?? new Error('Retry failed with unknown error');\n}\n\n/**\n * Create a retry wrapper with pre-configured options\n *\n * @param config - Retry configuration\n * @returns Function to wrap async operations with retry logic\n */\nexport function createRetryWrapper(config: RetryConfig) {\n return function retry<T>(\n fn: () => Promise<T>,\n options?: Partial<Omit<RetryOptions, 'config'>>\n ): Promise<T> {\n return withRetry(fn, {\n config,\n ...options,\n });\n };\n}\n","/**\n * HTTP Client Utility\n *\n * Provides a fetch wrapper with:\n * - URL building and query string encoding\n * - JSON request/response handling\n * - Timeout support via AbortController\n * - Automatic retry with exponential backoff\n * - Circuit breaker protection\n * - Case conversion (camelCase <-> snake_case)\n */\n\nimport type { ResolvedConfig, DebugFn } from '../config.js';\nimport { API_BASE_PATH } from '../config.js';\nimport type { RetryConfig } from '../config.js';\nimport {\n createErrorFromResponse,\n NetworkError,\n RateLimitError,\n TimeoutError,\n SpooledError,\n} from '../errors.js';\nimport { convertRequest, convertResponse, convertQueryParams } from './casing.js';\nimport { withRetry } from './retry.js';\nimport { CircuitBreaker } from './circuit-breaker.js';\n\n/**\n * HTTP methods considered idempotent per HTTP semantics.\n * Automatic retry on ambiguous failures (network/timeout/5xx) is only safe\n * for these; non-idempotent methods (POST/PATCH) may cause duplicate side\n * effects if retried after the request already reached the server.\n */\nconst IDEMPOTENT_METHODS = new Set<HttpMethod>(['GET', 'PUT', 'DELETE']);\n\n/** HTTP methods */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\n/** Query parameters type */\nexport type QueryParams = Record<string, string | number | boolean | undefined>;\n\n/** Request options for HTTP client */\nexport interface HttpRequestOptions {\n /** HTTP method (default: GET) */\n method?: HttpMethod;\n /** Request body (will be JSON stringified) */\n body?: unknown;\n /**\n * Raw request body (sent as-is, not JSON stringified).\n * Use this for endpoints that require an exact byte payload (e.g. webhook signature verification).\n */\n rawBody?: string | Uint8Array | ArrayBuffer;\n /** Query parameters */\n params?: QueryParams;\n /**\n * Skip automatically prefixing the path with `/api/v1`.\n * Use this for top-level endpoints like `/health` or `/metrics`.\n */\n skipApiPrefix?: boolean;\n /** Additional headers */\n headers?: Record<string, string>;\n /** Request timeout in milliseconds (overrides client default) */\n timeout?: number;\n /** Whether to skip case conversion for request body */\n skipRequestConversion?: boolean;\n /** Whether to skip case conversion for response body */\n skipResponseConversion?: boolean;\n /** Whether to skip retry logic */\n skipRetry?: boolean;\n /** Optional abort signal */\n signal?: AbortSignal;\n}\n\n/** HTTP response wrapper */\nexport interface HttpResponse<T> {\n /** Response status code */\n status: number;\n /** Response headers */\n headers: Headers;\n /** Parsed response body */\n data: T;\n}\n\n/**\n * HTTP Client class\n *\n * Handles all HTTP communication with the Spooled API.\n */\nexport class HttpClient {\n private readonly config: ResolvedConfig;\n private readonly circuitBreaker: CircuitBreaker;\n private readonly debug: DebugFn | null;\n\n /** Current authentication token (API key or JWT) */\n private authToken: string | undefined;\n\n /** Optional function to mint a fresh access token (set when auto-refresh is enabled) */\n private refreshTokenFn: (() => Promise<string>) | null = null;\n\n /** Guard to prevent a refresh request from recursively triggering another refresh */\n private isRefreshing = false;\n\n constructor(\n config: ResolvedConfig,\n circuitBreaker: CircuitBreaker\n ) {\n this.config = config;\n this.circuitBreaker = circuitBreaker;\n this.debug = config.debug;\n\n // Set initial auth token\n this.authToken = config.accessToken ?? config.apiKey;\n }\n\n /**\n * Set the authentication token\n */\n setAuthToken(token: string): void {\n this.authToken = token;\n }\n\n /**\n * Set the token refresh function.\n *\n * When set, an expired-token 401 on the data plane triggers a single\n * refresh + retry of the original request with the new token.\n */\n setRefreshTokenFn(fn: () => Promise<string>): void {\n this.refreshTokenFn = fn;\n }\n\n /**\n * Build full URL with query parameters\n */\n private buildUrl(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n skipApiPrefix?: boolean\n ): string {\n // Ensure path starts with /api/v1 unless explicitly skipped\n const fullPath = skipApiPrefix ? path : (path.startsWith('/api/') ? path : `${API_BASE_PATH}${path}`);\n const url = new URL(fullPath, this.config.baseUrl);\n\n if (params) {\n const convertedParams = convertQueryParams(params);\n for (const [key, value] of Object.entries(convertedParams)) {\n url.searchParams.append(key, value);\n }\n }\n\n return url.toString();\n }\n\n /**\n * Build request headers\n */\n private buildHeaders(customHeaders?: Record<string, string>): Headers {\n const headers = new Headers();\n\n // Add default headers\n for (const [key, value] of Object.entries(this.config.headers)) {\n headers.set(key, value);\n }\n\n // Add user agent\n headers.set('User-Agent', this.config.userAgent);\n\n // Add auth token if available\n if (this.authToken) {\n headers.set('Authorization', `Bearer ${this.authToken}`);\n }\n\n // Add custom headers\n if (customHeaders) {\n for (const [key, value] of Object.entries(customHeaders)) {\n headers.set(key, value);\n }\n }\n\n return headers;\n }\n\n /**\n * Execute a fetch request with timeout\n */\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n externalSignal?: AbortSignal\n ): Promise<Response> {\n const controller = new AbortController();\n const { signal } = controller;\n\n // Link external signal to our controller\n if (externalSignal) {\n if (externalSignal.aborted) {\n controller.abort();\n } else {\n externalSignal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n }\n\n // Set up timeout\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await this.config.fetch(url, {\n ...init,\n signal,\n });\n return response;\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n // Check if this was a timeout or user abort\n if (externalSignal?.aborted) {\n throw error; // User aborted\n }\n throw new TimeoutError(`Request timed out after ${timeoutMs}ms`, timeoutMs);\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Execute a single HTTP request (no retry)\n */\n private async executeRequest<T>(\n url: string,\n options: HttpRequestOptions,\n hasRefreshed = false\n ): Promise<HttpResponse<T>> {\n const method = options.method ?? 'GET';\n const headers = this.buildHeaders(options.headers);\n const timeout = options.timeout ?? this.config.timeout;\n\n // Build request init\n const init: RequestInit = {\n method,\n headers,\n };\n\n // Add body for methods that support it\n if (method !== 'GET') {\n if (options.rawBody !== undefined) {\n init.body = options.rawBody as unknown as RequestInit['body'];\n } else if (options.body !== undefined) {\n const body = options.skipRequestConversion ? options.body : convertRequest(options.body);\n init.body = JSON.stringify(body);\n }\n }\n\n this.debug?.(`${method} ${url}`, { timeout, hasBody: !!options.body });\n\n let response: Response;\n try {\n response = await this.fetchWithTimeout(url, init, timeout, options.signal);\n } catch (error) {\n if (error instanceof TimeoutError || error instanceof SpooledError) {\n throw error;\n }\n // Network error (fetch failed to get a response)\n const cause = error instanceof Error ? error : undefined;\n throw new NetworkError(`Network request failed: ${cause?.message ?? 'Unknown error'}`, cause);\n }\n\n this.debug?.(`Response: ${response.status}`, { url });\n\n // Handle non-OK responses\n if (!response.ok) {\n // On an expired-token 401, try refreshing the access token once and\n // retry the original request. Guarded so the refresh request itself\n // (or a genuinely invalid credential) can't loop.\n if (\n response.status === 401 &&\n this.refreshTokenFn &&\n !hasRefreshed &&\n !this.isRefreshing\n ) {\n let refreshed = false;\n this.isRefreshing = true;\n try {\n const newToken = await this.refreshTokenFn();\n this.setAuthToken(newToken);\n refreshed = true;\n } catch (refreshError) {\n const message = refreshError instanceof Error ? refreshError.message : 'unknown';\n this.debug?.('Token refresh failed', { error: message });\n } finally {\n this.isRefreshing = false;\n }\n\n if (refreshed) {\n return this.executeRequest<T>(url, options, true);\n }\n }\n\n const apiError = await createErrorFromResponse(response);\n throw apiError;\n }\n\n // Parse response body\n let data: T;\n const contentType = response.headers.get('Content-Type') || '';\n\n if (response.status === 204) {\n data = undefined as T;\n } else if (contentType.includes('application/json')) {\n const rawData = (await response.json()) as T;\n data = options.skipResponseConversion ? rawData : convertResponse(rawData);\n } else {\n // Non-JSON response (e.g. Prometheus metrics text)\n data = (await response.text()) as unknown as T;\n }\n\n return {\n status: response.status,\n headers: response.headers,\n data,\n };\n }\n\n /**\n * Make an HTTP request with retry and circuit breaker\n */\n async request<T>(path: string, options: HttpRequestOptions = {}): Promise<HttpResponse<T>> {\n const url = this.buildUrl(path, options.params, options.skipApiPrefix);\n const method = options.method ?? 'GET';\n\n // Wrap in circuit breaker\n const execute = async (): Promise<HttpResponse<T>> => {\n return this.circuitBreaker.execute(() => this.executeRequest<T>(url, options));\n };\n\n // Apply retry logic if not skipped\n if (options.skipRetry) {\n return execute();\n }\n\n return withRetry(execute, {\n config: this.resolveRetryConfig(method, options),\n signal: options.signal,\n onRetry: (attempt, error, delayMs) => {\n this.debug?.(`Retry attempt ${attempt} after ${delayMs}ms`, { error: error.message });\n },\n });\n }\n\n /**\n * Determine whether a request carries an idempotency key (making a\n * non-idempotent method safe to retry).\n */\n private hasIdempotencyKey(options: HttpRequestOptions): boolean {\n if (!options.headers) {\n return false;\n }\n return Object.keys(options.headers).some((key) => key.toLowerCase() === 'idempotency-key');\n }\n\n /**\n * Resolve the retry configuration for a request.\n *\n * Idempotent methods (GET/PUT/DELETE) and any request carrying an\n * idempotency key retry normally. Non-idempotent methods (POST/PATCH)\n * without an idempotency key must NOT be retried on ambiguous failures\n * (network/timeout/5xx) — doing so risks duplicate jobs, double claims,\n * etc. They are still retried on 429, which is rejected before the\n * server processes the request and is therefore side-effect-free.\n */\n private resolveRetryConfig(method: HttpMethod, options: HttpRequestOptions): RetryConfig {\n const base = this.config.retry;\n\n // Respect an explicit user-provided retry predicate.\n if (base.retryOn) {\n return base;\n }\n\n if (IDEMPOTENT_METHODS.has(method) || this.hasIdempotencyKey(options)) {\n return base;\n }\n\n return {\n ...base,\n retryOn: (error) => error instanceof RateLimitError,\n };\n }\n\n /**\n * Make a GET request\n */\n async get<T>(path: string, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'GET' });\n return response.data;\n }\n\n /**\n * Make a POST request\n */\n async post<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'POST', body });\n return response.data;\n }\n\n /**\n * Make a PUT request\n */\n async put<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'PUT', body });\n return response.data;\n }\n\n /**\n * Make a PATCH request\n */\n async patch<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'PATCH', body });\n return response.data;\n }\n\n /**\n * Make a DELETE request\n */\n async delete<T = void>(path: string, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'DELETE' });\n return response.data;\n }\n}\n\n/**\n * Create an HTTP client instance\n */\nexport function createHttpClient(\n config: ResolvedConfig,\n circuitBreaker: CircuitBreaker\n): HttpClient {\n return new HttpClient(config, circuitBreaker);\n}\n","/**\n * Circuit Breaker Utility\n *\n * Implements the circuit breaker pattern to prevent cascading failures.\n * States: CLOSED (normal) -> OPEN (failing) -> HALF_OPEN (testing) -> CLOSED\n */\n\nimport type { CircuitBreakerConfig } from '../config.js';\nimport { CircuitBreakerOpenError, isRetryableError } from '../errors.js';\n\n/** Circuit breaker states */\nexport enum CircuitState {\n /** Normal operation - requests flow through */\n CLOSED = 'CLOSED',\n /** Circuit is open - requests are rejected immediately */\n OPEN = 'OPEN',\n /** Testing state - limited requests allowed to test recovery */\n HALF_OPEN = 'HALF_OPEN',\n}\n\n/** Circuit breaker state change event */\nexport interface CircuitStateChange {\n from: CircuitState;\n to: CircuitState;\n timestamp: Date;\n failureCount: number;\n}\n\n/** Circuit breaker options */\nexport interface CircuitBreakerOptions extends CircuitBreakerConfig {\n /** Callback when state changes */\n onStateChange?: (event: CircuitStateChange) => void;\n /** Custom function to determine if an error should count as a failure */\n isFailure?: (error: Error) => boolean;\n}\n\n/**\n * Circuit Breaker implementation\n *\n * Tracks failures and prevents requests when the failure threshold is reached.\n */\nexport class CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failureCount = 0;\n private successCount = 0;\n private lastFailureTime: number = 0;\n private readonly config: CircuitBreakerOptions;\n\n constructor(config: CircuitBreakerOptions) {\n this.config = config;\n }\n\n /**\n * Get current circuit state\n */\n getState(): CircuitState {\n // Check if we should transition from OPEN to HALF_OPEN\n if (this.state === CircuitState.OPEN) {\n const now = Date.now();\n if (now - this.lastFailureTime >= this.config.timeout) {\n this.transitionTo(CircuitState.HALF_OPEN);\n }\n }\n return this.state;\n }\n\n /**\n * Check if circuit breaker is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Check if requests are currently allowed\n */\n isAllowed(): boolean {\n if (!this.config.enabled) {\n return true;\n }\n\n const state = this.getState();\n return state === CircuitState.CLOSED || state === CircuitState.HALF_OPEN;\n }\n\n /**\n * Record a successful request\n */\n recordSuccess(): void {\n if (!this.config.enabled) {\n return;\n }\n\n if (this.state === CircuitState.HALF_OPEN) {\n this.successCount++;\n\n if (this.successCount >= this.config.successThreshold) {\n this.transitionTo(CircuitState.CLOSED);\n }\n } else if (this.state === CircuitState.CLOSED) {\n // Reset failure count on success in closed state\n this.failureCount = 0;\n }\n }\n\n /**\n * Record a failed request\n */\n recordFailure(error: Error): void {\n if (!this.config.enabled) {\n return;\n }\n\n // Check if this error should count as a failure\n const shouldCount = this.config.isFailure\n ? this.config.isFailure(error)\n : isRetryableError(error);\n\n if (!shouldCount) {\n return;\n }\n\n this.lastFailureTime = Date.now();\n\n if (this.state === CircuitState.HALF_OPEN) {\n // Any failure in half-open state reopens the circuit\n this.transitionTo(CircuitState.OPEN);\n } else if (this.state === CircuitState.CLOSED) {\n this.failureCount++;\n\n if (this.failureCount >= this.config.failureThreshold) {\n this.transitionTo(CircuitState.OPEN);\n }\n }\n }\n\n /**\n * Transition to a new state\n */\n private transitionTo(newState: CircuitState): void {\n if (this.state === newState) {\n return;\n }\n\n const oldState = this.state;\n this.state = newState;\n\n // Reset counters on state change\n if (newState === CircuitState.CLOSED) {\n this.failureCount = 0;\n this.successCount = 0;\n } else if (newState === CircuitState.HALF_OPEN) {\n this.successCount = 0;\n } else if (newState === CircuitState.OPEN) {\n this.successCount = 0;\n }\n\n // Notify listener\n this.config.onStateChange?.({\n from: oldState,\n to: newState,\n timestamp: new Date(),\n failureCount: this.failureCount,\n });\n }\n\n /**\n * Reset the circuit breaker to closed state\n */\n reset(): void {\n this.state = CircuitState.CLOSED;\n this.failureCount = 0;\n this.successCount = 0;\n this.lastFailureTime = 0;\n }\n\n /**\n * Execute a function with circuit breaker protection\n *\n * @param fn - Async function to execute\n * @returns Promise resolving to the function result\n * @throws CircuitBreakerOpenError if circuit is open\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n if (!this.isAllowed()) {\n throw new CircuitBreakerOpenError(\n `Circuit breaker is open. Will retry after ${this.config.timeout}ms`\n );\n }\n\n try {\n const result = await fn();\n this.recordSuccess();\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.recordFailure(err);\n throw error;\n }\n }\n\n /**\n * Get circuit breaker statistics\n */\n getStats(): {\n state: CircuitState;\n failureCount: number;\n successCount: number;\n lastFailureTime: Date | null;\n config: CircuitBreakerConfig;\n } {\n return {\n state: this.getState(),\n failureCount: this.failureCount,\n successCount: this.successCount,\n lastFailureTime: this.lastFailureTime ? new Date(this.lastFailureTime) : null,\n config: {\n enabled: this.config.enabled,\n failureThreshold: this.config.failureThreshold,\n successThreshold: this.config.successThreshold,\n timeout: this.config.timeout,\n },\n };\n }\n}\n\n/**\n * Create a circuit breaker instance from configuration\n */\nexport function createCircuitBreaker(config: CircuitBreakerConfig): CircuitBreaker {\n return new CircuitBreaker(config);\n}\n\n/**\n * Create a disabled circuit breaker (pass-through)\n */\nexport function createDisabledCircuitBreaker(): CircuitBreaker {\n return new CircuitBreaker({\n enabled: false,\n failureThreshold: 0,\n successThreshold: 0,\n timeout: 0,\n });\n}\n","/**\n * Auth Resource\n *\n * Handles authentication operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n LoginParams,\n LoginResponse,\n RefreshTokenParams,\n RefreshTokenResponse,\n CurrentUserResponse,\n ValidateTokenParams,\n ValidateTokenResponse,\n} from '../types/auth.js';\n\nexport class AuthResource {\n constructor(\n private readonly http: HttpClient,\n /** Optional accessor for the client's current refresh token (used by logout) */\n private readonly getRefreshToken?: () => string | undefined\n ) {}\n\n /**\n * Exchange API key for JWT tokens\n */\n async login(params: LoginParams): Promise<LoginResponse> {\n return this.http.post<LoginResponse>('/auth/login', params);\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refresh(params: RefreshTokenParams): Promise<RefreshTokenResponse> {\n return this.http.post<RefreshTokenResponse>('/auth/refresh', params);\n }\n\n /**\n * Logout and revoke the refresh token server-side.\n *\n * The backend requires the refresh token in the body to invalidate the\n * session. When omitted, the client's current refresh token (if any) is\n * used automatically.\n */\n async logout(refreshToken?: string): Promise<void> {\n const token = refreshToken ?? this.getRefreshToken?.();\n await this.http.post<void>('/auth/logout', token ? { refreshToken: token } : undefined);\n }\n\n /**\n * Get current user/session info\n */\n async me(): Promise<CurrentUserResponse> {\n return this.http.get<CurrentUserResponse>('/auth/me');\n }\n\n /**\n * Validate a token\n */\n async validate(params: ValidateTokenParams): Promise<ValidateTokenResponse> {\n return this.http.post<ValidateTokenResponse>('/auth/validate', params);\n }\n\n /**\n * Start email-based login flow (sends magic link)\n */\n async startEmailLogin(email: string): Promise<{ success: boolean; message: string }> {\n return this.http.post<{ success: boolean; message: string }>('/auth/email/start', { email });\n }\n\n /**\n * Check if an email address exists in the system\n */\n async checkEmail(email: string): Promise<{ exists: boolean }> {\n return this.http.get<{ exists: boolean }>('/auth/check-email', {\n params: { email },\n });\n }\n}\n","/**\n * Jobs Resource\n *\n * Handles job operations including worker processing endpoints.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n Job,\n JobSummary,\n JobStats,\n CreateJobParams,\n CreateJobResult,\n ListJobsParams,\n BatchJobStatus,\n ClaimJobsParams,\n ClaimJobsResult,\n CompleteJobParams,\n FailJobParams,\n HeartbeatJobParams,\n BoostPriorityResponse,\n BulkEnqueueParams,\n BulkEnqueueResponse,\n ListDlqParams,\n RetryDlqParams,\n RetryDlqResponse,\n PurgeDlqParams,\n PurgeDlqResponse,\n} from '../types/jobs.js';\n\n/** DLQ operations */\nexport interface DlqOperations {\n /** List jobs in dead-letter queue */\n list(params?: ListDlqParams): Promise<JobSummary[]>;\n /** Retry jobs from DLQ */\n retry(params: RetryDlqParams): Promise<RetryDlqResponse>;\n /** Purge jobs from DLQ */\n purge(params: PurgeDlqParams): Promise<PurgeDlqResponse>;\n}\n\nexport class JobsResource {\n /** Dead-letter queue operations */\n readonly dlq: DlqOperations;\n\n constructor(private readonly http: HttpClient) {\n this.dlq = {\n list: this.listDlq.bind(this),\n retry: this.retryDlq.bind(this),\n purge: this.purgeDlq.bind(this),\n };\n }\n\n /**\n * Create a new job\n */\n async create(params: CreateJobParams): Promise<CreateJobResult> {\n return this.http.post<CreateJobResult>('/jobs', params);\n }\n\n /**\n * Create a job and return the full job object\n */\n async createAndGet(params: CreateJobParams): Promise<Job> {\n const result = await this.create(params);\n return this.get(result.id);\n }\n\n /**\n * List jobs with optional filtering\n */\n async list(params?: ListJobsParams): Promise<JobSummary[]> {\n return this.http.get<JobSummary[]>('/jobs', { params: params as Record<string, string | number | boolean | undefined> });\n }\n\n /**\n * Get a job by ID\n */\n async get(id: string): Promise<Job> {\n return this.http.get<Job>(`/jobs/${id}`);\n }\n\n /**\n * Cancel a pending or scheduled job\n */\n async cancel(id: string): Promise<void> {\n await this.http.delete(`/jobs/${id}`);\n }\n\n /**\n * Retry a failed or dead-lettered job\n */\n async retry(id: string): Promise<Job> {\n return this.http.post<Job>(`/jobs/${id}/retry`);\n }\n\n /**\n * Boost job priority\n */\n async boostPriority(id: string, priority: number): Promise<BoostPriorityResponse> {\n return this.http.put<BoostPriorityResponse>(`/jobs/${id}/priority`, { priority });\n }\n\n /**\n * Get job statistics\n */\n async getStats(): Promise<JobStats> {\n return this.http.get<JobStats>('/jobs/stats');\n }\n\n /**\n * Get status of multiple jobs at once\n */\n async batchStatus(ids: string[]): Promise<BatchJobStatus[]> {\n if (ids.length === 0) {\n return [];\n }\n if (ids.length > 100) {\n throw new Error('Maximum 100 job IDs allowed per request');\n }\n return this.http.get<BatchJobStatus[]>('/jobs/status', {\n params: { ids: ids.join(',') },\n });\n }\n\n /**\n * Bulk enqueue multiple jobs\n */\n async bulkEnqueue(params: BulkEnqueueParams): Promise<BulkEnqueueResponse> {\n return this.http.post<BulkEnqueueResponse>('/jobs/bulk', params);\n }\n\n // Worker processing endpoints\n\n /**\n * Claim jobs for worker processing\n */\n async claim(params: ClaimJobsParams): Promise<ClaimJobsResult> {\n return this.http.post<ClaimJobsResult>('/jobs/claim', params);\n }\n\n /**\n * Complete a job (worker ack)\n */\n async complete(id: string, params: CompleteJobParams): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/jobs/${id}/complete`, params);\n }\n\n /**\n * Fail a job (worker nack)\n */\n async fail(id: string, params: FailJobParams): Promise<{ success: boolean; error?: string }> {\n return this.http.post<{ success: boolean; error?: string }>(`/jobs/${id}/fail`, params);\n }\n\n /**\n * Extend job lease (heartbeat)\n */\n async heartbeat(id: string, params: HeartbeatJobParams): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/jobs/${id}/heartbeat`, params);\n }\n\n // DLQ operations (private implementations)\n\n private async listDlq(params?: ListDlqParams): Promise<JobSummary[]> {\n return this.http.get<JobSummary[]>('/jobs/dlq', { params: params as Record<string, string | number | boolean | undefined> });\n }\n\n private async retryDlq(params: RetryDlqParams): Promise<RetryDlqResponse> {\n return this.http.post<RetryDlqResponse>('/jobs/dlq/retry', params);\n }\n\n private async purgeDlq(params: PurgeDlqParams): Promise<PurgeDlqResponse> {\n return this.http.post<PurgeDlqResponse>('/jobs/dlq/purge', params);\n }\n}\n","/**\n * Queues Resource\n *\n * Handles queue configuration and control operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n QueueConfig,\n QueueConfigSummary,\n QueueStats,\n UpdateQueueConfigParams,\n PauseQueueResponse,\n ResumeQueueResponse,\n} from '../types/queues.js';\n\nexport class QueuesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all queues\n */\n async list(): Promise<QueueConfigSummary[]> {\n return this.http.get<QueueConfigSummary[]>('/queues');\n }\n\n /**\n * Get queue configuration by name\n */\n async get(name: string): Promise<QueueConfig> {\n return this.http.get<QueueConfig>(`/queues/${encodeURIComponent(name)}`);\n }\n\n /**\n * Update queue configuration\n */\n async updateConfig(name: string, params: UpdateQueueConfigParams): Promise<QueueConfig> {\n return this.http.put<QueueConfig>(`/queues/${encodeURIComponent(name)}/config`, params);\n }\n\n /**\n * Get queue statistics\n */\n async getStats(name: string): Promise<QueueStats> {\n return this.http.get<QueueStats>(`/queues/${encodeURIComponent(name)}/stats`);\n }\n\n /**\n * Pause a queue\n */\n async pause(name: string, reason?: string): Promise<PauseQueueResponse> {\n return this.http.post<PauseQueueResponse>(\n `/queues/${encodeURIComponent(name)}/pause`,\n reason ? { reason } : undefined\n );\n }\n\n /**\n * Resume a paused queue\n */\n async resume(name: string): Promise<ResumeQueueResponse> {\n return this.http.post<ResumeQueueResponse>(`/queues/${encodeURIComponent(name)}/resume`);\n }\n\n /**\n * Delete a queue configuration\n */\n async delete(name: string): Promise<void> {\n await this.http.delete(`/queues/${encodeURIComponent(name)}`);\n }\n}\n","/**\n * Workers Resource\n *\n * Handles worker registration and management.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n Worker,\n WorkerSummary,\n RegisterWorkerParams,\n RegisterWorkerResponse,\n WorkerHeartbeatParams,\n} from '../types/workers.js';\n\nexport class WorkersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all workers\n */\n async list(): Promise<WorkerSummary[]> {\n return this.http.get<WorkerSummary[]>('/workers');\n }\n\n /**\n * Get a worker by ID\n */\n async get(id: string): Promise<Worker> {\n return this.http.get<Worker>(`/workers/${id}`);\n }\n\n /**\n * Register a new worker\n */\n async register(params: RegisterWorkerParams): Promise<RegisterWorkerResponse> {\n return this.http.post<RegisterWorkerResponse>('/workers/register', params);\n }\n\n /**\n * Send worker heartbeat\n */\n async heartbeat(id: string, params: WorkerHeartbeatParams): Promise<void> {\n await this.http.post(`/workers/${id}/heartbeat`, params);\n }\n\n /**\n * Deregister a worker\n */\n async deregister(id: string): Promise<void> {\n await this.http.post(`/workers/${id}/deregister`);\n }\n}\n","/**\n * Schedules Resource\n *\n * Handles cron schedule operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n Schedule,\n CreateScheduleParams,\n CreateScheduleResponse,\n UpdateScheduleParams,\n ListSchedulesParams,\n TriggerScheduleResponse,\n ScheduleRun,\n} from '../types/schedules.js';\n\nexport class SchedulesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all schedules\n */\n async list(params?: ListSchedulesParams): Promise<Schedule[]> {\n return this.http.get<Schedule[]>('/schedules', { params: params as Record<string, string | number | boolean | undefined> });\n }\n\n /**\n * Create a new schedule\n */\n async create(params: CreateScheduleParams): Promise<CreateScheduleResponse> {\n return this.http.post<CreateScheduleResponse>('/schedules', params);\n }\n\n /**\n * Get a schedule by ID\n */\n async get(id: string): Promise<Schedule> {\n return this.http.get<Schedule>(`/schedules/${id}`);\n }\n\n /**\n * Update a schedule\n */\n async update(id: string, params: UpdateScheduleParams): Promise<Schedule> {\n return this.http.put<Schedule>(`/schedules/${id}`, params);\n }\n\n /**\n * Delete a schedule\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/schedules/${id}`);\n }\n\n /**\n * Pause a schedule\n */\n async pause(id: string): Promise<Schedule> {\n return this.http.post<Schedule>(`/schedules/${id}/pause`);\n }\n\n /**\n * Resume a paused schedule\n */\n async resume(id: string): Promise<Schedule> {\n return this.http.post<Schedule>(`/schedules/${id}/resume`);\n }\n\n /**\n * Manually trigger a schedule\n */\n async trigger(id: string): Promise<TriggerScheduleResponse> {\n return this.http.post<TriggerScheduleResponse>(`/schedules/${id}/trigger`);\n }\n\n /**\n * Get schedule execution history\n */\n async getHistory(id: string, limit?: number): Promise<ScheduleRun[]> {\n return this.http.get<ScheduleRun[]>(`/schedules/${id}/history`, {\n params: limit ? { limit } : undefined,\n });\n }\n}\n","/**\n * Workflows Resource\n *\n * Handles workflow operations including job dependencies.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n WorkflowResponse,\n CreateWorkflowParams,\n CreateWorkflowResponse,\n ListWorkflowsParams,\n JobWithDependencies,\n AddDependenciesParams,\n AddDependenciesResponse,\n WorkflowJob,\n WorkflowJobStatus,\n} from '../types/workflows.js';\n\n/** Workflow job operations */\nexport interface WorkflowJobOperations {\n /**\n * List all jobs in a workflow.\n *\n * @param workflowId - The workflow ID\n * @example\n * ```typescript\n * const jobs = await client.workflows.jobs.list('wf_123');\n * console.log('Jobs:', jobs.map(j => j.key));\n * ```\n */\n list(workflowId: string): Promise<WorkflowJob[]>;\n\n /**\n * Get a specific job within a workflow.\n *\n * @param workflowId - The workflow ID\n * @param jobId - The job ID\n * @example\n * ```typescript\n * const job = await client.workflows.jobs.get('wf_123', 'job_456');\n * console.log('Job status:', job.status);\n * ```\n */\n get(workflowId: string, jobId: string): Promise<WorkflowJob>;\n\n /**\n * Get the status of all jobs in a workflow.\n *\n * Returns a summary of each job's status and progress.\n *\n * @param workflowId - The workflow ID\n * @example\n * ```typescript\n * const statuses = await client.workflows.jobs.getStatus('wf_123');\n * for (const s of statuses) {\n * console.log(`${s.key}: ${s.status}`);\n * }\n * ```\n */\n getStatus(workflowId: string): Promise<WorkflowJobStatus[]>;\n\n /**\n * Get job dependencies.\n *\n * @param jobId - The job ID\n * @example\n * ```typescript\n * const deps = await client.workflows.jobs.getDependencies('job_456');\n * console.log('Depends on:', deps.dependencies);\n * ```\n */\n getDependencies(jobId: string): Promise<JobWithDependencies>;\n\n /**\n * Add dependencies to a job.\n *\n * @param jobId - The job ID\n * @param params - Dependencies to add\n * @example\n * ```typescript\n * await client.workflows.jobs.addDependencies('job_456', {\n * dependsOnJobIds: ['job_123'],\n * });\n * ```\n */\n addDependencies(jobId: string, params: AddDependenciesParams): Promise<AddDependenciesResponse>;\n}\n\nexport class WorkflowsResource {\n /** Workflow job operations */\n readonly jobs: WorkflowJobOperations;\n\n constructor(private readonly http: HttpClient) {\n this.jobs = {\n list: this.listWorkflowJobs.bind(this),\n get: this.getWorkflowJob.bind(this),\n getStatus: this.getWorkflowJobsStatus.bind(this),\n getDependencies: this.getJobDependencies.bind(this),\n addDependencies: this.addJobDependencies.bind(this),\n };\n }\n\n /**\n * List all workflows\n */\n async list(params?: ListWorkflowsParams): Promise<WorkflowResponse[]> {\n return this.http.get<WorkflowResponse[]>('/workflows', { params: params as Record<string, string | number | boolean | undefined> });\n }\n\n /**\n * Create a new workflow\n */\n async create(params: CreateWorkflowParams): Promise<CreateWorkflowResponse> {\n return this.http.post<CreateWorkflowResponse>('/workflows', params);\n }\n\n /**\n * Get a workflow by ID\n */\n async get(id: string): Promise<WorkflowResponse> {\n return this.http.get<WorkflowResponse>(`/workflows/${id}`);\n }\n\n /**\n * Cancel a workflow\n */\n async cancel(id: string): Promise<WorkflowResponse> {\n return this.http.post<WorkflowResponse>(`/workflows/${id}/cancel`);\n }\n\n /**\n * Retry a failed workflow\n *\n * Resets all failed/deadletter jobs back to pending and resumes the workflow.\n * Only workflows with status 'failed' can be retried.\n */\n async retry(id: string): Promise<WorkflowResponse> {\n return this.http.post<WorkflowResponse>(`/workflows/${id}/retry`);\n }\n\n // Workflow job operations (private implementations)\n\n private async listWorkflowJobs(workflowId: string): Promise<WorkflowJob[]> {\n return this.http.get<WorkflowJob[]>(`/workflows/${workflowId}/jobs`);\n }\n\n private async getWorkflowJob(workflowId: string, jobId: string): Promise<WorkflowJob> {\n return this.http.get<WorkflowJob>(`/workflows/${workflowId}/jobs/${jobId}`);\n }\n\n private async getWorkflowJobsStatus(workflowId: string): Promise<WorkflowJobStatus[]> {\n return this.http.get<WorkflowJobStatus[]>(`/workflows/${workflowId}/jobs/status`);\n }\n\n private async getJobDependencies(jobId: string): Promise<JobWithDependencies> {\n return this.http.get<JobWithDependencies>(`/jobs/${jobId}/dependencies`);\n }\n\n private async addJobDependencies(\n jobId: string,\n params: AddDependenciesParams\n ): Promise<AddDependenciesResponse> {\n return this.http.post<AddDependenciesResponse>(`/jobs/${jobId}/dependencies`, params);\n }\n}\n","/**\n * Webhooks Resource\n *\n * Handles outgoing webhook operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n OutgoingWebhook,\n CreateOutgoingWebhookParams,\n UpdateOutgoingWebhookParams,\n TestWebhookResponse,\n OutgoingWebhookDelivery,\n} from '../types/webhooks.js';\n\nexport class WebhooksResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all outgoing webhooks\n */\n async list(): Promise<OutgoingWebhook[]> {\n return this.http.get<OutgoingWebhook[]>('/outgoing-webhooks');\n }\n\n /**\n * Create a new outgoing webhook\n */\n async create(params: CreateOutgoingWebhookParams): Promise<OutgoingWebhook> {\n return this.http.post<OutgoingWebhook>('/outgoing-webhooks', params);\n }\n\n /**\n * Get an outgoing webhook by ID\n */\n async get(id: string): Promise<OutgoingWebhook> {\n return this.http.get<OutgoingWebhook>(`/outgoing-webhooks/${id}`);\n }\n\n /**\n * Update an outgoing webhook\n */\n async update(id: string, params: UpdateOutgoingWebhookParams): Promise<OutgoingWebhook> {\n return this.http.put<OutgoingWebhook>(`/outgoing-webhooks/${id}`, params);\n }\n\n /**\n * Delete an outgoing webhook\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/outgoing-webhooks/${id}`);\n }\n\n /**\n * Test an outgoing webhook\n */\n async test(id: string): Promise<TestWebhookResponse> {\n return this.http.post<TestWebhookResponse>(`/outgoing-webhooks/${id}/test`);\n }\n\n /**\n * Get webhook delivery history\n */\n async getDeliveries(id: string): Promise<OutgoingWebhookDelivery[]> {\n return this.http.get<OutgoingWebhookDelivery[]>(`/outgoing-webhooks/${id}/deliveries`);\n }\n\n /**\n * Retry a specific webhook delivery\n */\n async retryDelivery(webhookId: string, deliveryId: string): Promise<{ success: boolean; message: string }> {\n return this.http.post<{ success: boolean; message: string }>(\n `/outgoing-webhooks/${webhookId}/retry/${deliveryId}`\n );\n }\n}\n","/**\n * API Keys Resource\n *\n * Handles API key operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n ApiKeySummary,\n CreateApiKeyParams,\n CreateApiKeyResponse,\n UpdateApiKeyParams,\n} from '../types/api-keys.js';\n\nexport class ApiKeysResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all API keys (without sensitive data)\n */\n async list(): Promise<ApiKeySummary[]> {\n return this.http.get<ApiKeySummary[]>('/api-keys');\n }\n\n /**\n * Create a new API key\n */\n async create(params: CreateApiKeyParams): Promise<CreateApiKeyResponse> {\n return this.http.post<CreateApiKeyResponse>('/api-keys', params);\n }\n\n /**\n * Get an API key by ID (without sensitive data)\n */\n async get(id: string): Promise<ApiKeySummary> {\n return this.http.get<ApiKeySummary>(`/api-keys/${id}`);\n }\n\n /**\n * Update an API key\n */\n async update(id: string, params: UpdateApiKeyParams): Promise<ApiKeySummary> {\n return this.http.put<ApiKeySummary>(`/api-keys/${id}`, params);\n }\n\n /**\n * Revoke an API key\n */\n async revoke(id: string): Promise<void> {\n await this.http.delete(`/api-keys/${id}`);\n }\n}\n","/**\n * Organizations Resource\n *\n * Handles organization operations including webhook token management.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n Organization,\n OrganizationSummary,\n CreateOrganizationParams,\n CreateOrganizationResponse,\n UpdateOrganizationParams,\n OrganizationUsage,\n OrganizationMember,\n CheckSlugResponse,\n WebhookTokenResponse,\n} from '../types/organizations.js';\n\nexport class OrganizationsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Create a new organization (public endpoint, no auth required)\n */\n async create(params: CreateOrganizationParams): Promise<CreateOrganizationResponse> {\n return this.http.post<CreateOrganizationResponse>('/organizations', params);\n }\n\n /**\n * List organizations\n */\n async list(): Promise<OrganizationSummary[]> {\n return this.http.get<OrganizationSummary[]>('/organizations');\n }\n\n /**\n * Get an organization by ID\n */\n async get(id: string): Promise<Organization> {\n return this.http.get<Organization>(`/organizations/${id}`);\n }\n\n /**\n * Update an organization\n */\n async update(id: string, params: UpdateOrganizationParams): Promise<Organization> {\n return this.http.put<Organization>(`/organizations/${id}`, params);\n }\n\n /**\n * Delete an organization\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/organizations/${id}`);\n }\n\n /**\n * Get organization usage and limits\n */\n async getUsage(): Promise<OrganizationUsage> {\n return this.http.get<OrganizationUsage>('/organizations/usage');\n }\n\n /**\n * Get organization members\n */\n async getMembers(id: string): Promise<OrganizationMember[]> {\n return this.http.get<OrganizationMember[]>(`/organizations/${id}/members`);\n }\n\n /**\n * Check slug availability\n */\n async checkSlug(slug: string): Promise<CheckSlugResponse> {\n return this.http.get<CheckSlugResponse>('/organizations/check-slug', {\n params: { slug },\n });\n }\n\n /**\n * Generate a unique slug from an organization name\n */\n async generateSlug(name: string): Promise<{ slug: string }> {\n return this.http.post<{ slug: string }>('/organizations/generate-slug', { name });\n }\n\n /**\n * Get the webhook token for the current organization.\n *\n * This token is used to verify incoming webhook payloads from Spooled.\n * Use this token to validate webhook signatures.\n *\n * @example\n * ```typescript\n * const { token } = await client.organizations.getWebhookToken();\n * console.log('Webhook token:', token);\n * ```\n */\n async getWebhookToken(): Promise<WebhookTokenResponse> {\n return this.http.get<WebhookTokenResponse>('/organizations/webhook-token');\n }\n\n /**\n * Regenerate the webhook token for the current organization.\n *\n * This invalidates the old token immediately. All webhook signature\n * verification using the old token will fail after regeneration.\n *\n * @example\n * ```typescript\n * const { token: newToken } = await client.organizations.regenerateWebhookToken();\n * console.log('New webhook token:', newToken);\n * ```\n */\n async regenerateWebhookToken(): Promise<WebhookTokenResponse> {\n return this.http.post<WebhookTokenResponse>('/organizations/webhook-token/regenerate');\n }\n\n /**\n * Clear/delete the webhook token for the current organization.\n *\n * After this, webhook signature verification will fail until a new\n * token is generated via regenerateWebhookToken().\n *\n * @example\n * ```typescript\n * await client.organizations.clearWebhookToken();\n * ```\n */\n async clearWebhookToken(): Promise<void> {\n await this.http.post('/organizations/webhook-token/clear');\n }\n}\n","/**\n * Billing Resource\n *\n * Stripe billing integration endpoints.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type { BillingStatus, CreateBillingPortalParams, CreateBillingPortalResponse } from '../types/billing.js';\n\nexport class BillingResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get billing status for the authenticated organization.\n *\n * GET /api/v1/billing/status\n */\n async getStatus(): Promise<BillingStatus> {\n return this.http.get<BillingStatus>('/billing/status');\n }\n\n /**\n * Create a Stripe billing portal session.\n *\n * POST /api/v1/billing/portal\n */\n async createPortal(params: CreateBillingPortalParams): Promise<CreateBillingPortalResponse> {\n return this.http.post<CreateBillingPortalResponse>('/billing/portal', params);\n }\n}\n","/**\n * Dashboard Resource\n *\n * Provides aggregated dashboard data (used by the Spooled dashboard UI).\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type { DashboardData } from '../types/dashboard.js';\n\nexport class DashboardResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get dashboard data for the current organization.\n *\n * GET /api/v1/dashboard\n */\n async get(): Promise<DashboardData> {\n return this.http.get<DashboardData>('/dashboard');\n }\n}\n","/**\n * Health Resource\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type { HealthResponse } from '../types/health.js';\n\nexport class HealthResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Basic health check (public).\n *\n * GET /health\n */\n async get(): Promise<HealthResponse> {\n return this.http.get<HealthResponse>('/health', { skipApiPrefix: true });\n }\n\n /**\n * Kubernetes liveness probe (public).\n *\n * GET /health/live\n */\n async liveness(): Promise<boolean> {\n try {\n await this.http.request<string>('/health/live', {\n method: 'GET',\n skipApiPrefix: true,\n skipRetry: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Kubernetes readiness probe (public).\n *\n * GET /health/ready\n */\n async readiness(): Promise<boolean> {\n try {\n await this.http.request<string>('/health/ready', {\n method: 'GET',\n skipApiPrefix: true,\n skipRetry: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n}\n","/**\n * Metrics Resource\n */\n\nimport type { HttpClient } from '../utils/http.js';\n\nexport class MetricsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Prometheus metrics (public; may be protected by METRICS_TOKEN on the server).\n *\n * GET /metrics\n */\n async get(): Promise<string> {\n return this.http.get<string>('/metrics', {\n skipApiPrefix: true,\n // Ensure we get the raw text response.\n headers: { Accept: 'text/plain' },\n });\n }\n}\n","/**\n * Admin Resource\n *\n * Platform administration endpoints.\n * All endpoints require `X-Admin-Key` header.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n AdminListOrganizationsParams,\n AdminOrganizationList,\n AdminOrganizationDetail,\n AdminUpdateOrganizationParams,\n AdminCreateOrganizationParams,\n AdminCreateOrganizationResponse,\n AdminCreateApiKeyParams,\n AdminApiKeyResponse,\n AdminDeleteOrganizationParams,\n AdminPlatformStats,\n AdminPlanLimits,\n} from '../types/admin.js';\nimport type { Organization } from '../types/organizations.js';\nimport { AuthenticationError } from '../errors.js';\n\nexport class AdminResource {\n constructor(\n private readonly http: HttpClient,\n private readonly adminKey: string | undefined\n ) {}\n\n private headers(): Record<string, string> {\n if (!this.adminKey) {\n throw new AuthenticationError('Admin key is required for admin endpoints. Provide `adminKey` in SpooledClient config.');\n }\n return { 'X-Admin-Key': this.adminKey };\n }\n\n /** GET /api/v1/admin/organizations */\n async listOrganizations(params?: AdminListOrganizationsParams): Promise<AdminOrganizationList> {\n const qp: Record<string, string | number | boolean | undefined> | undefined = params\n ? {\n planTier: params.planTier,\n search: params.search,\n limit: params.limit,\n offset: params.offset,\n sortBy: params.sortBy,\n sortOrder: params.sortOrder,\n }\n : undefined;\n return this.http.get<AdminOrganizationList>('/admin/organizations', {\n params: qp,\n headers: this.headers(),\n });\n }\n\n /** POST /api/v1/admin/organizations */\n async createOrganization(params: AdminCreateOrganizationParams): Promise<AdminCreateOrganizationResponse> {\n return this.http.post<AdminCreateOrganizationResponse>('/admin/organizations', params, {\n headers: this.headers(),\n });\n }\n\n /** GET /api/v1/admin/organizations/{id} */\n async getOrganization(id: string): Promise<AdminOrganizationDetail> {\n return this.http.get<AdminOrganizationDetail>(`/admin/organizations/${id}`, {\n headers: this.headers(),\n });\n }\n\n /** PATCH /api/v1/admin/organizations/{id} */\n async updateOrganization(id: string, params: AdminUpdateOrganizationParams): Promise<Organization> {\n return this.http.patch<Organization>(`/admin/organizations/${id}`, params, {\n headers: this.headers(),\n });\n }\n\n /** DELETE /api/v1/admin/organizations/{id}?hard_delete=true */\n async deleteOrganization(id: string, params?: AdminDeleteOrganizationParams): Promise<void> {\n const qp: Record<string, string | number | boolean | undefined> | undefined = params\n ? { hardDelete: params.hardDelete }\n : undefined;\n await this.http.delete(`/admin/organizations/${id}`, {\n headers: this.headers(),\n params: qp,\n });\n }\n\n /** POST /api/v1/admin/organizations/{id}/api-keys */\n async createApiKey(orgId: string, params: AdminCreateApiKeyParams): Promise<AdminApiKeyResponse> {\n return this.http.post<AdminApiKeyResponse>(`/admin/organizations/${orgId}/api-keys`, params, {\n headers: this.headers(),\n });\n }\n\n /** POST /api/v1/admin/organizations/{id}/reset-usage */\n async resetUsage(orgId: string): Promise<void> {\n await this.http.post<void>(`/admin/organizations/${orgId}/reset-usage`, undefined, {\n headers: this.headers(),\n });\n }\n\n /** GET /api/v1/admin/stats */\n async getStats(): Promise<AdminPlatformStats> {\n return this.http.get<AdminPlatformStats>('/admin/stats', {\n headers: this.headers(),\n });\n }\n\n /** GET /api/v1/admin/plans */\n async listPlans(): Promise<AdminPlanLimits[]> {\n return this.http.get<AdminPlanLimits[]>('/admin/plans', {\n headers: this.headers(),\n });\n }\n}\n","/**\n * Webhook Ingestion Resource\n *\n * These endpoints are intended for webhook providers (GitHub/Stripe/custom) to enqueue jobs.\n * They are authenticated via signatures (not API keys).\n */\n\nimport { createHmac } from 'node:crypto';\nimport { Buffer } from 'node:buffer';\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n IngestCustomWebhookParams,\n IngestGitHubWebhookOptions,\n IngestStripeWebhookOptions,\n} from '../types/webhook-ingestion.js';\nimport { ValidationError } from '../errors.js';\n\nfunction toBytes(body: string | Uint8Array | ArrayBuffer): Uint8Array {\n if (typeof body === 'string') {\n return Buffer.from(body, 'utf8');\n }\n if (body instanceof Uint8Array) {\n return body;\n }\n return new Uint8Array(body);\n}\n\nfunction githubSignature(secret: string, body: Uint8Array): string {\n const hex = createHmac('sha256', secret).update(body).digest('hex');\n return `sha256=${hex}`;\n}\n\nfunction stripeSignature(secret: string, body: Uint8Array, timestamp: number): string {\n // Stripe signs: `${timestamp}.${rawBodyUtf8}`\n const payload = `${timestamp}.${Buffer.from(body).toString('utf8')}`;\n const hex = createHmac('sha256', secret).update(payload, 'utf8').digest('hex');\n return `t=${timestamp},v1=${hex}`;\n}\n\nexport class WebhookIngestionResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Ingest a GitHub webhook.\n *\n * POST /api/v1/webhooks/{org_id}/github\n */\n async github(orgId: string, body: string | Uint8Array | ArrayBuffer, options: IngestGitHubWebhookOptions): Promise<void> {\n const bytes = toBytes(body);\n\n const signature = options.signature ?? (options.secret ? githubSignature(options.secret, bytes) : undefined);\n if (!signature) {\n throw new ValidationError('GitHub webhook signature is required (provide `signature` or `secret`)');\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-GitHub-Event': options.githubEvent,\n 'X-Hub-Signature-256': signature,\n };\n\n if (options.webhookToken) {\n headers['X-Webhook-Token'] = options.webhookToken;\n }\n if (options.forwardedProto) {\n headers['X-Forwarded-Proto'] = options.forwardedProto;\n }\n\n await this.http.request<void>(`/webhooks/${orgId}/github`, {\n method: 'POST',\n rawBody: bytes,\n headers,\n skipRequestConversion: true,\n skipResponseConversion: true,\n });\n }\n\n /**\n * Ingest a Stripe webhook.\n *\n * POST /api/v1/webhooks/{org_id}/stripe\n */\n async stripe(orgId: string, body: string | Uint8Array | ArrayBuffer, options: IngestStripeWebhookOptions = {}): Promise<void> {\n const bytes = toBytes(body);\n const timestamp = options.timestamp ?? Math.floor(Date.now() / 1000);\n\n const signature = options.signature ?? (options.secret ? stripeSignature(options.secret, bytes, timestamp) : undefined);\n if (!signature) {\n throw new ValidationError('Stripe webhook signature is required (provide `signature` or `secret`)');\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Stripe-Signature': signature,\n };\n\n if (options.webhookToken) {\n headers['X-Webhook-Token'] = options.webhookToken;\n }\n if (options.forwardedProto) {\n headers['X-Forwarded-Proto'] = options.forwardedProto;\n }\n\n await this.http.request<void>(`/webhooks/${orgId}/stripe`, {\n method: 'POST',\n rawBody: bytes,\n headers,\n skipRequestConversion: true,\n skipResponseConversion: true,\n });\n }\n\n /**\n * Ingest a custom webhook.\n *\n * POST /api/v1/webhooks/{org_id}/custom\n */\n async custom(orgId: string, params: IngestCustomWebhookParams, opts?: { webhookToken?: string; forwardedProto?: string }): Promise<void> {\n const headers: Record<string, string> = {\n ...(opts?.webhookToken ? { 'X-Webhook-Token': opts.webhookToken } : {}),\n ...(opts?.forwardedProto ? { 'X-Forwarded-Proto': opts.forwardedProto } : {}),\n };\n\n await this.http.post<void>(`/webhooks/${orgId}/custom`, params, {\n headers,\n });\n }\n}\n","/**\n * Backend → SDK realtime event-name mapping.\n *\n * The backend's `RealtimeEvent` enum is serialized with\n * `#[serde(tag = \"type\", content = \"data\")]`, so events arrive on the wire as\n * `{ \"type\": \"<PascalCaseVariant>\", \"data\": { ...snake_case fields } }`, e.g.\n * `{ \"type\": \"JobCompleted\", \"data\": { \"job_id\": \"…\", \"duration_ms\": 12 } }`.\n *\n * The SDK's public event API, however, uses dotted names (`job.completed`,\n * `queue.stats`, …). Without translation, `rt.on('job.completed', …)` never\n * fires because the transport dispatches under the raw wire name\n * (`JobCompleted`). This map bridges the two: every variant of the backend enum\n * maps to its dotted SDK name.\n */\nexport const BACKEND_EVENT_TYPE_MAP: Record<string, string> = {\n JobStatusChange: 'job.status_changed',\n JobCreated: 'job.created',\n JobCompleted: 'job.completed',\n JobFailed: 'job.failed',\n QueueStats: 'queue.stats',\n WorkerHeartbeat: 'worker.heartbeat',\n WorkerRegistered: 'worker.registered',\n WorkerDeregistered: 'worker.deregistered',\n SystemHealth: 'system.health',\n Ping: 'ping',\n Error: 'error',\n};\n\n/**\n * Translate a wire event `type` to the SDK's dotted event name.\n *\n * Names that are already dotted (or otherwise unknown) pass through unchanged,\n * so this is safe to call on every inbound message and keeps working if the\n * backend ever starts sending pre-dotted names.\n */\nexport function mapEventType(type: string): string {\n return BACKEND_EVENT_TYPE_MAP[type] ?? type;\n}\n","/**\n * WebSocket Realtime Client\n *\n * Provides real-time event streaming over WebSocket.\n */\n\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n WebSocketCommand,\n} from './types.js';\nimport { convertResponse } from '../utils/casing.js';\nimport { mapEventType } from './event-map.js';\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * WebSocket Realtime Client\n *\n * Connects to the Spooled API WebSocket endpoint and emits typed events.\n */\nexport class WebSocketRealtimeClient {\n private readonly options: Required<RealtimeConnectionOptions>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private ws: any = null;\n private state: ConnectionState = 'disconnected';\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n /**\n * Set when the server rejected our token on the upgrade (e.g. HTTP 401/403).\n * The next (re)connect uses it to force the token provider to mint a fresh\n * JWT instead of replaying the rejected one (which would loop forever).\n */\n private authFailure = false;\n private subscriptions: Map<string, SubscriptionFilter> = new Map();\n\n // Event handlers\n private eventHandlers: Map<RealtimeEventType, Set<EventHandler>> = new Map();\n private allEventsHandlers: Set<GenericEventHandler> = new Set();\n private stateChangeHandlers: Set<(state: ConnectionState) => void> = new Set();\n\n constructor(options: RealtimeConnectionOptions) {\n // All defaults are applied AFTER the spread. SpooledRealtime forwards each of\n // these options as possibly-`undefined`, and a pre-spread default is clobbered\n // by an explicit `undefined` — e.g. autoReconnect would resolve to undefined\n // (falsy), silently disabling reconnect despite the documented default `true`,\n // and debug would become undefined and throw when connect() calls it.\n this.options = {\n ...options,\n autoReconnect: options.autoReconnect ?? true,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n // Always resolve to a provider so reconnects can mint a fresh JWT.\n // Falls back to the static token when no provider is supplied.\n tokenProvider: options.tokenProvider ?? (async () => options.token),\n debug: options.debug ?? (() => {}),\n };\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Get WebSocket implementation (browser native or Node.js ws package)\n */\n private async getWebSocketImpl(): Promise<typeof WebSocket> {\n if (typeof WebSocket !== 'undefined') {\n return WebSocket;\n }\n // Node.js environment - use ws package with dynamic import for ESM compatibility\n const wsModule = await import('ws');\n return wsModule.default as unknown as typeof WebSocket;\n }\n\n /**\n * Connect to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.state === 'connected' || this.state === 'connecting') {\n return;\n }\n\n this.setState('connecting');\n\n // Build WebSocket URL with a freshly-minted token\n let wsUrl: string;\n try {\n wsUrl = await this.buildWsUrl();\n } catch (error) {\n this.setState('disconnected');\n throw new Error(`Failed to acquire realtime token: ${error}`);\n }\n // Redact the token query param so JWTs never land in logs.\n this.options.debug(`Connecting to ${redactToken(wsUrl)}`);\n\n // Get WebSocket implementation (async for ESM compatibility in Node.js)\n let WebSocketImpl: typeof WebSocket;\n try {\n WebSocketImpl = await this.getWebSocketImpl();\n } catch (error) {\n this.setState('disconnected');\n throw new Error(`Failed to load WebSocket implementation: ${error}`);\n }\n\n return new Promise((resolve, reject) => {\n try {\n this.ws = new WebSocketImpl(wsUrl);\n\n this.ws.onopen = () => {\n this.options.debug('WebSocket connected');\n this.setState('connected');\n this.reconnectAttempts = 0;\n this.resubscribeAll();\n resolve();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onmessage = (event: any) => {\n this.handleMessage(typeof event.data === 'string' ? event.data : String(event.data));\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onclose = (event: any) => {\n this.options.debug(`WebSocket closed: ${event.code} ${event.reason}`);\n this.handleDisconnect();\n if (this.state === 'connecting') {\n reject(new Error(`WebSocket connection failed: ${event.reason || 'Unknown error'}`));\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onerror = (event: any) => {\n this.options.debug('WebSocket error', event);\n // The Node `ws` package surfaces a rejected upgrade here as an error\n // whose message is e.g. \"Unexpected server response: 401\". Flag it so\n // the next reconnect forces a fresh token rather than replaying the\n // rejected one. (Browsers don't expose the status; expiry-based\n // refresh still covers the common case there.)\n if (isAuthFailureEvent(event)) {\n this.authFailure = true;\n }\n };\n } catch (error) {\n this.setState('disconnected');\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.onclose = null; // Prevent reconnect\n this.ws.close(1000, 'Client disconnect');\n this.ws = null;\n }\n\n this.setState('disconnected');\n this.subscriptions.clear();\n }\n\n /**\n * Subscribe to events matching a filter.\n *\n * The server applies filtering itself and sends no acknowledgement, so this\n * resolves as soon as the command has been written to the socket. The filter\n * is tracked locally so it is replayed automatically on reconnect.\n */\n async subscribe(filter: SubscriptionFilter): Promise<void> {\n const filterId = this.filterToId(filter);\n\n if (this.subscriptions.has(filterId)) {\n return; // Already subscribed\n }\n\n this.subscriptions.set(filterId, filter);\n\n if (this.state === 'connected') {\n this.sendCommand('Subscribe', filter);\n }\n }\n\n /**\n * Unsubscribe from events matching a filter.\n *\n * Fire-and-forget, like {@link subscribe} — the server sends no ack.\n */\n async unsubscribe(filter: SubscriptionFilter): Promise<void> {\n const filterId = this.filterToId(filter);\n\n if (!this.subscriptions.has(filterId)) {\n return; // Not subscribed\n }\n\n this.subscriptions.delete(filterId);\n\n if (this.state === 'connected') {\n this.sendCommand('Unsubscribe', filter);\n }\n }\n\n /**\n * Add an event listener for a specific event type\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n if (!this.eventHandlers.has(type)) {\n this.eventHandlers.set(type, new Set());\n }\n this.eventHandlers.get(type)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n const handlers = this.eventHandlers.get(type);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n\n /**\n * Add a listener for all events\n */\n onEvent(handler: GenericEventHandler): () => void {\n this.allEventsHandlers.add(handler);\n return () => this.allEventsHandlers.delete(handler);\n }\n\n /**\n * Add a listener for state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => this.stateChangeHandlers.delete(handler);\n }\n\n // Private methods\n\n private async buildWsUrl(): Promise<string> {\n // wsUrl should already be ws:// or wss://\n const wsBase = this.options.wsUrl;\n // Reuse the provider's cached JWT unless the previous attempt was rejected\n // for auth (401/403 on the upgrade), in which case force a fresh token so a\n // stale/revoked one can't block recovery. Clear the flag either way.\n const forceRefresh = this.authFailure;\n this.authFailure = false;\n const token = await this.options.tokenProvider(forceRefresh);\n return `${wsBase}/api/v1/ws?token=${encodeURIComponent(token)}`;\n }\n\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.stateChangeHandlers.forEach((handler) => handler(state));\n }\n }\n\n private handleMessage(data: string): void {\n try {\n // Backend emits snake_case; convert to camelCase to match the typed\n // event shapes (jobId, queueName, durationMs, ...). User blobs like\n // `result`/`payload` are preserved via SKIP_CONVERSION_KEYS.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const message = convertResponse(JSON.parse(data)) as any;\n\n // The backend tags events with the PascalCase enum variant name\n // (`JobCompleted`, `QueueStats`, ...); the SDK's public API dispatches by\n // dotted name (`job.completed`, `queue.stats`). Translate before dispatch\n // so `on('job.completed', ...)` fires. Unknown/pre-dotted names pass\n // through unchanged.\n const eventType = mapEventType(String(message.type));\n message.type = eventType;\n const event = message as RealtimeEvent;\n this.options.debug(`Received event: ${eventType}`, event);\n\n // Emit to specific handlers\n const handlers = this.eventHandlers.get(eventType as RealtimeEventType);\n if (handlers) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventData = (event as any).data;\n handlers.forEach((handler) => {\n try {\n handler(eventData);\n } catch (error) {\n this.options.debug('Event handler error', error);\n }\n });\n }\n\n // Emit to all-events handlers\n this.allEventsHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n this.options.debug('Event handler error', error);\n }\n });\n } catch (error) {\n this.options.debug('Failed to parse message', { data, error });\n }\n }\n\n private handleDisconnect(): void {\n this.ws = null;\n\n if (this.options.autoReconnect && this.reconnectAttempts < this.options.maxReconnectAttempts) {\n this.scheduleReconnect();\n } else {\n this.setState('disconnected');\n }\n }\n\n private scheduleReconnect(): void {\n this.setState('reconnecting');\n this.reconnectAttempts++;\n\n const baseDelay = Math.min(\n this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n this.options.maxReconnectDelay\n );\n // Add randomized jitter (up to +25%) to avoid a thundering-herd reconnect\n // storm when many clients drop at the same moment. Matches utils/retry.ts.\n const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);\n\n this.options.debug(`Scheduling reconnect attempt ${this.reconnectAttempts} in ${delay}ms`);\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await this.connect();\n } catch (error) {\n this.options.debug('Reconnect failed', error);\n // handleDisconnect will schedule another attempt if needed\n }\n }, delay);\n }\n\n private resubscribeAll(): void {\n for (const filter of this.subscriptions.values()) {\n try {\n this.sendCommand('Subscribe', filter);\n } catch (error) {\n this.options.debug('Failed to resubscribe', { filter, error });\n }\n }\n }\n\n /**\n * Send a subscribe/unsubscribe command to the server.\n *\n * The backend `ClientCommand` shape is `{ cmd, queue, job_id }` and it sends\n * no acknowledgement, so this is fire-and-forget — it writes to the socket\n * and returns. The `SubscriptionFilter`'s `workerId`/`scheduleId` have no\n * server-side equivalent and are ignored.\n */\n private sendCommand(cmd: 'Subscribe' | 'Unsubscribe', filter: SubscriptionFilter): void {\n if (!this.ws || this.state !== 'connected') {\n throw new Error('WebSocket not connected');\n }\n\n const command: WebSocketCommand = {\n cmd,\n queue: filter.queueName,\n job_id: filter.jobId,\n };\n this.ws.send(JSON.stringify(command));\n }\n\n private filterToId(filter: SubscriptionFilter): string {\n return JSON.stringify(filter);\n }\n}\n\n/**\n * Redact sensitive auth query params (token/api_key) from a URL for logging.\n */\nexport function redactToken(url: string): string {\n return url.replace(/([?&](?:token|api_key)=)[^&]*/gi, '$1***');\n}\n\n/**\n * Detect whether a WebSocket error event represents an auth rejection on the\n * upgrade (HTTP 401/403). The Node `ws` package reports these as an error whose\n * message is like \"Unexpected server response: 401\"; different runtimes may put\n * the text on `message`, `error.message`, or `reason`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isAuthFailureEvent(event: any): boolean {\n if (!event) {\n return false;\n }\n const status = event.status ?? event.statusCode ?? event.error?.status;\n if (status === 401 || status === 403) {\n return true;\n }\n const text = String(event.message ?? event.error?.message ?? event.reason ?? '');\n return /\\b(401|403)\\b/.test(text);\n}\n","/**\n * SSE Realtime Client\n *\n * Provides real-time event streaming over Server-Sent Events.\n */\n\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n} from './types.js';\nimport { convertResponse } from '../utils/casing.js';\nimport { mapEventType } from './event-map.js';\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * SSE Realtime Client\n *\n * Connects to the Spooled API SSE endpoint and emits typed events.\n * SSE is unidirectional - subscriptions must be set at connection time.\n */\nexport class SseRealtimeClient {\n private readonly options: Required<RealtimeConnectionOptions>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private eventSource: any = null;\n private state: ConnectionState = 'disconnected';\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private filter: SubscriptionFilter | null = null;\n\n // Event handlers\n private eventHandlers: Map<RealtimeEventType, Set<EventHandler>> = new Map();\n private allEventsHandlers: Set<GenericEventHandler> = new Set();\n private stateChangeHandlers: Set<(state: ConnectionState) => void> = new Set();\n\n constructor(options: RealtimeConnectionOptions) {\n // Defaults applied AFTER the spread — a pre-spread default is clobbered by an\n // explicit `undefined` forwarded from SpooledRealtime (e.g. autoReconnect would\n // resolve to undefined/falsy, silently disabling reconnect despite the\n // documented default `true`).\n this.options = {\n ...options,\n autoReconnect: options.autoReconnect ?? true,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n // Always resolve to a provider so reconnects can mint a fresh token.\n // Falls back to the static token when no provider is supplied.\n tokenProvider: options.tokenProvider ?? (async () => options.token),\n // Coalesce debug to a no-op AFTER the spread. A caller that omits debug\n // still passes `debug: undefined` explicitly (e.g. via SpooledRealtime),\n // and spreading that would overwrite a pre-spread default with undefined,\n // making connect() call `this.options.debug(...)` on undefined and throw\n // \"this.options.debug is not a function\". Guarding here keeps it callable\n // regardless of what the caller passes.\n debug: options.debug ?? (() => {}),\n };\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Connect to the SSE server with a subscription filter\n */\n async connect(filter?: SubscriptionFilter): Promise<void> {\n if (this.state === 'connected' || this.state === 'connecting') {\n return;\n }\n\n this.filter = filter || null;\n\n this.setState('connecting');\n\n const sseUrl = this.buildSseUrl(filter);\n this.options.debug(`Connecting to SSE: ${sseUrl}`);\n\n // Use eventsource package in Node.js, native EventSource in browser\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let EventSourceImpl: any;\n if (typeof EventSource !== 'undefined') {\n EventSourceImpl = EventSource;\n } else {\n // Dynamic import for ESM compatibility\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = await import('eventsource') as any;\n EventSourceImpl = mod.default || mod.EventSource || mod;\n } catch {\n this.setState('disconnected');\n throw new Error('eventsource package is required for SSE in Node.js. Install it with: npm install eventsource');\n }\n }\n\n // Mint a fresh token on every (re)connect so a stale token never blocks recovery.\n let token: string;\n try {\n token = await this.options.tokenProvider();\n } catch (error) {\n this.setState('disconnected');\n throw new Error(`Failed to acquire realtime token: ${error}`);\n }\n\n return new Promise((resolve, reject) => {\n try {\n // Create EventSource with authorization header\n // Note: eventsource v4 changed API - headers are now passed via custom fetch\n this.eventSource = new EventSourceImpl(sseUrl, {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fetch: (input: any, init: any) =>\n fetch(input, {\n ...init,\n headers: {\n ...init?.headers,\n Authorization: `Bearer ${token}`,\n },\n }),\n });\n\n this.eventSource.onopen = () => {\n this.options.debug('SSE connected');\n this.setState('connected');\n this.reconnectAttempts = 0;\n resolve();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.eventSource.onmessage = (event: any) => {\n this.handleMessage(event.data);\n };\n\n this.eventSource.onerror = () => {\n this.options.debug('SSE error');\n\n if (this.state === 'connecting') {\n this.setState('disconnected');\n // Close the abandoned EventSource so it doesn't keep auto-reconnecting\n // in the background after we reject the initial connect promise.\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n reject(new Error('SSE connection failed'));\n return;\n }\n\n this.handleDisconnect();\n };\n } catch (error) {\n this.setState('disconnected');\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the SSE server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n\n this.setState('disconnected');\n this.filter = null;\n }\n\n /**\n * Reconnect with a new filter (SSE requires reconnection to change subscriptions)\n */\n async reconnect(filter?: SubscriptionFilter): Promise<void> {\n this.disconnect();\n await this.connect(filter);\n }\n\n /**\n * Add an event listener for a specific event type\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n if (!this.eventHandlers.has(type)) {\n this.eventHandlers.set(type, new Set());\n }\n this.eventHandlers.get(type)!.add(handler);\n\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n const handlers = this.eventHandlers.get(type);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n\n /**\n * Add a listener for all events\n */\n onEvent(handler: GenericEventHandler): () => void {\n this.allEventsHandlers.add(handler);\n return () => this.allEventsHandlers.delete(handler);\n }\n\n /**\n * Add a listener for state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => this.stateChangeHandlers.delete(handler);\n }\n\n // Private methods\n\n private buildSseUrl(filter?: SubscriptionFilter): string {\n // Backend SSE endpoints:\n // - GET /api/v1/events (all events)\n // - GET /api/v1/events/jobs/{id} (single job polling stream)\n // - GET /api/v1/events/queues/{name} (queue stats polling stream)\n //\n // Note: SSE in the backend is unidirectional and subscriptions are effectively set by endpoint.\n if (filter?.jobId) {\n return `${this.options.baseUrl}/api/v1/events/jobs/${encodeURIComponent(filter.jobId)}`;\n }\n if (filter?.queueName) {\n return `${this.options.baseUrl}/api/v1/events/queues/${encodeURIComponent(filter.queueName)}`;\n }\n return `${this.options.baseUrl}/api/v1/events`;\n }\n\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.stateChangeHandlers.forEach((handler) => handler(state));\n }\n }\n\n private handleMessage(data: string): void {\n try {\n // Backend emits snake_case; convert to camelCase to match the typed\n // event shapes. User blobs (`result`/`payload`) are preserved via\n // SKIP_CONVERSION_KEYS.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const parsed = convertResponse(JSON.parse(data)) as any;\n // Translate the backend's PascalCase variant name (`JobCompleted`) to the\n // SDK's dotted event name (`job.completed`) before dispatch, matching the\n // WebSocket client. Unknown/pre-dotted names pass through unchanged.\n const eventType = mapEventType(String(parsed.type));\n parsed.type = eventType;\n const event = parsed as RealtimeEvent;\n this.options.debug(`Received SSE event: ${eventType}`, event);\n\n // Emit to specific handlers\n const handlers = this.eventHandlers.get(eventType as RealtimeEventType);\n if (handlers) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventData = (event as any).data;\n handlers.forEach((handler) => {\n try {\n handler(eventData);\n } catch (error) {\n this.options.debug('Event handler error', error);\n }\n });\n }\n\n // Emit to all-events handlers\n this.allEventsHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n this.options.debug('Event handler error', error);\n }\n });\n } catch (error) {\n this.options.debug('Failed to parse SSE message', { data, error });\n }\n }\n\n private handleDisconnect(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n\n if (this.options.autoReconnect && this.reconnectAttempts < this.options.maxReconnectAttempts) {\n this.scheduleReconnect();\n } else {\n this.setState('disconnected');\n }\n }\n\n private scheduleReconnect(): void {\n this.setState('reconnecting');\n this.reconnectAttempts++;\n\n const baseDelay = Math.min(\n this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n this.options.maxReconnectDelay\n );\n // Add randomized jitter (up to +25%) to avoid synchronized reconnect\n // storms across clients. Matches utils/retry.ts.\n const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);\n\n this.options.debug(`Scheduling SSE reconnect attempt ${this.reconnectAttempts} in ${delay}ms`);\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await this.connect(this.filter || undefined);\n } catch (error) {\n this.options.debug('SSE reconnect failed', error);\n }\n }, delay);\n }\n}\n","/**\n * Realtime Module\n *\n * Provides WebSocket and SSE clients for real-time event streaming.\n */\n\nexport * from './types.js';\nexport { WebSocketRealtimeClient } from './websocket.js';\nexport { SseRealtimeClient } from './sse.js';\n\nimport { WebSocketRealtimeClient } from './websocket.js';\nimport { SseRealtimeClient } from './sse.js';\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n} from './types.js';\n\n/** Options for creating a SpooledRealtime instance */\nexport interface SpooledRealtimeOptions {\n /**\n * Connection type: 'websocket' or 'sse' (default: 'websocket').\n *\n * Default is WebSocket because it’s typically the lowest server load:\n * - WebSocket uses push/pubsub in the backend\n * - SSE job/queue endpoints poll the database periodically\n */\n type?: 'websocket' | 'sse';\n /** Auto-reconnect on disconnect (default: true) */\n autoReconnect?: boolean;\n /** Maximum reconnect attempts (default: 10) */\n maxReconnectAttempts?: number;\n /** Initial reconnect delay in ms (default: 1000) */\n reconnectDelay?: number;\n /** Maximum reconnect delay in ms (default: 30000) */\n maxReconnectDelay?: number;\n}\n\n/** Full options including internal fields */\ninterface FullRealtimeOptions extends SpooledRealtimeOptions {\n baseUrl: string;\n wsUrl: string;\n token: string;\n /** Async provider that supplies a valid JWT for each (re)connect */\n tokenProvider?: (forceRefresh?: boolean) => Promise<string>;\n debug?: (message: string, meta?: unknown) => void;\n}\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * Unified Realtime Client\n *\n * Wraps WebSocket and SSE clients with a common interface.\n */\nexport class SpooledRealtime {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly client: any;\n\n constructor(options: FullRealtimeOptions) {\n const connectionOptions: RealtimeConnectionOptions = {\n baseUrl: options.baseUrl,\n wsUrl: options.wsUrl,\n token: options.token,\n tokenProvider: options.tokenProvider,\n autoReconnect: options.autoReconnect,\n maxReconnectAttempts: options.maxReconnectAttempts,\n reconnectDelay: options.reconnectDelay,\n maxReconnectDelay: options.maxReconnectDelay,\n debug: options.debug,\n };\n\n if (options.type === 'sse') {\n this.client = new SseRealtimeClient(connectionOptions);\n } else {\n this.client = new WebSocketRealtimeClient(connectionOptions);\n }\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.client.getState();\n }\n\n /**\n * Connect to the realtime server\n */\n async connect(): Promise<void> {\n return this.client.connect();\n }\n\n /**\n * Disconnect from the realtime server\n */\n disconnect(): void {\n this.client.disconnect();\n }\n\n /**\n * Subscribe to events matching a filter\n *\n * @example\n * ```typescript\n * // Subscribe to all events from a queue\n * await realtime.subscribe({ queueName: 'my-queue' });\n *\n * // Subscribe to events for a specific job\n * await realtime.subscribe({ jobId: 'job-123' });\n * ```\n */\n async subscribe(filter: SubscriptionFilter): Promise<void> {\n // SSE subscriptions are effectively endpoint-based; change requires reconnect.\n if (typeof this.client.subscribe === 'function') {\n return this.client.subscribe(filter);\n }\n return this.client.reconnect(filter);\n }\n\n /**\n * Unsubscribe from events matching a filter\n */\n async unsubscribe(filter: SubscriptionFilter): Promise<void> {\n if (typeof this.client.unsubscribe === 'function') {\n return this.client.unsubscribe(filter);\n }\n // For SSE, unsubscribing means disconnecting if the filter matches current connection.\n this.client.disconnect();\n }\n\n /**\n * Add an event listener for a specific event type\n *\n * @example\n * ```typescript\n * realtime.on('job.completed', (data) => {\n * console.log('Job completed:', data.jobId);\n * });\n *\n * realtime.on('job.failed', (data) => {\n * console.error('Job failed:', data.error);\n * });\n * ```\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n return this.client.on(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n this.client.off(type, handler);\n }\n\n /**\n * Add a listener for all events\n *\n * @example\n * ```typescript\n * realtime.onEvent((event) => {\n * console.log(`Event: ${event.type}`, event.data);\n * });\n * ```\n */\n onEvent(handler: GenericEventHandler): () => void {\n return this.client.onEvent(handler);\n }\n\n /**\n * Add a listener for connection state changes\n *\n * @example\n * ```typescript\n * realtime.onStateChange((state) => {\n * console.log('Connection state:', state);\n * });\n * ```\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n return this.client.onStateChange(handler);\n }\n}\n","/**\n * Proto Loader Utility\n *\n * Dynamically loads the Spooled proto file for gRPC communication.\n */\n\n/* global __dirname */\n\nimport * as grpc from '@grpc/grpc-js';\nimport * as protoLoader from '@grpc/proto-loader';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport type { ServiceClientConstructor } from '@grpc/grpc-js';\n\n/** Proto loader options for consistent parsing */\nexport const PROTO_LOADER_OPTIONS: protoLoader.Options = {\n keepCase: false, // Convert snake_case to camelCase\n longs: String, // Represent int64 as strings\n enums: String, // Represent enums as strings\n defaults: true, // Include default values\n oneofs: true, // Support oneofs\n};\n\nexport interface SpooledProtoDefinition {\n spooled: {\n v1: {\n QueueService: ServiceClientConstructor;\n WorkerService: ServiceClientConstructor;\n };\n };\n}\n\nlet cachedDefinition: SpooledProtoDefinition | null = null;\n\n/**\n * Get the path to the proto file.\n * Supports both ESM and CJS environments.\n */\nfunction getProtoPath(): string {\n // In ESM, use import.meta.url\n if (typeof import.meta?.url !== 'undefined') {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n return join(__dirname, '../../proto/spooled.proto');\n }\n\n // Fallback for CJS (when bundled)\n return join(__dirname, '../../proto/spooled.proto');\n}\n\n/**\n * Load the Spooled proto definition synchronously.\n * Caches the result for subsequent calls.\n */\nexport function loadProtoDefinition(): SpooledProtoDefinition {\n if (cachedDefinition) {\n return cachedDefinition;\n }\n\n const protoPath = getProtoPath();\n\n const packageDefinition = protoLoader.loadSync(protoPath, PROTO_LOADER_OPTIONS);\n const grpcObject = grpc.loadPackageDefinition(packageDefinition);\n\n cachedDefinition = grpcObject as unknown as SpooledProtoDefinition;\n return cachedDefinition;\n}\n\n/**\n * Load the Spooled proto definition asynchronously.\n */\nexport async function loadProtoDefinitionAsync(): Promise<SpooledProtoDefinition> {\n if (cachedDefinition) {\n return cachedDefinition;\n }\n\n const protoPath = getProtoPath();\n\n const packageDefinition = await protoLoader.load(protoPath, PROTO_LOADER_OPTIONS);\n const grpcObject = grpc.loadPackageDefinition(packageDefinition);\n\n cachedDefinition = grpcObject as unknown as SpooledProtoDefinition;\n return cachedDefinition;\n}\n\n/**\n * Clear the cached proto definition (mainly for testing).\n */\nexport function clearProtoCache(): void {\n cachedDefinition = null;\n}\n","/**\n * gRPC Streaming Helpers\n *\n * Utilities for working with gRPC streaming in a TypeScript-friendly way.\n */\n\nimport type * as grpc from '@grpc/grpc-js';\nimport type { GrpcJob, GrpcProcessRequest, GrpcProcessResponse } from './types.js';\n\n/**\n * Options for streaming operations\n */\nexport interface StreamOptions {\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Called when connection is established */\n onConnected?: () => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n /** Called when the stream ends */\n onEnd?: () => void;\n}\n\n/**\n * Async iterable wrapper for gRPC readable streams (server streaming).\n */\nexport async function* asyncIterableFromStream<T>(\n stream: grpc.ClientReadableStream<T>,\n options?: StreamOptions\n): AsyncGenerator<T, void, undefined> {\n const { signal, onConnected, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener('abort', () => {\n stream.cancel();\n });\n }\n\n return yield* new AsyncIterableStream(stream, { onConnected, onError, onEnd });\n}\n\n/**\n * AsyncIterable wrapper for grpc.ClientReadableStream\n */\nclass AsyncIterableStream<T> implements AsyncIterable<T> {\n private stream: grpc.ClientReadableStream<T>;\n private options: Omit<StreamOptions, 'signal'>;\n\n constructor(\n stream: grpc.ClientReadableStream<T>,\n options: Omit<StreamOptions, 'signal'> = {}\n ) {\n this.stream = stream;\n this.options = options;\n }\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T, void, undefined> {\n const { onConnected, onError, onEnd } = this.options;\n const queue: T[] = [];\n let error: Error | null = null;\n let ended = false;\n let resolve: (() => void) | null = null;\n\n this.stream.on('data', (data: T) => {\n queue.push(data);\n resolve?.();\n });\n\n this.stream.on('error', (err: Error) => {\n error = err;\n onError?.(err);\n resolve?.();\n });\n\n this.stream.on('end', () => {\n ended = true;\n onEnd?.();\n resolve?.();\n });\n\n this.stream.on('status', (status: grpc.StatusObject) => {\n if (status.code === 0) {\n onConnected?.();\n }\n });\n\n while (true) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n\n if (error) {\n throw error;\n }\n\n if (ended) {\n return;\n }\n\n // Wait for next event\n await new Promise<void>((r) => {\n resolve = r;\n });\n }\n }\n}\n\n/**\n * Bidirectional stream wrapper for ProcessJobs\n */\nexport interface ProcessJobsStream {\n /** Send a request to the server */\n send(request: GrpcProcessRequest): void;\n /** Get async iterable for receiving responses */\n receive(): AsyncIterable<GrpcProcessResponse>;\n /** Signal that no more requests will be sent */\n end(): void;\n /** Cancel the stream */\n cancel(): void;\n}\n\n/**\n * Create a ProcessJobsStream from a gRPC duplex stream\n */\nexport function createProcessJobsStream(\n call: grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>,\n options?: StreamOptions\n): ProcessJobsStream {\n const { signal, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener('abort', () => {\n call.cancel();\n });\n }\n\n return {\n send(request: GrpcProcessRequest): void {\n call.write(request);\n },\n\n receive(): AsyncIterable<GrpcProcessResponse> {\n return new AsyncIterableStream(call, { onError, onEnd });\n },\n\n end(): void {\n call.end();\n },\n\n cancel(): void {\n call.cancel();\n },\n };\n}\n\n/**\n * Job stream for server-side streaming (StreamJobs)\n */\nexport interface JobStream extends AsyncIterable<GrpcJob> {\n /** Cancel the stream */\n cancel(): void;\n}\n\n/**\n * Create a JobStream from a gRPC server stream\n */\nexport function createJobStream(\n call: grpc.ClientReadableStream<GrpcJob>,\n options?: StreamOptions\n): JobStream {\n const { signal, onConnected, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener('abort', () => {\n call.cancel();\n });\n }\n\n const iterable = new AsyncIterableStream<GrpcJob>(call, {\n onConnected,\n onError,\n onEnd,\n });\n\n return {\n [Symbol.asyncIterator]() {\n return iterable[Symbol.asyncIterator]();\n },\n cancel() {\n call.cancel();\n },\n };\n}\n","/**\n * gRPC Client\n *\n * Real gRPC client using @grpc/grpc-js for HTTP/2 + Protobuf communication.\n * Supports unary calls, server streaming, and bidirectional streaming.\n */\n\nimport * as grpc from '@grpc/grpc-js';\nimport { loadProtoDefinition } from './loader.js';\nimport {\n createJobStream,\n createProcessJobsStream,\n type JobStream,\n type ProcessJobsStream,\n type StreamOptions,\n} from './streaming.js';\nimport type {\n GrpcClientOptions,\n GrpcEnqueueRequest,\n GrpcEnqueueResponse,\n GrpcDequeueRequest,\n GrpcDequeueResponse,\n GrpcCompleteRequest,\n GrpcCompleteResponse,\n GrpcFailRequest,\n GrpcFailResponse,\n GrpcRenewLeaseRequest,\n GrpcRenewLeaseResponse,\n GrpcGetJobRequest,\n GrpcGetJobResponse,\n GrpcGetQueueStatsRequest,\n GrpcGetQueueStatsResponse,\n GrpcStreamJobsRequest,\n GrpcRegisterWorkerRequest,\n GrpcRegisterWorkerResponse,\n GrpcHeartbeatRequest,\n GrpcHeartbeatResponse,\n GrpcDeregisterRequest,\n GrpcDeregisterResponse,\n GrpcProcessRequest,\n GrpcProcessResponse,\n GrpcJob,\n} from './types.js';\n\n// Type definitions for dynamic gRPC clients\ntype UnaryCallback<T> = (error: grpc.ServiceError | null, response: T) => void;\n\ninterface QueueServiceClient extends grpc.Client {\n Enqueue(request: GrpcEnqueueRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcEnqueueResponse>): void;\n Dequeue(request: GrpcDequeueRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcDequeueResponse>): void;\n Complete(request: GrpcCompleteRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcCompleteResponse>): void;\n Fail(request: GrpcFailRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcFailResponse>): void;\n RenewLease(request: GrpcRenewLeaseRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcRenewLeaseResponse>): void;\n GetJob(request: GrpcGetJobRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcGetJobResponse>): void;\n GetQueueStats(request: GrpcGetQueueStatsRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcGetQueueStatsResponse>): void;\n StreamJobs(request: GrpcStreamJobsRequest, metadata: grpc.Metadata): grpc.ClientReadableStream<GrpcJob>;\n ProcessJobs(metadata: grpc.Metadata): grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>;\n}\n\ninterface WorkerServiceClient extends grpc.Client {\n Register(request: GrpcRegisterWorkerRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcRegisterWorkerResponse>): void;\n Heartbeat(request: GrpcHeartbeatRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcHeartbeatResponse>): void;\n Deregister(request: GrpcDeregisterRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcDeregisterResponse>): void;\n}\n\n/**\n * Wrap a callback-based gRPC call in a Promise\n */\nfunction promisify<TReq, TRes>(\n client: grpc.Client,\n method: (request: TReq, metadata: grpc.Metadata, callback: UnaryCallback<TRes>) => void,\n request: TReq,\n metadata: grpc.Metadata\n): Promise<TRes> {\n return new Promise((resolve, reject) => {\n method.call(client, request, metadata, (error, response) => {\n if (error) {\n reject(error);\n } else {\n resolve(response);\n }\n });\n });\n}\n\n/**\n * Determine if TLS should be used based on address\n */\nfunction shouldUseTls(address: string, explicitTls?: boolean): boolean {\n if (explicitTls !== undefined) {\n return explicitTls;\n }\n // Default to insecure for localhost/127.0.0.1\n const host = address.split(':')[0].toLowerCase();\n return host !== 'localhost' && host !== '127.0.0.1' && !host.startsWith('[::1]');\n}\n\n/**\n * Queue operations for the gRPC client\n */\nexport class GrpcQueueOperations {\n constructor(\n private readonly client: QueueServiceClient,\n private readonly metadata: grpc.Metadata\n ) {}\n\n /**\n * Enqueue a new job\n */\n async enqueue(params: GrpcEnqueueRequest): Promise<GrpcEnqueueResponse> {\n return promisify(this.client, this.client.Enqueue, params, this.metadata);\n }\n\n /**\n * Dequeue a job (for workers)\n */\n async dequeue(params: GrpcDequeueRequest): Promise<GrpcDequeueResponse> {\n return promisify(this.client, this.client.Dequeue, params, this.metadata);\n }\n\n /**\n * Complete a job successfully\n */\n async complete(params: GrpcCompleteRequest): Promise<GrpcCompleteResponse> {\n return promisify(this.client, this.client.Complete, params, this.metadata);\n }\n\n /**\n * Fail a job\n */\n async fail(params: GrpcFailRequest): Promise<GrpcFailResponse> {\n return promisify(this.client, this.client.Fail, params, this.metadata);\n}\n\n /**\n * Renew a job's lease\n */\n async renewLease(params: GrpcRenewLeaseRequest): Promise<GrpcRenewLeaseResponse> {\n return promisify(this.client, this.client.RenewLease, params, this.metadata);\n }\n\n /**\n * Get a job by ID\n */\n async getJob(jobId: string): Promise<GrpcGetJobResponse> {\n return promisify(this.client, this.client.GetJob, { jobId }, this.metadata);\n }\n\n /**\n * Get queue statistics\n */\n async getQueueStats(queueName: string): Promise<GrpcGetQueueStatsResponse> {\n return promisify(this.client, this.client.GetQueueStats, { queueName }, this.metadata);\n }\n\n /**\n * Stream jobs from a queue (server-side streaming)\n *\n * @example\n * ```typescript\n * const stream = client.grpc.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * });\n *\n * for await (const job of stream) {\n * console.log('Received job:', job.id);\n * }\n * ```\n */\n streamJobs(params: GrpcStreamJobsRequest, options?: StreamOptions): JobStream {\n const call = this.client.StreamJobs(params, this.metadata);\n return createJobStream(call, options);\n }\n\n /**\n * Open a bidirectional stream for processing jobs\n *\n * @example\n * ```typescript\n * const stream = client.grpc.queue.processJobs();\n *\n * // Request jobs\n * stream.send({ dequeue: { queueName: 'my-queue', workerId: 'worker-1' } });\n *\n * // Process responses\n * for await (const response of stream.receive()) {\n * if (response.job) {\n * // Process the job\n * stream.send({ complete: { jobId: response.job.id, workerId: 'worker-1' } });\n * }\n * }\n *\n * stream.end();\n * ```\n */\n processJobs(options?: StreamOptions): ProcessJobsStream {\n const call = this.client.ProcessJobs(this.metadata);\n return createProcessJobsStream(call, options);\n }\n}\n\n/**\n * Worker operations for the gRPC client\n */\nexport class GrpcWorkerOperations {\n constructor(\n private readonly client: WorkerServiceClient,\n private readonly metadata: grpc.Metadata\n ) {}\n\n /**\n * Register a new worker\n */\n async register(params: GrpcRegisterWorkerRequest): Promise<GrpcRegisterWorkerResponse> {\n return promisify(this.client, this.client.Register, params, this.metadata);\n }\n\n /**\n * Send heartbeat\n */\n async heartbeat(params: GrpcHeartbeatRequest): Promise<GrpcHeartbeatResponse> {\n return promisify(this.client, this.client.Heartbeat, params, this.metadata);\n }\n\n /**\n * Deregister a worker\n */\n async deregister(workerId: string): Promise<GrpcDeregisterResponse> {\n return promisify(this.client, this.client.Deregister, { workerId }, this.metadata);\n }\n}\n\n/**\n * Spooled gRPC Client\n *\n * Real gRPC client for high-performance job queue operations.\n *\n * @example\n * ```typescript\n * const client = new SpooledGrpcClient({\n * address: 'grpc.spooled.cloud:443',\n * apiKey: 'sk_live_...',\n * });\n *\n * // Enqueue a job\n * const { jobId } = await client.queue.enqueue({\n * queueName: 'my-queue',\n * payload: { message: 'Hello!' },\n * });\n *\n * // Stream jobs\n * for await (const job of client.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * })) {\n * console.log('Job:', job);\n * }\n * ```\n */\nexport class SpooledGrpcClient {\n private readonly queueClient: QueueServiceClient;\n private readonly workerClient: WorkerServiceClient;\n private readonly metadata: grpc.Metadata;\n\n /** Queue operations */\n readonly queue: GrpcQueueOperations;\n\n /** Worker operations */\n readonly workers: GrpcWorkerOperations;\n\n constructor(options: GrpcClientOptions) {\n const { address, apiKey, useTls, credentials, channelOptions } = options;\n\n // Create credentials\n const creds = credentials ?? (shouldUseTls(address, useTls)\n ? grpc.credentials.createSsl()\n : grpc.credentials.createInsecure());\n\n // Create metadata with API key\n this.metadata = new grpc.Metadata();\n this.metadata.add('x-api-key', apiKey);\n\n // Load proto definition\n const proto = loadProtoDefinition();\n\n // Create service clients\n this.queueClient = new proto.spooled.v1.QueueService(\n address,\n creds,\n channelOptions\n ) as unknown as QueueServiceClient;\n\n this.workerClient = new proto.spooled.v1.WorkerService(\n address,\n creds,\n channelOptions\n ) as unknown as WorkerServiceClient;\n\n // Initialize operation namespaces\n this.queue = new GrpcQueueOperations(this.queueClient, this.metadata);\n this.workers = new GrpcWorkerOperations(this.workerClient, this.metadata);\n }\n\n /**\n * Close all gRPC connections\n */\n close(): void {\n this.queueClient.close();\n this.workerClient.close();\n }\n\n /**\n * Wait for the clients to be ready\n */\n async waitForReady(deadline?: Date): Promise<void> {\n const d = deadline ?? new Date(Date.now() + 10000);\n await Promise.all([\n new Promise<void>((resolve, reject) => {\n this.queueClient.waitForReady(d, (error) => {\n if (error) reject(error);\n else resolve();\n });\n }),\n new Promise<void>((resolve, reject) => {\n this.workerClient.waitForReady(d, (error) => {\n if (error) reject(error);\n else resolve();\n });\n }),\n ]);\n }\n\n /**\n * Get the current connection state\n */\n getState(tryToConnect?: boolean): grpc.connectivityState {\n return this.queueClient.getChannel().getConnectivityState(tryToConnect ?? false);\n }\n}\n","/**\n * Spooled Client\n *\n * Main entry point for the Spooled SDK.\n */\n\nimport {\n type SpooledClientConfig,\n type ResolvedConfig,\n resolveConfig,\n validateConfig,\n} from './config.js';\nimport { AuthenticationError } from './errors.js';\nimport { HttpClient, createHttpClient } from './utils/http.js';\nimport { CircuitBreaker, createCircuitBreaker } from './utils/circuit-breaker.js';\nimport {\n AuthResource,\n JobsResource,\n QueuesResource,\n WorkersResource,\n SchedulesResource,\n WorkflowsResource,\n WebhooksResource,\n ApiKeysResource,\n OrganizationsResource,\n BillingResource,\n DashboardResource,\n HealthResource,\n MetricsResource,\n AdminResource,\n WebhookIngestionResource,\n} from './resources/index.js';\nimport { SpooledRealtime } from './realtime/index.js';\nimport type { SpooledRealtimeOptions } from './realtime/index.js';\nimport { SpooledGrpcClient } from './grpc/client.js';\n\n/**\n * Spooled Cloud SDK Client\n *\n * @example\n * ```typescript\n * const client = new SpooledClient({\n * apiKey: 'sk_live_...'\n * });\n *\n * // Create a job\n * const result = await client.jobs.create({\n * queueName: 'my-queue',\n * payload: { message: 'Hello, World!' }\n * });\n *\n * // List queues\n * const queues = await client.queues.list();\n * ```\n */\nexport class SpooledClient {\n private readonly config: ResolvedConfig;\n private readonly http: HttpClient;\n private readonly circuitBreaker: CircuitBreaker;\n private _grpc: SpooledGrpcClient | null = null;\n\n /** Authentication operations */\n readonly auth: AuthResource;\n\n /** Job operations */\n readonly jobs: JobsResource;\n\n /** Queue operations */\n readonly queues: QueuesResource;\n\n /** Worker operations */\n readonly workers: WorkersResource;\n\n /** Schedule operations */\n readonly schedules: SchedulesResource;\n\n /** Workflow operations */\n readonly workflows: WorkflowsResource;\n\n /** Outgoing webhook operations */\n readonly webhooks: WebhooksResource;\n\n /** API key operations */\n readonly apiKeys: ApiKeysResource;\n\n /** Organization operations */\n readonly organizations: OrganizationsResource;\n\n /** Billing operations */\n readonly billing: BillingResource;\n\n /** Dashboard operations */\n readonly dashboard: DashboardResource;\n\n /** Health endpoints (public) */\n readonly health: HealthResource;\n\n /** Metrics endpoint (public) */\n readonly metrics: MetricsResource;\n\n /** Admin endpoints (requires adminKey) */\n readonly admin: AdminResource;\n\n /** Webhook ingestion endpoints (signature-based) */\n readonly ingest: WebhookIngestionResource;\n\n /** Token refresh state */\n private refreshPromise: Promise<string> | null = null;\n private tokenExpiresAt: number | null = null;\n\n /**\n * Cached JWT for realtime connections (API-key auth path).\n *\n * The realtime layer requests a token on every (re)connect. Minting a brand\n * new JWT via POST /auth/login each time trips the login rate limit (429)\n * under a reconnect storm, after which realtime can never recover. We cache\n * the token here — at the client level, shared across reconnects — and reuse\n * it until it nears expiry.\n */\n private cachedJwt: string | null = null;\n /** Deduplicates concurrent logins (e.g. WS + SSE reconnecting together). */\n private jwtLoginPromise: Promise<string> | null = null;\n\n constructor(options: SpooledClientConfig) {\n // Resolve and validate configuration\n this.config = resolveConfig(options);\n validateConfig(this.config);\n\n // Create circuit breaker\n this.circuitBreaker = createCircuitBreaker(this.config.circuitBreaker);\n\n // Create HTTP client\n this.http = createHttpClient(this.config, this.circuitBreaker);\n\n // Set up token refresh if using JWT\n if (this.config.accessToken && this.config.refreshToken && this.config.autoRefreshToken) {\n this.http.setRefreshTokenFn(this.refreshAccessToken.bind(this));\n }\n\n // Create resource instances\n this.auth = new AuthResource(this.http, () => this.config.refreshToken);\n this.jobs = new JobsResource(this.http);\n this.queues = new QueuesResource(this.http);\n this.workers = new WorkersResource(this.http);\n this.schedules = new SchedulesResource(this.http);\n this.workflows = new WorkflowsResource(this.http);\n this.webhooks = new WebhooksResource(this.http);\n this.apiKeys = new ApiKeysResource(this.http);\n this.organizations = new OrganizationsResource(this.http);\n this.billing = new BillingResource(this.http);\n this.dashboard = new DashboardResource(this.http);\n this.health = new HealthResource(this.http);\n this.metrics = new MetricsResource(this.http);\n this.admin = new AdminResource(this.http, this.config.adminKey);\n this.ingest = new WebhookIngestionResource(this.http);\n\n this.config.debug?.('SpooledClient initialized', {\n baseUrl: this.config.baseUrl,\n hasApiKey: !!this.config.apiKey,\n hasAccessToken: !!this.config.accessToken,\n });\n }\n\n /**\n * Real gRPC client for high-performance operations (HTTP/2 + Protobuf)\n *\n * The gRPC client is created lazily on first access to avoid\n * loading the proto file unless it's actually needed.\n *\n * @example\n * ```typescript\n * // Enqueue via gRPC\n * const { jobId } = await client.grpc.queue.enqueue({\n * queueName: 'my-queue',\n * payload: { message: 'Hello!' },\n * });\n *\n * // Stream jobs\n * for await (const job of client.grpc.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * })) {\n * console.log('Job:', job);\n * }\n * ```\n */\n get grpc(): SpooledGrpcClient {\n if (!this._grpc) {\n const grpcAddress = this.resolveGrpcAddress();\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new AuthenticationError('gRPC client requires an API key');\n }\n\n this._grpc = new SpooledGrpcClient({\n address: grpcAddress,\n apiKey,\n });\n }\n return this._grpc;\n }\n\n /**\n * Create a realtime connection for WebSocket or SSE events\n *\n * @example\n * ```typescript\n * const realtime = await client.realtime();\n *\n * realtime.on('job.created', (event) => {\n * console.log('New job:', event.jobId);\n * });\n *\n * await realtime.connect();\n * await realtime.subscribe({ queueName: 'my-queue' });\n * ```\n */\n async realtime(options?: SpooledRealtimeOptions): Promise<SpooledRealtime> {\n // Get an initial JWT (fails fast on auth errors at call time).\n const token = await this.getJwtToken();\n\n return new SpooledRealtime({\n baseUrl: this.config.baseUrl,\n wsUrl: this.config.wsUrl,\n token,\n // Provider the realtime layer calls on every (re)connect. It returns a\n // cached JWT and only re-logs-in when the token is absent, near expiry,\n // or the transport asks to force a refresh (e.g. after a 401 upgrade).\n tokenProvider: (forceRefresh) => this.getJwtToken(forceRefresh),\n ...options,\n // Only forward debug when the client actually has a logger, so we never\n // hand the realtime layer an explicit `debug: undefined`. The WS/SSE\n // constructors also guard against this, but keeping the undefined out of\n // the option object makes the intent clear at the call site.\n ...(this.config.debug ? { debug: this.config.debug } : {}),\n });\n }\n\n /**\n * Get or acquire a JWT token for realtime connections.\n *\n * The realtime layer calls this on every (re)connect. We cache the JWT and\n * reuse it until it nears expiry so a reconnect storm doesn't hammer\n * /auth/login and trip its rate limit. A fresh login happens only when the\n * cached token is absent, within ~60s of its `exp`, or a refresh is forced.\n *\n * @param forceRefresh Bypass the cache and mint a new token. Set by the\n * transport when the server rejected the current token (e.g. a 401 on the\n * WebSocket upgrade), so a stale/revoked token is replaced without waiting\n * for it to expire.\n */\n private async getJwtToken(forceRefresh = false): Promise<string> {\n // A JWT access token supplied directly: reuse it, refreshing via the\n // refresh token when it nears expiry (or when a refresh is forced).\n if (this.config.accessToken) {\n if (forceRefresh || this.shouldRefreshToken()) {\n return this.refreshAccessToken();\n }\n return this.config.accessToken;\n }\n\n // API-key auth: exchange the key for a JWT once, then reuse the cached JWT\n // across (re)connects until it nears expiry. Only then log in again.\n if (this.config.apiKey) {\n if (forceRefresh) {\n this.cachedJwt = null;\n }\n if (this.cachedJwt && !isJwtNearExpiry(this.cachedJwt)) {\n return this.cachedJwt;\n }\n return this.loginForJwt();\n }\n\n throw new AuthenticationError('No authentication method available for realtime connection');\n }\n\n /**\n * Exchange the API key for a JWT via /auth/login and cache the result.\n *\n * Concurrent callers share a single in-flight login so a burst of reconnects\n * (e.g. WebSocket and SSE at once) issues just one request.\n */\n private async loginForJwt(): Promise<string> {\n if (this.jwtLoginPromise) {\n return this.jwtLoginPromise;\n }\n\n this.jwtLoginPromise = (async () => {\n const response = await this.auth.login({ apiKey: this.config.apiKey! });\n\n // Update internal state and cache the token for future (re)connects.\n this.http.setAuthToken(response.accessToken);\n this.tokenExpiresAt = Date.now() + response.expiresIn * 1000;\n (this.config as ResolvedConfig).refreshToken = response.refreshToken;\n this.cachedJwt = response.accessToken;\n\n return response.accessToken;\n })();\n\n try {\n return await this.jwtLoginPromise;\n } finally {\n this.jwtLoginPromise = null;\n }\n }\n\n /**\n * Check if token should be refreshed\n */\n private shouldRefreshToken(): boolean {\n if (!this.tokenExpiresAt) {\n return false;\n }\n // Refresh 5 minutes before expiry\n const bufferMs = 5 * 60 * 1000;\n return Date.now() >= this.tokenExpiresAt - bufferMs;\n }\n\n /**\n * Refresh the access token\n */\n private async refreshAccessToken(): Promise<string> {\n // Deduplicate concurrent refresh requests\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n if (!this.config.refreshToken) {\n throw new AuthenticationError('No refresh token available');\n }\n\n this.refreshPromise = this.doRefreshToken();\n\n try {\n return await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n /**\n * Actually perform the token refresh\n */\n private async doRefreshToken(): Promise<string> {\n const response = await this.auth.refresh({\n refreshToken: this.config.refreshToken!,\n });\n\n // Update state\n this.http.setAuthToken(response.accessToken);\n this.tokenExpiresAt = Date.now() + response.expiresIn * 1000;\n (this.config as ResolvedConfig).accessToken = response.accessToken;\n\n this.config.debug?.('Token refreshed successfully');\n\n return response.accessToken;\n }\n\n /**\n * Get current configuration (read-only)\n */\n getConfig(): Readonly<ResolvedConfig> {\n return this.config;\n }\n\n /**\n * Get circuit breaker statistics\n */\n getCircuitBreakerStats() {\n return this.circuitBreaker.getStats();\n }\n\n /**\n * Reset the circuit breaker\n */\n resetCircuitBreaker(): void {\n this.circuitBreaker.reset();\n }\n\n /**\n * Create a new client with different options\n */\n withOptions(options: Partial<SpooledClientConfig>): SpooledClient {\n return new SpooledClient({\n apiKey: this.config.apiKey,\n accessToken: this.config.accessToken,\n refreshToken: this.config.refreshToken,\n adminKey: this.config.adminKey,\n grpcAddress: this.config.grpcAddress,\n baseUrl: this.config.baseUrl,\n timeout: this.config.timeout,\n retry: this.config.retry,\n circuitBreaker: this.config.circuitBreaker,\n headers: this.config.headers,\n fetch: this.config.fetch,\n userAgent: this.config.userAgent,\n debug: this.config.debug ?? undefined,\n autoRefreshToken: this.config.autoRefreshToken,\n ...options,\n });\n }\n\n /**\n * Resolve gRPC address (host:port format)\n */\n private resolveGrpcAddress(): string {\n return this.config.grpcAddress;\n }\n\n /**\n * Close all connections including gRPC\n */\n close(): void {\n if (this._grpc) {\n this._grpc.close();\n this._grpc = null;\n }\n }\n}\n\n/**\n * Create a new SpooledClient instance\n *\n * @example\n * ```typescript\n * const client = createClient({\n * apiKey: process.env.SPOOLED_API_KEY\n * });\n * ```\n */\nexport function createClient(options: SpooledClientConfig): SpooledClient {\n return new SpooledClient(options);\n}\n\n/**\n * Decode a JWT's `exp` claim (seconds since epoch) without verifying the\n * signature — we only need the expiry to decide when to refresh, not to trust\n * the token. Returns null for a malformed token or one with no numeric `exp`.\n */\nexport function decodeJwtExp(token: string): number | null {\n const parts = token.split('.');\n if (parts.length < 2) {\n return null;\n }\n try {\n const payload = JSON.parse(base64UrlDecode(parts[1])) as { exp?: unknown };\n return typeof payload.exp === 'number' ? payload.exp : null;\n } catch {\n return null;\n }\n}\n\n/**\n * True when a token is missing an `exp` we can read or is within `skewMs` of it.\n * A token whose expiry can't be decoded is treated as expiring, so we fall back\n * to a fresh login rather than reuse a token we can't reason about.\n */\nexport function isJwtNearExpiry(token: string, skewMs = 60_000): boolean {\n const exp = decodeJwtExp(token);\n if (exp === null) {\n return true;\n }\n return Date.now() >= exp * 1000 - skewMs;\n}\n\n/** Base64url-decode a JWT segment to a UTF-8 string, across Node and browsers. */\nfunction base64UrlDecode(segment: string): string {\n const b64 = segment.replace(/-/g, '+').replace(/_/g, '/');\n // Prefer Node's Buffer; fall back to atob for browsers / non-Node runtimes.\n // Referenced via globalThis so neither global is a hard dependency.\n if (typeof globalThis.Buffer !== 'undefined') {\n return globalThis.Buffer.from(b64, 'base64').toString('utf8');\n }\n const binary = globalThis.atob(b64);\n const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));\n return new globalThis.TextDecoder().decode(bytes);\n}\n","/**\n * Common Types\n *\n * Shared types used across the SDK.\n */\n\n/** JSON primitive types */\nexport type JsonPrimitive = string | number | boolean | null;\n\n/** JSON value type */\nexport type JsonValue = JsonPrimitive | JsonObject | JsonArray;\n\n/** JSON object type */\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\n/** JSON array type */\nexport type JsonArray = JsonValue[];\n\n/** Job status enum values */\nexport type JobStatus =\n | 'pending'\n | 'scheduled'\n | 'processing'\n | 'completed'\n | 'failed'\n | 'deadletter'\n | 'cancelled';\n\n/** Worker status enum values */\nexport type WorkerStatus = 'healthy' | 'degraded' | 'offline' | 'draining';\n\n/** Workflow status enum values */\nexport type WorkflowStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';\n\n/** Plan tier enum values */\nexport type PlanTier = 'free' | 'starter' | 'pro' | 'enterprise';\n\n/** Schedule run status */\nexport type ScheduleRunStatus = 'pending' | 'running' | 'completed' | 'failed';\n\n/** Webhook delivery status */\nexport type WebhookDeliveryStatus = 'pending' | 'success' | 'failed';\n\n/** Webhook event types */\nexport type WebhookEventType =\n | 'job.created'\n | 'job.started'\n | 'job.completed'\n | 'job.failed'\n | 'job.cancelled'\n | 'queue.paused'\n | 'queue.resumed'\n | 'worker.registered'\n | 'worker.deregistered'\n | 'schedule.triggered';\n\n/** Dependency mode for workflows */\nexport type DependencyMode = 'all' | 'any';\n\n/** Pagination parameters */\nexport interface PaginationParams {\n /** Maximum number of results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\n/** List parameters with optional sorting */\nexport interface ListParams extends PaginationParams {\n /** Field to order by */\n orderBy?: string;\n /** Sort direction */\n orderDir?: 'asc' | 'desc';\n}\n\n/** Paginated response wrapper */\nexport interface PaginatedResponse<T> {\n /** Items in current page */\n data: T[];\n /** Total count (if available) */\n total?: number;\n /** Current page offset */\n offset: number;\n /** Page size limit */\n limit: number;\n /** Whether there are more results */\n hasMore: boolean;\n}\n\n/**\n * Helper to create a paginated response from an array\n */\nexport function createPaginatedResponse<T>(\n items: T[],\n limit: number,\n offset: number = 0,\n total?: number\n): PaginatedResponse<T> {\n return {\n data: items,\n total,\n offset,\n limit,\n hasMore: items.length === limit,\n };\n}\n","/**\n * gRPC Types\n *\n * Types that mirror the protobuf definitions in spooled.proto.\n * Uses proper enum names matching the proto (JOB_STATUS_PENDING, etc.)\n */\n\nimport type * as grpc from '@grpc/grpc-js';\n\n// ============================================================================\n// Job Status Enum\n// ============================================================================\n\n/** Job status enum values (proto-style naming) */\nexport enum GrpcJobStatus {\n JOB_STATUS_UNSPECIFIED = 'JOB_STATUS_UNSPECIFIED',\n JOB_STATUS_PENDING = 'JOB_STATUS_PENDING',\n JOB_STATUS_SCHEDULED = 'JOB_STATUS_SCHEDULED',\n JOB_STATUS_PROCESSING = 'JOB_STATUS_PROCESSING',\n JOB_STATUS_COMPLETED = 'JOB_STATUS_COMPLETED',\n JOB_STATUS_FAILED = 'JOB_STATUS_FAILED',\n JOB_STATUS_DEADLETTER = 'JOB_STATUS_DEADLETTER',\n JOB_STATUS_CANCELLED = 'JOB_STATUS_CANCELLED',\n}\n\n/** Numeric job status values (for backward compatibility) */\nexport const GrpcJobStatusNumber = {\n UNSPECIFIED: 0,\n PENDING: 1,\n SCHEDULED: 2,\n PROCESSING: 3,\n COMPLETED: 4,\n FAILED: 5,\n DEADLETTER: 6,\n CANCELLED: 7,\n} as const;\n\n// ============================================================================\n// Timestamp handling\n// ============================================================================\n\n/** Timestamp as returned by gRPC (can be object or ISO string) */\nexport interface GrpcTimestamp {\n seconds?: string | number;\n nanos?: number;\n}\n\n/** Convert timestamp to Date */\nexport function timestampToDate(ts: GrpcTimestamp | string | undefined | null): Date | null {\n if (!ts) return null;\n\n if (typeof ts === 'string') {\n return new Date(ts);\n }\n\n const seconds = typeof ts.seconds === 'string' ? parseInt(ts.seconds, 10) : (ts.seconds ?? 0);\n const nanos = ts.nanos ?? 0;\n return new Date(seconds * 1000 + Math.floor(nanos / 1_000_000));\n}\n\n/** Convert Date to timestamp object */\nexport function dateToTimestamp(date: Date | string): GrpcTimestamp {\n const d = typeof date === 'string' ? new Date(date) : date;\n const ms = d.getTime();\n return {\n seconds: Math.floor(ms / 1000).toString(),\n nanos: (ms % 1000) * 1_000_000,\n };\n}\n\n// ============================================================================\n// Job Message\n// ============================================================================\n\n/** Job message as returned by gRPC */\nexport interface GrpcJob {\n id: string;\n organizationId: string;\n queueName: string;\n status: GrpcJobStatus | string;\n /** Payload as google.protobuf.Struct (object) */\n payload?: Record<string, unknown> | null;\n /** Result as google.protobuf.Struct (object) */\n result?: Record<string, unknown> | null;\n retryCount: number;\n maxRetries: number;\n lastError?: string | null;\n priority: number;\n timeoutSeconds: number;\n createdAt?: GrpcTimestamp | string | null;\n scheduledAt?: GrpcTimestamp | string | null;\n startedAt?: GrpcTimestamp | string | null;\n completedAt?: GrpcTimestamp | string | null;\n leaseExpiresAt?: GrpcTimestamp | string | null;\n assignedWorkerId?: string | null;\n idempotencyKey?: string | null;\n}\n\n// ============================================================================\n// Queue Service - Request/Response Types\n// ============================================================================\n\n/** Enqueue request */\nexport interface GrpcEnqueueRequest {\n queueName: string;\n /** Payload as object (will be converted to google.protobuf.Struct) */\n payload?: Record<string, unknown>;\n priority?: number;\n maxRetries?: number;\n timeoutSeconds?: number;\n scheduledAt?: GrpcTimestamp | string;\n idempotencyKey?: string;\n tags?: Record<string, string>;\n}\n\n/** Enqueue response */\nexport interface GrpcEnqueueResponse {\n jobId: string;\n created: boolean;\n}\n\n/** Dequeue request */\nexport interface GrpcDequeueRequest {\n queueName: string;\n workerId: string;\n leaseDurationSecs?: number;\n batchSize?: number;\n}\n\n/** Dequeue response */\nexport interface GrpcDequeueResponse {\n jobs: GrpcJob[];\n}\n\n/** Complete request */\nexport interface GrpcCompleteRequest {\n jobId: string;\n workerId: string;\n /** Result as object (will be converted to google.protobuf.Struct) */\n result?: Record<string, unknown>;\n}\n\n/** Complete response */\nexport interface GrpcCompleteResponse {\n success: boolean;\n}\n\n/** Fail request */\nexport interface GrpcFailRequest {\n jobId: string;\n workerId: string;\n error: string;\n retry?: boolean;\n}\n\n/** Fail response */\nexport interface GrpcFailResponse {\n success: boolean;\n willRetry?: boolean;\n nextRetryDelaySecs?: number;\n}\n\n/** Renew lease request */\nexport interface GrpcRenewLeaseRequest {\n jobId: string;\n workerId: string;\n extensionSecs: number;\n}\n\n/** Renew lease response */\nexport interface GrpcRenewLeaseResponse {\n success: boolean;\n newExpiresAt?: GrpcTimestamp | string | null;\n}\n\n/** Get job request */\nexport interface GrpcGetJobRequest {\n jobId: string;\n}\n\n/** Get job response */\nexport interface GrpcGetJobResponse {\n job?: GrpcJob | null;\n}\n\n/** Get queue stats request */\nexport interface GrpcGetQueueStatsRequest {\n queueName: string;\n}\n\n/** Get queue stats response */\nexport interface GrpcGetQueueStatsResponse {\n queueName: string;\n pending: number | string;\n scheduled: number | string;\n processing: number | string;\n completed: number | string;\n failed: number | string;\n deadletter: number | string;\n total: number | string;\n maxAgeMs?: number | string | null;\n}\n\n/** Stream jobs request (server streaming) */\nexport interface GrpcStreamJobsRequest {\n queueName: string;\n workerId: string;\n leaseDurationSecs?: number;\n}\n\n// ============================================================================\n// Bidirectional Streaming Types\n// ============================================================================\n\n/** Process request (for bidirectional streaming) */\nexport interface GrpcProcessRequest {\n dequeue?: GrpcDequeueRequest;\n complete?: GrpcCompleteRequest;\n fail?: GrpcFailRequest;\n renewLease?: GrpcRenewLeaseRequest;\n}\n\n/** Error response */\nexport interface GrpcErrorResponse {\n code: string;\n message: string;\n}\n\n/** Process response (for bidirectional streaming) */\nexport interface GrpcProcessResponse {\n job?: GrpcJob;\n complete?: GrpcCompleteResponse;\n fail?: GrpcFailResponse;\n renewLease?: GrpcRenewLeaseResponse;\n error?: GrpcErrorResponse;\n}\n\n// ============================================================================\n// Worker Service Types\n// ============================================================================\n\n/** Register worker request */\nexport interface GrpcRegisterWorkerRequest {\n queueName: string;\n hostname?: string;\n workerType?: string;\n maxConcurrency?: number;\n version?: string;\n metadata?: Record<string, string>;\n}\n\n/** Register worker response */\nexport interface GrpcRegisterWorkerResponse {\n workerId: string;\n leaseDurationSecs: number;\n heartbeatIntervalSecs: number;\n}\n\n/** Heartbeat request */\nexport interface GrpcHeartbeatRequest {\n workerId: string;\n currentJobs?: number;\n status?: string;\n metadata?: Record<string, string>;\n}\n\n/** Heartbeat response */\nexport interface GrpcHeartbeatResponse {\n acknowledged: boolean;\n shouldDrain?: boolean;\n}\n\n/** Deregister request */\nexport interface GrpcDeregisterRequest {\n workerId: string;\n}\n\n/** Deregister response */\nexport interface GrpcDeregisterResponse {\n success: boolean;\n}\n\n// ============================================================================\n// gRPC Client Options\n// ============================================================================\n\n/** Options for creating a gRPC client */\nexport interface GrpcClientOptions {\n /** gRPC server address (host:port) */\n address: string;\n /** API key for authentication */\n apiKey: string;\n /** Use TLS (default: true for production, false for localhost) */\n useTls?: boolean;\n /** Custom channel credentials */\n credentials?: grpc.ChannelCredentials;\n /** Channel options */\n channelOptions?: grpc.ChannelOptions;\n}\n\n// ============================================================================\n// Legacy types (backward compatibility)\n// ============================================================================\n\n/** @deprecated Use GrpcEnqueueRequest */\nexport type GrpcEnqueueJobParams = GrpcEnqueueRequest & {\n organizationId?: string;\n};\n\n/** @deprecated Use GrpcEnqueueResponse */\nexport type GrpcEnqueueJobResponse = GrpcEnqueueResponse;\n\n/** @deprecated Use GrpcDequeueRequest */\nexport type GrpcDequeueJobParams = GrpcDequeueRequest & {\n organizationId?: string;\n leaseDurationSeconds?: number;\n};\n\n/** @deprecated Use GrpcDequeueResponse */\nexport interface GrpcDequeueJobResponse {\n job?: GrpcJob | null;\n}\n\n/** @deprecated Use GrpcCompleteRequest */\nexport type GrpcCompleteJobParams = GrpcCompleteRequest;\n\n/** @deprecated Use GrpcCompleteResponse */\nexport type GrpcCompleteJobResponse = GrpcCompleteResponse;\n\n/** @deprecated Use GrpcFailRequest */\nexport interface GrpcFailJobParams {\n jobId: string;\n workerId: string;\n errorMessage: string;\n}\n\n/** @deprecated Use GrpcFailResponse */\nexport type GrpcFailJobResponse = GrpcFailResponse;\n\n/** @deprecated Use GrpcRenewLeaseRequest */\nexport interface GrpcRenewLeaseParams {\n jobId: string;\n workerId: string;\n leaseDurationSeconds: number;\n}\n\n/** @deprecated Use GrpcRenewLeaseResponse */\nexport interface GrpcRenewLeaseResponse_Legacy {\n renewed: boolean;\n newLeaseExpiresAt?: string | null;\n}\n\n/** @deprecated Use GrpcGetQueueStatsResponse */\nexport interface GrpcGetQueueStatsResponse_Legacy {\n queueName: string;\n pending: number;\n scheduled: number;\n processing: number;\n completed: number;\n failed: number;\n deadletter: number;\n total: number;\n maxAgeMs?: number | null;\n}\n\n/** @deprecated Use GrpcRegisterWorkerRequest */\nexport interface GrpcRegisterWorkerParams {\n workerId: string;\n organizationId?: string;\n queueNames: string[];\n maxConcurrentJobs?: number;\n hostname?: string;\n metadata?: Record<string, unknown> | string;\n}\n\n/** @deprecated Use GrpcRegisterWorkerResponse */\nexport interface GrpcRegisterWorkerResponse_Legacy {\n registered: boolean;\n heartbeatIntervalSeconds: number;\n}\n\n/** @deprecated Use GrpcHeartbeatRequest */\nexport interface GrpcHeartbeatParams {\n workerId: string;\n currentJobIds: string[];\n status: string;\n}\n\n/** @deprecated Use GrpcHeartbeatResponse */\nexport type GrpcHeartbeatResponse_Legacy = GrpcHeartbeatResponse;\n","/**\n * Spooled Worker\n *\n * Worker runtime for processing jobs from a queue.\n */\n\nimport type { SpooledClient } from '../client.js';\nimport type { JsonObject } from '../types/common.js';\nimport type { ClaimedJob } from '../types/jobs.js';\nimport type {\n SpooledWorkerOptions,\n WorkerState,\n JobHandler,\n JobContext,\n WorkerEvent,\n WorkerEventData,\n ActiveJob,\n} from './types.js';\nimport { hostname as osHostname } from 'os';\n\n/** Default options */\nconst DEFAULT_OPTIONS = {\n concurrency: 5,\n pollInterval: 1000,\n leaseDuration: 30,\n heartbeatFraction: 0.5,\n autoStart: false,\n shutdownTimeout: 30000,\n} as const;\n\n/** Event handler type */\ntype EventHandler<E extends WorkerEvent> = (data: WorkerEventData[E]) => void;\n\n/**\n * Spooled Worker\n *\n * @example\n * ```typescript\n * const worker = new SpooledWorker(client, {\n * queueName: 'my-queue',\n * concurrency: 10,\n * });\n *\n * worker.process(async (ctx) => {\n * console.log('Processing job:', ctx.jobId);\n * await doSomeWork(ctx.payload);\n * return { success: true };\n * });\n *\n * await worker.start();\n *\n * // Graceful shutdown\n * process.on('SIGTERM', () => worker.stop());\n * ```\n */\nexport class SpooledWorker {\n private readonly client: SpooledClient;\n private readonly options: Required<SpooledWorkerOptions>;\n private readonly debug: (msg: string, meta?: unknown) => void;\n\n private state: WorkerState = 'idle';\n private workerId: string | null = null;\n private handler: JobHandler | null = null;\n private activeJobs: Map<string, ActiveJob> = new Map();\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private workerHeartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private shutdownPromise: Promise<void> | null = null;\n\n // Event handlers\n private eventHandlers: Map<WorkerEvent, Set<EventHandler<WorkerEvent>>> = new Map();\n\n constructor(client: SpooledClient, options: SpooledWorkerOptions) {\n this.client = client;\n this.options = {\n ...DEFAULT_OPTIONS,\n hostname: osHostname(),\n workerType: 'nodejs',\n version: '1.0.26',\n metadata: {},\n ...options,\n } as Required<SpooledWorkerOptions>;\n\n // Get debug from client config\n const config = client.getConfig();\n this.debug = config.debug ?? (() => {});\n\n if (this.options.autoStart) {\n // Defer to next tick to allow process() to be called\n setImmediate(() => this.start());\n }\n }\n\n /**\n * Get current worker state\n */\n getState(): WorkerState {\n return this.state;\n }\n\n /**\n * Get worker ID (available after start)\n */\n getWorkerId(): string | null {\n return this.workerId;\n }\n\n /**\n * Get number of active jobs\n */\n getActiveJobCount(): number {\n return this.activeJobs.size;\n }\n\n /**\n * Register job handler\n */\n process(handler: JobHandler): void {\n if (this.state !== 'idle') {\n throw new Error('Cannot set handler after worker has started');\n }\n this.handler = handler;\n }\n\n /**\n * Start the worker\n */\n async start(): Promise<void> {\n if (this.state !== 'idle') {\n throw new Error(`Cannot start worker in state: ${this.state}`);\n }\n\n if (!this.handler) {\n throw new Error('No job handler registered. Call process() first.');\n }\n\n this.state = 'starting';\n this.debug(`Starting worker for queue: ${this.options.queueName}`);\n\n try {\n // Register with the API\n const registration = await this.client.workers.register({\n queueName: this.options.queueName,\n hostname: this.options.hostname,\n workerType: this.options.workerType,\n maxConcurrency: this.options.concurrency,\n metadata: this.options.metadata,\n version: this.options.version,\n });\n\n this.workerId = registration.id;\n this.debug(`Worker registered: ${this.workerId}`, registration);\n\n // Start worker heartbeat\n const heartbeatInterval = registration.heartbeatIntervalSecs * 1000;\n this.workerHeartbeatTimer = setInterval(() => {\n this.sendWorkerHeartbeat();\n }, heartbeatInterval);\n\n // Start polling\n this.state = 'running';\n this.emit('started', { workerId: this.workerId, queueName: this.options.queueName });\n this.schedulePoll();\n } catch (error) {\n this.state = 'error';\n this.emit('error', { error: error as Error });\n throw error;\n }\n }\n\n /**\n * Stop the worker gracefully\n */\n async stop(): Promise<void> {\n if (this.state !== 'running') {\n return;\n }\n\n // Deduplicate concurrent stop calls\n if (this.shutdownPromise) {\n return this.shutdownPromise;\n }\n\n this.shutdownPromise = this.doStop();\n return this.shutdownPromise;\n }\n\n private async doStop(): Promise<void> {\n this.state = 'stopping';\n this.debug('Stopping worker...');\n\n // Stop polling\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n\n // Stop worker heartbeat\n if (this.workerHeartbeatTimer) {\n clearInterval(this.workerHeartbeatTimer);\n this.workerHeartbeatTimer = null;\n }\n\n // Signal all active jobs to stop\n for (const active of this.activeJobs.values()) {\n active.abortController.abort();\n }\n\n // Wait for active jobs to complete (with timeout)\n if (this.activeJobs.size > 0) {\n this.debug(`Waiting for ${this.activeJobs.size} active jobs to complete...`);\n\n await Promise.race([\n this.waitForActiveJobs(),\n this.sleep(this.options.shutdownTimeout),\n ]);\n\n // Force-fail any remaining jobs. Snapshot the entries first because\n // cleanupJob() mutates the activeJobs map as we go.\n const remaining = Array.from(this.activeJobs.entries());\n for (const [jobId, active] of remaining) {\n this.debug(`Force-failing job ${jobId} due to shutdown timeout`);\n await this.failJob(active.job, 'Worker shutdown timeout');\n // Clear the per-job heartbeat interval and drop the job from the map.\n // The handler's finally (which normally does this) may never run if\n // user code ignores the abort signal, so the timer would leak forever.\n this.cleanupJob(jobId);\n }\n }\n\n // Deregister worker\n if (this.workerId) {\n try {\n await this.client.workers.deregister(this.workerId);\n this.debug('Worker deregistered');\n } catch (error) {\n this.debug('Failed to deregister worker', error);\n }\n }\n\n this.state = 'stopped';\n this.workerId = null;\n this.emit('stopped', { workerId: this.workerId ?? '', reason: 'graceful' });\n this.shutdownPromise = null;\n }\n\n /**\n * Add event listener\n */\n on<E extends WorkerEvent>(event: E, handler: EventHandler<E>): () => void {\n if (!this.eventHandlers.has(event)) {\n this.eventHandlers.set(event, new Set());\n }\n this.eventHandlers.get(event)!.add(handler as EventHandler<WorkerEvent>);\n return () => this.off(event, handler);\n }\n\n /**\n * Remove event listener\n */\n off<E extends WorkerEvent>(event: E, handler: EventHandler<E>): void {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler as EventHandler<WorkerEvent>);\n }\n }\n\n // Private methods\n\n private emit<E extends WorkerEvent>(event: E, data: WorkerEventData[E]): void {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n this.debug('Event handler error', { event, error });\n }\n });\n }\n }\n\n private schedulePoll(): void {\n if (this.state !== 'running') {\n return;\n }\n\n this.pollTimer = setTimeout(() => this.poll(), this.options.pollInterval);\n }\n\n private async poll(): Promise<void> {\n if (this.state !== 'running' || !this.workerId) {\n return;\n }\n\n // Check if we have capacity\n const availableSlots = this.options.concurrency - this.activeJobs.size;\n if (availableSlots <= 0) {\n this.schedulePoll();\n return;\n }\n\n try {\n // Claim jobs\n const result = await this.client.jobs.claim({\n queueName: this.options.queueName,\n workerId: this.workerId,\n limit: availableSlots,\n leaseDurationSecs: this.options.leaseDuration,\n });\n\n // Process claimed jobs\n for (const job of result.jobs) {\n this.processJob(job);\n }\n } catch (error) {\n this.debug('Poll failed', error);\n this.emit('error', { error: error as Error });\n }\n\n // Schedule next poll\n this.schedulePoll();\n }\n\n private processJob(job: ClaimedJob): void {\n this.emit('job:claimed', { jobId: job.id, queueName: job.queueName });\n\n const abortController = new AbortController();\n const activeJob: ActiveJob = {\n job,\n startedAt: new Date(),\n abortController,\n };\n\n this.activeJobs.set(job.id, activeJob);\n\n // Start per-job heartbeat\n const heartbeatInterval = this.options.leaseDuration * this.options.heartbeatFraction * 1000;\n activeJob.heartbeatTimer = setInterval(() => {\n this.sendJobHeartbeat(job.id);\n }, heartbeatInterval);\n\n // Execute handler\n this.executeHandler(activeJob);\n }\n\n private async executeHandler(activeJob: ActiveJob): Promise<void> {\n const { job, abortController } = activeJob;\n const { signal } = abortController;\n\n this.emit('job:started', { jobId: job.id, queueName: job.queueName });\n\n const context: JobContext = {\n jobId: job.id,\n queueName: job.queueName,\n payload: job.payload,\n retryCount: job.retryCount,\n maxRetries: job.maxRetries,\n signal,\n progress: async (_percent: number, _message?: string) => {\n // Progress tracking could be implemented via heartbeat metadata\n // For now, this is a no-op\n },\n log: (level, message, meta) => {\n this.debug(`[${job.id}] [${level}] ${message}`, meta);\n },\n };\n\n try {\n const result = await this.handler!(context);\n\n // Check if aborted\n if (signal.aborted) {\n this.debug(`Job ${job.id} was aborted`);\n return;\n }\n\n // Complete the job\n await this.completeJob(job, result ?? undefined);\n } catch (error) {\n // Check if aborted\n if (signal.aborted) {\n this.debug(`Job ${job.id} was aborted`);\n return;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n await this.failJob(job, errorMessage);\n } finally {\n this.cleanupJob(job.id);\n }\n }\n\n private async completeJob(job: ClaimedJob, result?: JsonObject): Promise<void> {\n if (!this.workerId) return;\n\n try {\n await this.client.jobs.complete(job.id, {\n workerId: this.workerId,\n result,\n });\n\n this.emit('job:completed', {\n jobId: job.id,\n queueName: job.queueName,\n result,\n });\n } catch (error) {\n this.debug(`Failed to complete job ${job.id}`, error);\n }\n }\n\n private async failJob(job: ClaimedJob, errorMessage: string): Promise<void> {\n if (!this.workerId) return;\n\n const willRetry = job.retryCount < job.maxRetries;\n\n try {\n await this.client.jobs.fail(job.id, {\n workerId: this.workerId,\n error: errorMessage,\n });\n\n this.emit('job:failed', {\n jobId: job.id,\n queueName: job.queueName,\n error: errorMessage,\n willRetry,\n });\n } catch (error) {\n this.debug(`Failed to fail job ${job.id}`, error);\n }\n }\n\n private cleanupJob(jobId: string): void {\n const activeJob = this.activeJobs.get(jobId);\n if (activeJob?.heartbeatTimer) {\n clearInterval(activeJob.heartbeatTimer);\n }\n this.activeJobs.delete(jobId);\n }\n\n private async sendJobHeartbeat(jobId: string): Promise<void> {\n if (!this.workerId) return;\n\n try {\n await this.client.jobs.heartbeat(jobId, {\n workerId: this.workerId,\n leaseDurationSecs: this.options.leaseDuration,\n });\n } catch (error) {\n this.debug(`Job heartbeat failed for ${jobId}`, error);\n }\n }\n\n private async sendWorkerHeartbeat(): Promise<void> {\n if (!this.workerId || this.state !== 'running') return;\n\n try {\n await this.client.workers.heartbeat(this.workerId, {\n currentJobs: this.activeJobs.size,\n status: 'healthy',\n });\n } catch (error) {\n this.debug('Worker heartbeat failed', error);\n }\n }\n\n private async waitForActiveJobs(): Promise<void> {\n while (this.activeJobs.size > 0) {\n await this.sleep(100);\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/utils/casing.ts","../src/utils/retry.ts","../src/utils/http.ts","../src/utils/circuit-breaker.ts","../src/resources/auth.ts","../src/resources/jobs.ts","../src/resources/queues.ts","../src/resources/workers.ts","../src/resources/schedules.ts","../src/resources/workflows.ts","../src/resources/webhooks.ts","../src/resources/api-keys.ts","../src/resources/organizations.ts","../src/resources/billing.ts","../src/resources/dashboard.ts","../src/resources/health.ts","../src/resources/metrics.ts","../src/resources/admin.ts","../src/resources/webhook-ingestion.ts","../src/realtime/event-map.ts","../src/realtime/websocket.ts","../src/realtime/sse.ts","../src/realtime/index.ts","../src/grpc/loader.ts","../src/grpc/streaming.ts","../src/grpc/client.ts","../src/client.ts","../src/types/common.ts","../src/grpc/types.ts","../src/worker/worker.ts"],"names":["CircuitState","Buffer","createHmac","fileURLToPath","__dirname","dirname","join","protoLoader","grpc","credentials","grpc2","GrpcJobStatus","osHostname"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+FO,IAAM,cAAA,GAAiB;AAAA,EAC5B,OAAA,EAAS,2BAAA;AAAA,EACT,KAAA,EAAO,yBAAA;AAAA,EACP,WAAA,EAAa,wBAAA;AAAA,EACb,OAAA,EAAS,GAAA;AAAA,EACT,KAAA,EAAO;AAAA,IACL,UAAA,EAAY,CAAA;AAAA,IACZ,SAAA,EAAW,GAAA;AAAA,IACX,QAAA,EAAU,GAAA;AAAA,IACV,MAAA,EAAQ,CAAA;AAAA,IACR,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,OAAA,EAAS,IAAA;AAAA,IACT,gBAAA,EAAkB,CAAA;AAAA,IAClB,gBAAA,EAAkB,CAAA;AAAA,IAClB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,SAAA,EAAW,4BAAA;AAAA,EACX,gBAAA,EAAkB;AACpB;AAGO,IAAM,WAAA,GAAc;AAGpB,IAAM,WAAA,GAAc;AAGpB,IAAM,aAAA,GAAgB,QAAQ,WAAW,CAAA,CAAA;AAOhD,SAAS,oBAAoB,KAAA,EAA+C;AAC1E,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,EAAA,OAAO,OAAA,KAAY,KAAK,MAAA,GAAY,OAAA;AACtC;AAKO,SAAS,cAAc,OAAA,EAA8C;AAE1E,EAAA,IAAI,OAAA,GAA0B,IAAA;AAC9B,EAAA,IAAI,OAAA,CAAQ,UAAU,IAAA,EAAM;AAC1B,IAAA,OAAA,GAAU,CAAC,SAAiB,IAAA,KAAmB;AAE7C,MAAA,OAAA,CAAQ,IAAI,CAAA,cAAA,EAAiB,OAAO,IAAI,IAAA,KAAS,MAAA,GAAY,OAAO,EAAE,CAAA;AAAA,IACxE,CAAA;AAAA,EACF,CAAA,MAAA,IAAW,OAAO,OAAA,CAAQ,KAAA,KAAU,UAAA,EAAY;AAC9C,IAAA,OAAA,GAAU,OAAA,CAAQ,KAAA;AAAA,EACpB;AAGA,EAAA,MAAM,KAAA,GAAqB;AAAA,IACzB,GAAG,cAAA,CAAe,KAAA;AAAA,IAClB,GAAG,OAAA,CAAQ,KAAA;AAAA;AAAA,IAEX,GAAI,OAAA,CAAQ,OAAA,KAAY,UAAa,EAAE,UAAA,EAAY,QAAQ,OAAA,EAAQ;AAAA,IACnE,GAAI,OAAA,CAAQ,UAAA,KAAe,UAAa,EAAE,SAAA,EAAW,QAAQ,UAAA;AAAW,GAC1E;AAGA,EAAA,MAAM,cAAA,GAAuC;AAAA,IAC3C,GAAG,cAAA,CAAe,cAAA;AAAA,IAClB,GAAG,OAAA,CAAQ;AAAA,GACb;AAGA,EAAA,MAAM,OAAA,GAAkC;AAAA,IACtC,cAAA,EAAgB,kBAAA;AAAA,IAChB,MAAA,EAAQ,kBAAA;AAAA,IACR,GAAG,OAAA,CAAQ;AAAA,GACb;AAGA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,cAAA,CAAe,OAAA;AAIlD,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,OAAA,CAAQ,OAAA,EAAS,IAAI,CAAA;AAClD,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,YAAA;AAO/B,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,mBAAA,CAAoB,OAAA,CAAQ,MAAM,CAAA;AAAA,IAC1C,WAAA,EAAa,mBAAA,CAAoB,OAAA,CAAQ,WAAW,CAAA;AAAA,IACpD,YAAA,EAAc,mBAAA,CAAoB,OAAA,CAAQ,YAAY,CAAA;AAAA,IACtD,QAAA,EAAU,mBAAA,CAAoB,OAAA,CAAQ,QAAQ,CAAA;AAAA,IAC9C,OAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA,EAAa,OAAA,CAAQ,WAAA,IAAe,cAAA,CAAe,WAAA;AAAA,IACnD,OAAA,EAAS,OAAA,CAAQ,OAAA,IAAW,cAAA,CAAe,OAAA;AAAA,IAC3C,KAAA;AAAA,IACA,cAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA,EAAO,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAAA,IACnC,SAAA,EAAW,OAAA,CAAQ,SAAA,IAAa,cAAA,CAAe,SAAA;AAAA,IAC/C,KAAA,EAAO,OAAA;AAAA,IACP,gBAAA,EAAkB,OAAA,CAAQ,gBAAA,IAAoB,cAAA,CAAe;AAAA,GAC/D;AACF;AAMO,SAAS,eAAe,MAAA,EAA8B;AAE3D,EAAA,IAAI,CAAC,MAAA,CAAO,MAAA,IAAU,CAAC,OAAO,WAAA,EAAa;AACzC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAIA,EAAA,IAAI,MAAA,CAAO,MAAA,IAAU,CAAC,MAAA,CAAO,MAAA,CAAO,UAAA,CAAW,KAAK,CAAA,IAAK,CAAC,MAAA,CAAO,MAAA,CAAO,UAAA,CAAW,KAAK,CAAA,EAAG;AACzF,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,SAAS,CAAA,IAAK,CAAC,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,UAAU,CAAA,EAAG;AACnF,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC/D;AAGA,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,MAAM,IAAI,MAAM,mCAAmC,CAAA;AAAA,EACrD;AAGA,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,UAAA,GAAa,CAAA,EAAG;AAC/B,IAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,EACzD;AACA,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,SAAA,IAAa,CAAA,EAAG;AAC/B,IAAA,MAAM,IAAI,MAAM,kCAAkC,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,QAAA,GAAW,MAAA,CAAO,MAAM,SAAA,EAAW;AAClD,IAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,EAC7D;AACA,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAAA,EAC7C;AAGA,EAAA,IAAI,MAAA,CAAO,eAAe,OAAA,EAAS;AACjC,IAAA,IAAI,MAAA,CAAO,cAAA,CAAe,gBAAA,IAAoB,CAAA,EAAG;AAC/C,MAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,IACpE;AACA,IAAA,IAAI,MAAA,CAAO,cAAA,CAAe,gBAAA,IAAoB,CAAA,EAAG;AAC/C,MAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,IACpE;AACA,IAAA,IAAI,MAAA,CAAO,cAAA,CAAe,OAAA,IAAW,CAAA,EAAG;AACtC,MAAA,MAAM,IAAI,MAAM,yCAAyC,CAAA;AAAA,IAC3D;AAAA,EACF;AACF;;;AC5OO,IAAM,YAAA,GAAN,cAA2B,KAAA,CAAM;AAAA;AAAA,EAE7B,UAAA;AAAA;AAAA,EAEA,IAAA;AAAA;AAAA,EAEA,OAAA;AAAA;AAAA,EAEA,SAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EAET,WAAA,CACE,SACA,UAAA,GAAqB,CAAA,EACrB,OAAe,eAAA,EACf,OAAA,EACA,WACA,KAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAGb,IAAA,IAAI,MAAM,iBAAA,EAAmB;AAC3B,MAAA,KAAA,CAAM,iBAAA,CAAkB,IAAA,EAAM,IAAA,CAAK,WAAW,CAAA;AAAA,IAChD;AAAA,EACF;AAAA;AAAA,EAGA,WAAA,GAAuB;AACrB,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAA,GAAkC;AAChC,IAAA,OAAO;AAAA,MACL,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,WAAW,IAAA,CAAK;AAAA,KAClB;AAAA,EACF;AACF;AAMO,IAAM,mBAAA,GAAN,cAAkC,YAAA,CAAa;AAAA,EACpD,YACE,OAAA,GAAkB,uBAAA,EAClB,IAAA,GAAe,uBAAA,EACf,SACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AAC5C,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF;AAMO,IAAM,kBAAA,GAAN,cAAiC,YAAA,CAAa;AAAA,EACnD,YACE,OAAA,GAAkB,eAAA,EAClB,IAAA,GAAe,eAAA,EACf,SACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AAC5C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EACd;AACF;AAMO,IAAM,aAAA,GAAN,cAA4B,YAAA,CAAa;AAAA,EAC9C,YACE,OAAA,GAAkB,oBAAA,EAClB,IAAA,GAAe,WAAA,EACf,SACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AAC5C,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AACF;AAMO,IAAM,aAAA,GAAN,cAA4B,YAAA,CAAa;AAAA,EAC9C,YACE,OAAA,GAAkB,UAAA,EAClB,IAAA,GAAe,UAAA,EACf,SACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AAC5C,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AACF;AAMO,IAAM,eAAA,GAAN,cAA8B,YAAA,CAAa;AAAA,EAChD,YACE,OAAA,GAAkB,mBAAA,EAClB,IAAA,GAAe,kBAAA,EACf,SACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AAC5C,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AAAA,EACd;AACF;AAMO,IAAM,oBAAA,GAAN,cAAmC,YAAA,CAAa;AAAA,EACrD,YACE,OAAA,GAAkB,2BAAA,EAClB,IAAA,GAAe,mBAAA,EACf,SACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AAC5C,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AAAA,EACd;AACF;AAMO,IAAM,cAAA,GAAN,cAA6B,YAAA,CAAa;AAAA;AAAA,EAEtC,aAAA;AAAA,EAET,WAAA,CACE,UAAkB,qBAAA,EAClB,IAAA,GAAe,uBACf,aAAA,GAA+B,EAAC,EAChC,OAAA,EACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AAC5C,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,IAAA,CAAK,aAAA,GAAgB,aAAA;AAAA,EACvB;AAAA,EAES,WAAA,GAAuB;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,aAAA,GAAwB;AACtB,IAAA,IAAI,IAAA,CAAK,aAAA,CAAc,UAAA,KAAe,MAAA,EAAW;AAC/C,MAAA,OAAO,KAAK,aAAA,CAAc,UAAA;AAAA,IAC5B;AACA,IAAA,IAAI,IAAA,CAAK,cAAc,KAAA,EAAO;AAC5B,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,aAAA,CAAc,KAAA,CAAM,OAAA,EAAQ;AACnD,MAAA,OAAO,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,MAAM,SAAA,GAAY,GAAA,IAAO,GAAI,CAAC,CAAA;AAAA,IACxD;AACA,IAAA,OAAO,EAAA;AAAA,EACT;AAAA,EAES,MAAA,GAAkC;AACzC,IAAA,OAAO;AAAA,MACL,GAAG,MAAM,MAAA,EAAO;AAAA,MAChB,eAAe,IAAA,CAAK;AAAA,KACtB;AAAA,EACF;AACF;AAMO,IAAM,WAAA,GAAN,cAA0B,YAAA,CAAa;AAAA,EAC5C,WAAA,CACE,UAAkB,cAAA,EAClB,UAAA,GAAqB,KACrB,IAAA,GAAe,cAAA,EACf,SACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,UAAA,EAAY,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AACnD,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AAAA,EACd;AAAA,EAES,WAAA,GAAuB;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMO,IAAM,YAAA,GAAN,cAA2B,YAAA,CAAa;AAAA,EAC7C,WAAA,CAAY,OAAA,GAAkB,wBAAA,EAA0B,KAAA,EAAe;AACrE,IAAA,KAAA,CAAM,OAAA,EAAS,CAAA,EAAG,eAAA,EAAiB,MAAA,EAAW,QAAW,KAAK,CAAA;AAC9D,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AAAA,EACd;AAAA,EAES,WAAA,GAAuB;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMO,IAAM,YAAA,GAAN,cAA2B,YAAA,CAAa;AAAA;AAAA,EAEpC,SAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAAkB,mBAAA,EAAqB,SAAA,GAAoB,CAAA,EAAG;AACxE,IAAA,KAAA,CAAM,OAAA,EAAS,CAAA,EAAG,SAAA,EAAW,EAAE,WAAW,CAAA;AAC1C,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAAA,EAES,WAAA,GAAuB;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMO,IAAM,uBAAA,GAAN,cAAsC,YAAA,CAAa;AAAA,EACxD,WAAA,CAAY,UAAkB,yBAAA,EAA2B;AACvD,IAAA,KAAA,CAAM,OAAA,EAAS,GAAG,sBAAsB,CAAA;AACxC,IAAA,IAAA,CAAK,IAAA,GAAO,yBAAA;AAAA,EACd;AAAA,EAES,WAAA,GAAuB;AAC9B,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAKO,SAAS,sBAAsB,OAAA,EAAiC;AACrE,EAAA,MAAM,OAAsB,EAAC;AAE7B,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AAC5C,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,UAAA,EAAY,EAAE,CAAA;AACvC,IAAA,IAAI,CAAC,KAAA,CAAM,OAAO,CAAA,EAAG;AACnB,MAAA,IAAA,CAAK,UAAA,GAAa,OAAA;AAAA,IACpB;AAAA,EACF;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AAC7C,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,EAAO,EAAE,CAAA;AACjC,IAAA,IAAI,CAAC,KAAA,CAAM,MAAM,CAAA,EAAG;AAClB,MAAA,IAAA,CAAK,KAAA,GAAQ,MAAA;AAAA,IACf;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,GAAA,CAAI,uBAAuB,CAAA;AACrD,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,SAAA,EAAW,EAAE,CAAA;AACrC,IAAA,IAAI,CAAC,KAAA,CAAM,MAAM,CAAA,EAAG;AAClB,MAAA,IAAA,CAAK,SAAA,GAAY,MAAA;AAAA,IACnB;AAAA,EACF;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AAC7C,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,KAAA,EAAO,EAAE,CAAA;AACpC,IAAA,IAAI,CAAC,KAAA,CAAM,SAAS,CAAA,EAAG;AACrB,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,IAAA,CAAK,SAAA,GAAY,GAAI,CAAA;AAAA,IACxC;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAGA,IAAM,wBAAA,GAA2B,GAAA;AAYjC,eAAe,eAAe,QAAA,EAAkD;AAC9E,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA;AAE5D,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAM,SAAS,IAAA,EAAK;AAAA,EAC5B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,kBAAkB,CAAA,EAAG;AAC5C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC3B,MAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,IAAA,EAAM;AAI7C,QAAA,MAAM,OAAA,GAAA,CAAY,IAAA,CAAK,OAAA,IAAuB,IAAA,CAAK,UAAqB,QAAA,CAAS,UAAA;AACjF,QAAA,OAAO;AAAA,UACL,IAAA,EAAO,KAAK,IAAA,IAAmB,eAAA;AAAA,UAC/B,OAAA;AAAA,UACA,SAAS,IAAA,CAAK;AAAA,SAChB;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAGR;AAAA,EACF;AAGA,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AACzB,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,OAAA,GACJ,OAAA,CAAQ,MAAA,GAAS,wBAAA,GACb,CAAA,EAAG,QAAQ,KAAA,CAAM,CAAA,EAAG,wBAAwB,CAAC,CAAA,MAAA,CAAA,GAC7C,OAAA;AACN,IAAA,OAAO,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAQ;AAAA,EAC1C;AAEA,EAAA,OAAO,IAAA;AACT;AAKA,eAAsB,wBAAwB,QAAA,EAA2C;AACvF,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,MAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,MAAM,cAAA,CAAe,QAAQ,CAAA;AAE1C,EAAA,MAAM,UAAU,IAAA,EAAM,OAAA,IAAW,SAAS,UAAA,IAAc,CAAA,KAAA,EAAQ,SAAS,MAAM,CAAA,CAAA;AAC/E,EAAA,MAAM,IAAA,GAAO,MAAM,IAAA,IAAQ,eAAA;AAC3B,EAAA,MAAM,UAAU,IAAA,EAAM,OAAA;AAEtB,EAAA,QAAQ,SAAS,MAAA;AAAQ,IACvB,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,eAAA,CAAgB,OAAA,EAAS,IAAA,EAAM,SAAS,SAAS,CAAA;AAAA,IAE9D,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,mBAAA,CAAoB,OAAA,EAAS,IAAA,EAAM,SAAS,SAAS,CAAA;AAAA,IAElE,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,kBAAA,CAAmB,OAAA,EAAS,IAAA,EAAM,SAAS,SAAS,CAAA;AAAA,IAEjE,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,aAAA,CAAc,OAAA,EAAS,IAAA,EAAM,SAAS,SAAS,CAAA;AAAA,IAE5D,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,aAAA,CAAc,OAAA,EAAS,IAAA,EAAM,SAAS,SAAS,CAAA;AAAA,IAE5D,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,oBAAA,CAAqB,OAAA,EAAS,IAAA,EAAM,SAAS,SAAS,CAAA;AAAA,IAEnE,KAAK,GAAA,EAAK;AACR,MAAA,MAAM,aAAA,GAAgB,qBAAA,CAAsB,QAAA,CAAS,OAAO,CAAA;AAC5D,MAAA,OAAO,IAAI,cAAA,CAAe,OAAA,EAAS,IAAA,EAAM,aAAA,EAAe,SAAS,SAAS,CAAA;AAAA,IAC5E;AAAA,IAEA;AACE,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,OAAO,IAAI,WAAA,CAAY,OAAA,EAAS,SAAS,MAAA,EAAQ,IAAA,EAAM,SAAS,SAAS,CAAA;AAAA,MAC3E;AACA,MAAA,OAAO,IAAI,YAAA,CAAa,OAAA,EAAS,SAAS,MAAA,EAAQ,IAAA,EAAM,SAAS,SAAS,CAAA;AAAA;AAEhF;AAKO,SAAS,eAAe,KAAA,EAAuC;AACpE,EAAA,OAAO,KAAA,YAAiB,YAAA;AAC1B;AAKO,SAAS,iBAAiB,KAAA,EAAyB;AACxD,EAAA,IAAI,iBAAiB,YAAA,EAAc;AACjC,IAAA,OAAO,MAAM,WAAA,EAAY;AAAA,EAC3B;AAEA,EAAA,IAAI,iBAAiB,SAAA,EAAW;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;;;ACvbA,IAAM,oBAAA,uBAA2B,GAAA,CAAI;AAAA,EACnC,SAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,iBAAA;AAAA,EACA,kBAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAC,CAAA;AAKD,SAAS,cAAc,KAAA,EAAkD;AACvE,EAAA,OACE,OAAO,UAAU,QAAA,IACjB,KAAA,KAAU,QACV,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA,IACpB,EAAE,KAAA,YAAiB,IAAA,CAAA,IACnB,EAAE,KAAA,YAAiB,MAAA,CAAA,IACnB,OAAO,SAAA,CAAU,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA,KAAM,iBAAA;AAE9C;AAKO,SAAS,aAAa,GAAA,EAAqB;AAChD,EAAA,OAAO,GAAA,CAAI,QAAQ,QAAA,EAAU,CAAC,WAAW,CAAA,CAAA,EAAI,MAAA,CAAO,WAAA,EAAa,CAAA,CAAE,CAAA;AACrE;AAKO,SAAS,aAAa,GAAA,EAAqB;AAGhD,EAAA,OAAO,GAAA,CACJ,OAAA,CAAQ,YAAA,EAAc,CAAC,GAAG,MAAA,KAAW,MAAM,CAAA,CAC3C,OAAA,CAAQ,aAAa,CAAC,CAAA,EAAG,MAAA,KAAW,MAAA,CAAO,aAAa,CAAA;AAC7D;AAUO,SAAS,WAAA,CAAyB,GAAA,EAAQ,kBAAA,GAAqB,KAAA,EAAU;AAC9E,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,MAAA,EAAW;AACrC,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtB,IAAA,OAAO,IAAI,GAAA,CAAI,CAAC,SAAS,WAAA,CAAY,IAAA,EAAM,kBAAkB,CAAC,CAAA;AAAA,EAChE;AAEA,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAO,IAAI,WAAA,EAAY;AAAA,EACzB;AAEA,EAAA,IAAI,CAAC,aAAA,CAAc,GAAG,CAAA,EAAG;AACvB,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAkC,EAAC;AAEzC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9C,IAAA,MAAM,QAAA,GAAW,aAAa,GAAG,CAAA;AAGjC,IAAA,MAAM,UAAA,GAAa,sBAAsB,oBAAA,CAAqB,GAAA,CAAI,GAAG,CAAA,IAAK,oBAAA,CAAqB,IAAI,QAAQ,CAAA;AAE3G,IAAA,IAAI,UAAA,EAAY;AAEd,MAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,KAAA;AAAA,IACrB,CAAA,MAAO;AAEL,MAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,WAAA,CAAY,KAAA,EAAO,KAAK,CAAA;AAAA,IAC7C;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,WAAA,CAAyB,GAAA,EAAQ,kBAAA,GAAqB,KAAA,EAAU;AAC9E,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,MAAA,EAAW;AACrC,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtB,IAAA,OAAO,IAAI,GAAA,CAAI,CAAC,SAAS,WAAA,CAAY,IAAA,EAAM,kBAAkB,CAAC,CAAA;AAAA,EAChE;AAEA,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,aAAA,CAAc,GAAG,CAAA,EAAG;AACvB,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAkC,EAAC;AAEzC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9C,IAAA,MAAM,QAAA,GAAW,aAAa,GAAG,CAAA;AAGjC,IAAA,MAAM,UAAA,GAAa,sBAAsB,oBAAA,CAAqB,GAAA,CAAI,GAAG,CAAA,IAAK,oBAAA,CAAqB,IAAI,QAAQ,CAAA;AAE3G,IAAA,IAAI,UAAA,EAAY;AAEd,MAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,KAAA;AAAA,IACrB,CAAA,MAAO;AAEL,MAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,WAAA,CAAY,KAAA,EAAO,KAAK,CAAA;AAAA,IAC7C;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,eAAkB,IAAA,EAAY;AAC5C,EAAA,OAAO,YAAY,IAAI,CAAA;AACzB;AAKO,SAAS,gBAAmB,IAAA,EAAY;AAC7C,EAAA,OAAO,YAAY,IAAI,CAAA;AACzB;AAMO,SAAS,mBACd,MAAA,EACwB;AACxB,EAAA,MAAM,SAAiC,EAAC;AAExC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACjD,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,MAAM,QAAA,GAAW,aAAa,GAAG,CAAA;AACjC,MAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,IACjC;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;;;ACvJO,SAAS,cAAA,CACd,OAAA,EACA,MAAA,EACA,iBAAA,EACQ;AAER,EAAA,IAAI,iBAAA,KAAsB,MAAA,IAAa,iBAAA,GAAoB,CAAA,EAAG;AAC5D,IAAA,MAAM,eAAe,iBAAA,GAAoB,GAAA;AACzC,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC/C;AAGA,EAAA,MAAM,gBAAA,GAAmB,OAAO,SAAA,GAAY,IAAA,CAAK,IAAI,MAAA,CAAO,MAAA,EAAQ,UAAU,CAAC,CAAA;AAG/E,EAAA,IAAI,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,gBAAA,EAAkB,OAAO,QAAQ,CAAA;AAGtD,EAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,IAAA,MAAM,cAAc,KAAA,GAAQ,IAAA;AAC5B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,EAAO,GAAI,WAAA;AAC/B,IAAA,KAAA,GAAQ,KAAA,GAAQ,MAAA;AAAA,EAClB;AAEA,EAAA,OAAO,IAAA,CAAK,MAAM,KAAK,CAAA;AACzB;AAUO,SAAS,WAAA,CAAY,KAAA,EAAc,OAAA,EAAiB,MAAA,EAA8B;AAGvF,EAAA,IAAI,OAAA,GAAU,OAAO,UAAA,EAAY;AAC/B,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAO,OAAO,CAAA;AAAA,EACtC;AAGA,EAAA,OAAO,iBAAiB,KAAK,CAAA;AAC/B;AASO,SAAS,KAAA,CAAM,IAAY,MAAA,EAAqC;AACrE,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,MAAA,CAAO,IAAI,YAAA,CAAa,SAAA,EAAW,YAAY,CAAC,CAAA;AAChD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GAAY,WAAW,MAAM;AACjC,MAAA,MAAA,EAAQ,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAC5C,MAAA,OAAA,EAAQ;AAAA,IACV,GAAG,EAAE,CAAA;AAEL,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,YAAA,CAAa,SAAS,CAAA;AACtB,MAAA,MAAA,CAAO,IAAI,YAAA,CAAa,SAAA,EAAW,YAAY,CAAC,CAAA;AAAA,IAClD,CAAA;AAEA,IAAA,MAAA,EAAQ,iBAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,EAC3D,CAAC,CAAA;AACH;AAUA,eAAsB,SAAA,CACpB,IACA,OAAA,EACY;AACZ,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAQ,GAAI,OAAA;AACpC,EAAA,IAAI,SAAA;AAEJ,EAAA,KAAA,IAAS,UAAU,CAAA,EAAG,OAAA,IAAW,MAAA,CAAO,UAAA,GAAa,GAAG,OAAA,EAAA,EAAW;AAEjE,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,MAAM,IAAI,YAAA,CAAa,SAAA,EAAW,YAAY,CAAA;AAAA,IAChD;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,EAAA,EAAG;AAAA,IAClB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,GAAA,GAAM,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACpE,MAAA,SAAA,GAAY,GAAA;AAGZ,MAAA,IAAI,CAAC,WAAA,CAAY,GAAA,EAAK,OAAA,EAAS,MAAM,CAAA,EAAG;AACtC,QAAA,MAAM,GAAA;AAAA,MACR;AAGA,MAAA,IAAI,UAAA;AACJ,MAAA,IAAI,eAAe,cAAA,EAAgB;AACjC,QAAA,UAAA,GAAa,IAAI,aAAA,EAAc;AAAA,MACjC;AACA,MAAA,MAAM,OAAA,GAAU,cAAA,CAAe,OAAA,EAAS,MAAA,EAAQ,UAAU,CAAA;AAG1D,MAAA,OAAA,GAAU,OAAA,EAAS,KAAK,OAAO,CAAA;AAG/B,MAAA,MAAM,KAAA,CAAM,SAAS,MAAM,CAAA;AAAA,IAC7B;AAAA,EACF;AAGA,EAAA,MAAM,SAAA,IAAa,IAAI,KAAA,CAAM,iCAAiC,CAAA;AAChE;AAQO,SAAS,mBAAmB,MAAA,EAAqB;AACtD,EAAA,OAAO,SAAS,KAAA,CACd,EAAA,EACA,OAAA,EACY;AACZ,IAAA,OAAO,UAAU,EAAA,EAAI;AAAA,MACnB,MAAA;AAAA,MACA,GAAG;AAAA,KACJ,CAAA;AAAA,EACH,CAAA;AACF;;;AC7IA,IAAM,qCAAqB,IAAI,GAAA,CAAgB,CAAC,KAAA,EAAO,KAAA,EAAO,QAAQ,CAAC,CAAA;AAuDhE,IAAM,aAAN,MAAiB;AAAA,EACL,MAAA;AAAA,EACA,cAAA;AAAA,EACA,KAAA;AAAA;AAAA,EAGT,SAAA;AAAA;AAAA,EAGA,cAAA,GAAiD,IAAA;AAAA;AAAA,EAGjD,YAAA,GAAe,KAAA;AAAA,EAEvB,WAAA,CACE,QACA,cAAA,EACA;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,cAAA,GAAiB,cAAA;AACtB,IAAA,IAAA,CAAK,QAAQ,MAAA,CAAO,KAAA;AAGpB,IAAA,IAAA,CAAK,SAAA,GAAY,MAAA,CAAO,WAAA,IAAe,MAAA,CAAO,MAAA;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,KAAA,EAAqB;AAChC,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAkB,EAAA,EAAiC;AACjD,IAAA,IAAA,CAAK,cAAA,GAAiB,EAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,QAAA,CACN,IAAA,EACA,MAAA,EACA,aAAA,EACQ;AAER,IAAA,MAAM,QAAA,GAAW,aAAA,GAAgB,IAAA,GAAQ,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA,GAAI,IAAA,GAAO,CAAA,EAAG,aAAa,CAAA,EAAG,IAAI,CAAA,CAAA;AAClG,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,QAAA,EAAU,IAAA,CAAK,OAAO,OAAO,CAAA;AAEjD,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,eAAA,GAAkB,mBAAmB,MAAM,CAAA;AACjD,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,eAAe,CAAA,EAAG;AAC1D,QAAA,GAAA,CAAI,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,KAAK,CAAA;AAAA,MACpC;AAAA,IACF;AAEA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,aAAA,EAAiD;AACpE,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAG5B,IAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAG;AAC9D,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,IACxB;AAGA,IAAA,OAAA,CAAQ,GAAA,CAAI,YAAA,EAAc,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA;AAG/C,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,OAAA,CAAQ,GAAA,CAAI,eAAA,EAAiB,CAAA,OAAA,EAAU,IAAA,CAAK,SAAS,CAAA,CAAE,CAAA;AAAA,IACzD;AAGA,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAA,EAAG;AACxD,QAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,MACxB;AAAA,IACF;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBAAA,CACZ,GAAA,EACA,IAAA,EACA,WACA,cAAA,EACmB;AACnB,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,EAAE,QAAO,GAAI,UAAA;AAGnB,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,QAAA,UAAA,CAAW,KAAA,EAAM;AAAA,MACnB,CAAA,MAAO;AACL,QAAA,cAAA,CAAe,gBAAA,CAAiB,SAAS,MAAM,UAAA,CAAW,OAAM,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,MACnF;AAAA,IACF;AAGA,IAAA,MAAM,YAAY,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAEhE,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,MAAA,CAAO,MAAM,GAAA,EAAK;AAAA,QAC5C,GAAG,IAAA;AAAA,QACH;AAAA,OACD,CAAA;AACD,MAAA,OAAO,QAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,KAAA,YAAiB,YAAA,IAAgB,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AAEhE,QAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,UAAA,MAAM,KAAA;AAAA,QACR;AACA,QAAA,MAAM,IAAI,YAAA,CAAa,CAAA,wBAAA,EAA2B,SAAS,MAAM,SAAS,CAAA;AAAA,MAC5E;AACA,MAAA,MAAM,KAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAAA,CACZ,GAAA,EACA,OAAA,EACA,eAAe,KAAA,EACW;AAC1B,IAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,KAAA;AACjC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,OAAO,CAAA;AACjD,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,IAAA,CAAK,MAAA,CAAO,OAAA;AAG/C,IAAA,MAAM,IAAA,GAAoB;AAAA,MACxB,MAAA;AAAA,MACA;AAAA,KACF;AAGA,IAAA,IAAI,WAAW,KAAA,EAAO;AACpB,MAAA,IAAI,OAAA,CAAQ,YAAY,MAAA,EAAW;AACjC,QAAA,IAAA,CAAK,OAAO,OAAA,CAAQ,OAAA;AAAA,MACtB,CAAA,MAAA,IAAW,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW;AACrC,QAAA,MAAM,OAAO,OAAA,CAAQ,qBAAA,GAAwB,QAAQ,IAAA,GAAO,cAAA,CAAe,QAAQ,IAAI,CAAA;AACvF,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAAA,MACjC;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,EAAE,OAAA,EAAS,OAAA,EAAS,CAAC,CAAC,OAAA,CAAQ,MAAM,CAAA;AAErE,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,gBAAA,CAAiB,KAAK,IAAA,EAAM,OAAA,EAAS,QAAQ,MAAM,CAAA;AAAA,IAC3E,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,KAAA,YAAiB,YAAA,IAAgB,KAAA,YAAiB,YAAA,EAAc;AAClE,QAAA,MAAM,KAAA;AAAA,MACR;AAEA,MAAA,MAAM,KAAA,GAAQ,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,MAAA;AAC/C,MAAA,MAAM,IAAI,YAAA,CAAa,CAAA,wBAAA,EAA2B,OAAO,OAAA,IAAW,eAAe,IAAI,KAAK,CAAA;AAAA,IAC9F;AAEA,IAAA,IAAA,CAAK,QAAQ,CAAA,UAAA,EAAa,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA;AAGpD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAIhB,MAAA,IACE,QAAA,CAAS,WAAW,GAAA,IACpB,IAAA,CAAK,kBACL,CAAC,YAAA,IACD,CAAC,IAAA,CAAK,YAAA,EACN;AACA,QAAA,IAAI,SAAA,GAAY,KAAA;AAChB,QAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,QAAA,IAAI;AACF,UAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,cAAA,EAAe;AAC3C,UAAA,IAAA,CAAK,aAAa,QAAQ,CAAA;AAC1B,UAAA,SAAA,GAAY,IAAA;AAAA,QACd,SAAS,YAAA,EAAc;AACrB,UAAA,MAAM,OAAA,GAAU,YAAA,YAAwB,KAAA,GAAQ,YAAA,CAAa,OAAA,GAAU,SAAA;AACvE,UAAA,IAAA,CAAK,KAAA,GAAQ,sBAAA,EAAwB,EAAE,KAAA,EAAO,SAAS,CAAA;AAAA,QACzD,CAAA,SAAE;AACA,UAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AAAA,QACtB;AAEA,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,OAAO,IAAA,CAAK,cAAA,CAAkB,GAAA,EAAK,OAAA,EAAS,IAAI,CAAA;AAAA,QAClD;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,uBAAA,CAAwB,QAAQ,CAAA;AACvD,MAAA,MAAM,QAAA;AAAA,IACR;AAGA,IAAA,IAAI,IAAA;AACJ,IAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA;AAE5D,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,IAAA,GAAO,MAAA;AAAA,IACT,CAAA,MAAA,IAAW,WAAA,CAAY,QAAA,CAAS,kBAAkB,CAAA,EAAG;AACnD,MAAA,MAAM,OAAA,GAAW,MAAM,QAAA,CAAS,IAAA,EAAK;AACrC,MAAA,IAAA,GAAO,OAAA,CAAQ,sBAAA,GAAyB,OAAA,GAAU,eAAA,CAAgB,OAAO,CAAA;AAAA,IAC3E,CAAA,MAAO;AAEL,MAAA,IAAA,GAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,IAC9B;AAEA,IAAA,OAAO;AAAA,MACL,QAAQ,QAAA,CAAS,MAAA;AAAA,MACjB,SAAS,QAAA,CAAS,OAAA;AAAA,MAClB;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,CAAW,IAAA,EAAc,OAAA,GAA8B,EAAC,EAA6B;AACzF,IAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,MAAM,OAAA,CAAQ,MAAA,EAAQ,QAAQ,aAAa,CAAA;AACrE,IAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,KAAA;AAGjC,IAAA,MAAM,UAAU,YAAsC;AACpD,MAAA,OAAO,IAAA,CAAK,eAAe,OAAA,CAAQ,MAAM,KAAK,cAAA,CAAkB,GAAA,EAAK,OAAO,CAAC,CAAA;AAAA,IAC/E,CAAA;AAGA,IAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,MAAA,OAAO,OAAA,EAAQ;AAAA,IACjB;AAEA,IAAA,OAAO,UAAU,OAAA,EAAS;AAAA,MACxB,MAAA,EAAQ,IAAA,CAAK,kBAAA,CAAmB,MAAA,EAAQ,OAAO,CAAA;AAAA,MAC/C,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,OAAA,EAAS,CAAC,OAAA,EAAS,KAAA,EAAO,OAAA,KAAY;AACpC,QAAA,IAAA,CAAK,KAAA,GAAQ,CAAA,cAAA,EAAiB,OAAO,CAAA,OAAA,EAAU,OAAO,MAAM,EAAE,KAAA,EAAO,KAAA,CAAM,OAAA,EAAS,CAAA;AAAA,MACtF;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,OAAA,EAAsC;AAC9D,IAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AACpB,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,OAAO,CAAA,CAAE,IAAA,CAAK,CAAC,GAAA,KAAQ,GAAA,CAAI,WAAA,EAAY,KAAM,iBAAiB,CAAA;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,kBAAA,CAAmB,QAAoB,OAAA,EAA0C;AACvF,IAAA,MAAM,IAAA,GAAO,KAAK,MAAA,CAAO,KAAA;AAGzB,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,mBAAmB,GAAA,CAAI,MAAM,KAAK,IAAA,CAAK,iBAAA,CAAkB,OAAO,CAAA,EAAG;AACrE,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO;AAAA,MACL,GAAG,IAAA;AAAA,MACH,OAAA,EAAS,CAAC,KAAA,KAAU,KAAA,YAAiB;AAAA,KACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CAAO,IAAA,EAAc,OAAA,EAAmE;AAC5F,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAW,IAAA,EAAM,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,KAAA,EAAO,CAAA;AAC1E,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,CAAQ,IAAA,EAAc,IAAA,EAAgB,OAAA,EAAmE;AAC7G,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAW,IAAA,EAAM,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA;AACjF,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CAAO,IAAA,EAAc,IAAA,EAAgB,OAAA,EAAmE;AAC5G,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAW,IAAA,EAAM,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,CAAA;AAChF,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,CAAS,IAAA,EAAc,IAAA,EAAgB,OAAA,EAAmE;AAC9G,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAW,IAAA,EAAM,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,CAAA;AAClF,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAiB,IAAA,EAAc,OAAA,EAAmE;AACtG,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAW,IAAA,EAAM,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,QAAA,EAAU,CAAA;AAC7E,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AACF;AAKO,SAAS,gBAAA,CACd,QACA,cAAA,EACY;AACZ,EAAA,OAAO,IAAI,UAAA,CAAW,MAAA,EAAQ,cAAc,CAAA;AAC9C;;;AC1aO,IAAK,YAAA,qBAAAA,aAAAA,KAAL;AAEL,EAAAA,cAAA,QAAA,CAAA,GAAS,QAAA;AAET,EAAAA,cAAA,MAAA,CAAA,GAAO,MAAA;AAEP,EAAAA,cAAA,WAAA,CAAA,GAAY,WAAA;AANF,EAAA,OAAAA,aAAAA;AAAA,CAAA,EAAA,YAAA,IAAA,EAAA;AA8BL,IAAM,iBAAN,MAAqB;AAAA,EAClB,KAAA,GAAsB,QAAA;AAAA,EACtB,YAAA,GAAe,CAAA;AAAA,EACf,YAAA,GAAe,CAAA;AAAA,EACf,eAAA,GAA0B,CAAA;AAAA,EACjB,MAAA;AAAA,EAEjB,YAAY,MAAA,EAA+B;AACzC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAyB;AAEvB,IAAA,IAAI,IAAA,CAAK,UAAU,MAAA,aAAmB;AACpC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,IAAI,GAAA,GAAM,IAAA,CAAK,eAAA,IAAmB,IAAA,CAAK,OAAO,OAAA,EAAS;AACrD,QAAA,IAAA,CAAK,aAAa,WAAA,iBAAsB;AAAA,MAC1C;AAAA,IACF;AACA,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAAqB;AACnB,IAAA,OAAO,KAAK,MAAA,CAAO,OAAA;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAAqB;AACnB,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS;AACxB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,KAAA,GAAQ,KAAK,QAAA,EAAS;AAC5B,IAAA,OAAO,KAAA,KAAU,yBAAuB,KAAA,KAAU,WAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,GAAsB;AACpB,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,UAAU,WAAA,kBAAwB;AACzC,MAAA,IAAA,CAAK,YAAA,EAAA;AAEL,MAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,IAAA,CAAK,MAAA,CAAO,gBAAA,EAAkB;AACrD,QAAA,IAAA,CAAK,aAAa,QAAA,cAAmB;AAAA,MACvC;AAAA,IACF,CAAA,MAAA,IAAW,IAAA,CAAK,KAAA,KAAU,QAAA,eAAqB;AAE7C,MAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,KAAA,EAAoB;AAChC,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS;AACxB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,MAAA,CAAO,SAAA,GAC5B,IAAA,CAAK,OAAO,SAAA,CAAU,KAAK,CAAA,GAC3B,gBAAA,CAAiB,KAAK,CAAA;AAE1B,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAK,GAAA,EAAI;AAEhC,IAAA,IAAI,IAAA,CAAK,UAAU,WAAA,kBAAwB;AAEzC,MAAA,IAAA,CAAK,aAAa,MAAA,YAAiB;AAAA,IACrC,CAAA,MAAA,IAAW,IAAA,CAAK,KAAA,KAAU,QAAA,eAAqB;AAC7C,MAAA,IAAA,CAAK,YAAA,EAAA;AAEL,MAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,IAAA,CAAK,MAAA,CAAO,gBAAA,EAAkB;AACrD,QAAA,IAAA,CAAK,aAAa,MAAA,YAAiB;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,QAAA,EAA8B;AACjD,IAAA,IAAI,IAAA,CAAK,UAAU,QAAA,EAAU;AAC3B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,WAAW,IAAA,CAAK,KAAA;AACtB,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AAGb,IAAA,IAAI,aAAa,QAAA,eAAqB;AACpC,MAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AACpB,MAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AAAA,IACtB,CAAA,MAAA,IAAW,aAAa,WAAA,kBAAwB;AAC9C,MAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AAAA,IACtB,CAAA,MAAA,IAAW,aAAa,MAAA,aAAmB;AACzC,MAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AAAA,IACtB;AAGA,IAAA,IAAA,CAAK,OAAO,aAAA,GAAgB;AAAA,MAC1B,IAAA,EAAM,QAAA;AAAA,MACN,EAAA,EAAI,QAAA;AAAA,MACJ,SAAA,sBAAe,IAAA,EAAK;AAAA,MACpB,cAAc,IAAA,CAAK;AAAA,KACpB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AACpB,IAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AACpB,IAAA,IAAA,CAAK,eAAA,GAAkB,CAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAW,EAAA,EAAkC;AACjD,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,EAAU,EAAG;AACrB,MAAA,MAAM,IAAI,uBAAA;AAAA,QACR,CAAA,0CAAA,EAA6C,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAA;AAAA,OAClE;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,EAAG;AACxB,MAAA,IAAA,CAAK,aAAA,EAAc;AACnB,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,GAAA,GAAM,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACpE,MAAA,IAAA,CAAK,cAAc,GAAG,CAAA;AACtB,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAME;AACA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,KAAK,QAAA,EAAS;AAAA,MACrB,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,iBAAiB,IAAA,CAAK,eAAA,GAAkB,IAAI,IAAA,CAAK,IAAA,CAAK,eAAe,CAAA,GAAI,IAAA;AAAA,MACzE,MAAA,EAAQ;AAAA,QACN,OAAA,EAAS,KAAK,MAAA,CAAO,OAAA;AAAA,QACrB,gBAAA,EAAkB,KAAK,MAAA,CAAO,gBAAA;AAAA,QAC9B,gBAAA,EAAkB,KAAK,MAAA,CAAO,gBAAA;AAAA,QAC9B,OAAA,EAAS,KAAK,MAAA,CAAO;AAAA;AACvB,KACF;AAAA,EACF;AACF;AAKO,SAAS,qBAAqB,MAAA,EAA8C;AACjF,EAAA,OAAO,IAAI,eAAe,MAAM,CAAA;AAClC;;;ACtNO,IAAM,eAAN,MAAmB;AAAA,EACxB,WAAA,CACmB,MAEA,eAAA,EACjB;AAHiB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAEA,IAAA,IAAA,CAAA,eAAA,GAAA,eAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKH,MAAM,MAAM,MAAA,EAA6C;AACvD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAoB,aAAA,EAAe,MAAM,CAAA;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,MAAA,EAA2D;AACvE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA2B,eAAA,EAAiB,MAAM,CAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,YAAA,EAAsC;AACjD,IAAA,MAAM,KAAA,GAAQ,YAAA,IAAgB,IAAA,CAAK,eAAA,IAAkB;AACrD,IAAA,MAAM,IAAA,CAAK,KAAK,IAAA,CAAW,cAAA,EAAgB,QAAQ,EAAE,YAAA,EAAc,KAAA,EAAM,GAAI,MAAS,CAAA;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,EAAA,GAAmC;AACvC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAyB,UAAU,CAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,MAAA,EAA6D;AAC1E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA4B,gBAAA,EAAkB,MAAM,CAAA;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,KAAA,EAA+D;AACnF,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAA4C,mBAAA,EAAqB,EAAE,OAAO,CAAA;AAAA,EAC7F;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,KAAA,EAA6C;AAC5D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAyB,mBAAA,EAAqB;AAAA,MAC7D,MAAA,EAAQ,EAAE,KAAA;AAAM,KACjB,CAAA;AAAA,EACH;AACF;;;ACvCO,IAAM,eAAN,MAAmB;AAAA,EAIxB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAC3B,IAAA,IAAA,CAAK,GAAA,GAAM;AAAA,MACT,IAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAAA,MAC5B,KAAA,EAAO,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAAA,MAC9B,KAAA,EAAO,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,IAAI;AAAA,KAChC;AAAA,EACF;AAAA;AAAA,EARS,GAAA;AAAA;AAAA;AAAA;AAAA,EAaT,MAAM,OAAO,MAAA,EAAmD;AAC9D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAsB,OAAA,EAAS,MAAM,CAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,MAAA,EAAuC;AACxD,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AACvC,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,MAAA,EAAgD;AACzD,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAkB,OAAA,EAAS,EAAE,QAAyE,CAAA;AAAA,EACzH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,EAAA,EAA0B;AAClC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAS,CAAA,MAAA,EAAS,EAAE,CAAA,CAAE,CAAA;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,EAAA,EAA2B;AACtC,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAA,MAAA,EAAS,EAAE,CAAA,CAAE,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,EAAA,EAA0B;AACpC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAU,CAAA,MAAA,EAAS,EAAE,CAAA,MAAA,CAAQ,CAAA;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CAAc,EAAA,EAAY,QAAA,EAAkD;AAChF,IAAA,OAAO,IAAA,CAAK,KAAK,GAAA,CAA2B,CAAA,MAAA,EAAS,EAAE,CAAA,SAAA,CAAA,EAAa,EAAE,UAAU,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,GAA8B;AAClC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAc,aAAa,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,GAAA,EAA0C;AAC1D,IAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,IAAI,GAAA,CAAI,SAAS,GAAA,EAAK;AACpB,MAAA,MAAM,IAAI,MAAM,yCAAyC,CAAA;AAAA,IAC3D;AACA,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAsB,cAAA,EAAgB;AAAA,MACrD,QAAQ,EAAE,GAAA,EAAK,GAAA,CAAI,IAAA,CAAK,GAAG,CAAA;AAAE,KAC9B,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,MAAA,EAAyD;AACzE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA0B,YAAA,EAAc,MAAM,CAAA;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,MAAA,EAAmD;AAC7D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAsB,aAAA,EAAe,MAAM,CAAA;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,CAAS,EAAA,EAAY,MAAA,EAA0D;AACnF,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAA2B,CAAA,MAAA,EAAS,EAAE,aAAa,MAAM,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,CAAK,EAAA,EAAY,MAAA,EAAsE;AAC3F,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAA2C,CAAA,MAAA,EAAS,EAAE,SAAS,MAAM,CAAA;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAA,CAAU,EAAA,EAAY,MAAA,EAA2D;AACrF,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAA2B,CAAA,MAAA,EAAS,EAAE,cAAc,MAAM,CAAA;AAAA,EAC7E;AAAA;AAAA,EAIA,MAAc,QAAQ,MAAA,EAA+C;AACnE,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAkB,WAAA,EAAa,EAAE,QAAyE,CAAA;AAAA,EAC7H;AAAA,EAEA,MAAc,SAAS,MAAA,EAAmD;AACxE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAuB,iBAAA,EAAmB,MAAM,CAAA;AAAA,EACnE;AAAA,EAEA,MAAc,SAAS,MAAA,EAAmD;AACxE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAuB,iBAAA,EAAmB,MAAM,CAAA;AAAA,EACnE;AACF;;;AC9JO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKhD,MAAM,IAAA,GAAsC;AAC1C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA0B,SAAS,CAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,IAAA,EAAoC;AAC5C,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAiB,WAAW,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAA,CAAa,IAAA,EAAc,MAAA,EAAuD;AACtF,IAAA,OAAO,IAAA,CAAK,KAAK,GAAA,CAAiB,CAAA,QAAA,EAAW,mBAAmB,IAAI,CAAC,WAAW,MAAM,CAAA;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,IAAA,EAAmC;AAChD,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAgB,WAAW,kBAAA,CAAmB,IAAI,CAAC,CAAA,MAAA,CAAQ,CAAA;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,CAAM,IAAA,EAAc,MAAA,EAA8C;AACtE,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA;AAAA,MACf,CAAA,QAAA,EAAW,kBAAA,CAAmB,IAAI,CAAC,CAAA,MAAA,CAAA;AAAA,MACnC,MAAA,GAAS,EAAE,MAAA,EAAO,GAAI;AAAA,KACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,IAAA,EAA4C;AACvD,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAA0B,WAAW,kBAAA,CAAmB,IAAI,CAAC,CAAA,OAAA,CAAS,CAAA;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,IAAA,EAA6B;AACxC,IAAA,MAAM,KAAK,IAAA,CAAK,MAAA,CAAO,WAAW,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EAC9D;AACF;;;ACvDO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKhD,MAAM,IAAA,GAAiC;AACrC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAqB,UAAU,CAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,EAAA,EAA6B;AACrC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAY,CAAA,SAAA,EAAY,EAAE,CAAA,CAAE,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,MAAA,EAA+D;AAC5E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA6B,mBAAA,EAAqB,MAAM,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAA,CAAU,EAAA,EAAY,MAAA,EAA8C;AACxE,IAAA,MAAM,KAAK,IAAA,CAAK,IAAA,CAAK,CAAA,SAAA,EAAY,EAAE,cAAc,MAAM,CAAA;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,EAAA,EAA2B;AAC1C,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAA,SAAA,EAAY,EAAE,CAAA,WAAA,CAAa,CAAA;AAAA,EAClD;AACF;;;ACnCO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKhD,MAAM,KAAK,MAAA,EAAmD;AAC5D,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAgB,YAAA,EAAc,EAAE,QAAyE,CAAA;AAAA,EAC5H;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,MAAA,EAA+D;AAC1E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA6B,YAAA,EAAc,MAAM,CAAA;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,EAAA,EAA+B;AACvC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAc,CAAA,WAAA,EAAc,EAAE,CAAA,CAAE,CAAA;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,EAAA,EAAY,MAAA,EAAiD;AACxE,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAc,CAAA,WAAA,EAAc,EAAE,IAAI,MAAM,CAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,EAAA,EAA2B;AACtC,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAA,WAAA,EAAc,EAAE,CAAA,CAAE,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,EAAA,EAA+B;AACzC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAe,CAAA,WAAA,EAAc,EAAE,CAAA,MAAA,CAAQ,CAAA;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,EAAA,EAA+B;AAC1C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAe,CAAA,WAAA,EAAc,EAAE,CAAA,OAAA,CAAS,CAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,EAAA,EAA8C;AAC1D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA8B,CAAA,WAAA,EAAc,EAAE,CAAA,QAAA,CAAU,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,CAAW,EAAA,EAAY,KAAA,EAAwC;AACnE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAmB,CAAA,WAAA,EAAc,EAAE,CAAA,QAAA,CAAA,EAAY;AAAA,MAC9D,MAAA,EAAQ,KAAA,GAAQ,EAAE,KAAA,EAAM,GAAI;AAAA,KAC7B,CAAA;AAAA,EACH;AACF;;;ACKO,IAAM,oBAAN,MAAwB;AAAA,EAI7B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO;AAAA,MACV,IAAA,EAAM,IAAA,CAAK,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AAAA,MACrC,GAAA,EAAK,IAAA,CAAK,cAAA,CAAe,IAAA,CAAK,IAAI,CAAA;AAAA,MAClC,SAAA,EAAW,IAAA,CAAK,qBAAA,CAAsB,IAAA,CAAK,IAAI,CAAA;AAAA,MAC/C,eAAA,EAAiB,IAAA,CAAK,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA;AAAA,MAClD,eAAA,EAAiB,IAAA,CAAK,kBAAA,CAAmB,IAAA,CAAK,IAAI;AAAA,KACpD;AAAA,EACF;AAAA;AAAA,EAVS,IAAA;AAAA;AAAA;AAAA;AAAA,EAeT,MAAM,KAAK,MAAA,EAA2D;AACpE,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAwB,YAAA,EAAc,EAAE,QAAyE,CAAA;AAAA,EACpI;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,MAAA,EAA+D;AAC1E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA6B,YAAA,EAAc,MAAM,CAAA;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,EAAA,EAAuC;AAC/C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAsB,CAAA,WAAA,EAAc,EAAE,CAAA,CAAE,CAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,EAAA,EAAuC;AAClD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAuB,CAAA,WAAA,EAAc,EAAE,CAAA,OAAA,CAAS,CAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MAAM,EAAA,EAAuC;AACjD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAuB,CAAA,WAAA,EAAc,EAAE,CAAA,MAAA,CAAQ,CAAA;AAAA,EAClE;AAAA;AAAA,EAIA,MAAc,iBAAiB,UAAA,EAA4C;AACzE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAmB,CAAA,WAAA,EAAc,UAAU,CAAA,KAAA,CAAO,CAAA;AAAA,EACrE;AAAA,EAEA,MAAc,cAAA,CAAe,UAAA,EAAoB,KAAA,EAAqC;AACpF,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAiB,cAAc,UAAU,CAAA,MAAA,EAAS,KAAK,CAAA,CAAE,CAAA;AAAA,EAC5E;AAAA,EAEA,MAAc,sBAAsB,UAAA,EAAkD;AACpF,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAyB,CAAA,WAAA,EAAc,UAAU,CAAA,YAAA,CAAc,CAAA;AAAA,EAClF;AAAA,EAEA,MAAc,mBAAmB,KAAA,EAA6C;AAC5E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAyB,CAAA,MAAA,EAAS,KAAK,CAAA,aAAA,CAAe,CAAA;AAAA,EACzE;AAAA,EAEA,MAAc,kBAAA,CACZ,KAAA,EACA,MAAA,EACkC;AAClC,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAA8B,CAAA,MAAA,EAAS,KAAK,iBAAiB,MAAM,CAAA;AAAA,EACtF;AACF;;;ACtJO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKhD,MAAM,IAAA,GAAmC;AACvC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAuB,oBAAoB,CAAA;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,MAAA,EAA+D;AAC1E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAsB,oBAAA,EAAsB,MAAM,CAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,EAAA,EAAsC;AAC9C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAqB,CAAA,mBAAA,EAAsB,EAAE,CAAA,CAAE,CAAA;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,EAAA,EAAY,MAAA,EAA+D;AACtF,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAqB,CAAA,mBAAA,EAAsB,EAAE,IAAI,MAAM,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,EAAA,EAA2B;AACtC,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAA,mBAAA,EAAsB,EAAE,CAAA,CAAE,CAAA;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,EAAA,EAA0C;AACnD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA0B,CAAA,mBAAA,EAAsB,EAAE,CAAA,KAAA,CAAO,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,EAAA,EAAgD;AAClE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA+B,CAAA,mBAAA,EAAsB,EAAE,CAAA,WAAA,CAAa,CAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CAAc,SAAA,EAAmB,UAAA,EAAoE;AACzG,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA;AAAA,MACf,CAAA,mBAAA,EAAsB,SAAS,CAAA,OAAA,EAAU,UAAU,CAAA;AAAA,KACrD;AAAA,EACF;AACF;;;AC7DO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKhD,MAAM,IAAA,GAAiC;AACrC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAqB,WAAW,CAAA;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,MAAA,EAA2D;AACtE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA2B,WAAA,EAAa,MAAM,CAAA;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,EAAA,EAAoC;AAC5C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAmB,CAAA,UAAA,EAAa,EAAE,CAAA,CAAE,CAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,EAAA,EAAY,MAAA,EAAoD;AAC3E,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAmB,CAAA,UAAA,EAAa,EAAE,IAAI,MAAM,CAAA;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,EAAA,EAA2B;AACtC,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAA,UAAA,EAAa,EAAE,CAAA,CAAE,CAAA;AAAA,EAC1C;AACF;;;AChCO,IAAM,wBAAN,MAA4B;AAAA,EACjC,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKhD,MAAM,OAAO,MAAA,EAAuE;AAClF,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAiC,gBAAA,EAAkB,MAAM,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,GAAuC;AAC3C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA2B,gBAAgB,CAAA;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,EAAA,EAAmC;AAC3C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAkB,CAAA,eAAA,EAAkB,EAAE,CAAA,CAAE,CAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,EAAA,EAAY,MAAA,EAAyD;AAChF,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAkB,CAAA,eAAA,EAAkB,EAAE,IAAI,MAAM,CAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,EAAA,EAA2B;AACtC,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAA,eAAA,EAAkB,EAAE,CAAA,CAAE,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,GAAuC;AAC3C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAuB,sBAAsB,CAAA;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,EAAA,EAA2C;AAC1D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA0B,CAAA,eAAA,EAAkB,EAAE,CAAA,QAAA,CAAU,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,IAAA,EAA0C;AACxD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAuB,2BAAA,EAA6B;AAAA,MACnE,MAAA,EAAQ,EAAE,IAAA;AAAK,KAChB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,IAAA,EAAyC;AAC1D,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAAuB,8BAAA,EAAgC,EAAE,MAAM,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,eAAA,GAAiD;AACrD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA0B,8BAA8B,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,sBAAA,GAAwD;AAC5D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA2B,yCAAyC,CAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,iBAAA,GAAmC;AACvC,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,oCAAoC,CAAA;AAAA,EAC3D;AACF;;;AC5HO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,MAAM,SAAA,GAAoC;AACxC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAmB,iBAAiB,CAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,MAAA,EAAyE;AAC1F,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAkC,iBAAA,EAAmB,MAAM,CAAA;AAAA,EAC9E;AACF;;;ACpBO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,MAAM,GAAA,GAA8B;AAClC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAmB,YAAY,CAAA;AAAA,EAClD;AACF;;;ACbO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,MAAM,GAAA,GAA+B;AACnC,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAoB,WAAW,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAA,GAA6B;AACjC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAgB,cAAA,EAAgB;AAAA,QAC9C,MAAA,EAAQ,KAAA;AAAA,QACR,aAAA,EAAe,IAAA;AAAA,QACf,SAAA,EAAW;AAAA,OACZ,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAA,GAA8B;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAgB,eAAA,EAAiB;AAAA,QAC/C,MAAA,EAAQ,KAAA;AAAA,QACR,aAAA,EAAe,IAAA;AAAA,QACf,SAAA,EAAW;AAAA,OACZ,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AACF;;;AChDO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,MAAM,GAAA,GAAuB;AAC3B,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAY,UAAA,EAAY;AAAA,MACvC,aAAA,EAAe,IAAA;AAAA;AAAA,MAEf,OAAA,EAAS,EAAE,MAAA,EAAQ,YAAA;AAAa,KACjC,CAAA;AAAA,EACH;AACF;;;ACGO,IAAM,gBAAN,MAAoB;AAAA,EACzB,WAAA,CACmB,MACA,QAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAChB;AAAA,EAEK,OAAA,GAAkC;AACxC,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAClB,MAAA,MAAM,IAAI,oBAAoB,wFAAwF,CAAA;AAAA,IACxH;AACA,IAAA,OAAO,EAAE,aAAA,EAAe,IAAA,CAAK,QAAA,EAAS;AAAA,EACxC;AAAA;AAAA,EAGA,MAAM,kBAAkB,MAAA,EAAuE;AAC7F,IAAA,MAAM,KAAwE,MAAA,GAC1E;AAAA,MACE,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,WAAW,MAAA,CAAO;AAAA,KACpB,GACA,MAAA;AACJ,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA2B,sBAAA,EAAwB;AAAA,MAClE,MAAA,EAAQ,EAAA;AAAA,MACR,OAAA,EAAS,KAAK,OAAA;AAAQ,KACvB,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,mBAAmB,MAAA,EAAiF;AACxG,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAsC,sBAAA,EAAwB,MAAA,EAAQ;AAAA,MACrF,OAAA,EAAS,KAAK,OAAA;AAAQ,KACvB,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,gBAAgB,EAAA,EAA8C;AAClE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA6B,CAAA,qBAAA,EAAwB,EAAE,CAAA,CAAA,EAAI;AAAA,MAC1E,OAAA,EAAS,KAAK,OAAA;AAAQ,KACvB,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,kBAAA,CAAmB,EAAA,EAAY,MAAA,EAA8D;AACjG,IAAA,OAAO,KAAK,IAAA,CAAK,KAAA,CAAoB,CAAA,qBAAA,EAAwB,EAAE,IAAI,MAAA,EAAQ;AAAA,MACzE,OAAA,EAAS,KAAK,OAAA;AAAQ,KACvB,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,kBAAA,CAAmB,EAAA,EAAY,MAAA,EAAuD;AAC1F,IAAA,MAAM,KAAwE,MAAA,GAC1E,EAAE,UAAA,EAAY,MAAA,CAAO,YAAW,GAChC,MAAA;AACJ,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAA,qBAAA,EAAwB,EAAE,CAAA,CAAA,EAAI;AAAA,MACnD,OAAA,EAAS,KAAK,OAAA,EAAQ;AAAA,MACtB,MAAA,EAAQ;AAAA,KACT,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,YAAA,CAAa,KAAA,EAAe,MAAA,EAA+D;AAC/F,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAA0B,CAAA,qBAAA,EAAwB,KAAK,aAAa,MAAA,EAAQ;AAAA,MAC3F,OAAA,EAAS,KAAK,OAAA;AAAQ,KACvB,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,WAAW,KAAA,EAA8B;AAC7C,IAAA,MAAM,KAAK,IAAA,CAAK,IAAA,CAAW,CAAA,qBAAA,EAAwB,KAAK,gBAAgB,MAAA,EAAW;AAAA,MACjF,OAAA,EAAS,KAAK,OAAA;AAAQ,KACvB,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,QAAA,GAAwC;AAC5C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAwB,cAAA,EAAgB;AAAA,MACvD,OAAA,EAAS,KAAK,OAAA;AAAQ,KACvB,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,SAAA,GAAwC;AAC5C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAuB,cAAA,EAAgB;AAAA,MACtD,OAAA,EAAS,KAAK,OAAA;AAAQ,KACvB,CAAA;AAAA,EACH;AACF;ACjGA,SAAS,QAAQ,IAAA,EAAqD;AACpE,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,OAAOC,aAAA,CAAO,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAAA,EACjC;AACA,EAAA,IAAI,gBAAgB,UAAA,EAAY;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAI,WAAW,IAAI,CAAA;AAC5B;AAEA,SAAS,eAAA,CAAgB,QAAgB,IAAA,EAA0B;AACjE,EAAA,MAAM,GAAA,GAAMC,kBAAW,QAAA,EAAU,MAAM,EAAE,MAAA,CAAO,IAAI,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AAClE,EAAA,OAAO,UAAU,GAAG,CAAA,CAAA;AACtB;AAEA,SAAS,eAAA,CAAgB,MAAA,EAAgB,IAAA,EAAkB,SAAA,EAA2B;AAEpF,EAAA,MAAM,OAAA,GAAU,CAAA,EAAG,SAAS,CAAA,CAAA,EAAID,aAAA,CAAO,KAAK,IAAI,CAAA,CAAE,QAAA,CAAS,MAAM,CAAC,CAAA,CAAA;AAClE,EAAA,MAAM,GAAA,GAAMC,iBAAA,CAAW,QAAA,EAAU,MAAM,CAAA,CAAE,OAAO,OAAA,EAAS,MAAM,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AAC7E,EAAA,OAAO,CAAA,EAAA,EAAK,SAAS,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA;AACjC;AAEO,IAAM,2BAAN,MAA+B;AAAA,EACpC,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,MAAM,MAAA,CAAO,KAAA,EAAe,IAAA,EAAyC,OAAA,EAAoD;AACvH,IAAA,MAAM,KAAA,GAAQ,QAAQ,IAAI,CAAA;AAE1B,IAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,KAAc,OAAA,CAAQ,SAAS,eAAA,CAAgB,OAAA,CAAQ,MAAA,EAAQ,KAAK,CAAA,GAAI,MAAA,CAAA;AAClG,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAI,gBAAgB,wEAAwE,CAAA;AAAA,IACpG;AAEA,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,cAAA,EAAgB,kBAAA;AAAA,MAChB,kBAAkB,OAAA,CAAQ,WAAA;AAAA,MAC1B,qBAAA,EAAuB;AAAA,KACzB;AAEA,IAAA,IAAI,QAAQ,YAAA,EAAc;AACxB,MAAA,OAAA,CAAQ,iBAAiB,IAAI,OAAA,CAAQ,YAAA;AAAA,IACvC;AACA,IAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,MAAA,OAAA,CAAQ,mBAAmB,IAAI,OAAA,CAAQ,cAAA;AAAA,IACzC;AAEA,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAc,CAAA,UAAA,EAAa,KAAK,CAAA,OAAA,CAAA,EAAW;AAAA,MACzD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,KAAA;AAAA,MACT,OAAA;AAAA,MACA,qBAAA,EAAuB,IAAA;AAAA,MACvB,sBAAA,EAAwB;AAAA,KACzB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAA,CAAO,KAAA,EAAe,IAAA,EAAyC,OAAA,GAAsC,EAAC,EAAkB;AAC5H,IAAA,MAAM,KAAA,GAAQ,QAAQ,IAAI,CAAA;AAC1B,IAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AAEnE,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,KAAc,OAAA,CAAQ,MAAA,GAAS,gBAAgB,OAAA,CAAQ,MAAA,EAAQ,KAAA,EAAO,SAAS,CAAA,GAAI,MAAA,CAAA;AAC7G,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAI,gBAAgB,wEAAwE,CAAA;AAAA,IACpG;AAEA,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,cAAA,EAAgB,kBAAA;AAAA,MAChB,kBAAA,EAAoB;AAAA,KACtB;AAEA,IAAA,IAAI,QAAQ,YAAA,EAAc;AACxB,MAAA,OAAA,CAAQ,iBAAiB,IAAI,OAAA,CAAQ,YAAA;AAAA,IACvC;AACA,IAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,MAAA,OAAA,CAAQ,mBAAmB,IAAI,OAAA,CAAQ,cAAA;AAAA,IACzC;AAEA,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAc,CAAA,UAAA,EAAa,KAAK,CAAA,OAAA,CAAA,EAAW;AAAA,MACzD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,KAAA;AAAA,MACT,OAAA;AAAA,MACA,qBAAA,EAAuB,IAAA;AAAA,MACvB,sBAAA,EAAwB;AAAA,KACzB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAA,CAAO,KAAA,EAAe,MAAA,EAAmC,IAAA,EAA0E;AACvI,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,GAAI,MAAM,YAAA,GAAe,EAAE,mBAAmB,IAAA,CAAK,YAAA,KAAiB,EAAC;AAAA,MACrE,GAAI,MAAM,cAAA,GAAiB,EAAE,qBAAqB,IAAA,CAAK,cAAA,KAAmB;AAAC,KAC7E;AAEA,IAAA,MAAM,KAAK,IAAA,CAAK,IAAA,CAAW,CAAA,UAAA,EAAa,KAAK,WAAW,MAAA,EAAQ;AAAA,MAC9D;AAAA,KACD,CAAA;AAAA,EACH;AACF;;;ACjHO,IAAM,sBAAA,GAAiD;AAAA,EAC5D,eAAA,EAAiB,oBAAA;AAAA,EACjB,UAAA,EAAY,aAAA;AAAA,EACZ,YAAA,EAAc,eAAA;AAAA,EACd,SAAA,EAAW,YAAA;AAAA,EACX,UAAA,EAAY,aAAA;AAAA,EACZ,eAAA,EAAiB,kBAAA;AAAA,EACjB,gBAAA,EAAkB,mBAAA;AAAA,EAClB,kBAAA,EAAoB,qBAAA;AAAA,EACpB,YAAA,EAAc,eAAA;AAAA,EACd,IAAA,EAAM,MAAA;AAAA,EACN,KAAA,EAAO;AACT,CAAA;AASO,SAAS,aAAa,IAAA,EAAsB;AACjD,EAAA,OAAO,sBAAA,CAAuB,IAAI,CAAA,IAAK,IAAA;AACzC;;;ACRO,IAAM,0BAAN,MAA8B;AAAA,EAClB,OAAA;AAAA;AAAA,EAET,EAAA,GAAU,IAAA;AAAA,EACV,KAAA,GAAyB,cAAA;AAAA,EACzB,iBAAA,GAAoB,CAAA;AAAA,EACpB,cAAA,GAAuD,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvD,WAAA,GAAc,KAAA;AAAA,EACd,aAAA,uBAAqD,GAAA,EAAI;AAAA;AAAA,EAGzD,aAAA,uBAA+D,GAAA,EAAI;AAAA,EACnE,iBAAA,uBAAkD,GAAA,EAAI;AAAA,EACtD,mBAAA,uBAAiE,GAAA,EAAI;AAAA,EAE7E,YAAY,OAAA,EAAoC;AAM9C,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,GAAG,OAAA;AAAA,MACH,aAAA,EAAe,QAAQ,aAAA,IAAiB,IAAA;AAAA,MACxC,oBAAA,EAAsB,QAAQ,oBAAA,IAAwB,EAAA;AAAA,MACtD,cAAA,EAAgB,QAAQ,cAAA,IAAkB,GAAA;AAAA,MAC1C,iBAAA,EAAmB,QAAQ,iBAAA,IAAqB,GAAA;AAAA;AAAA;AAAA,MAGhD,aAAA,EAAe,OAAA,CAAQ,aAAA,KAAkB,YAAY,OAAA,CAAQ,KAAA,CAAA;AAAA,MAC7D,KAAA,EAAO,OAAA,CAAQ,KAAA,KAAU,MAAM;AAAA,MAAC,CAAA;AAAA,KAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBAAA,GAA8C;AAC1D,IAAA,IAAI,OAAO,cAAc,WAAA,EAAa;AACpC,MAAA,OAAO,SAAA;AAAA,IACT;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,OAAO,IAAI,CAAA;AAClC,IAAA,OAAO,QAAA,CAAS,OAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,GAAyB;AAC7B,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,WAAA,IAAe,IAAA,CAAK,UAAU,YAAA,EAAc;AAC7D,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AAG1B,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI;AACF,MAAA,KAAA,GAAQ,MAAM,KAAK,UAAA,EAAW;AAAA,IAChC,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,KAAK,CAAA,CAAE,CAAA;AAAA,IAC9D;AAEA,IAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,CAAA,cAAA,EAAiB,WAAA,CAAY,KAAK,CAAC,CAAA,CAAE,CAAA;AAGxD,IAAA,IAAI,aAAA;AACJ,IAAA,IAAI;AACF,MAAA,aAAA,GAAgB,MAAM,KAAK,gBAAA,EAAiB;AAAA,IAC9C,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yCAAA,EAA4C,KAAK,CAAA,CAAE,CAAA;AAAA,IACrE;AAEA,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,EAAA,GAAK,IAAI,aAAA,CAAc,KAAK,CAAA;AAEjC,QAAA,IAAA,CAAK,EAAA,CAAG,SAAS,MAAM;AACrB,UAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,qBAAqB,CAAA;AACxC,UAAA,IAAA,CAAK,SAAS,WAAW,CAAA;AACzB,UAAA,IAAA,CAAK,iBAAA,GAAoB,CAAA;AACzB,UAAA,IAAA,CAAK,cAAA,EAAe;AACpB,UAAA,OAAA,EAAQ;AAAA,QACV,CAAA;AAGA,QAAA,IAAA,CAAK,EAAA,CAAG,SAAA,GAAY,CAAC,KAAA,KAAe;AAClC,UAAA,IAAA,CAAK,aAAA,CAAc,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,GAAW,MAAM,IAAA,GAAO,MAAA,CAAO,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,QACrF,CAAA;AAGA,QAAA,IAAA,CAAK,EAAA,CAAG,OAAA,GAAU,CAAC,KAAA,KAAe;AAChC,UAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA,kBAAA,EAAqB,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,MAAM,CAAA,CAAE,CAAA;AACpE,UAAA,IAAA,CAAK,gBAAA,EAAiB;AACtB,UAAA,IAAI,IAAA,CAAK,UAAU,YAAA,EAAc;AAC/B,YAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,MAAM,MAAA,IAAU,eAAe,EAAE,CAAC,CAAA;AAAA,UACrF;AAAA,QACF,CAAA;AAGA,QAAA,IAAA,CAAK,EAAA,CAAG,OAAA,GAAU,CAAC,KAAA,KAAe;AAChC,UAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,iBAAA,EAAmB,KAAK,CAAA;AAM3C,UAAA,IAAI,kBAAA,CAAmB,KAAK,CAAA,EAAG;AAC7B,YAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,UACrB;AAAA,QACF,CAAA;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,QAAA,MAAA,CAAO,KAAK,CAAA;AAAA,MACd;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAmB;AACjB,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAChC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AAEA,IAAA,IAAI,KAAK,EAAA,EAAI;AACX,MAAA,IAAA,CAAK,GAAG,OAAA,GAAU,IAAA;AAClB,MAAA,IAAA,CAAK,EAAA,CAAG,KAAA,CAAM,GAAA,EAAM,mBAAmB,CAAA;AACvC,MAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AAAA,IACZ;AAEA,IAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAU,MAAA,EAA2C;AACzD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA;AAEvC,IAAA,IAAI,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,QAAQ,CAAA,EAAG;AACpC,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,QAAA,EAAU,MAAM,CAAA;AAEvC,IAAA,IAAI,IAAA,CAAK,UAAU,WAAA,EAAa;AAC9B,MAAA,IAAA,CAAK,WAAA,CAAY,aAAa,MAAM,CAAA;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAY,MAAA,EAA2C;AAC3D,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA;AAEvC,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,QAAQ,CAAA,EAAG;AACrC,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,OAAO,QAAQ,CAAA;AAElC,IAAA,IAAI,IAAA,CAAK,UAAU,WAAA,EAAa;AAC9B,MAAA,IAAA,CAAK,WAAA,CAAY,eAAe,MAAM,CAAA;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,EAAA,CAAgC,MAAS,OAAA,EAAmC;AAC1E,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA,EAAG;AACjC,MAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAA,kBAAM,IAAI,KAAK,CAAA;AAAA,IACxC;AACA,IAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA,CAAG,IAAI,OAAO,CAAA;AAGzC,IAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAAiC,MAAS,OAAA,EAA6B;AACrE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA;AAC5C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAO,OAAO,CAAA;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,OAAA,EAA0C;AAChD,IAAA,IAAA,CAAK,iBAAA,CAAkB,IAAI,OAAO,CAAA;AAClC,IAAA,OAAO,MAAM,IAAA,CAAK,iBAAA,CAAkB,MAAA,CAAO,OAAO,CAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,OAAA,EAAuD;AACnE,IAAA,IAAA,CAAK,mBAAA,CAAoB,IAAI,OAAO,CAAA;AACpC,IAAA,OAAO,MAAM,IAAA,CAAK,mBAAA,CAAoB,MAAA,CAAO,OAAO,CAAA;AAAA,EACtD;AAAA;AAAA,EAIA,MAAc,UAAA,GAA8B;AAE1C,IAAA,MAAM,MAAA,GAAS,KAAK,OAAA,CAAQ,KAAA;AAI5B,IAAA,MAAM,eAAe,IAAA,CAAK,WAAA;AAC1B,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,OAAA,CAAQ,cAAc,YAAY,CAAA;AAC3D,IAAA,OAAO,CAAA,EAAG,MAAM,CAAA,iBAAA,EAAoB,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAAA,EAC/D;AAAA,EAEQ,SAAS,KAAA,EAA8B;AAC7C,IAAA,IAAI,IAAA,CAAK,UAAU,KAAA,EAAO;AACxB,MAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,MAAA,IAAA,CAAK,oBAAoB,OAAA,CAAQ,CAAC,OAAA,KAAY,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAC9D;AAAA,EACF;AAAA,EAEQ,cAAc,IAAA,EAAoB;AACxC,IAAA,IAAI;AAKF,MAAA,MAAM,OAAA,GAAU,eAAA,CAAgB,IAAA,CAAK,KAAA,CAAM,IAAI,CAAC,CAAA;AAOhD,MAAA,MAAM,SAAA,GAAY,YAAA,CAAa,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA;AACnD,MAAA,OAAA,CAAQ,IAAA,GAAO,SAAA;AACf,MAAA,MAAM,KAAA,GAAQ,OAAA;AACd,MAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,gBAAA,EAAmB,SAAS,IAAI,KAAK,CAAA;AAGxD,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,SAA8B,CAAA;AACtE,MAAA,IAAI,QAAA,EAAU;AAEZ,QAAA,MAAM,YAAa,KAAA,CAAc,IAAA;AACjC,QAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,UAAA,IAAI;AACF,YAAA,OAAA,CAAQ,SAAS,CAAA;AAAA,UACnB,SAAS,KAAA,EAAO;AACd,YAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,qBAAA,EAAuB,KAAK,CAAA;AAAA,UACjD;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAGA,MAAA,IAAA,CAAK,iBAAA,CAAkB,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC1C,QAAA,IAAI;AACF,UAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,QACf,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,qBAAA,EAAuB,KAAK,CAAA;AAAA,QACjD;AAAA,MACF,CAAC,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,yBAAA,EAA2B,EAAE,IAAA,EAAM,OAAO,CAAA;AAAA,IAC/D;AAAA,EACF;AAAA,EAEQ,gBAAA,GAAyB;AAC/B,IAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AAEV,IAAA,IAAI,KAAK,OAAA,CAAQ,aAAA,IAAiB,KAAK,iBAAA,GAAoB,IAAA,CAAK,QAAQ,oBAAA,EAAsB;AAC5F,MAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,IACzB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,iBAAA,GAA0B;AAChC,IAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,IAAA,IAAA,CAAK,iBAAA,EAAA;AAEL,IAAA,MAAM,YAAY,IAAA,CAAK,GAAA;AAAA,MACrB,IAAA,CAAK,QAAQ,cAAA,GAAiB,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,oBAAoB,CAAC,CAAA;AAAA,MACpE,KAAK,OAAA,CAAQ;AAAA,KACf;AAGA,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,SAAA,GAAY,KAAK,MAAA,EAAO,GAAI,YAAY,IAAI,CAAA;AAErE,IAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,KAAK,iBAAiB,CAAA,IAAA,EAAO,KAAK,CAAA,EAAA,CAAI,CAAA;AAEzF,IAAA,IAAA,CAAK,cAAA,GAAiB,WAAW,YAAY;AAC3C,MAAA,IAAI;AACF,QAAA,MAAM,KAAK,OAAA,EAAQ;AAAA,MACrB,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,kBAAA,EAAoB,KAAK,CAAA;AAAA,MAE9C;AAAA,IACF,GAAG,KAAK,CAAA;AAAA,EACV;AAAA,EAEQ,cAAA,GAAuB;AAC7B,IAAA,KAAA,MAAW,MAAA,IAAU,IAAA,CAAK,aAAA,CAAc,MAAA,EAAO,EAAG;AAChD,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,WAAA,CAAY,aAAa,MAAM,CAAA;AAAA,MACtC,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,uBAAA,EAAyB,EAAE,MAAA,EAAQ,OAAO,CAAA;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,WAAA,CAAY,KAAkC,MAAA,EAAkC;AACtF,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,IAAM,IAAA,CAAK,UAAU,WAAA,EAAa;AAC1C,MAAA,MAAM,IAAI,MAAM,yBAAyB,CAAA;AAAA,IAC3C;AAEA,IAAA,MAAM,OAAA,GAA4B;AAAA,MAChC,GAAA;AAAA,MACA,OAAO,MAAA,CAAO,SAAA;AAAA,MACd,QAAQ,MAAA,CAAO;AAAA,KACjB;AACA,IAAA,IAAA,CAAK,EAAA,CAAG,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA;AAAA,EACtC;AAAA,EAEQ,WAAW,MAAA,EAAoC;AACrD,IAAA,OAAO,IAAA,CAAK,UAAU,MAAM,CAAA;AAAA,EAC9B;AACF;AAKO,SAAS,YAAY,GAAA,EAAqB;AAC/C,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,iCAAA,EAAmC,OAAO,CAAA;AAC/D;AASO,SAAS,mBAAmB,KAAA,EAAqB;AACtD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,UAAA,IAAc,MAAM,KAAA,EAAO,MAAA;AAChE,EAAA,IAAI,MAAA,KAAW,GAAA,IAAO,MAAA,KAAW,GAAA,EAAK;AACpC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAA,GAAO,OAAO,KAAA,CAAM,OAAA,IAAW,MAAM,KAAA,EAAO,OAAA,IAAW,KAAA,CAAM,MAAA,IAAU,EAAE,CAAA;AAC/E,EAAA,OAAO,eAAA,CAAgB,KAAK,IAAI,CAAA;AAClC;;;ACvYO,IAAM,oBAAN,MAAwB;AAAA,EACZ,OAAA;AAAA;AAAA,EAET,WAAA,GAAmB,IAAA;AAAA,EACnB,KAAA,GAAyB,cAAA;AAAA,EACzB,iBAAA,GAAoB,CAAA;AAAA,EACpB,cAAA,GAAuD,IAAA;AAAA,EACvD,MAAA,GAAoC,IAAA;AAAA;AAAA,EAGpC,aAAA,uBAA+D,GAAA,EAAI;AAAA,EACnE,iBAAA,uBAAkD,GAAA,EAAI;AAAA,EACtD,mBAAA,uBAAiE,GAAA,EAAI;AAAA,EAE7E,YAAY,OAAA,EAAoC;AAK9C,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,GAAG,OAAA;AAAA,MACH,aAAA,EAAe,QAAQ,aAAA,IAAiB,IAAA;AAAA,MACxC,oBAAA,EAAsB,QAAQ,oBAAA,IAAwB,EAAA;AAAA,MACtD,cAAA,EAAgB,QAAQ,cAAA,IAAkB,GAAA;AAAA,MAC1C,iBAAA,EAAmB,QAAQ,iBAAA,IAAqB,GAAA;AAAA;AAAA;AAAA,MAGhD,aAAA,EAAe,OAAA,CAAQ,aAAA,KAAkB,YAAY,OAAA,CAAQ,KAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAO7D,KAAA,EAAO,OAAA,CAAQ,KAAA,KAAU,MAAM;AAAA,MAAC,CAAA;AAAA,KAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,MAAA,EAA4C;AACxD,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,WAAA,IAAe,IAAA,CAAK,UAAU,YAAA,EAAc;AAC7D,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,SAAS,MAAA,IAAU,IAAA;AAExB,IAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AAE1B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AACtC,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,mBAAA,EAAsB,MAAM,CAAA,CAAE,CAAA;AAIjD,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI,OAAO,gBAAgB,WAAA,EAAa;AACtC,MAAA,eAAA,GAAkB,WAAA;AAAA,IACpB,CAAA,MAAO;AAEL,MAAA,IAAI;AAEF,QAAA,MAAM,GAAA,GAAM,MAAM,OAAO,aAAa,CAAA;AACtC,QAAA,eAAA,GAAkB,GAAA,CAAI,OAAA,IAAW,GAAA,CAAI,WAAA,IAAe,GAAA;AAAA,MACtD,CAAA,CAAA,MAAQ;AACN,QAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,QAAA,MAAM,IAAI,MAAM,8FAA8F,CAAA;AAAA,MAChH;AAAA,IACF;AAGA,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI;AACF,MAAA,KAAA,GAAQ,MAAM,IAAA,CAAK,OAAA,CAAQ,aAAA,EAAc;AAAA,IAC3C,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,KAAK,CAAA,CAAE,CAAA;AAAA,IAC9D;AAEA,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,IAAI;AAGF,QAAA,IAAA,CAAK,WAAA,GAAc,IAAI,eAAA,CAAgB,MAAA,EAAQ;AAAA;AAAA,UAE7C,KAAA,EAAO,CAAC,KAAA,EAAY,IAAA,KAClB,MAAM,KAAA,EAAO;AAAA,YACX,GAAG,IAAA;AAAA,YACH,OAAA,EAAS;AAAA,cACP,GAAG,IAAA,EAAM,OAAA;AAAA,cACT,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC,WACD;AAAA,SACJ,CAAA;AAED,QAAA,IAAA,CAAK,WAAA,CAAY,SAAS,MAAM;AAC9B,UAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,eAAe,CAAA;AAClC,UAAA,IAAA,CAAK,SAAS,WAAW,CAAA;AACzB,UAAA,IAAA,CAAK,iBAAA,GAAoB,CAAA;AACzB,UAAA,OAAA,EAAQ;AAAA,QACV,CAAA;AAGA,QAAA,IAAA,CAAK,WAAA,CAAY,SAAA,GAAY,CAAC,KAAA,KAAe;AAC3C,UAAA,IAAA,CAAK,aAAA,CAAc,MAAM,IAAI,CAAA;AAAA,QAC/B,CAAA;AAEA,QAAA,IAAA,CAAK,WAAA,CAAY,UAAU,MAAM;AAC/B,UAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,WAAW,CAAA;AAE9B,UAAA,IAAI,IAAA,CAAK,UAAU,YAAA,EAAc;AAC/B,YAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAG5B,YAAA,IAAI,KAAK,WAAA,EAAa;AACpB,cAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,cAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,YACrB;AACA,YAAA,MAAA,CAAO,IAAI,KAAA,CAAM,uBAAuB,CAAC,CAAA;AACzC,YAAA;AAAA,UACF;AAEA,UAAA,IAAA,CAAK,gBAAA,EAAiB;AAAA,QACxB,CAAA;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,QAAA,MAAA,CAAO,KAAK,CAAA;AAAA,MACd;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAmB;AACjB,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAChC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AAEA,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAEA,IAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,MAAA,EAA4C;AAC1D,IAAA,IAAA,CAAK,UAAA,EAAW;AAChB,IAAA,MAAM,IAAA,CAAK,QAAQ,MAAM,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,EAAA,CAAgC,MAAS,OAAA,EAAmC;AAC1E,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA,EAAG;AACjC,MAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAA,kBAAM,IAAI,KAAK,CAAA;AAAA,IACxC;AACA,IAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA,CAAG,IAAI,OAAO,CAAA;AAEzC,IAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAAiC,MAAS,OAAA,EAA6B;AACrE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA;AAC5C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAO,OAAO,CAAA;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,OAAA,EAA0C;AAChD,IAAA,IAAA,CAAK,iBAAA,CAAkB,IAAI,OAAO,CAAA;AAClC,IAAA,OAAO,MAAM,IAAA,CAAK,iBAAA,CAAkB,MAAA,CAAO,OAAO,CAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,OAAA,EAAuD;AACnE,IAAA,IAAA,CAAK,mBAAA,CAAoB,IAAI,OAAO,CAAA;AACpC,IAAA,OAAO,MAAM,IAAA,CAAK,mBAAA,CAAoB,MAAA,CAAO,OAAO,CAAA;AAAA,EACtD;AAAA;AAAA,EAIQ,YAAY,MAAA,EAAqC;AAOvD,IAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,MAAA,OAAO,CAAA,EAAG,KAAK,OAAA,CAAQ,OAAO,uBAAuB,kBAAA,CAAmB,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAAA,IACvF;AACA,IAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,MAAA,OAAO,CAAA,EAAG,KAAK,OAAA,CAAQ,OAAO,yBAAyB,kBAAA,CAAmB,MAAA,CAAO,SAAS,CAAC,CAAA,CAAA;AAAA,IAC7F;AACA,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,OAAA,CAAQ,OAAO,CAAA,cAAA,CAAA;AAAA,EAChC;AAAA,EAEQ,SAAS,KAAA,EAA8B;AAC7C,IAAA,IAAI,IAAA,CAAK,UAAU,KAAA,EAAO;AACxB,MAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,MAAA,IAAA,CAAK,oBAAoB,OAAA,CAAQ,CAAC,OAAA,KAAY,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAC9D;AAAA,EACF;AAAA,EAEQ,cAAc,IAAA,EAAoB;AACxC,IAAA,IAAI;AAKF,MAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,IAAA,CAAK,KAAA,CAAM,IAAI,CAAC,CAAA;AAI/C,MAAA,MAAM,SAAA,GAAY,YAAA,CAAa,MAAA,CAAO,MAAA,CAAO,IAAI,CAAC,CAAA;AAClD,MAAA,MAAA,CAAO,IAAA,GAAO,SAAA;AACd,MAAA,MAAM,KAAA,GAAQ,MAAA;AACd,MAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,oBAAA,EAAuB,SAAS,IAAI,KAAK,CAAA;AAG5D,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,SAA8B,CAAA;AACtE,MAAA,IAAI,QAAA,EAAU;AAEZ,QAAA,MAAM,YAAa,KAAA,CAAc,IAAA;AACjC,QAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,UAAA,IAAI;AACF,YAAA,OAAA,CAAQ,SAAS,CAAA;AAAA,UACnB,SAAS,KAAA,EAAO;AACd,YAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,qBAAA,EAAuB,KAAK,CAAA;AAAA,UACjD;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAGA,MAAA,IAAA,CAAK,iBAAA,CAAkB,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC1C,QAAA,IAAI;AACF,UAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,QACf,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,qBAAA,EAAuB,KAAK,CAAA;AAAA,QACjD;AAAA,MACF,CAAC,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,6BAAA,EAA+B,EAAE,IAAA,EAAM,OAAO,CAAA;AAAA,IACnE;AAAA,EACF;AAAA,EAEQ,gBAAA,GAAyB;AAC/B,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAEA,IAAA,IAAI,KAAK,OAAA,CAAQ,aAAA,IAAiB,KAAK,iBAAA,GAAoB,IAAA,CAAK,QAAQ,oBAAA,EAAsB;AAC5F,MAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,IACzB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,iBAAA,GAA0B;AAChC,IAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,IAAA,IAAA,CAAK,iBAAA,EAAA;AAEL,IAAA,MAAM,YAAY,IAAA,CAAK,GAAA;AAAA,MACrB,IAAA,CAAK,QAAQ,cAAA,GAAiB,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,oBAAoB,CAAC,CAAA;AAAA,MACpE,KAAK,OAAA,CAAQ;AAAA,KACf;AAGA,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,SAAA,GAAY,KAAK,MAAA,EAAO,GAAI,YAAY,IAAI,CAAA;AAErE,IAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,CAAA,iCAAA,EAAoC,KAAK,iBAAiB,CAAA,IAAA,EAAO,KAAK,CAAA,EAAA,CAAI,CAAA;AAE7F,IAAA,IAAA,CAAK,cAAA,GAAiB,WAAW,YAAY;AAC3C,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,MAAA,IAAU,KAAA,CAAS,CAAA;AAAA,MAC7C,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,sBAAA,EAAwB,KAAK,CAAA;AAAA,MAClD;AAAA,IACF,GAAG,KAAK,CAAA;AAAA,EACV;AACF;;;AC/QO,IAAM,kBAAN,MAAsB;AAAA;AAAA,EAEV,MAAA;AAAA,EAEjB,YAAY,OAAA,EAA8B;AACxC,IAAA,MAAM,iBAAA,GAA+C;AAAA,MACnD,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,eAAe,OAAA,CAAQ,aAAA;AAAA,MACvB,eAAe,OAAA,CAAQ,aAAA;AAAA,MACvB,sBAAsB,OAAA,CAAQ,oBAAA;AAAA,MAC9B,gBAAgB,OAAA,CAAQ,cAAA;AAAA,MACxB,mBAAmB,OAAA,CAAQ,iBAAA;AAAA,MAC3B,OAAO,OAAA,CAAQ;AAAA,KACjB;AAEA,IAAA,IAAI,OAAA,CAAQ,SAAS,KAAA,EAAO;AAC1B,MAAA,IAAA,CAAK,MAAA,GAAS,IAAI,iBAAA,CAAkB,iBAAiB,CAAA;AAAA,IACvD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAA,GAAS,IAAI,uBAAA,CAAwB,iBAAiB,CAAA;AAAA,IAC7D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,OAAO,QAAA,EAAS;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,GAAyB;AAC7B,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,EAAQ;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,OAAO,UAAA,EAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,UAAU,MAAA,EAA2C;AAEzD,IAAA,IAAI,OAAO,IAAA,CAAK,MAAA,CAAO,SAAA,KAAc,UAAA,EAAY;AAC/C,MAAA,OAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA;AAAA,IACrC;AACA,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,MAAA,EAA2C;AAC3D,IAAA,IAAI,OAAO,IAAA,CAAK,MAAA,CAAO,WAAA,KAAgB,UAAA,EAAY;AACjD,MAAA,OAAO,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,MAAM,CAAA;AAAA,IACvC;AAEA,IAAA,IAAA,CAAK,OAAO,UAAA,EAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,EAAA,CAAgC,MAAS,OAAA,EAAmC;AAC1E,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,IAAA,EAAM,OAAO,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAAiC,MAAS,OAAA,EAA6B;AACrE,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,QAAQ,OAAA,EAA0C;AAChD,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,cAAc,OAAA,EAAuD;AACnE,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,aAAA,CAAc,OAAO,CAAA;AAAA,EAC1C;AACF;AC/KO,IAAM,oBAAA,GAA4C;AAAA,EACvD,QAAA,EAAU,KAAA;AAAA;AAAA,EACV,KAAA,EAAO,MAAA;AAAA;AAAA,EACP,KAAA,EAAO,MAAA;AAAA;AAAA,EACP,QAAA,EAAU,IAAA;AAAA;AAAA,EACV,MAAA,EAAQ;AAAA;AACV;AAWA,IAAI,gBAAA,GAAkD,IAAA;AAMtD,SAAS,YAAA,GAAuB;AAE9B,EAAA,IAAI,OAAO,2PAAa,KAAQ,WAAA,EAAa;AAC3C,IAAA,MAAM,UAAA,GAAaC,iBAAA,CAAc,2PAAe,CAAA;AAChD,IAAA,MAAMC,UAAAA,GAAYC,aAAQ,UAAU,CAAA;AACpC,IAAA,OAAOC,SAAA,CAAKF,YAAW,2BAA2B,CAAA;AAAA,EACpD;AAGA,EAAA,OAAOE,SAAA,CAAK,WAAW,2BAA2B,CAAA;AACpD;AAMO,SAAS,mBAAA,GAA8C;AAC5D,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,OAAO,gBAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAY,YAAA,EAAa;AAE/B,EAAA,MAAM,iBAAA,GAAgCC,sBAAA,CAAA,QAAA,CAAS,SAAA,EAAW,oBAAoB,CAAA;AAC9E,EAAA,MAAM,UAAA,GAAkBC,uCAAsB,iBAAiB,CAAA;AAE/D,EAAA,gBAAA,GAAmB,UAAA;AACnB,EAAA,OAAO,gBAAA;AACT;AAKA,eAAsB,wBAAA,GAA4D;AAChF,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,OAAO,gBAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAY,YAAA,EAAa;AAE/B,EAAA,MAAM,iBAAA,GAAoB,MAAkBD,sBAAA,CAAA,IAAA,CAAK,SAAA,EAAW,oBAAoB,CAAA;AAChF,EAAA,MAAM,UAAA,GAAkBC,uCAAsB,iBAAiB,CAAA;AAE/D,EAAA,gBAAA,GAAmB,UAAA;AACnB,EAAA,OAAO,gBAAA;AACT;AAKO,SAAS,eAAA,GAAwB;AACtC,EAAA,gBAAA,GAAmB,IAAA;AACrB;;;AChEA,gBAAuB,uBAAA,CACrB,QACA,OAAA,EACoC;AACpC,EAAA,MAAM,EAAE,MAAA,EAAQ,WAAA,EAAa,SAAS,KAAA,EAAM,GAAI,WAAW,EAAC;AAG5D,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,MAAM;AACrC,MAAA,MAAA,CAAO,MAAA,EAAO;AAAA,IAChB,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAO,IAAI,mBAAA,CAAoB,MAAA,EAAQ,EAAE,WAAA,EAAa,OAAA,EAAS,OAAO,CAAA;AAC/E;AAKA,IAAM,sBAAN,MAAyD;AAAA,EAC/C,MAAA;AAAA,EACA,OAAA;AAAA,EAER,WAAA,CACE,MAAA,EACA,OAAA,GAAyC,EAAC,EAC1C;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,QAAQ,MAAA,CAAO,aAAa,CAAA,GAAwC;AAClE,IAAA,MAAM,EAAE,WAAA,EAAa,OAAA,EAAS,KAAA,KAAU,IAAA,CAAK,OAAA;AAC7C,IAAA,MAAM,QAAa,EAAC;AACpB,IAAA,IAAI,KAAA,GAAsB,IAAA;AAC1B,IAAA,IAAI,KAAA,GAAQ,KAAA;AACZ,IAAA,IAAI,OAAA,GAA+B,IAAA;AAEnC,IAAA,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,IAAA,KAAY;AAClC,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,MAAA,OAAA,IAAU;AAAA,IACZ,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAe;AACtC,MAAA,KAAA,GAAQ,GAAA;AACR,MAAA,OAAA,GAAU,GAAG,CAAA;AACb,MAAA,OAAA,IAAU;AAAA,IACZ,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,MAAM;AAC1B,MAAA,KAAA,GAAQ,IAAA;AACR,MAAA,KAAA,IAAQ;AACR,MAAA,OAAA,IAAU;AAAA,IACZ,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,QAAA,EAAU,CAAC,MAAA,KAA8B;AACtD,MAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,QAAA,WAAA,IAAc;AAAA,MAChB;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,IAAA,EAAM;AACX,MAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,QAAA,MAAM,MAAM,KAAA,EAAM;AAClB,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAM,KAAA;AAAA,MACR;AAEA,MAAA,IAAI,KAAA,EAAO;AACT,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,IAAI,OAAA,CAAc,CAAC,CAAA,KAAM;AAC7B,QAAA,OAAA,GAAU,CAAA;AAAA,MACZ,CAAC,CAAA;AAAA,IACH;AAAA,EACF;AACF,CAAA;AAmBO,SAAS,uBAAA,CACd,MACA,OAAA,EACmB;AACnB,EAAA,MAAM,EAAE,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAM,GAAI,WAAW,EAAC;AAG/C,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,MAAM;AACrC,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,KAAK,OAAA,EAAmC;AACtC,MAAA,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,IACpB,CAAA;AAAA,IAEA,OAAA,GAA8C;AAC5C,MAAA,OAAO,IAAI,mBAAA,CAAoB,IAAA,EAAM,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,IACzD,CAAA;AAAA,IAEA,GAAA,GAAY;AACV,MAAA,IAAA,CAAK,GAAA,EAAI;AAAA,IACX,CAAA;AAAA,IAEA,MAAA,GAAe;AACb,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd;AAAA,GACF;AACF;AAaO,SAAS,eAAA,CACd,MACA,OAAA,EACW;AACX,EAAA,MAAM,EAAE,MAAA,EAAQ,WAAA,EAAa,SAAS,KAAA,EAAM,GAAI,WAAW,EAAC;AAG5D,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,MAAM;AACrC,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,QAAA,GAAW,IAAI,mBAAA,CAA6B,IAAA,EAAM;AAAA,IACtD,WAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,OAAO;AAAA,IACL,CAAC,MAAA,CAAO,aAAa,CAAA,GAAI;AACvB,MAAA,OAAO,QAAA,CAAS,MAAA,CAAO,aAAa,CAAA,EAAE;AAAA,IACxC,CAAA;AAAA,IACA,MAAA,GAAS;AACP,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd;AAAA,GACF;AACF;;;AChIA,SAAS,SAAA,CACP,MAAA,EACA,MAAA,EACA,OAAA,EACA,QAAA,EACe;AACf,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAA,CAAO,KAAK,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAU,CAAC,OAAO,QAAA,KAAa;AAC1D,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAA,CAAO,KAAK,CAAA;AAAA,MACd,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,MAClB;AAAA,IACF,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AAKA,SAAS,YAAA,CAAa,SAAiB,WAAA,EAAgC;AACrE,EAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAO,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,EAAE,WAAA,EAAY;AAC/C,EAAA,OAAO,SAAS,WAAA,IAAe,IAAA,KAAS,eAAe,CAAC,IAAA,CAAK,WAAW,OAAO,CAAA;AACjF;AAKO,IAAM,sBAAN,MAA0B;AAAA,EAC/B,WAAA,CACmB,QACA,QAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKH,MAAM,QAAQ,MAAA,EAA0D;AACtE,IAAA,OAAO,SAAA,CAAU,KAAK,MAAA,EAAQ,IAAA,CAAK,OAAO,OAAA,EAAS,MAAA,EAAQ,KAAK,QAAQ,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,MAAA,EAA0D;AACtE,IAAA,OAAO,SAAA,CAAU,KAAK,MAAA,EAAQ,IAAA,CAAK,OAAO,OAAA,EAAS,MAAA,EAAQ,KAAK,QAAQ,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,MAAA,EAA4D;AACzE,IAAA,OAAO,SAAA,CAAU,KAAK,MAAA,EAAQ,IAAA,CAAK,OAAO,QAAA,EAAU,MAAA,EAAQ,KAAK,QAAQ,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,MAAA,EAAoD;AAC7D,IAAA,OAAO,SAAA,CAAU,KAAK,MAAA,EAAQ,IAAA,CAAK,OAAO,IAAA,EAAM,MAAA,EAAQ,KAAK,QAAQ,CAAA;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKE,MAAM,WAAW,MAAA,EAAgE;AAC/E,IAAA,OAAO,SAAA,CAAU,KAAK,MAAA,EAAQ,IAAA,CAAK,OAAO,UAAA,EAAY,MAAA,EAAQ,KAAK,QAAQ,CAAA;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,KAAA,EAA4C;AACvD,IAAA,OAAO,SAAA,CAAU,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,QAAQ,EAAE,KAAA,EAAM,EAAG,IAAA,CAAK,QAAQ,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,SAAA,EAAuD;AACzE,IAAA,OAAO,SAAA,CAAU,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,eAAe,EAAE,SAAA,EAAU,EAAG,IAAA,CAAK,QAAQ,CAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,UAAA,CAAW,QAA+B,OAAA,EAAoC;AAC5E,IAAA,MAAM,OAAO,IAAA,CAAK,MAAA,CAAO,UAAA,CAAW,MAAA,EAAQ,KAAK,QAAQ,CAAA;AACzD,IAAA,OAAO,eAAA,CAAgB,MAAM,OAAO,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,YAAY,OAAA,EAA4C;AACtD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,KAAK,QAAQ,CAAA;AAClD,IAAA,OAAO,uBAAA,CAAwB,MAAM,OAAO,CAAA;AAAA,EAC9C;AACF;AAKO,IAAM,uBAAN,MAA2B;AAAA,EAChC,WAAA,CACmB,QACA,QAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKH,MAAM,SAAS,MAAA,EAAwE;AACrF,IAAA,OAAO,SAAA,CAAU,KAAK,MAAA,EAAQ,IAAA,CAAK,OAAO,QAAA,EAAU,MAAA,EAAQ,KAAK,QAAQ,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,MAAA,EAA8D;AAC5E,IAAA,OAAO,SAAA,CAAU,KAAK,MAAA,EAAQ,IAAA,CAAK,OAAO,SAAA,EAAW,MAAA,EAAQ,KAAK,QAAQ,CAAA;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,QAAA,EAAmD;AAClE,IAAA,OAAO,SAAA,CAAU,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,YAAY,EAAE,QAAA,EAAS,EAAG,IAAA,CAAK,QAAQ,CAAA;AAAA,EACnF;AACF;AA6BO,IAAM,oBAAN,MAAwB;AAAA,EACZ,WAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGR,KAAA;AAAA;AAAA,EAGA,OAAA;AAAA,EAET,YAAY,OAAA,EAA4B;AACtC,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,QAAQ,WAAA,EAAAC,YAAAA,EAAa,gBAAe,GAAI,OAAA;AAGjE,IAAA,MAAM,KAAA,GAAQA,YAAAA,KAAgB,YAAA,CAAa,OAAA,EAAS,MAAM,IACjDC,gBAAA,CAAA,WAAA,CAAY,SAAA,EAAU,GACtBA,gBAAA,CAAA,WAAA,CAAY,cAAA,EAAe,CAAA;AAGpC,IAAA,IAAA,CAAK,QAAA,GAAW,IAASA,gBAAA,CAAA,QAAA,EAAS;AAClC,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,WAAA,EAAa,MAAM,CAAA;AAGrC,IAAA,MAAM,QAAQ,mBAAA,EAAoB;AAGlC,IAAA,IAAA,CAAK,WAAA,GAAc,IAAI,KAAA,CAAM,OAAA,CAAQ,EAAA,CAAG,YAAA;AAAA,MACtC,OAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,KAAA,CAAM,OAAA,CAAQ,EAAA,CAAG,aAAA;AAAA,MACvC,OAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACF;AAGA,IAAA,IAAA,CAAK,QAAQ,IAAI,mBAAA,CAAoB,IAAA,CAAK,WAAA,EAAa,KAAK,QAAQ,CAAA;AACpE,IAAA,IAAA,CAAK,UAAU,IAAI,oBAAA,CAAqB,IAAA,CAAK,YAAA,EAAc,KAAK,QAAQ,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,IAAA,IAAA,CAAK,aAAa,KAAA,EAAM;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,QAAA,EAAgC;AACjD,IAAA,MAAM,IAAI,QAAA,IAAY,IAAI,KAAK,IAAA,CAAK,GAAA,KAAQ,GAAK,CAAA;AACjD,IAAA,MAAM,QAAQ,GAAA,CAAI;AAAA,MAChB,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AACrC,QAAA,IAAA,CAAK,WAAA,CAAY,YAAA,CAAa,CAAA,EAAG,CAAC,KAAA,KAAU;AAC1C,UAAA,IAAI,KAAA,SAAc,KAAK,CAAA;AAAA,eAClB,OAAA,EAAQ;AAAA,QACf,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AAAA,MACD,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AACrC,QAAA,IAAA,CAAK,YAAA,CAAa,YAAA,CAAa,CAAA,EAAG,CAAC,KAAA,KAAU;AAC3C,UAAA,IAAI,KAAA,SAAc,KAAK,CAAA;AAAA,eAClB,OAAA,EAAQ;AAAA,QACf,CAAC,CAAA;AAAA,MACH,CAAC;AAAA,KACF,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,YAAA,EAAgD;AACvD,IAAA,OAAO,KAAK,WAAA,CAAY,UAAA,EAAW,CAAE,oBAAA,CAAqB,gBAAgB,KAAK,CAAA;AAAA,EACjF;AACF;;;AC5RO,IAAM,aAAA,GAAN,MAAM,cAAA,CAAc;AAAA,EACR,MAAA;AAAA,EACA,IAAA;AAAA,EACA,cAAA;AAAA,EACT,KAAA,GAAkC,IAAA;AAAA;AAAA,EAGjC,IAAA;AAAA;AAAA,EAGA,IAAA;AAAA;AAAA,EAGA,MAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGA,SAAA;AAAA;AAAA,EAGA,SAAA;AAAA;AAAA,EAGA,QAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGA,aAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGA,SAAA;AAAA;AAAA,EAGA,MAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGA,KAAA;AAAA;AAAA,EAGA,MAAA;AAAA;AAAA,EAGD,cAAA,GAAyC,IAAA;AAAA,EACzC,cAAA,GAAgC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWhC,SAAA,GAA2B,IAAA;AAAA;AAAA,EAE3B,eAAA,GAA0C,IAAA;AAAA,EAElD,YAAY,OAAA,EAA8B;AAExC,IAAA,IAAA,CAAK,MAAA,GAAS,cAAc,OAAO,CAAA;AACnC,IAAA,cAAA,CAAe,KAAK,MAAM,CAAA;AAG1B,IAAA,IAAA,CAAK,cAAA,GAAiB,oBAAA,CAAqB,IAAA,CAAK,MAAA,CAAO,cAAc,CAAA;AAGrE,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA,CAAiB,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAc,CAAA;AAG7D,IAAA,IAAI,IAAA,CAAK,OAAO,WAAA,IAAe,IAAA,CAAK,OAAO,YAAA,IAAgB,IAAA,CAAK,OAAO,gBAAA,EAAkB;AACvF,MAAA,IAAA,CAAK,KAAK,iBAAA,CAAkB,IAAA,CAAK,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAChE;AAGA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,YAAA,CAAa,IAAA,CAAK,MAAM,MAAM,IAAA,CAAK,OAAO,YAAY,CAAA;AACtE,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AACtC,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,cAAA,CAAe,IAAA,CAAK,IAAI,CAAA;AAC1C,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AAC5C,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAChD,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAChD,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AAC9C,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AAC5C,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAI,qBAAA,CAAsB,IAAA,CAAK,IAAI,CAAA;AACxD,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AAC5C,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA;AAChD,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,cAAA,CAAe,IAAA,CAAK,IAAI,CAAA;AAC1C,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AAC5C,IAAA,IAAA,CAAK,QAAQ,IAAI,aAAA,CAAc,KAAK,IAAA,EAAM,IAAA,CAAK,OAAO,QAAQ,CAAA;AAC9D,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,wBAAA,CAAyB,IAAA,CAAK,IAAI,CAAA;AAEpD,IAAA,IAAA,CAAK,MAAA,CAAO,QAAQ,2BAAA,EAA6B;AAAA,MAC/C,OAAA,EAAS,KAAK,MAAA,CAAO,OAAA;AAAA,MACrB,SAAA,EAAW,CAAC,CAAC,IAAA,CAAK,MAAA,CAAO,MAAA;AAAA,MACzB,cAAA,EAAgB,CAAC,CAAC,IAAA,CAAK,MAAA,CAAO;AAAA,KAC/B,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,IAAI,IAAA,GAA0B;AAC5B,IAAA,IAAI,CAAC,KAAK,KAAA,EAAO;AACf,MAAA,MAAM,WAAA,GAAc,KAAK,kBAAA,EAAmB;AAC5C,MAAA,MAAM,MAAA,GAAS,KAAK,MAAA,CAAO,MAAA;AAE3B,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,MAAM,IAAI,oBAAoB,iCAAiC,CAAA;AAAA,MACjE;AAEA,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,iBAAA,CAAkB;AAAA,QACjC,OAAA,EAAS,WAAA;AAAA,QACT;AAAA,OACD,CAAA;AAAA,IACH;AACA,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,SAAS,OAAA,EAA4D;AAEzE,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,WAAA,EAAY;AAErC,IAAA,OAAO,IAAI,eAAA,CAAgB;AAAA,MACzB,OAAA,EAAS,KAAK,MAAA,CAAO,OAAA;AAAA,MACrB,KAAA,EAAO,KAAK,MAAA,CAAO,KAAA;AAAA,MACnB,KAAA;AAAA;AAAA;AAAA;AAAA,MAIA,aAAA,EAAe,CAAC,YAAA,KAAiB,IAAA,CAAK,YAAY,YAAY,CAAA;AAAA,MAC9D,GAAG,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKH,GAAI,IAAA,CAAK,MAAA,CAAO,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,MAAA,CAAO,KAAA,EAAM,GAAI;AAAC,KACzD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAc,WAAA,CAAY,YAAA,GAAe,KAAA,EAAwB;AAG/D,IAAA,IAAI,IAAA,CAAK,OAAO,WAAA,EAAa;AAC3B,MAAA,IAAI,YAAA,IAAgB,IAAA,CAAK,kBAAA,EAAmB,EAAG;AAC7C,QAAA,OAAO,KAAK,kBAAA,EAAmB;AAAA,MACjC;AACA,MAAA,OAAO,KAAK,MAAA,CAAO,WAAA;AAAA,IACrB;AAIA,IAAA,IAAI,IAAA,CAAK,OAAO,MAAA,EAAQ;AACtB,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,MACnB;AACA,MAAA,IAAI,KAAK,SAAA,IAAa,CAAC,eAAA,CAAgB,IAAA,CAAK,SAAS,CAAA,EAAG;AACtD,QAAA,OAAO,IAAA,CAAK,SAAA;AAAA,MACd;AACA,MAAA,OAAO,KAAK,WAAA,EAAY;AAAA,IAC1B;AAEA,IAAA,MAAM,IAAI,oBAAoB,4DAA4D,CAAA;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,WAAA,GAA+B;AAC3C,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,OAAO,IAAA,CAAK,eAAA;AAAA,IACd;AAEA,IAAA,IAAA,CAAK,mBAAmB,YAAY;AAClC,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,MAAA,EAAS,CAAA;AAGtE,MAAA,IAAA,CAAK,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,WAAW,CAAA;AAC3C,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAS,SAAA,GAAY,GAAA;AACxD,MAAC,IAAA,CAAK,MAAA,CAA0B,YAAA,GAAe,QAAA,CAAS,YAAA;AACxD,MAAA,IAAA,CAAK,YAAY,QAAA,CAAS,WAAA;AAE1B,MAAA,OAAO,QAAA,CAAS,WAAA;AAAA,IAClB,CAAA,GAAG;AAEH,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,IACpB,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAA,GAA8B;AACpC,IAAA,IAAI,CAAC,KAAK,cAAA,EAAgB;AACxB,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,QAAA,GAAW,IAAI,EAAA,GAAK,GAAA;AAC1B,IAAA,OAAO,IAAA,CAAK,GAAA,EAAI,IAAK,IAAA,CAAK,cAAA,GAAiB,QAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAA,GAAsC;AAElD,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,OAAO,IAAA,CAAK,cAAA;AAAA,IACd;AAEA,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,YAAA,EAAc;AAC7B,MAAA,MAAM,IAAI,oBAAoB,4BAA4B,CAAA;AAAA,IAC5D;AAEA,IAAA,IAAA,CAAK,cAAA,GAAiB,KAAK,cAAA,EAAe;AAE1C,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,cAAA;AAAA,IACpB,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAAA,GAAkC;AAC9C,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ;AAAA,MACvC,YAAA,EAAc,KAAK,MAAA,CAAO;AAAA,KAC3B,CAAA;AAGD,IAAA,IAAA,CAAK,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,WAAW,CAAA;AAC3C,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAS,SAAA,GAAY,GAAA;AACxD,IAAC,IAAA,CAAK,MAAA,CAA0B,WAAA,GAAc,QAAA,CAAS,WAAA;AAEvD,IAAA,IAAA,CAAK,MAAA,CAAO,QAAQ,8BAA8B,CAAA;AAElD,IAAA,OAAO,QAAA,CAAS,WAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAAsC;AACpC,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAA,GAAyB;AACvB,IAAA,OAAO,IAAA,CAAK,eAAe,QAAA,EAAS;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAA,GAA4B;AAC1B,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAA,EAAsD;AAChE,IAAA,OAAO,IAAI,cAAA,CAAc;AAAA,MACvB,MAAA,EAAQ,KAAK,MAAA,CAAO,MAAA;AAAA,MACpB,WAAA,EAAa,KAAK,MAAA,CAAO,WAAA;AAAA,MACzB,YAAA,EAAc,KAAK,MAAA,CAAO,YAAA;AAAA,MAC1B,QAAA,EAAU,KAAK,MAAA,CAAO,QAAA;AAAA,MACtB,WAAA,EAAa,KAAK,MAAA,CAAO,WAAA;AAAA,MACzB,OAAA,EAAS,KAAK,MAAA,CAAO,OAAA;AAAA,MACrB,OAAA,EAAS,KAAK,MAAA,CAAO,OAAA;AAAA,MACrB,KAAA,EAAO,KAAK,MAAA,CAAO,KAAA;AAAA,MACnB,cAAA,EAAgB,KAAK,MAAA,CAAO,cAAA;AAAA,MAC5B,OAAA,EAAS,KAAK,MAAA,CAAO,OAAA;AAAA,MACrB,KAAA,EAAO,KAAK,MAAA,CAAO,KAAA;AAAA,MACnB,SAAA,EAAW,KAAK,MAAA,CAAO,SAAA;AAAA,MACvB,KAAA,EAAO,IAAA,CAAK,MAAA,CAAO,KAAA,IAAS,MAAA;AAAA,MAC5B,gBAAA,EAAkB,KAAK,MAAA,CAAO,gBAAA;AAAA,MAC9B,GAAG;AAAA,KACJ,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAA,GAA6B;AACnC,IAAA,OAAO,KAAK,MAAA,CAAO,WAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKF,KAAA,GAAc;AACZ,IAAA,IAAI,KAAK,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AACjB,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,IACf;AAAA,EACF;AACF;AAYO,SAAS,aAAa,OAAA,EAA6C;AACxE,EAAA,OAAO,IAAI,cAAc,OAAO,CAAA;AAClC;AAOO,SAAS,aAAa,KAAA,EAA8B;AACzD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,MAAM,UAAU,IAAA,CAAK,KAAA,CAAM,gBAAgB,KAAA,CAAM,CAAC,CAAC,CAAC,CAAA;AACpD,IAAA,OAAO,OAAO,OAAA,CAAQ,GAAA,KAAQ,QAAA,GAAW,QAAQ,GAAA,GAAM,IAAA;AAAA,EACzD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAOO,SAAS,eAAA,CAAgB,KAAA,EAAe,MAAA,GAAS,GAAA,EAAiB;AACvE,EAAA,MAAM,GAAA,GAAM,aAAa,KAAK,CAAA;AAC9B,EAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA,CAAK,GAAA,EAAI,IAAK,GAAA,GAAM,GAAA,GAAO,MAAA;AACpC;AAGA,SAAS,gBAAgB,OAAA,EAAyB;AAChD,EAAA,MAAM,GAAA,GAAM,QAAQ,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA;AAGxD,EAAA,IAAI,OAAO,UAAA,CAAW,MAAA,KAAW,WAAA,EAAa;AAC5C,IAAA,OAAO,WAAW,MAAA,CAAO,IAAA,CAAK,KAAK,QAAQ,CAAA,CAAE,SAAS,MAAM,CAAA;AAAA,EAC9D;AACA,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA;AAClC,EAAA,MAAM,KAAA,GAAQ,WAAW,IAAA,CAAK,MAAA,EAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,UAAA,CAAW,CAAC,CAAC,CAAA;AAC5D,EAAA,OAAO,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,OAAO,KAAK,CAAA;AAClD;;;AC/XO,SAAS,uBAAA,CACd,KAAA,EACA,KAAA,EACA,MAAA,GAAiB,GACjB,KAAA,EACsB;AACtB,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,KAAA;AAAA,IACN,KAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,EAAS,MAAM,MAAA,KAAW;AAAA,GAC5B;AACF;;;AC7FO,IAAK,aAAA,qBAAAC,cAAAA,KAAL;AACL,EAAAA,eAAA,wBAAA,CAAA,GAAyB,wBAAA;AACzB,EAAAA,eAAA,oBAAA,CAAA,GAAqB,oBAAA;AACrB,EAAAA,eAAA,sBAAA,CAAA,GAAuB,sBAAA;AACvB,EAAAA,eAAA,uBAAA,CAAA,GAAwB,uBAAA;AACxB,EAAAA,eAAA,sBAAA,CAAA,GAAuB,sBAAA;AACvB,EAAAA,eAAA,mBAAA,CAAA,GAAoB,mBAAA;AACpB,EAAAA,eAAA,uBAAA,CAAA,GAAwB,uBAAA;AACxB,EAAAA,eAAA,sBAAA,CAAA,GAAuB,sBAAA;AARb,EAAA,OAAAA,cAAAA;AAAA,CAAA,EAAA,aAAA,IAAA,EAAA;AAYL,IAAM,mBAAA,GAAsB;AAAA,EACjC,WAAA,EAAa,CAAA;AAAA,EACb,OAAA,EAAS,CAAA;AAAA,EACT,SAAA,EAAW,CAAA;AAAA,EACX,UAAA,EAAY,CAAA;AAAA,EACZ,SAAA,EAAW,CAAA;AAAA,EACX,MAAA,EAAQ,CAAA;AAAA,EACR,UAAA,EAAY,CAAA;AAAA,EACZ,SAAA,EAAW;AACb;AAaO,SAAS,gBAAgB,EAAA,EAA4D;AAC1F,EAAA,IAAI,CAAC,IAAI,OAAO,IAAA;AAEhB,EAAA,IAAI,OAAO,OAAO,QAAA,EAAU;AAC1B,IAAA,OAAO,IAAI,KAAK,EAAE,CAAA;AAAA,EACpB;AAEA,EAAA,MAAM,OAAA,GAAU,OAAO,EAAA,CAAG,OAAA,KAAY,QAAA,GAAW,QAAA,CAAS,EAAA,CAAG,OAAA,EAAS,EAAE,CAAA,GAAK,EAAA,CAAG,OAAA,IAAW,CAAA;AAC3F,EAAA,MAAM,KAAA,GAAQ,GAAG,KAAA,IAAS,CAAA;AAC1B,EAAA,OAAO,IAAI,KAAK,OAAA,GAAU,GAAA,GAAO,KAAK,KAAA,CAAM,KAAA,GAAQ,GAAS,CAAC,CAAA;AAChE;AAGO,SAAS,gBAAgB,IAAA,EAAoC;AAClE,EAAA,MAAM,IAAI,OAAO,IAAA,KAAS,WAAW,IAAI,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AACtD,EAAA,MAAM,EAAA,GAAK,EAAE,OAAA,EAAQ;AACrB,EAAA,OAAO;AAAA,IACL,SAAS,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,GAAI,EAAE,QAAA,EAAS;AAAA,IACxC,KAAA,EAAQ,KAAK,GAAA,GAAQ;AAAA,GACvB;AACF;AC/CA,IAAM,eAAA,GAAkB;AAAA,EACtB,WAAA,EAAa,CAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,aAAA,EAAe,EAAA;AAAA,EACf,iBAAA,EAAmB,GAAA;AAAA,EACnB,SAAA,EAAW,KAAA;AAAA,EACX,eAAA,EAAiB;AACnB,CAAA;AA2BO,IAAM,gBAAN,MAAoB;AAAA,EACR,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EAET,KAAA,GAAqB,MAAA;AAAA,EACrB,QAAA,GAA0B,IAAA;AAAA,EAC1B,OAAA,GAA6B,IAAA;AAAA,EAC7B,UAAA,uBAAyC,GAAA,EAAI;AAAA,EAC7C,SAAA,GAAkD,IAAA;AAAA,EAClD,oBAAA,GAA8D,IAAA;AAAA,EAC9D,eAAA,GAAwC,IAAA;AAAA;AAAA,EAGxC,aAAA,uBAAsE,GAAA,EAAI;AAAA,EAElF,WAAA,CAAY,QAAuB,OAAA,EAA+B;AAChE,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,GAAG,eAAA;AAAA,MACH,UAAUC,WAAA,EAAW;AAAA,MACrB,UAAA,EAAY,QAAA;AAAA,MACZ,OAAA,EAAS,QAAA;AAAA,MACT,UAAU,EAAC;AAAA,MACX,GAAG;AAAA,KACL;AAGA,IAAA,MAAM,MAAA,GAAS,OAAO,SAAA,EAAU;AAChC,IAAA,IAAA,CAAK,KAAA,GAAQ,MAAA,CAAO,KAAA,KAAU,MAAM;AAAA,IAAC,CAAA,CAAA;AAErC,IAAA,IAAI,IAAA,CAAK,QAAQ,SAAA,EAAW;AAE1B,MAAA,YAAA,CAAa,MAAM,IAAA,CAAK,KAAA,EAAO,CAAA;AAAA,IACjC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAwB;AACtB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,GAA6B;AAC3B,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAA,GAA4B;AAC1B,IAAA,OAAO,KAAK,UAAA,CAAW,IAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,OAAA,EAA2B;AACjC,IAAA,IAAI,IAAA,CAAK,UAAU,MAAA,EAAQ;AACzB,MAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,IAC/D;AACA,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,IAAA,CAAK,UAAU,MAAA,EAAQ;AACzB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,IAAA,CAAK,KAAK,CAAA,CAAE,CAAA;AAAA,IAC/D;AAEA,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,IACpE;AAEA,IAAA,IAAA,CAAK,KAAA,GAAQ,UAAA;AACb,IAAA,IAAA,CAAK,KAAA,CAAM,CAAA,2BAAA,EAA8B,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA,CAAE,CAAA;AAEjE,IAAA,IAAI;AAEF,MAAA,MAAM,YAAA,GAAe,MAAM,IAAA,CAAK,MAAA,CAAO,QAAQ,QAAA,CAAS;AAAA,QACtD,SAAA,EAAW,KAAK,OAAA,CAAQ,SAAA;AAAA,QACxB,QAAA,EAAU,KAAK,OAAA,CAAQ,QAAA;AAAA,QACvB,UAAA,EAAY,KAAK,OAAA,CAAQ,UAAA;AAAA,QACzB,cAAA,EAAgB,KAAK,OAAA,CAAQ,WAAA;AAAA,QAC7B,QAAA,EAAU,KAAK,OAAA,CAAQ,QAAA;AAAA,QACvB,OAAA,EAAS,KAAK,OAAA,CAAQ;AAAA,OACvB,CAAA;AAED,MAAA,IAAA,CAAK,WAAW,YAAA,CAAa,EAAA;AAC7B,MAAA,IAAA,CAAK,KAAA,CAAM,CAAA,mBAAA,EAAsB,IAAA,CAAK,QAAQ,IAAI,YAAY,CAAA;AAG9D,MAAA,MAAM,iBAAA,GAAoB,aAAa,qBAAA,GAAwB,GAAA;AAC/D,MAAA,IAAA,CAAK,oBAAA,GAAuB,YAAY,MAAM;AAC5C,QAAA,IAAA,CAAK,mBAAA,EAAoB;AAAA,MAC3B,GAAG,iBAAiB,CAAA;AAGpB,MAAA,IAAA,CAAK,KAAA,GAAQ,SAAA;AACb,MAAA,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,EAAE,QAAA,EAAU,IAAA,CAAK,UAAU,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,CAAA;AACnF,MAAA,IAAA,CAAK,YAAA,EAAa;AAAA,IACpB,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAA,GAAQ,OAAA;AACb,MAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,EAAuB,CAAA;AAC5C,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,GAAsB;AAC1B,IAAA,IAAI,IAAA,CAAK,UAAU,SAAA,EAAW;AAC5B,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,OAAO,IAAA,CAAK,eAAA;AAAA,IACd;AAEA,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAK,MAAA,EAAO;AACnC,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,EACd;AAAA,EAEA,MAAc,MAAA,GAAwB;AACpC,IAAA,IAAA,CAAK,KAAA,GAAQ,UAAA;AACb,IAAA,IAAA,CAAK,MAAM,oBAAoB,CAAA;AAG/B,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,YAAA,CAAa,KAAK,SAAS,CAAA;AAC3B,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,IACnB;AAGA,IAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,MAAA,aAAA,CAAc,KAAK,oBAAoB,CAAA;AACvC,MAAA,IAAA,CAAK,oBAAA,GAAuB,IAAA;AAAA,IAC9B;AAGA,IAAA,KAAA,MAAW,MAAA,IAAU,IAAA,CAAK,UAAA,CAAW,MAAA,EAAO,EAAG;AAC7C,MAAA,MAAA,CAAO,gBAAgB,KAAA,EAAM;AAAA,IAC/B;AAGA,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,IAAA,GAAO,CAAA,EAAG;AAC5B,MAAA,IAAA,CAAK,KAAA,CAAM,CAAA,YAAA,EAAe,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA,2BAAA,CAA6B,CAAA;AAE3E,MAAA,MAAM,QAAQ,IAAA,CAAK;AAAA,QACjB,KAAK,iBAAA,EAAkB;AAAA,QACvB,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,eAAe;AAAA,OACxC,CAAA;AAID,MAAA,MAAM,YAAY,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,SAAS,CAAA;AACtD,MAAA,KAAA,MAAW,CAAC,KAAA,EAAO,MAAM,CAAA,IAAK,SAAA,EAAW;AACvC,QAAA,IAAA,CAAK,KAAA,CAAM,CAAA,kBAAA,EAAqB,KAAK,CAAA,wBAAA,CAA0B,CAAA;AAC/D,QAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,GAAA,EAAK,yBAAyB,CAAA;AAIxD,QAAA,IAAA,CAAK,WAAW,KAAK,CAAA;AAAA,MACvB;AAAA,IACF;AAGA,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,KAAK,QAAQ,CAAA;AAClD,QAAA,IAAA,CAAK,MAAM,qBAAqB,CAAA;AAAA,MAClC,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAAA,MACjD;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,KAAA,GAAQ,SAAA;AACb,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,IAAA,CAAK,WAAW,EAAE,QAAA,EAAU,KAAK,QAAA,IAAY,EAAA,EAAI,MAAA,EAAQ,UAAA,EAAY,CAAA;AAC1E,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,EAAA,CAA0B,OAAU,OAAA,EAAsC;AACxE,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,EAAG;AAClC,MAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,KAAA,kBAAO,IAAI,KAAK,CAAA;AAAA,IACzC;AACA,IAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,CAAG,IAAI,OAAoC,CAAA;AACvE,IAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAA2B,OAAU,OAAA,EAAgC;AACnE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AAC7C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAO,OAAoC,CAAA;AAAA,IACtD;AAAA,EACF;AAAA;AAAA,EAIQ,IAAA,CAA4B,OAAU,IAAA,EAAgC;AAC5E,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AAC7C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,QAAA,IAAI;AACF,UAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,QACd,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,KAAA,CAAM,qBAAA,EAAuB,EAAE,KAAA,EAAO,OAAO,CAAA;AAAA,QACpD;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,YAAA,GAAqB;AAC3B,IAAA,IAAI,IAAA,CAAK,UAAU,SAAA,EAAW;AAC5B,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,SAAA,GAAY,WAAW,MAAM,IAAA,CAAK,MAAK,EAAG,IAAA,CAAK,QAAQ,YAAY,CAAA;AAAA,EAC1E;AAAA,EAEA,MAAc,IAAA,GAAsB;AAClC,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,SAAA,IAAa,CAAC,KAAK,QAAA,EAAU;AAC9C,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,WAAA,GAAc,KAAK,UAAA,CAAW,IAAA;AAClE,IAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,MAAA,IAAA,CAAK,YAAA,EAAa;AAClB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI;AAEF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,MAAA,CAAO,KAAK,KAAA,CAAM;AAAA,QAC1C,SAAA,EAAW,KAAK,OAAA,CAAQ,SAAA;AAAA,QACxB,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,KAAA,EAAO,cAAA;AAAA,QACP,iBAAA,EAAmB,KAAK,OAAA,CAAQ;AAAA,OACjC,CAAA;AAGD,MAAA,KAAA,MAAW,GAAA,IAAO,OAAO,IAAA,EAAM;AAC7B,QAAA,IAAA,CAAK,WAAW,GAAG,CAAA;AAAA,MACrB;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAA,CAAM,eAAe,KAAK,CAAA;AAC/B,MAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,EAAuB,CAAA;AAAA,IAC9C;AAGA,IAAA,IAAA,CAAK,YAAA,EAAa;AAAA,EACpB;AAAA,EAEQ,WAAW,GAAA,EAAuB;AACxC,IAAA,IAAA,CAAK,IAAA,CAAK,eAAe,EAAE,KAAA,EAAO,IAAI,EAAA,EAAI,SAAA,EAAW,GAAA,CAAI,SAAA,EAAW,CAAA;AAEpE,IAAA,MAAM,eAAA,GAAkB,IAAI,eAAA,EAAgB;AAC5C,IAAA,MAAM,SAAA,GAAuB;AAAA,MAC3B,GAAA;AAAA,MACA,SAAA,sBAAe,IAAA,EAAK;AAAA,MACpB;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,SAAS,CAAA;AAGrC,IAAA,MAAM,oBAAoB,IAAA,CAAK,OAAA,CAAQ,aAAA,GAAgB,IAAA,CAAK,QAAQ,iBAAA,GAAoB,GAAA;AACxF,IAAA,SAAA,CAAU,cAAA,GAAiB,YAAY,MAAM;AAC3C,MAAA,IAAA,CAAK,gBAAA,CAAiB,IAAI,EAAE,CAAA;AAAA,IAC9B,GAAG,iBAAiB,CAAA;AAGpB,IAAA,IAAA,CAAK,eAAe,SAAS,CAAA;AAAA,EAC/B;AAAA,EAEA,MAAc,eAAe,SAAA,EAAqC;AAChE,IAAA,MAAM,EAAE,GAAA,EAAK,eAAA,EAAgB,GAAI,SAAA;AACjC,IAAA,MAAM,EAAE,QAAO,GAAI,eAAA;AAEnB,IAAA,IAAA,CAAK,IAAA,CAAK,eAAe,EAAE,KAAA,EAAO,IAAI,EAAA,EAAI,SAAA,EAAW,GAAA,CAAI,SAAA,EAAW,CAAA;AAEpE,IAAA,MAAM,OAAA,GAAsB;AAAA,MAC1B,OAAO,GAAA,CAAI,EAAA;AAAA,MACX,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,SAAS,GAAA,CAAI,OAAA;AAAA,MACb,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,MAAA;AAAA,MACA,QAAA,EAAU,OAAO,QAAA,EAAkB,QAAA,KAAsB;AAAA,MAGzD,CAAA;AAAA,MACA,GAAA,EAAK,CAAC,KAAA,EAAO,OAAA,EAAS,IAAA,KAAS;AAC7B,QAAA,IAAA,CAAK,KAAA,CAAM,IAAI,GAAA,CAAI,EAAE,MAAM,KAAK,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,EAAI,IAAI,CAAA;AAAA,MACtD;AAAA,KACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAS,OAAO,CAAA;AAG1C,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,IAAA,CAAK,KAAA,CAAM,CAAA,IAAA,EAAO,GAAA,CAAI,EAAE,CAAA,YAAA,CAAc,CAAA;AACtC,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,IAAA,CAAK,WAAA,CAAY,GAAA,EAAK,MAAA,IAAU,KAAA,CAAS,CAAA;AAAA,IACjD,SAAS,KAAA,EAAO;AAEd,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,IAAA,CAAK,KAAA,CAAM,CAAA,IAAA,EAAO,GAAA,CAAI,EAAE,CAAA,YAAA,CAAc,CAAA;AACtC,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,eAAe,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC1E,MAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,YAAY,CAAA;AAAA,IACtC,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,UAAA,CAAW,IAAI,EAAE,CAAA;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,WAAA,CAAY,GAAA,EAAiB,MAAA,EAAoC;AAC7E,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAEpB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,IAAI,EAAA,EAAI;AAAA,QACtC,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,MAAA;AAAA,QACA,GAAI,GAAA,CAAI,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,IAAI,OAAA;AAAQ,OACzD,CAAA;AAED,MAAA,IAAA,CAAK,KAAK,eAAA,EAAiB;AAAA,QACzB,OAAO,GAAA,CAAI,EAAA;AAAA,QACX,WAAW,GAAA,CAAI,SAAA;AAAA,QACf;AAAA,OACD,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAA,CAAM,CAAA,uBAAA,EAA0B,GAAA,CAAI,EAAE,IAAI,KAAK,CAAA;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,MAAc,OAAA,CAAQ,GAAA,EAAiB,YAAA,EAAqC;AAC1E,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAEpB,IAAA,MAAM,SAAA,GAAY,GAAA,CAAI,UAAA,GAAa,GAAA,CAAI,UAAA;AAEvC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,IAAI,EAAA,EAAI;AAAA,QAClC,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,KAAA,EAAO,YAAA;AAAA,QACP,GAAI,GAAA,CAAI,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,IAAI,OAAA;AAAQ,OACzD,CAAA;AAED,MAAA,IAAA,CAAK,KAAK,YAAA,EAAc;AAAA,QACtB,OAAO,GAAA,CAAI,EAAA;AAAA,QACX,WAAW,GAAA,CAAI,SAAA;AAAA,QACf,KAAA,EAAO,YAAA;AAAA,QACP;AAAA,OACD,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAA,CAAM,CAAA,mBAAA,EAAsB,GAAA,CAAI,EAAE,IAAI,KAAK,CAAA;AAAA,IAClD;AAAA,EACF;AAAA,EAEQ,WAAW,KAAA,EAAqB;AACtC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,KAAK,CAAA;AAC3C,IAAA,IAAI,WAAW,cAAA,EAAgB;AAC7B,MAAA,aAAA,CAAc,UAAU,cAAc,CAAA;AAAA,IACxC;AACA,IAAA,IAAA,CAAK,UAAA,CAAW,OAAO,KAAK,CAAA;AAAA,EAC9B;AAAA,EAEA,MAAc,iBAAiB,KAAA,EAA8B;AAC3D,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAEpB,IAAA,MAAM,UAAU,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,KAAK,GAAG,GAAA,CAAI,OAAA;AAEhD,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO;AAAA,QACtC,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,iBAAA,EAAmB,KAAK,OAAA,CAAQ,aAAA;AAAA,QAChC,GAAI,OAAA,KAAY,KAAA,CAAA,IAAa,EAAE,OAAA;AAAQ,OACxC,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAA,CAAM,CAAA,yBAAA,EAA4B,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,MAAc,mBAAA,GAAqC;AACjD,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,UAAU,SAAA,EAAW;AAEhD,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,SAAA,CAAU,KAAK,QAAA,EAAU;AAAA,QACjD,WAAA,EAAa,KAAK,UAAA,CAAW,IAAA;AAAA,QAC7B,MAAA,EAAQ;AAAA,OACT,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAA,CAAM,2BAA2B,KAAK,CAAA;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,MAAc,iBAAA,GAAmC;AAC/C,IAAA,OAAO,IAAA,CAAK,UAAA,CAAW,IAAA,GAAO,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IACtB;AAAA,EACF;AAAA,EAEQ,MAAM,EAAA,EAA2B;AACvC,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AAAA,EACzD;AACF","file":"index.cjs","sourcesContent":["/**\n * SDK Configuration\n *\n * Defines configuration types and defaults for the Spooled SDK.\n */\n\n/** Retry configuration options */\nexport interface RetryConfig {\n /** Maximum number of retry attempts (default: 3) */\n maxRetries: number;\n /** Base delay in milliseconds for exponential backoff (default: 1000) */\n baseDelay: number;\n /** Maximum delay in milliseconds (default: 30000) */\n maxDelay: number;\n /** Exponential backoff factor (default: 2) */\n factor: number;\n /** Whether to add jitter to delays (default: true) */\n jitter: boolean;\n /** Custom function to determine if an error is retryable */\n retryOn?: (error: Error, attempt: number) => boolean;\n}\n\n/** Circuit breaker configuration options */\nexport interface CircuitBreakerConfig {\n /** Whether circuit breaker is enabled (default: true) */\n enabled: boolean;\n /** Number of failures before opening the circuit (default: 5) */\n failureThreshold: number;\n /** Number of successes in half-open state to close circuit (default: 3) */\n successThreshold: number;\n /** Time in milliseconds to wait before trying again after opening (default: 30000) */\n timeout: number;\n}\n\n/** Debug logging function type */\nexport type DebugFn = (message: string, meta?: unknown) => void;\n\n/** Main SDK configuration options */\nexport interface SpooledClientConfig {\n /** API key for authentication (starts with sp_live_, sp_test_, sk_live_, or sk_test_) */\n apiKey?: string;\n /** JWT access token (alternative to API key) */\n accessToken?: string;\n /** JWT refresh token for automatic token renewal */\n refreshToken?: string;\n /** Admin API key (for /api/v1/admin/* endpoints; uses X-Admin-Key header) */\n adminKey?: string;\n /** Base URL for the REST API (default: https://api.spooled.cloud) */\n baseUrl?: string;\n /** WebSocket URL for realtime events (default: derived from baseUrl, e.g., wss://api.spooled.cloud) */\n wsUrl?: string;\n /** gRPC server address (default: grpc.spooled.cloud:443) */\n grpcAddress?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Number of retry attempts (shorthand for retry.maxRetries) */\n retries?: number;\n /** Base retry delay in milliseconds (shorthand for retry.baseDelay) */\n retryDelay?: number;\n /** Full retry configuration */\n retry?: Partial<RetryConfig>;\n /** Circuit breaker configuration */\n circuitBreaker?: Partial<CircuitBreakerConfig>;\n /** Additional headers to include in all requests */\n headers?: Record<string, string>;\n /** Custom fetch implementation (for testing or special runtimes) */\n fetch?: typeof fetch;\n /** Custom user agent string */\n userAgent?: string;\n /** Enable debug logging */\n debug?: boolean | DebugFn;\n /** Whether to automatically refresh tokens when they expire (default: true) */\n autoRefreshToken?: boolean;\n}\n\n/** Resolved configuration with all defaults applied */\nexport interface ResolvedConfig {\n apiKey?: string;\n accessToken?: string;\n refreshToken?: string;\n adminKey?: string;\n baseUrl: string;\n wsUrl: string;\n grpcAddress: string;\n timeout: number;\n retry: RetryConfig;\n circuitBreaker: CircuitBreakerConfig;\n headers: Record<string, string>;\n fetch: typeof fetch;\n userAgent: string;\n debug: DebugFn | null;\n autoRefreshToken: boolean;\n}\n\n/** Default configuration values */\nexport const DEFAULT_CONFIG = {\n baseUrl: 'https://api.spooled.cloud',\n wsUrl: 'wss://api.spooled.cloud',\n grpcAddress: 'grpc.spooled.cloud:443',\n timeout: 30000,\n retry: {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 30000,\n factor: 2,\n jitter: true,\n } satisfies RetryConfig,\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n successThreshold: 3,\n timeout: 30000,\n } satisfies CircuitBreakerConfig,\n userAgent: '@spooled/sdk-nodejs/1.0.33',\n autoRefreshToken: true,\n} as const;\n\n/** SDK version */\nexport const SDK_VERSION = '1.0.33';\n\n/** API version prefix */\nexport const API_VERSION = 'v1';\n\n/** API base path */\nexport const API_BASE_PATH = `/api/${API_VERSION}`;\n\n/**\n * Trim surrounding whitespace from a credential string and treat an\n * all-whitespace input as unset. Mirrors the trim policy in the Go, PHP,\n * and Python SDKs so behavior is consistent across languages.\n */\nfunction normalizeCredential(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed === '' ? undefined : trimmed;\n}\n\n/**\n * Resolve configuration by merging user options with defaults\n */\nexport function resolveConfig(options: SpooledClientConfig): ResolvedConfig {\n // Create debug function\n let debugFn: DebugFn | null = null;\n if (options.debug === true) {\n debugFn = (message: string, meta?: unknown) => {\n // eslint-disable-next-line no-console\n console.log(`[spooled-sdk] ${message}`, meta !== undefined ? meta : '');\n };\n } else if (typeof options.debug === 'function') {\n debugFn = options.debug;\n }\n\n // Merge retry config\n const retry: RetryConfig = {\n ...DEFAULT_CONFIG.retry,\n ...options.retry,\n // Allow shorthand overrides\n ...(options.retries !== undefined && { maxRetries: options.retries }),\n ...(options.retryDelay !== undefined && { baseDelay: options.retryDelay }),\n };\n\n // Merge circuit breaker config\n const circuitBreaker: CircuitBreakerConfig = {\n ...DEFAULT_CONFIG.circuitBreaker,\n ...options.circuitBreaker,\n };\n\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...options.headers,\n };\n\n // Resolve base URL first\n const baseUrl = options.baseUrl ?? DEFAULT_CONFIG.baseUrl;\n \n // Derive WebSocket URL from base URL if not explicitly set\n // Replace http(s):// with ws(s)://\n const derivedWsUrl = baseUrl.replace(/^http/, 'ws');\n const wsUrl = options.wsUrl ?? derivedWsUrl;\n\n // Trim whitespace (including a stray trailing '\\n') from every credential.\n // Node's `undici` fetch rejects `Authorization: Bearer <key>\\n` with an\n // opaque `TypeError: HeaderValue` and users routinely paste keys from\n // `.env` files that include a newline; normalizing here keeps behavior\n // consistent with the Go, PHP, and Python SDKs.\n return {\n apiKey: normalizeCredential(options.apiKey),\n accessToken: normalizeCredential(options.accessToken),\n refreshToken: normalizeCredential(options.refreshToken),\n adminKey: normalizeCredential(options.adminKey),\n baseUrl,\n wsUrl,\n grpcAddress: options.grpcAddress ?? DEFAULT_CONFIG.grpcAddress,\n timeout: options.timeout ?? DEFAULT_CONFIG.timeout,\n retry,\n circuitBreaker,\n headers,\n fetch: options.fetch ?? globalThis.fetch,\n userAgent: options.userAgent ?? DEFAULT_CONFIG.userAgent,\n debug: debugFn,\n autoRefreshToken: options.autoRefreshToken ?? DEFAULT_CONFIG.autoRefreshToken,\n };\n}\n\n/**\n * Validate configuration options\n * @throws Error if configuration is invalid\n */\nexport function validateConfig(config: ResolvedConfig): void {\n // Must have at least one auth method\n if (!config.apiKey && !config.accessToken) {\n throw new Error(\n 'SpooledClient requires either apiKey or accessToken for authentication'\n );\n }\n\n // Validate API key format if provided\n // Accept both sp_ (new standard) and sk_ (legacy) prefixes\n if (config.apiKey && !config.apiKey.startsWith('sp_') && !config.apiKey.startsWith('sk_')) {\n throw new Error(\n 'Invalid API key format. API keys should start with sp_live_, sp_test_, sk_live_, or sk_test_'\n );\n }\n\n // Validate baseUrl\n if (!config.baseUrl.startsWith('http://') && !config.baseUrl.startsWith('https://')) {\n throw new Error('baseUrl must start with http:// or https://');\n }\n\n // Validate timeout\n if (config.timeout <= 0) {\n throw new Error('timeout must be a positive number');\n }\n\n // Validate retry config\n if (config.retry.maxRetries < 0) {\n throw new Error('retry.maxRetries must be non-negative');\n }\n if (config.retry.baseDelay <= 0) {\n throw new Error('retry.baseDelay must be positive');\n }\n if (config.retry.maxDelay < config.retry.baseDelay) {\n throw new Error('retry.maxDelay must be >= retry.baseDelay');\n }\n if (config.retry.factor < 1) {\n throw new Error('retry.factor must be >= 1');\n }\n\n // Validate circuit breaker config\n if (config.circuitBreaker.enabled) {\n if (config.circuitBreaker.failureThreshold <= 0) {\n throw new Error('circuitBreaker.failureThreshold must be positive');\n }\n if (config.circuitBreaker.successThreshold <= 0) {\n throw new Error('circuitBreaker.successThreshold must be positive');\n }\n if (config.circuitBreaker.timeout <= 0) {\n throw new Error('circuitBreaker.timeout must be positive');\n }\n }\n}\n","/**\n * Custom Error Classes\n *\n * Provides a hierarchy of error types for the Spooled SDK.\n */\n\n/** Error response body from the API */\nexport interface ApiErrorBody {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\n/** Rate limit information parsed from headers */\nexport interface RateLimitInfo {\n /** Maximum requests per window */\n limit?: number;\n /** Remaining requests in current window */\n remaining?: number;\n /** Unix timestamp when the window resets */\n reset?: Date;\n /** Seconds to wait before retrying */\n retryAfter?: number;\n}\n\n/**\n * Base error class for all Spooled SDK errors\n */\nexport class SpooledError extends Error {\n /** HTTP status code (if applicable) */\n readonly statusCode: number;\n /** Error code from API response */\n readonly code: string;\n /** Additional error details */\n readonly details?: Record<string, unknown>;\n /** Request ID for debugging */\n readonly requestId?: string;\n /** Original cause of the error */\n readonly cause?: Error;\n\n constructor(\n message: string,\n statusCode: number = 0,\n code: string = 'UNKNOWN_ERROR',\n details?: Record<string, unknown>,\n requestId?: string,\n cause?: Error\n ) {\n super(message);\n this.name = 'SpooledError';\n this.statusCode = statusCode;\n this.code = code;\n this.details = details;\n this.requestId = requestId;\n this.cause = cause;\n\n // Maintain proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /** Whether this error is retryable */\n isRetryable(): boolean {\n return false;\n }\n\n /** Convert to plain object for logging */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n code: this.code,\n details: this.details,\n requestId: this.requestId,\n };\n }\n}\n\n/**\n * Authentication error (401)\n * Thrown when authentication fails (invalid/expired token or API key)\n */\nexport class AuthenticationError extends SpooledError {\n constructor(\n message: string = 'Authentication failed',\n code: string = 'AUTHENTICATION_FAILED',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 401, code, details, requestId);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Authorization error (403)\n * Thrown when the authenticated user lacks permission\n */\nexport class AuthorizationError extends SpooledError {\n constructor(\n message: string = 'Access denied',\n code: string = 'ACCESS_DENIED',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 403, code, details, requestId);\n this.name = 'AuthorizationError';\n }\n}\n\n/**\n * Not found error (404)\n * Thrown when a requested resource doesn't exist\n */\nexport class NotFoundError extends SpooledError {\n constructor(\n message: string = 'Resource not found',\n code: string = 'NOT_FOUND',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 404, code, details, requestId);\n this.name = 'NotFoundError';\n }\n}\n\n/**\n * Conflict error (409)\n * Thrown when there's a conflict (e.g., duplicate resource)\n */\nexport class ConflictError extends SpooledError {\n constructor(\n message: string = 'Conflict',\n code: string = 'CONFLICT',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 409, code, details, requestId);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Validation error (400)\n * Thrown when request validation fails\n */\nexport class ValidationError extends SpooledError {\n constructor(\n message: string = 'Validation failed',\n code: string = 'VALIDATION_ERROR',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 400, code, details, requestId);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Payload too large error (413)\n * Thrown when request body exceeds size limit\n */\nexport class PayloadTooLargeError extends SpooledError {\n constructor(\n message: string = 'Request payload too large',\n code: string = 'PAYLOAD_TOO_LARGE',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 413, code, details, requestId);\n this.name = 'PayloadTooLargeError';\n }\n}\n\n/**\n * Rate limit error (429)\n * Thrown when rate limit is exceeded\n */\nexport class RateLimitError extends SpooledError {\n /** Rate limit information */\n readonly rateLimitInfo: RateLimitInfo;\n\n constructor(\n message: string = 'Rate limit exceeded',\n code: string = 'RATE_LIMIT_EXCEEDED',\n rateLimitInfo: RateLimitInfo = {},\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, 429, code, details, requestId);\n this.name = 'RateLimitError';\n this.rateLimitInfo = rateLimitInfo;\n }\n\n override isRetryable(): boolean {\n return true;\n }\n\n /** Get the number of seconds to wait before retrying */\n getRetryAfter(): number {\n if (this.rateLimitInfo.retryAfter !== undefined) {\n return this.rateLimitInfo.retryAfter;\n }\n if (this.rateLimitInfo.reset) {\n const now = Date.now();\n const resetTime = this.rateLimitInfo.reset.getTime();\n return Math.max(0, Math.ceil((resetTime - now) / 1000));\n }\n return 60; // Default to 60 seconds\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n rateLimitInfo: this.rateLimitInfo,\n };\n }\n}\n\n/**\n * Server error (5xx)\n * Thrown when the server encounters an error\n */\nexport class ServerError extends SpooledError {\n constructor(\n message: string = 'Server error',\n statusCode: number = 500,\n code: string = 'SERVER_ERROR',\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message, statusCode, code, details, requestId);\n this.name = 'ServerError';\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Network error\n * Thrown when a network request fails (no response received)\n */\nexport class NetworkError extends SpooledError {\n constructor(message: string = 'Network request failed', cause?: Error) {\n super(message, 0, 'NETWORK_ERROR', undefined, undefined, cause);\n this.name = 'NetworkError';\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Timeout error\n * Thrown when a request times out\n */\nexport class TimeoutError extends SpooledError {\n /** Timeout duration in milliseconds */\n readonly timeoutMs: number;\n\n constructor(message: string = 'Request timed out', timeoutMs: number = 0) {\n super(message, 0, 'TIMEOUT', { timeoutMs });\n this.name = 'TimeoutError';\n this.timeoutMs = timeoutMs;\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Circuit breaker open error\n * Thrown when the circuit breaker is open and rejecting requests\n */\nexport class CircuitBreakerOpenError extends SpooledError {\n constructor(message: string = 'Circuit breaker is open') {\n super(message, 0, 'CIRCUIT_BREAKER_OPEN');\n this.name = 'CircuitBreakerOpenError';\n }\n\n override isRetryable(): boolean {\n return false; // Should wait for circuit to close\n }\n}\n\n/**\n * Parse rate limit headers from a Response\n */\nexport function parseRateLimitHeaders(headers: Headers): RateLimitInfo {\n const info: RateLimitInfo = {};\n\n const retryAfter = headers.get('Retry-After');\n if (retryAfter) {\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n info.retryAfter = seconds;\n }\n }\n\n const limit = headers.get('X-RateLimit-Limit');\n if (limit) {\n const parsed = parseInt(limit, 10);\n if (!isNaN(parsed)) {\n info.limit = parsed;\n }\n }\n\n const remaining = headers.get('X-RateLimit-Remaining');\n if (remaining) {\n const parsed = parseInt(remaining, 10);\n if (!isNaN(parsed)) {\n info.remaining = parsed;\n }\n }\n\n const reset = headers.get('X-RateLimit-Reset');\n if (reset) {\n const timestamp = parseInt(reset, 10);\n if (!isNaN(timestamp)) {\n info.reset = new Date(timestamp * 1000);\n }\n }\n\n return info;\n}\n\n/** Cap a raw (non-JSON) error body so a stray HTML page can't become a huge message. */\nconst MAX_RAW_ERROR_BODY_CHARS = 500;\n\n/**\n * Parse an error response body.\n *\n * Reads the body once as text, then:\n * - if it parses as a JSON object, extracts `{code, message}` (falling back to\n * the `error` field when `message` is absent);\n * - otherwise (plain-text/HTML body, or malformed JSON) preserves the raw body\n * text as the message so a server's human-readable error — e.g. a proxy's\n * `502 Bad Gateway` page — is not silently discarded.\n */\nasync function parseErrorBody(response: Response): Promise<ApiErrorBody | null> {\n const contentType = response.headers.get('Content-Type') || '';\n\n let raw: string;\n try {\n raw = await response.text();\n } catch {\n return null;\n }\n\n if (contentType.includes('application/json')) {\n try {\n const body = JSON.parse(raw) as Record<string, unknown>;\n if (typeof body === 'object' && body !== null) {\n // Error bodies come in two shapes: {code, message} or {error, code, details}.\n // Fall back to `error` when `message` is absent so the server's\n // human-readable message is not lost.\n const message = ((body.message as string) ?? (body.error as string)) || response.statusText;\n return {\n code: (body.code as string) || 'UNKNOWN_ERROR',\n message,\n details: body.details as Record<string, unknown> | undefined,\n };\n }\n } catch {\n // Content-Type claimed JSON but the body did not parse — fall through and\n // preserve the raw text below instead of throwing it away.\n }\n }\n\n // Non-JSON body (or unparseable JSON): keep the raw text as the message.\n const trimmed = raw.trim();\n if (trimmed) {\n const message =\n trimmed.length > MAX_RAW_ERROR_BODY_CHARS\n ? `${trimmed.slice(0, MAX_RAW_ERROR_BODY_CHARS)}…`\n : trimmed;\n return { code: 'UNKNOWN_ERROR', message };\n }\n\n return null;\n}\n\n/**\n * Create an appropriate error from an HTTP response\n */\nexport async function createErrorFromResponse(response: Response): Promise<SpooledError> {\n const requestId = response.headers.get('X-Request-ID') ?? undefined;\n const body = await parseErrorBody(response);\n\n const message = body?.message || response.statusText || `HTTP ${response.status}`;\n const code = body?.code || 'UNKNOWN_ERROR';\n const details = body?.details;\n\n switch (response.status) {\n case 400:\n return new ValidationError(message, code, details, requestId);\n\n case 401:\n return new AuthenticationError(message, code, details, requestId);\n\n case 403:\n return new AuthorizationError(message, code, details, requestId);\n\n case 404:\n return new NotFoundError(message, code, details, requestId);\n\n case 409:\n return new ConflictError(message, code, details, requestId);\n\n case 413:\n return new PayloadTooLargeError(message, code, details, requestId);\n\n case 429: {\n const rateLimitInfo = parseRateLimitHeaders(response.headers);\n return new RateLimitError(message, code, rateLimitInfo, details, requestId);\n }\n\n default:\n if (response.status >= 500) {\n return new ServerError(message, response.status, code, details, requestId);\n }\n return new SpooledError(message, response.status, code, details, requestId);\n }\n}\n\n/**\n * Check if an error is a SpooledError instance\n */\nexport function isSpooledError(error: unknown): error is SpooledError {\n return error instanceof SpooledError;\n}\n\n/**\n * Check if an error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (error instanceof SpooledError) {\n return error.isRetryable();\n }\n // Network errors from fetch are typically retryable\n if (error instanceof TypeError) {\n return true;\n }\n return false;\n}\n","/**\n * Case Conversion Utilities\n *\n * Provides deep conversion between snake_case (API) and camelCase (SDK).\n * User-defined JSON blobs are preserved without conversion.\n */\n\n/**\n * Keys that should NOT have their values deeply converted.\n * These typically contain user-defined JSON that shouldn't be modified.\n */\nconst SKIP_CONVERSION_KEYS = new Set([\n 'payload',\n 'result',\n 'metadata',\n 'tags',\n 'settings',\n 'details',\n 'extra',\n 'payloadTemplate',\n 'payload_template',\n 'customLimits',\n 'custom_limits',\n]);\n\n/**\n * Check if a value is a plain object (not array, Date, null, etc.)\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !(value instanceof RegExp) &&\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\n/**\n * Convert a string from camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Convert a string from snake_case to camelCase\n */\nexport function snakeToCamel(str: string): string {\n // Handle numeric segments like `completed_24h` -> `completed24h`\n // and then standard `_x` -> `X` conversion.\n return str\n .replace(/_([0-9]+)/g, (_, digits) => digits)\n .replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Deep convert object keys from camelCase to snake_case.\n * Preserves values in SKIP_CONVERSION_KEYS without deep conversion.\n *\n * @param obj - Object to convert\n * @param skipDeepConversion - Whether current context should skip deep conversion of values\n * @returns Object with snake_case keys\n */\nexport function toSnakeCase<T = unknown>(obj: T, skipDeepConversion = false): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toSnakeCase(item, skipDeepConversion)) as T;\n }\n\n if (obj instanceof Date) {\n return obj.toISOString() as T;\n }\n\n if (!isPlainObject(obj)) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n\n // Check if this key's value should skip deep conversion\n const shouldSkip = skipDeepConversion || SKIP_CONVERSION_KEYS.has(key) || SKIP_CONVERSION_KEYS.has(snakeKey);\n\n if (shouldSkip) {\n // Don't convert the value, just preserve it as-is\n result[snakeKey] = value;\n } else {\n // Recursively convert the value\n result[snakeKey] = toSnakeCase(value, false);\n }\n }\n\n return result as T;\n}\n\n/**\n * Deep convert object keys from snake_case to camelCase.\n * Preserves values in SKIP_CONVERSION_KEYS without deep conversion.\n *\n * @param obj - Object to convert\n * @param skipDeepConversion - Whether current context should skip deep conversion of values\n * @returns Object with camelCase keys\n */\nexport function toCamelCase<T = unknown>(obj: T, skipDeepConversion = false): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toCamelCase(item, skipDeepConversion)) as T;\n }\n\n if (obj instanceof Date) {\n return obj as T;\n }\n\n if (!isPlainObject(obj)) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const camelKey = snakeToCamel(key);\n\n // Check if this key's value should skip deep conversion\n const shouldSkip = skipDeepConversion || SKIP_CONVERSION_KEYS.has(key) || SKIP_CONVERSION_KEYS.has(camelKey);\n\n if (shouldSkip) {\n // Don't convert the value, just preserve it as-is\n result[camelKey] = value;\n } else {\n // Recursively convert the value\n result[camelKey] = toCamelCase(value, false);\n }\n }\n\n return result as T;\n}\n\n/**\n * Convert request body from camelCase (SDK) to snake_case (API)\n */\nexport function convertRequest<T>(body: T): T {\n return toSnakeCase(body);\n}\n\n/**\n * Convert response body from snake_case (API) to camelCase (SDK)\n */\nexport function convertResponse<T>(body: T): T {\n return toCamelCase(body);\n}\n\n/**\n * Convert query parameters from camelCase to snake_case.\n * Only converts top-level keys, not nested objects.\n */\nexport function convertQueryParams(\n params: Record<string, string | number | boolean | undefined>\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = String(value);\n }\n }\n\n return result;\n}\n","/**\n * Retry Utility\n *\n * Implements exponential backoff with jitter for retrying failed requests.\n */\n\nimport type { RetryConfig } from '../config.js';\nimport { RateLimitError, isRetryableError } from '../errors.js';\n\n/** Options for a single retry operation */\nexport interface RetryOptions {\n /** Retry configuration */\n config: RetryConfig;\n /** Optional abort signal to cancel retries */\n signal?: AbortSignal;\n /** Callback for retry events (for logging/debugging) */\n onRetry?: (attempt: number, error: Error, delayMs: number) => void;\n}\n\n/**\n * Calculate delay for a given attempt using exponential backoff with optional jitter\n *\n * @param attempt - Current attempt number (1-based)\n * @param config - Retry configuration\n * @param retryAfterSeconds - Optional Retry-After header value\n * @returns Delay in milliseconds\n */\nexport function calculateDelay(\n attempt: number,\n config: RetryConfig,\n retryAfterSeconds?: number\n): number {\n // If we have a Retry-After value, use it (but respect maxDelay)\n if (retryAfterSeconds !== undefined && retryAfterSeconds > 0) {\n const retryAfterMs = retryAfterSeconds * 1000;\n return Math.min(retryAfterMs, config.maxDelay);\n }\n\n // Calculate exponential delay: baseDelay * factor^(attempt-1)\n const exponentialDelay = config.baseDelay * Math.pow(config.factor, attempt - 1);\n\n // Cap at maxDelay\n let delay = Math.min(exponentialDelay, config.maxDelay);\n\n // Add jitter if enabled (random value between 0 and 25% of delay)\n if (config.jitter) {\n const jitterRange = delay * 0.25;\n const jitter = Math.random() * jitterRange;\n delay = delay + jitter;\n }\n\n return Math.floor(delay);\n}\n\n/**\n * Check if an error should be retried\n *\n * @param error - The error to check\n * @param attempt - Current attempt number\n * @param config - Retry configuration\n * @returns Whether the error is retryable\n */\nexport function shouldRetry(error: Error, attempt: number, config: RetryConfig): boolean {\n // Don't retry if we've exhausted attempts\n // attempt is 1-based, so with maxRetries=2, we allow attempts 1, 2, 3 (initial + 2 retries)\n if (attempt > config.maxRetries) {\n return false;\n }\n\n // Use custom retry function if provided\n if (config.retryOn) {\n return config.retryOn(error, attempt);\n }\n\n // Default: retry on retryable errors\n return isRetryableError(error);\n}\n\n/**\n * Sleep for the specified duration\n *\n * @param ms - Duration in milliseconds\n * @param signal - Optional abort signal\n * @returns Promise that resolves after the delay or rejects if aborted\n */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException('Aborted', 'AbortError'));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n reject(new DOMException('Aborted', 'AbortError'));\n };\n\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\n/**\n * Execute a function with retry logic\n *\n * @param fn - Async function to execute\n * @param options - Retry options\n * @returns Promise resolving to the function result\n * @throws Last error if all retries fail\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): Promise<T> {\n const { config, signal, onRetry } = options;\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= config.maxRetries + 1; attempt++) {\n // Check if aborted before each attempt\n if (signal?.aborted) {\n throw new DOMException('Aborted', 'AbortError');\n }\n\n try {\n return await fn();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n lastError = err;\n\n // Check if we should retry\n if (!shouldRetry(err, attempt, config)) {\n throw err;\n }\n\n // Calculate delay\n let retryAfter: number | undefined;\n if (err instanceof RateLimitError) {\n retryAfter = err.getRetryAfter();\n }\n const delayMs = calculateDelay(attempt, config, retryAfter);\n\n // Notify about retry\n onRetry?.(attempt, err, delayMs);\n\n // Wait before retrying\n await sleep(delayMs, signal);\n }\n }\n\n // Should not reach here, but throw last error just in case\n throw lastError ?? new Error('Retry failed with unknown error');\n}\n\n/**\n * Create a retry wrapper with pre-configured options\n *\n * @param config - Retry configuration\n * @returns Function to wrap async operations with retry logic\n */\nexport function createRetryWrapper(config: RetryConfig) {\n return function retry<T>(\n fn: () => Promise<T>,\n options?: Partial<Omit<RetryOptions, 'config'>>\n ): Promise<T> {\n return withRetry(fn, {\n config,\n ...options,\n });\n };\n}\n","/**\n * HTTP Client Utility\n *\n * Provides a fetch wrapper with:\n * - URL building and query string encoding\n * - JSON request/response handling\n * - Timeout support via AbortController\n * - Automatic retry with exponential backoff\n * - Circuit breaker protection\n * - Case conversion (camelCase <-> snake_case)\n */\n\nimport type { ResolvedConfig, DebugFn } from '../config.js';\nimport { API_BASE_PATH } from '../config.js';\nimport type { RetryConfig } from '../config.js';\nimport {\n createErrorFromResponse,\n NetworkError,\n RateLimitError,\n TimeoutError,\n SpooledError,\n} from '../errors.js';\nimport { convertRequest, convertResponse, convertQueryParams } from './casing.js';\nimport { withRetry } from './retry.js';\nimport { CircuitBreaker } from './circuit-breaker.js';\n\n/**\n * HTTP methods considered idempotent per HTTP semantics.\n * Automatic retry on ambiguous failures (network/timeout/5xx) is only safe\n * for these; non-idempotent methods (POST/PATCH) may cause duplicate side\n * effects if retried after the request already reached the server.\n */\nconst IDEMPOTENT_METHODS = new Set<HttpMethod>(['GET', 'PUT', 'DELETE']);\n\n/** HTTP methods */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\n/** Query parameters type */\nexport type QueryParams = Record<string, string | number | boolean | undefined>;\n\n/** Request options for HTTP client */\nexport interface HttpRequestOptions {\n /** HTTP method (default: GET) */\n method?: HttpMethod;\n /** Request body (will be JSON stringified) */\n body?: unknown;\n /**\n * Raw request body (sent as-is, not JSON stringified).\n * Use this for endpoints that require an exact byte payload (e.g. webhook signature verification).\n */\n rawBody?: string | Uint8Array | ArrayBuffer;\n /** Query parameters */\n params?: QueryParams;\n /**\n * Skip automatically prefixing the path with `/api/v1`.\n * Use this for top-level endpoints like `/health` or `/metrics`.\n */\n skipApiPrefix?: boolean;\n /** Additional headers */\n headers?: Record<string, string>;\n /** Request timeout in milliseconds (overrides client default) */\n timeout?: number;\n /** Whether to skip case conversion for request body */\n skipRequestConversion?: boolean;\n /** Whether to skip case conversion for response body */\n skipResponseConversion?: boolean;\n /** Whether to skip retry logic */\n skipRetry?: boolean;\n /** Optional abort signal */\n signal?: AbortSignal;\n}\n\n/** HTTP response wrapper */\nexport interface HttpResponse<T> {\n /** Response status code */\n status: number;\n /** Response headers */\n headers: Headers;\n /** Parsed response body */\n data: T;\n}\n\n/**\n * HTTP Client class\n *\n * Handles all HTTP communication with the Spooled API.\n */\nexport class HttpClient {\n private readonly config: ResolvedConfig;\n private readonly circuitBreaker: CircuitBreaker;\n private readonly debug: DebugFn | null;\n\n /** Current authentication token (API key or JWT) */\n private authToken: string | undefined;\n\n /** Optional function to mint a fresh access token (set when auto-refresh is enabled) */\n private refreshTokenFn: (() => Promise<string>) | null = null;\n\n /** Guard to prevent a refresh request from recursively triggering another refresh */\n private isRefreshing = false;\n\n constructor(\n config: ResolvedConfig,\n circuitBreaker: CircuitBreaker\n ) {\n this.config = config;\n this.circuitBreaker = circuitBreaker;\n this.debug = config.debug;\n\n // Set initial auth token\n this.authToken = config.accessToken ?? config.apiKey;\n }\n\n /**\n * Set the authentication token\n */\n setAuthToken(token: string): void {\n this.authToken = token;\n }\n\n /**\n * Set the token refresh function.\n *\n * When set, an expired-token 401 on the data plane triggers a single\n * refresh + retry of the original request with the new token.\n */\n setRefreshTokenFn(fn: () => Promise<string>): void {\n this.refreshTokenFn = fn;\n }\n\n /**\n * Build full URL with query parameters\n */\n private buildUrl(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n skipApiPrefix?: boolean\n ): string {\n // Ensure path starts with /api/v1 unless explicitly skipped\n const fullPath = skipApiPrefix ? path : (path.startsWith('/api/') ? path : `${API_BASE_PATH}${path}`);\n const url = new URL(fullPath, this.config.baseUrl);\n\n if (params) {\n const convertedParams = convertQueryParams(params);\n for (const [key, value] of Object.entries(convertedParams)) {\n url.searchParams.append(key, value);\n }\n }\n\n return url.toString();\n }\n\n /**\n * Build request headers\n */\n private buildHeaders(customHeaders?: Record<string, string>): Headers {\n const headers = new Headers();\n\n // Add default headers\n for (const [key, value] of Object.entries(this.config.headers)) {\n headers.set(key, value);\n }\n\n // Add user agent\n headers.set('User-Agent', this.config.userAgent);\n\n // Add auth token if available\n if (this.authToken) {\n headers.set('Authorization', `Bearer ${this.authToken}`);\n }\n\n // Add custom headers\n if (customHeaders) {\n for (const [key, value] of Object.entries(customHeaders)) {\n headers.set(key, value);\n }\n }\n\n return headers;\n }\n\n /**\n * Execute a fetch request with timeout\n */\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n externalSignal?: AbortSignal\n ): Promise<Response> {\n const controller = new AbortController();\n const { signal } = controller;\n\n // Link external signal to our controller\n if (externalSignal) {\n if (externalSignal.aborted) {\n controller.abort();\n } else {\n externalSignal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n }\n\n // Set up timeout\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await this.config.fetch(url, {\n ...init,\n signal,\n });\n return response;\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n // Check if this was a timeout or user abort\n if (externalSignal?.aborted) {\n throw error; // User aborted\n }\n throw new TimeoutError(`Request timed out after ${timeoutMs}ms`, timeoutMs);\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Execute a single HTTP request (no retry)\n */\n private async executeRequest<T>(\n url: string,\n options: HttpRequestOptions,\n hasRefreshed = false\n ): Promise<HttpResponse<T>> {\n const method = options.method ?? 'GET';\n const headers = this.buildHeaders(options.headers);\n const timeout = options.timeout ?? this.config.timeout;\n\n // Build request init\n const init: RequestInit = {\n method,\n headers,\n };\n\n // Add body for methods that support it\n if (method !== 'GET') {\n if (options.rawBody !== undefined) {\n init.body = options.rawBody as unknown as RequestInit['body'];\n } else if (options.body !== undefined) {\n const body = options.skipRequestConversion ? options.body : convertRequest(options.body);\n init.body = JSON.stringify(body);\n }\n }\n\n this.debug?.(`${method} ${url}`, { timeout, hasBody: !!options.body });\n\n let response: Response;\n try {\n response = await this.fetchWithTimeout(url, init, timeout, options.signal);\n } catch (error) {\n if (error instanceof TimeoutError || error instanceof SpooledError) {\n throw error;\n }\n // Network error (fetch failed to get a response)\n const cause = error instanceof Error ? error : undefined;\n throw new NetworkError(`Network request failed: ${cause?.message ?? 'Unknown error'}`, cause);\n }\n\n this.debug?.(`Response: ${response.status}`, { url });\n\n // Handle non-OK responses\n if (!response.ok) {\n // On an expired-token 401, try refreshing the access token once and\n // retry the original request. Guarded so the refresh request itself\n // (or a genuinely invalid credential) can't loop.\n if (\n response.status === 401 &&\n this.refreshTokenFn &&\n !hasRefreshed &&\n !this.isRefreshing\n ) {\n let refreshed = false;\n this.isRefreshing = true;\n try {\n const newToken = await this.refreshTokenFn();\n this.setAuthToken(newToken);\n refreshed = true;\n } catch (refreshError) {\n const message = refreshError instanceof Error ? refreshError.message : 'unknown';\n this.debug?.('Token refresh failed', { error: message });\n } finally {\n this.isRefreshing = false;\n }\n\n if (refreshed) {\n return this.executeRequest<T>(url, options, true);\n }\n }\n\n const apiError = await createErrorFromResponse(response);\n throw apiError;\n }\n\n // Parse response body\n let data: T;\n const contentType = response.headers.get('Content-Type') || '';\n\n if (response.status === 204) {\n data = undefined as T;\n } else if (contentType.includes('application/json')) {\n const rawData = (await response.json()) as T;\n data = options.skipResponseConversion ? rawData : convertResponse(rawData);\n } else {\n // Non-JSON response (e.g. Prometheus metrics text)\n data = (await response.text()) as unknown as T;\n }\n\n return {\n status: response.status,\n headers: response.headers,\n data,\n };\n }\n\n /**\n * Make an HTTP request with retry and circuit breaker\n */\n async request<T>(path: string, options: HttpRequestOptions = {}): Promise<HttpResponse<T>> {\n const url = this.buildUrl(path, options.params, options.skipApiPrefix);\n const method = options.method ?? 'GET';\n\n // Wrap in circuit breaker\n const execute = async (): Promise<HttpResponse<T>> => {\n return this.circuitBreaker.execute(() => this.executeRequest<T>(url, options));\n };\n\n // Apply retry logic if not skipped\n if (options.skipRetry) {\n return execute();\n }\n\n return withRetry(execute, {\n config: this.resolveRetryConfig(method, options),\n signal: options.signal,\n onRetry: (attempt, error, delayMs) => {\n this.debug?.(`Retry attempt ${attempt} after ${delayMs}ms`, { error: error.message });\n },\n });\n }\n\n /**\n * Determine whether a request carries an idempotency key (making a\n * non-idempotent method safe to retry).\n */\n private hasIdempotencyKey(options: HttpRequestOptions): boolean {\n if (!options.headers) {\n return false;\n }\n return Object.keys(options.headers).some((key) => key.toLowerCase() === 'idempotency-key');\n }\n\n /**\n * Resolve the retry configuration for a request.\n *\n * Idempotent methods (GET/PUT/DELETE) and any request carrying an\n * idempotency key retry normally. Non-idempotent methods (POST/PATCH)\n * without an idempotency key must NOT be retried on ambiguous failures\n * (network/timeout/5xx) — doing so risks duplicate jobs, double claims,\n * etc. They are still retried on 429, which is rejected before the\n * server processes the request and is therefore side-effect-free.\n */\n private resolveRetryConfig(method: HttpMethod, options: HttpRequestOptions): RetryConfig {\n const base = this.config.retry;\n\n // Respect an explicit user-provided retry predicate.\n if (base.retryOn) {\n return base;\n }\n\n if (IDEMPOTENT_METHODS.has(method) || this.hasIdempotencyKey(options)) {\n return base;\n }\n\n return {\n ...base,\n retryOn: (error) => error instanceof RateLimitError,\n };\n }\n\n /**\n * Make a GET request\n */\n async get<T>(path: string, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'GET' });\n return response.data;\n }\n\n /**\n * Make a POST request\n */\n async post<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'POST', body });\n return response.data;\n }\n\n /**\n * Make a PUT request\n */\n async put<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'PUT', body });\n return response.data;\n }\n\n /**\n * Make a PATCH request\n */\n async patch<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'PATCH', body });\n return response.data;\n }\n\n /**\n * Make a DELETE request\n */\n async delete<T = void>(path: string, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: 'DELETE' });\n return response.data;\n }\n}\n\n/**\n * Create an HTTP client instance\n */\nexport function createHttpClient(\n config: ResolvedConfig,\n circuitBreaker: CircuitBreaker\n): HttpClient {\n return new HttpClient(config, circuitBreaker);\n}\n","/**\n * Circuit Breaker Utility\n *\n * Implements the circuit breaker pattern to prevent cascading failures.\n * States: CLOSED (normal) -> OPEN (failing) -> HALF_OPEN (testing) -> CLOSED\n */\n\nimport type { CircuitBreakerConfig } from '../config.js';\nimport { CircuitBreakerOpenError, isRetryableError } from '../errors.js';\n\n/** Circuit breaker states */\nexport enum CircuitState {\n /** Normal operation - requests flow through */\n CLOSED = 'CLOSED',\n /** Circuit is open - requests are rejected immediately */\n OPEN = 'OPEN',\n /** Testing state - limited requests allowed to test recovery */\n HALF_OPEN = 'HALF_OPEN',\n}\n\n/** Circuit breaker state change event */\nexport interface CircuitStateChange {\n from: CircuitState;\n to: CircuitState;\n timestamp: Date;\n failureCount: number;\n}\n\n/** Circuit breaker options */\nexport interface CircuitBreakerOptions extends CircuitBreakerConfig {\n /** Callback when state changes */\n onStateChange?: (event: CircuitStateChange) => void;\n /** Custom function to determine if an error should count as a failure */\n isFailure?: (error: Error) => boolean;\n}\n\n/**\n * Circuit Breaker implementation\n *\n * Tracks failures and prevents requests when the failure threshold is reached.\n */\nexport class CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failureCount = 0;\n private successCount = 0;\n private lastFailureTime: number = 0;\n private readonly config: CircuitBreakerOptions;\n\n constructor(config: CircuitBreakerOptions) {\n this.config = config;\n }\n\n /**\n * Get current circuit state\n */\n getState(): CircuitState {\n // Check if we should transition from OPEN to HALF_OPEN\n if (this.state === CircuitState.OPEN) {\n const now = Date.now();\n if (now - this.lastFailureTime >= this.config.timeout) {\n this.transitionTo(CircuitState.HALF_OPEN);\n }\n }\n return this.state;\n }\n\n /**\n * Check if circuit breaker is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Check if requests are currently allowed\n */\n isAllowed(): boolean {\n if (!this.config.enabled) {\n return true;\n }\n\n const state = this.getState();\n return state === CircuitState.CLOSED || state === CircuitState.HALF_OPEN;\n }\n\n /**\n * Record a successful request\n */\n recordSuccess(): void {\n if (!this.config.enabled) {\n return;\n }\n\n if (this.state === CircuitState.HALF_OPEN) {\n this.successCount++;\n\n if (this.successCount >= this.config.successThreshold) {\n this.transitionTo(CircuitState.CLOSED);\n }\n } else if (this.state === CircuitState.CLOSED) {\n // Reset failure count on success in closed state\n this.failureCount = 0;\n }\n }\n\n /**\n * Record a failed request\n */\n recordFailure(error: Error): void {\n if (!this.config.enabled) {\n return;\n }\n\n // Check if this error should count as a failure\n const shouldCount = this.config.isFailure\n ? this.config.isFailure(error)\n : isRetryableError(error);\n\n if (!shouldCount) {\n return;\n }\n\n this.lastFailureTime = Date.now();\n\n if (this.state === CircuitState.HALF_OPEN) {\n // Any failure in half-open state reopens the circuit\n this.transitionTo(CircuitState.OPEN);\n } else if (this.state === CircuitState.CLOSED) {\n this.failureCount++;\n\n if (this.failureCount >= this.config.failureThreshold) {\n this.transitionTo(CircuitState.OPEN);\n }\n }\n }\n\n /**\n * Transition to a new state\n */\n private transitionTo(newState: CircuitState): void {\n if (this.state === newState) {\n return;\n }\n\n const oldState = this.state;\n this.state = newState;\n\n // Reset counters on state change\n if (newState === CircuitState.CLOSED) {\n this.failureCount = 0;\n this.successCount = 0;\n } else if (newState === CircuitState.HALF_OPEN) {\n this.successCount = 0;\n } else if (newState === CircuitState.OPEN) {\n this.successCount = 0;\n }\n\n // Notify listener\n this.config.onStateChange?.({\n from: oldState,\n to: newState,\n timestamp: new Date(),\n failureCount: this.failureCount,\n });\n }\n\n /**\n * Reset the circuit breaker to closed state\n */\n reset(): void {\n this.state = CircuitState.CLOSED;\n this.failureCount = 0;\n this.successCount = 0;\n this.lastFailureTime = 0;\n }\n\n /**\n * Execute a function with circuit breaker protection\n *\n * @param fn - Async function to execute\n * @returns Promise resolving to the function result\n * @throws CircuitBreakerOpenError if circuit is open\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n if (!this.isAllowed()) {\n throw new CircuitBreakerOpenError(\n `Circuit breaker is open. Will retry after ${this.config.timeout}ms`\n );\n }\n\n try {\n const result = await fn();\n this.recordSuccess();\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.recordFailure(err);\n throw error;\n }\n }\n\n /**\n * Get circuit breaker statistics\n */\n getStats(): {\n state: CircuitState;\n failureCount: number;\n successCount: number;\n lastFailureTime: Date | null;\n config: CircuitBreakerConfig;\n } {\n return {\n state: this.getState(),\n failureCount: this.failureCount,\n successCount: this.successCount,\n lastFailureTime: this.lastFailureTime ? new Date(this.lastFailureTime) : null,\n config: {\n enabled: this.config.enabled,\n failureThreshold: this.config.failureThreshold,\n successThreshold: this.config.successThreshold,\n timeout: this.config.timeout,\n },\n };\n }\n}\n\n/**\n * Create a circuit breaker instance from configuration\n */\nexport function createCircuitBreaker(config: CircuitBreakerConfig): CircuitBreaker {\n return new CircuitBreaker(config);\n}\n\n/**\n * Create a disabled circuit breaker (pass-through)\n */\nexport function createDisabledCircuitBreaker(): CircuitBreaker {\n return new CircuitBreaker({\n enabled: false,\n failureThreshold: 0,\n successThreshold: 0,\n timeout: 0,\n });\n}\n","/**\n * Auth Resource\n *\n * Handles authentication operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n LoginParams,\n LoginResponse,\n RefreshTokenParams,\n RefreshTokenResponse,\n CurrentUserResponse,\n ValidateTokenParams,\n ValidateTokenResponse,\n} from '../types/auth.js';\n\nexport class AuthResource {\n constructor(\n private readonly http: HttpClient,\n /** Optional accessor for the client's current refresh token (used by logout) */\n private readonly getRefreshToken?: () => string | undefined\n ) {}\n\n /**\n * Exchange API key for JWT tokens\n */\n async login(params: LoginParams): Promise<LoginResponse> {\n return this.http.post<LoginResponse>('/auth/login', params);\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refresh(params: RefreshTokenParams): Promise<RefreshTokenResponse> {\n return this.http.post<RefreshTokenResponse>('/auth/refresh', params);\n }\n\n /**\n * Logout and revoke the refresh token server-side.\n *\n * The backend requires the refresh token in the body to invalidate the\n * session. When omitted, the client's current refresh token (if any) is\n * used automatically.\n */\n async logout(refreshToken?: string): Promise<void> {\n const token = refreshToken ?? this.getRefreshToken?.();\n await this.http.post<void>('/auth/logout', token ? { refreshToken: token } : undefined);\n }\n\n /**\n * Get current user/session info\n */\n async me(): Promise<CurrentUserResponse> {\n return this.http.get<CurrentUserResponse>('/auth/me');\n }\n\n /**\n * Validate a token\n */\n async validate(params: ValidateTokenParams): Promise<ValidateTokenResponse> {\n return this.http.post<ValidateTokenResponse>('/auth/validate', params);\n }\n\n /**\n * Start email-based login flow (sends magic link)\n */\n async startEmailLogin(email: string): Promise<{ success: boolean; message: string }> {\n return this.http.post<{ success: boolean; message: string }>('/auth/email/start', { email });\n }\n\n /**\n * Check if an email address exists in the system\n */\n async checkEmail(email: string): Promise<{ exists: boolean }> {\n return this.http.get<{ exists: boolean }>('/auth/check-email', {\n params: { email },\n });\n }\n}\n","/**\n * Jobs Resource\n *\n * Handles job operations including worker processing endpoints.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n Job,\n JobSummary,\n JobStats,\n CreateJobParams,\n CreateJobResult,\n ListJobsParams,\n BatchJobStatus,\n ClaimJobsParams,\n ClaimJobsResult,\n CompleteJobParams,\n FailJobParams,\n HeartbeatJobParams,\n BoostPriorityResponse,\n BulkEnqueueParams,\n BulkEnqueueResponse,\n ListDlqParams,\n RetryDlqParams,\n RetryDlqResponse,\n PurgeDlqParams,\n PurgeDlqResponse,\n} from '../types/jobs.js';\n\n/** DLQ operations */\nexport interface DlqOperations {\n /** List jobs in dead-letter queue */\n list(params?: ListDlqParams): Promise<JobSummary[]>;\n /** Retry jobs from DLQ */\n retry(params: RetryDlqParams): Promise<RetryDlqResponse>;\n /** Purge jobs from DLQ */\n purge(params: PurgeDlqParams): Promise<PurgeDlqResponse>;\n}\n\nexport class JobsResource {\n /** Dead-letter queue operations */\n readonly dlq: DlqOperations;\n\n constructor(private readonly http: HttpClient) {\n this.dlq = {\n list: this.listDlq.bind(this),\n retry: this.retryDlq.bind(this),\n purge: this.purgeDlq.bind(this),\n };\n }\n\n /**\n * Create a new job\n */\n async create(params: CreateJobParams): Promise<CreateJobResult> {\n return this.http.post<CreateJobResult>('/jobs', params);\n }\n\n /**\n * Create a job and return the full job object\n */\n async createAndGet(params: CreateJobParams): Promise<Job> {\n const result = await this.create(params);\n return this.get(result.id);\n }\n\n /**\n * List jobs with optional filtering\n */\n async list(params?: ListJobsParams): Promise<JobSummary[]> {\n return this.http.get<JobSummary[]>('/jobs', { params: params as Record<string, string | number | boolean | undefined> });\n }\n\n /**\n * Get a job by ID\n */\n async get(id: string): Promise<Job> {\n return this.http.get<Job>(`/jobs/${id}`);\n }\n\n /**\n * Cancel a pending or scheduled job\n */\n async cancel(id: string): Promise<void> {\n await this.http.delete(`/jobs/${id}`);\n }\n\n /**\n * Retry a failed or dead-lettered job\n */\n async retry(id: string): Promise<Job> {\n return this.http.post<Job>(`/jobs/${id}/retry`);\n }\n\n /**\n * Boost job priority\n */\n async boostPriority(id: string, priority: number): Promise<BoostPriorityResponse> {\n return this.http.put<BoostPriorityResponse>(`/jobs/${id}/priority`, { priority });\n }\n\n /**\n * Get job statistics\n */\n async getStats(): Promise<JobStats> {\n return this.http.get<JobStats>('/jobs/stats');\n }\n\n /**\n * Get status of multiple jobs at once\n */\n async batchStatus(ids: string[]): Promise<BatchJobStatus[]> {\n if (ids.length === 0) {\n return [];\n }\n if (ids.length > 100) {\n throw new Error('Maximum 100 job IDs allowed per request');\n }\n return this.http.get<BatchJobStatus[]>('/jobs/status', {\n params: { ids: ids.join(',') },\n });\n }\n\n /**\n * Bulk enqueue multiple jobs\n */\n async bulkEnqueue(params: BulkEnqueueParams): Promise<BulkEnqueueResponse> {\n return this.http.post<BulkEnqueueResponse>('/jobs/bulk', params);\n }\n\n // Worker processing endpoints\n\n /**\n * Claim jobs for worker processing\n */\n async claim(params: ClaimJobsParams): Promise<ClaimJobsResult> {\n return this.http.post<ClaimJobsResult>('/jobs/claim', params);\n }\n\n /**\n * Complete a job (worker ack)\n */\n async complete(id: string, params: CompleteJobParams): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/jobs/${id}/complete`, params);\n }\n\n /**\n * Fail a job (worker nack)\n */\n async fail(id: string, params: FailJobParams): Promise<{ success: boolean; error?: string }> {\n return this.http.post<{ success: boolean; error?: string }>(`/jobs/${id}/fail`, params);\n }\n\n /**\n * Extend job lease (heartbeat)\n */\n async heartbeat(id: string, params: HeartbeatJobParams): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/jobs/${id}/heartbeat`, params);\n }\n\n // DLQ operations (private implementations)\n\n private async listDlq(params?: ListDlqParams): Promise<JobSummary[]> {\n return this.http.get<JobSummary[]>('/jobs/dlq', { params: params as Record<string, string | number | boolean | undefined> });\n }\n\n private async retryDlq(params: RetryDlqParams): Promise<RetryDlqResponse> {\n return this.http.post<RetryDlqResponse>('/jobs/dlq/retry', params);\n }\n\n private async purgeDlq(params: PurgeDlqParams): Promise<PurgeDlqResponse> {\n return this.http.post<PurgeDlqResponse>('/jobs/dlq/purge', params);\n }\n}\n","/**\n * Queues Resource\n *\n * Handles queue configuration and control operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n QueueConfig,\n QueueConfigSummary,\n QueueStats,\n UpdateQueueConfigParams,\n PauseQueueResponse,\n ResumeQueueResponse,\n} from '../types/queues.js';\n\nexport class QueuesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all queues\n */\n async list(): Promise<QueueConfigSummary[]> {\n return this.http.get<QueueConfigSummary[]>('/queues');\n }\n\n /**\n * Get queue configuration by name\n */\n async get(name: string): Promise<QueueConfig> {\n return this.http.get<QueueConfig>(`/queues/${encodeURIComponent(name)}`);\n }\n\n /**\n * Update queue configuration\n */\n async updateConfig(name: string, params: UpdateQueueConfigParams): Promise<QueueConfig> {\n return this.http.put<QueueConfig>(`/queues/${encodeURIComponent(name)}/config`, params);\n }\n\n /**\n * Get queue statistics\n */\n async getStats(name: string): Promise<QueueStats> {\n return this.http.get<QueueStats>(`/queues/${encodeURIComponent(name)}/stats`);\n }\n\n /**\n * Pause a queue\n */\n async pause(name: string, reason?: string): Promise<PauseQueueResponse> {\n return this.http.post<PauseQueueResponse>(\n `/queues/${encodeURIComponent(name)}/pause`,\n reason ? { reason } : undefined\n );\n }\n\n /**\n * Resume a paused queue\n */\n async resume(name: string): Promise<ResumeQueueResponse> {\n return this.http.post<ResumeQueueResponse>(`/queues/${encodeURIComponent(name)}/resume`);\n }\n\n /**\n * Delete a queue configuration\n */\n async delete(name: string): Promise<void> {\n await this.http.delete(`/queues/${encodeURIComponent(name)}`);\n }\n}\n","/**\n * Workers Resource\n *\n * Handles worker registration and management.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n Worker,\n WorkerSummary,\n RegisterWorkerParams,\n RegisterWorkerResponse,\n WorkerHeartbeatParams,\n} from '../types/workers.js';\n\nexport class WorkersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all workers\n */\n async list(): Promise<WorkerSummary[]> {\n return this.http.get<WorkerSummary[]>('/workers');\n }\n\n /**\n * Get a worker by ID\n */\n async get(id: string): Promise<Worker> {\n return this.http.get<Worker>(`/workers/${id}`);\n }\n\n /**\n * Register a new worker\n */\n async register(params: RegisterWorkerParams): Promise<RegisterWorkerResponse> {\n return this.http.post<RegisterWorkerResponse>('/workers/register', params);\n }\n\n /**\n * Send worker heartbeat\n */\n async heartbeat(id: string, params: WorkerHeartbeatParams): Promise<void> {\n await this.http.post(`/workers/${id}/heartbeat`, params);\n }\n\n /**\n * Deregister a worker\n */\n async deregister(id: string): Promise<void> {\n await this.http.post(`/workers/${id}/deregister`);\n }\n}\n","/**\n * Schedules Resource\n *\n * Handles cron schedule operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n Schedule,\n CreateScheduleParams,\n CreateScheduleResponse,\n UpdateScheduleParams,\n ListSchedulesParams,\n TriggerScheduleResponse,\n ScheduleRun,\n} from '../types/schedules.js';\n\nexport class SchedulesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all schedules\n */\n async list(params?: ListSchedulesParams): Promise<Schedule[]> {\n return this.http.get<Schedule[]>('/schedules', { params: params as Record<string, string | number | boolean | undefined> });\n }\n\n /**\n * Create a new schedule\n */\n async create(params: CreateScheduleParams): Promise<CreateScheduleResponse> {\n return this.http.post<CreateScheduleResponse>('/schedules', params);\n }\n\n /**\n * Get a schedule by ID\n */\n async get(id: string): Promise<Schedule> {\n return this.http.get<Schedule>(`/schedules/${id}`);\n }\n\n /**\n * Update a schedule\n */\n async update(id: string, params: UpdateScheduleParams): Promise<Schedule> {\n return this.http.put<Schedule>(`/schedules/${id}`, params);\n }\n\n /**\n * Delete a schedule\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/schedules/${id}`);\n }\n\n /**\n * Pause a schedule\n */\n async pause(id: string): Promise<Schedule> {\n return this.http.post<Schedule>(`/schedules/${id}/pause`);\n }\n\n /**\n * Resume a paused schedule\n */\n async resume(id: string): Promise<Schedule> {\n return this.http.post<Schedule>(`/schedules/${id}/resume`);\n }\n\n /**\n * Manually trigger a schedule\n */\n async trigger(id: string): Promise<TriggerScheduleResponse> {\n return this.http.post<TriggerScheduleResponse>(`/schedules/${id}/trigger`);\n }\n\n /**\n * Get schedule execution history\n */\n async getHistory(id: string, limit?: number): Promise<ScheduleRun[]> {\n return this.http.get<ScheduleRun[]>(`/schedules/${id}/history`, {\n params: limit ? { limit } : undefined,\n });\n }\n}\n","/**\n * Workflows Resource\n *\n * Handles workflow operations including job dependencies.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n WorkflowResponse,\n CreateWorkflowParams,\n CreateWorkflowResponse,\n ListWorkflowsParams,\n JobWithDependencies,\n AddDependenciesParams,\n AddDependenciesResponse,\n WorkflowJob,\n WorkflowJobStatus,\n} from '../types/workflows.js';\n\n/** Workflow job operations */\nexport interface WorkflowJobOperations {\n /**\n * List all jobs in a workflow.\n *\n * @param workflowId - The workflow ID\n * @example\n * ```typescript\n * const jobs = await client.workflows.jobs.list('wf_123');\n * console.log('Jobs:', jobs.map(j => j.key));\n * ```\n */\n list(workflowId: string): Promise<WorkflowJob[]>;\n\n /**\n * Get a specific job within a workflow.\n *\n * @param workflowId - The workflow ID\n * @param jobId - The job ID\n * @example\n * ```typescript\n * const job = await client.workflows.jobs.get('wf_123', 'job_456');\n * console.log('Job status:', job.status);\n * ```\n */\n get(workflowId: string, jobId: string): Promise<WorkflowJob>;\n\n /**\n * Get the status of all jobs in a workflow.\n *\n * Returns a summary of each job's status and progress.\n *\n * @param workflowId - The workflow ID\n * @example\n * ```typescript\n * const statuses = await client.workflows.jobs.getStatus('wf_123');\n * for (const s of statuses) {\n * console.log(`${s.key}: ${s.status}`);\n * }\n * ```\n */\n getStatus(workflowId: string): Promise<WorkflowJobStatus[]>;\n\n /**\n * Get job dependencies.\n *\n * @param jobId - The job ID\n * @example\n * ```typescript\n * const deps = await client.workflows.jobs.getDependencies('job_456');\n * console.log('Depends on:', deps.dependencies);\n * ```\n */\n getDependencies(jobId: string): Promise<JobWithDependencies>;\n\n /**\n * Add dependencies to a job.\n *\n * @param jobId - The job ID\n * @param params - Dependencies to add\n * @example\n * ```typescript\n * await client.workflows.jobs.addDependencies('job_456', {\n * dependsOnJobIds: ['job_123'],\n * });\n * ```\n */\n addDependencies(jobId: string, params: AddDependenciesParams): Promise<AddDependenciesResponse>;\n}\n\nexport class WorkflowsResource {\n /** Workflow job operations */\n readonly jobs: WorkflowJobOperations;\n\n constructor(private readonly http: HttpClient) {\n this.jobs = {\n list: this.listWorkflowJobs.bind(this),\n get: this.getWorkflowJob.bind(this),\n getStatus: this.getWorkflowJobsStatus.bind(this),\n getDependencies: this.getJobDependencies.bind(this),\n addDependencies: this.addJobDependencies.bind(this),\n };\n }\n\n /**\n * List all workflows\n */\n async list(params?: ListWorkflowsParams): Promise<WorkflowResponse[]> {\n return this.http.get<WorkflowResponse[]>('/workflows', { params: params as Record<string, string | number | boolean | undefined> });\n }\n\n /**\n * Create a new workflow\n */\n async create(params: CreateWorkflowParams): Promise<CreateWorkflowResponse> {\n return this.http.post<CreateWorkflowResponse>('/workflows', params);\n }\n\n /**\n * Get a workflow by ID\n */\n async get(id: string): Promise<WorkflowResponse> {\n return this.http.get<WorkflowResponse>(`/workflows/${id}`);\n }\n\n /**\n * Cancel a workflow\n */\n async cancel(id: string): Promise<WorkflowResponse> {\n return this.http.post<WorkflowResponse>(`/workflows/${id}/cancel`);\n }\n\n /**\n * Retry a failed workflow\n *\n * Resets all failed/deadletter jobs back to pending and resumes the workflow.\n * Only workflows with status 'failed' can be retried.\n */\n async retry(id: string): Promise<WorkflowResponse> {\n return this.http.post<WorkflowResponse>(`/workflows/${id}/retry`);\n }\n\n // Workflow job operations (private implementations)\n\n private async listWorkflowJobs(workflowId: string): Promise<WorkflowJob[]> {\n return this.http.get<WorkflowJob[]>(`/workflows/${workflowId}/jobs`);\n }\n\n private async getWorkflowJob(workflowId: string, jobId: string): Promise<WorkflowJob> {\n return this.http.get<WorkflowJob>(`/workflows/${workflowId}/jobs/${jobId}`);\n }\n\n private async getWorkflowJobsStatus(workflowId: string): Promise<WorkflowJobStatus[]> {\n return this.http.get<WorkflowJobStatus[]>(`/workflows/${workflowId}/jobs/status`);\n }\n\n private async getJobDependencies(jobId: string): Promise<JobWithDependencies> {\n return this.http.get<JobWithDependencies>(`/jobs/${jobId}/dependencies`);\n }\n\n private async addJobDependencies(\n jobId: string,\n params: AddDependenciesParams\n ): Promise<AddDependenciesResponse> {\n return this.http.post<AddDependenciesResponse>(`/jobs/${jobId}/dependencies`, params);\n }\n}\n","/**\n * Webhooks Resource\n *\n * Handles outgoing webhook operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n OutgoingWebhook,\n CreateOutgoingWebhookParams,\n UpdateOutgoingWebhookParams,\n TestWebhookResponse,\n OutgoingWebhookDelivery,\n} from '../types/webhooks.js';\n\nexport class WebhooksResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all outgoing webhooks\n */\n async list(): Promise<OutgoingWebhook[]> {\n return this.http.get<OutgoingWebhook[]>('/outgoing-webhooks');\n }\n\n /**\n * Create a new outgoing webhook\n */\n async create(params: CreateOutgoingWebhookParams): Promise<OutgoingWebhook> {\n return this.http.post<OutgoingWebhook>('/outgoing-webhooks', params);\n }\n\n /**\n * Get an outgoing webhook by ID\n */\n async get(id: string): Promise<OutgoingWebhook> {\n return this.http.get<OutgoingWebhook>(`/outgoing-webhooks/${id}`);\n }\n\n /**\n * Update an outgoing webhook\n */\n async update(id: string, params: UpdateOutgoingWebhookParams): Promise<OutgoingWebhook> {\n return this.http.put<OutgoingWebhook>(`/outgoing-webhooks/${id}`, params);\n }\n\n /**\n * Delete an outgoing webhook\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/outgoing-webhooks/${id}`);\n }\n\n /**\n * Test an outgoing webhook\n */\n async test(id: string): Promise<TestWebhookResponse> {\n return this.http.post<TestWebhookResponse>(`/outgoing-webhooks/${id}/test`);\n }\n\n /**\n * Get webhook delivery history\n */\n async getDeliveries(id: string): Promise<OutgoingWebhookDelivery[]> {\n return this.http.get<OutgoingWebhookDelivery[]>(`/outgoing-webhooks/${id}/deliveries`);\n }\n\n /**\n * Retry a specific webhook delivery\n */\n async retryDelivery(webhookId: string, deliveryId: string): Promise<{ success: boolean; message: string }> {\n return this.http.post<{ success: boolean; message: string }>(\n `/outgoing-webhooks/${webhookId}/retry/${deliveryId}`\n );\n }\n}\n","/**\n * API Keys Resource\n *\n * Handles API key operations.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n ApiKeySummary,\n CreateApiKeyParams,\n CreateApiKeyResponse,\n UpdateApiKeyParams,\n} from '../types/api-keys.js';\n\nexport class ApiKeysResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all API keys (without sensitive data)\n */\n async list(): Promise<ApiKeySummary[]> {\n return this.http.get<ApiKeySummary[]>('/api-keys');\n }\n\n /**\n * Create a new API key\n */\n async create(params: CreateApiKeyParams): Promise<CreateApiKeyResponse> {\n return this.http.post<CreateApiKeyResponse>('/api-keys', params);\n }\n\n /**\n * Get an API key by ID (without sensitive data)\n */\n async get(id: string): Promise<ApiKeySummary> {\n return this.http.get<ApiKeySummary>(`/api-keys/${id}`);\n }\n\n /**\n * Update an API key\n */\n async update(id: string, params: UpdateApiKeyParams): Promise<ApiKeySummary> {\n return this.http.put<ApiKeySummary>(`/api-keys/${id}`, params);\n }\n\n /**\n * Revoke an API key\n */\n async revoke(id: string): Promise<void> {\n await this.http.delete(`/api-keys/${id}`);\n }\n}\n","/**\n * Organizations Resource\n *\n * Handles organization operations including webhook token management.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n Organization,\n OrganizationSummary,\n CreateOrganizationParams,\n CreateOrganizationResponse,\n UpdateOrganizationParams,\n OrganizationUsage,\n OrganizationMember,\n CheckSlugResponse,\n WebhookTokenResponse,\n} from '../types/organizations.js';\n\nexport class OrganizationsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Create a new organization (public endpoint, no auth required)\n */\n async create(params: CreateOrganizationParams): Promise<CreateOrganizationResponse> {\n return this.http.post<CreateOrganizationResponse>('/organizations', params);\n }\n\n /**\n * List organizations\n */\n async list(): Promise<OrganizationSummary[]> {\n return this.http.get<OrganizationSummary[]>('/organizations');\n }\n\n /**\n * Get an organization by ID\n */\n async get(id: string): Promise<Organization> {\n return this.http.get<Organization>(`/organizations/${id}`);\n }\n\n /**\n * Update an organization\n */\n async update(id: string, params: UpdateOrganizationParams): Promise<Organization> {\n return this.http.put<Organization>(`/organizations/${id}`, params);\n }\n\n /**\n * Delete an organization\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/organizations/${id}`);\n }\n\n /**\n * Get organization usage and limits\n */\n async getUsage(): Promise<OrganizationUsage> {\n return this.http.get<OrganizationUsage>('/organizations/usage');\n }\n\n /**\n * Get organization members\n */\n async getMembers(id: string): Promise<OrganizationMember[]> {\n return this.http.get<OrganizationMember[]>(`/organizations/${id}/members`);\n }\n\n /**\n * Check slug availability\n */\n async checkSlug(slug: string): Promise<CheckSlugResponse> {\n return this.http.get<CheckSlugResponse>('/organizations/check-slug', {\n params: { slug },\n });\n }\n\n /**\n * Generate a unique slug from an organization name\n */\n async generateSlug(name: string): Promise<{ slug: string }> {\n return this.http.post<{ slug: string }>('/organizations/generate-slug', { name });\n }\n\n /**\n * Get the webhook token for the current organization.\n *\n * This token is used to verify incoming webhook payloads from Spooled.\n * Use this token to validate webhook signatures.\n *\n * @example\n * ```typescript\n * const { token } = await client.organizations.getWebhookToken();\n * console.log('Webhook token:', token);\n * ```\n */\n async getWebhookToken(): Promise<WebhookTokenResponse> {\n return this.http.get<WebhookTokenResponse>('/organizations/webhook-token');\n }\n\n /**\n * Regenerate the webhook token for the current organization.\n *\n * This invalidates the old token immediately. All webhook signature\n * verification using the old token will fail after regeneration.\n *\n * @example\n * ```typescript\n * const { token: newToken } = await client.organizations.regenerateWebhookToken();\n * console.log('New webhook token:', newToken);\n * ```\n */\n async regenerateWebhookToken(): Promise<WebhookTokenResponse> {\n return this.http.post<WebhookTokenResponse>('/organizations/webhook-token/regenerate');\n }\n\n /**\n * Clear/delete the webhook token for the current organization.\n *\n * After this, webhook signature verification will fail until a new\n * token is generated via regenerateWebhookToken().\n *\n * @example\n * ```typescript\n * await client.organizations.clearWebhookToken();\n * ```\n */\n async clearWebhookToken(): Promise<void> {\n await this.http.post('/organizations/webhook-token/clear');\n }\n}\n","/**\n * Billing Resource\n *\n * Stripe billing integration endpoints.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type { BillingStatus, CreateBillingPortalParams, CreateBillingPortalResponse } from '../types/billing.js';\n\nexport class BillingResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get billing status for the authenticated organization.\n *\n * GET /api/v1/billing/status\n */\n async getStatus(): Promise<BillingStatus> {\n return this.http.get<BillingStatus>('/billing/status');\n }\n\n /**\n * Create a Stripe billing portal session.\n *\n * POST /api/v1/billing/portal\n */\n async createPortal(params: CreateBillingPortalParams): Promise<CreateBillingPortalResponse> {\n return this.http.post<CreateBillingPortalResponse>('/billing/portal', params);\n }\n}\n","/**\n * Dashboard Resource\n *\n * Provides aggregated dashboard data (used by the Spooled dashboard UI).\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type { DashboardData } from '../types/dashboard.js';\n\nexport class DashboardResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get dashboard data for the current organization.\n *\n * GET /api/v1/dashboard\n */\n async get(): Promise<DashboardData> {\n return this.http.get<DashboardData>('/dashboard');\n }\n}\n","/**\n * Health Resource\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type { HealthResponse } from '../types/health.js';\n\nexport class HealthResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Basic health check (public).\n *\n * GET /health\n */\n async get(): Promise<HealthResponse> {\n return this.http.get<HealthResponse>('/health', { skipApiPrefix: true });\n }\n\n /**\n * Kubernetes liveness probe (public).\n *\n * GET /health/live\n */\n async liveness(): Promise<boolean> {\n try {\n await this.http.request<string>('/health/live', {\n method: 'GET',\n skipApiPrefix: true,\n skipRetry: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Kubernetes readiness probe (public).\n *\n * GET /health/ready\n */\n async readiness(): Promise<boolean> {\n try {\n await this.http.request<string>('/health/ready', {\n method: 'GET',\n skipApiPrefix: true,\n skipRetry: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n}\n","/**\n * Metrics Resource\n */\n\nimport type { HttpClient } from '../utils/http.js';\n\nexport class MetricsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Prometheus metrics (public; may be protected by METRICS_TOKEN on the server).\n *\n * GET /metrics\n */\n async get(): Promise<string> {\n return this.http.get<string>('/metrics', {\n skipApiPrefix: true,\n // Ensure we get the raw text response.\n headers: { Accept: 'text/plain' },\n });\n }\n}\n","/**\n * Admin Resource\n *\n * Platform administration endpoints.\n * All endpoints require `X-Admin-Key` header.\n */\n\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n AdminListOrganizationsParams,\n AdminOrganizationList,\n AdminOrganizationDetail,\n AdminUpdateOrganizationParams,\n AdminCreateOrganizationParams,\n AdminCreateOrganizationResponse,\n AdminCreateApiKeyParams,\n AdminApiKeyResponse,\n AdminDeleteOrganizationParams,\n AdminPlatformStats,\n AdminPlanLimits,\n} from '../types/admin.js';\nimport type { Organization } from '../types/organizations.js';\nimport { AuthenticationError } from '../errors.js';\n\nexport class AdminResource {\n constructor(\n private readonly http: HttpClient,\n private readonly adminKey: string | undefined\n ) {}\n\n private headers(): Record<string, string> {\n if (!this.adminKey) {\n throw new AuthenticationError('Admin key is required for admin endpoints. Provide `adminKey` in SpooledClient config.');\n }\n return { 'X-Admin-Key': this.adminKey };\n }\n\n /** GET /api/v1/admin/organizations */\n async listOrganizations(params?: AdminListOrganizationsParams): Promise<AdminOrganizationList> {\n const qp: Record<string, string | number | boolean | undefined> | undefined = params\n ? {\n planTier: params.planTier,\n search: params.search,\n limit: params.limit,\n offset: params.offset,\n sortBy: params.sortBy,\n sortOrder: params.sortOrder,\n }\n : undefined;\n return this.http.get<AdminOrganizationList>('/admin/organizations', {\n params: qp,\n headers: this.headers(),\n });\n }\n\n /** POST /api/v1/admin/organizations */\n async createOrganization(params: AdminCreateOrganizationParams): Promise<AdminCreateOrganizationResponse> {\n return this.http.post<AdminCreateOrganizationResponse>('/admin/organizations', params, {\n headers: this.headers(),\n });\n }\n\n /** GET /api/v1/admin/organizations/{id} */\n async getOrganization(id: string): Promise<AdminOrganizationDetail> {\n return this.http.get<AdminOrganizationDetail>(`/admin/organizations/${id}`, {\n headers: this.headers(),\n });\n }\n\n /** PATCH /api/v1/admin/organizations/{id} */\n async updateOrganization(id: string, params: AdminUpdateOrganizationParams): Promise<Organization> {\n return this.http.patch<Organization>(`/admin/organizations/${id}`, params, {\n headers: this.headers(),\n });\n }\n\n /** DELETE /api/v1/admin/organizations/{id}?hard_delete=true */\n async deleteOrganization(id: string, params?: AdminDeleteOrganizationParams): Promise<void> {\n const qp: Record<string, string | number | boolean | undefined> | undefined = params\n ? { hardDelete: params.hardDelete }\n : undefined;\n await this.http.delete(`/admin/organizations/${id}`, {\n headers: this.headers(),\n params: qp,\n });\n }\n\n /** POST /api/v1/admin/organizations/{id}/api-keys */\n async createApiKey(orgId: string, params: AdminCreateApiKeyParams): Promise<AdminApiKeyResponse> {\n return this.http.post<AdminApiKeyResponse>(`/admin/organizations/${orgId}/api-keys`, params, {\n headers: this.headers(),\n });\n }\n\n /** POST /api/v1/admin/organizations/{id}/reset-usage */\n async resetUsage(orgId: string): Promise<void> {\n await this.http.post<void>(`/admin/organizations/${orgId}/reset-usage`, undefined, {\n headers: this.headers(),\n });\n }\n\n /** GET /api/v1/admin/stats */\n async getStats(): Promise<AdminPlatformStats> {\n return this.http.get<AdminPlatformStats>('/admin/stats', {\n headers: this.headers(),\n });\n }\n\n /** GET /api/v1/admin/plans */\n async listPlans(): Promise<AdminPlanLimits[]> {\n return this.http.get<AdminPlanLimits[]>('/admin/plans', {\n headers: this.headers(),\n });\n }\n}\n","/**\n * Webhook Ingestion Resource\n *\n * These endpoints are intended for webhook providers (GitHub/Stripe/custom) to enqueue jobs.\n * They are authenticated via signatures (not API keys).\n */\n\nimport { createHmac } from 'node:crypto';\nimport { Buffer } from 'node:buffer';\nimport type { HttpClient } from '../utils/http.js';\nimport type {\n IngestCustomWebhookParams,\n IngestGitHubWebhookOptions,\n IngestStripeWebhookOptions,\n} from '../types/webhook-ingestion.js';\nimport { ValidationError } from '../errors.js';\n\nfunction toBytes(body: string | Uint8Array | ArrayBuffer): Uint8Array {\n if (typeof body === 'string') {\n return Buffer.from(body, 'utf8');\n }\n if (body instanceof Uint8Array) {\n return body;\n }\n return new Uint8Array(body);\n}\n\nfunction githubSignature(secret: string, body: Uint8Array): string {\n const hex = createHmac('sha256', secret).update(body).digest('hex');\n return `sha256=${hex}`;\n}\n\nfunction stripeSignature(secret: string, body: Uint8Array, timestamp: number): string {\n // Stripe signs: `${timestamp}.${rawBodyUtf8}`\n const payload = `${timestamp}.${Buffer.from(body).toString('utf8')}`;\n const hex = createHmac('sha256', secret).update(payload, 'utf8').digest('hex');\n return `t=${timestamp},v1=${hex}`;\n}\n\nexport class WebhookIngestionResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Ingest a GitHub webhook.\n *\n * POST /api/v1/webhooks/{org_id}/github\n */\n async github(orgId: string, body: string | Uint8Array | ArrayBuffer, options: IngestGitHubWebhookOptions): Promise<void> {\n const bytes = toBytes(body);\n\n const signature = options.signature ?? (options.secret ? githubSignature(options.secret, bytes) : undefined);\n if (!signature) {\n throw new ValidationError('GitHub webhook signature is required (provide `signature` or `secret`)');\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-GitHub-Event': options.githubEvent,\n 'X-Hub-Signature-256': signature,\n };\n\n if (options.webhookToken) {\n headers['X-Webhook-Token'] = options.webhookToken;\n }\n if (options.forwardedProto) {\n headers['X-Forwarded-Proto'] = options.forwardedProto;\n }\n\n await this.http.request<void>(`/webhooks/${orgId}/github`, {\n method: 'POST',\n rawBody: bytes,\n headers,\n skipRequestConversion: true,\n skipResponseConversion: true,\n });\n }\n\n /**\n * Ingest a Stripe webhook.\n *\n * POST /api/v1/webhooks/{org_id}/stripe\n */\n async stripe(orgId: string, body: string | Uint8Array | ArrayBuffer, options: IngestStripeWebhookOptions = {}): Promise<void> {\n const bytes = toBytes(body);\n const timestamp = options.timestamp ?? Math.floor(Date.now() / 1000);\n\n const signature = options.signature ?? (options.secret ? stripeSignature(options.secret, bytes, timestamp) : undefined);\n if (!signature) {\n throw new ValidationError('Stripe webhook signature is required (provide `signature` or `secret`)');\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Stripe-Signature': signature,\n };\n\n if (options.webhookToken) {\n headers['X-Webhook-Token'] = options.webhookToken;\n }\n if (options.forwardedProto) {\n headers['X-Forwarded-Proto'] = options.forwardedProto;\n }\n\n await this.http.request<void>(`/webhooks/${orgId}/stripe`, {\n method: 'POST',\n rawBody: bytes,\n headers,\n skipRequestConversion: true,\n skipResponseConversion: true,\n });\n }\n\n /**\n * Ingest a custom webhook.\n *\n * POST /api/v1/webhooks/{org_id}/custom\n */\n async custom(orgId: string, params: IngestCustomWebhookParams, opts?: { webhookToken?: string; forwardedProto?: string }): Promise<void> {\n const headers: Record<string, string> = {\n ...(opts?.webhookToken ? { 'X-Webhook-Token': opts.webhookToken } : {}),\n ...(opts?.forwardedProto ? { 'X-Forwarded-Proto': opts.forwardedProto } : {}),\n };\n\n await this.http.post<void>(`/webhooks/${orgId}/custom`, params, {\n headers,\n });\n }\n}\n","/**\n * Backend → SDK realtime event-name mapping.\n *\n * The backend's `RealtimeEvent` enum is serialized with\n * `#[serde(tag = \"type\", content = \"data\")]`, so events arrive on the wire as\n * `{ \"type\": \"<PascalCaseVariant>\", \"data\": { ...snake_case fields } }`, e.g.\n * `{ \"type\": \"JobCompleted\", \"data\": { \"job_id\": \"…\", \"duration_ms\": 12 } }`.\n *\n * The SDK's public event API, however, uses dotted names (`job.completed`,\n * `queue.stats`, …). Without translation, `rt.on('job.completed', …)` never\n * fires because the transport dispatches under the raw wire name\n * (`JobCompleted`). This map bridges the two: every variant of the backend enum\n * maps to its dotted SDK name.\n */\nexport const BACKEND_EVENT_TYPE_MAP: Record<string, string> = {\n JobStatusChange: 'job.status_changed',\n JobCreated: 'job.created',\n JobCompleted: 'job.completed',\n JobFailed: 'job.failed',\n QueueStats: 'queue.stats',\n WorkerHeartbeat: 'worker.heartbeat',\n WorkerRegistered: 'worker.registered',\n WorkerDeregistered: 'worker.deregistered',\n SystemHealth: 'system.health',\n Ping: 'ping',\n Error: 'error',\n};\n\n/**\n * Translate a wire event `type` to the SDK's dotted event name.\n *\n * Names that are already dotted (or otherwise unknown) pass through unchanged,\n * so this is safe to call on every inbound message and keeps working if the\n * backend ever starts sending pre-dotted names.\n */\nexport function mapEventType(type: string): string {\n return BACKEND_EVENT_TYPE_MAP[type] ?? type;\n}\n","/**\n * WebSocket Realtime Client\n *\n * Provides real-time event streaming over WebSocket.\n */\n\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n WebSocketCommand,\n} from './types.js';\nimport { convertResponse } from '../utils/casing.js';\nimport { mapEventType } from './event-map.js';\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * WebSocket Realtime Client\n *\n * Connects to the Spooled API WebSocket endpoint and emits typed events.\n */\nexport class WebSocketRealtimeClient {\n private readonly options: Required<RealtimeConnectionOptions>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private ws: any = null;\n private state: ConnectionState = 'disconnected';\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n /**\n * Set when the server rejected our token on the upgrade (e.g. HTTP 401/403).\n * The next (re)connect uses it to force the token provider to mint a fresh\n * JWT instead of replaying the rejected one (which would loop forever).\n */\n private authFailure = false;\n private subscriptions: Map<string, SubscriptionFilter> = new Map();\n\n // Event handlers\n private eventHandlers: Map<RealtimeEventType, Set<EventHandler>> = new Map();\n private allEventsHandlers: Set<GenericEventHandler> = new Set();\n private stateChangeHandlers: Set<(state: ConnectionState) => void> = new Set();\n\n constructor(options: RealtimeConnectionOptions) {\n // All defaults are applied AFTER the spread. SpooledRealtime forwards each of\n // these options as possibly-`undefined`, and a pre-spread default is clobbered\n // by an explicit `undefined` — e.g. autoReconnect would resolve to undefined\n // (falsy), silently disabling reconnect despite the documented default `true`,\n // and debug would become undefined and throw when connect() calls it.\n this.options = {\n ...options,\n autoReconnect: options.autoReconnect ?? true,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n // Always resolve to a provider so reconnects can mint a fresh JWT.\n // Falls back to the static token when no provider is supplied.\n tokenProvider: options.tokenProvider ?? (async () => options.token),\n debug: options.debug ?? (() => {}),\n };\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Get WebSocket implementation (browser native or Node.js ws package)\n */\n private async getWebSocketImpl(): Promise<typeof WebSocket> {\n if (typeof WebSocket !== 'undefined') {\n return WebSocket;\n }\n // Node.js environment - use ws package with dynamic import for ESM compatibility\n const wsModule = await import('ws');\n return wsModule.default as unknown as typeof WebSocket;\n }\n\n /**\n * Connect to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.state === 'connected' || this.state === 'connecting') {\n return;\n }\n\n this.setState('connecting');\n\n // Build WebSocket URL with a freshly-minted token\n let wsUrl: string;\n try {\n wsUrl = await this.buildWsUrl();\n } catch (error) {\n this.setState('disconnected');\n throw new Error(`Failed to acquire realtime token: ${error}`);\n }\n // Redact the token query param so JWTs never land in logs.\n this.options.debug(`Connecting to ${redactToken(wsUrl)}`);\n\n // Get WebSocket implementation (async for ESM compatibility in Node.js)\n let WebSocketImpl: typeof WebSocket;\n try {\n WebSocketImpl = await this.getWebSocketImpl();\n } catch (error) {\n this.setState('disconnected');\n throw new Error(`Failed to load WebSocket implementation: ${error}`);\n }\n\n return new Promise((resolve, reject) => {\n try {\n this.ws = new WebSocketImpl(wsUrl);\n\n this.ws.onopen = () => {\n this.options.debug('WebSocket connected');\n this.setState('connected');\n this.reconnectAttempts = 0;\n this.resubscribeAll();\n resolve();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onmessage = (event: any) => {\n this.handleMessage(typeof event.data === 'string' ? event.data : String(event.data));\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onclose = (event: any) => {\n this.options.debug(`WebSocket closed: ${event.code} ${event.reason}`);\n this.handleDisconnect();\n if (this.state === 'connecting') {\n reject(new Error(`WebSocket connection failed: ${event.reason || 'Unknown error'}`));\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onerror = (event: any) => {\n this.options.debug('WebSocket error', event);\n // The Node `ws` package surfaces a rejected upgrade here as an error\n // whose message is e.g. \"Unexpected server response: 401\". Flag it so\n // the next reconnect forces a fresh token rather than replaying the\n // rejected one. (Browsers don't expose the status; expiry-based\n // refresh still covers the common case there.)\n if (isAuthFailureEvent(event)) {\n this.authFailure = true;\n }\n };\n } catch (error) {\n this.setState('disconnected');\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.onclose = null; // Prevent reconnect\n this.ws.close(1000, 'Client disconnect');\n this.ws = null;\n }\n\n this.setState('disconnected');\n this.subscriptions.clear();\n }\n\n /**\n * Subscribe to events matching a filter.\n *\n * The server applies filtering itself and sends no acknowledgement, so this\n * resolves as soon as the command has been written to the socket. The filter\n * is tracked locally so it is replayed automatically on reconnect.\n */\n async subscribe(filter: SubscriptionFilter): Promise<void> {\n const filterId = this.filterToId(filter);\n\n if (this.subscriptions.has(filterId)) {\n return; // Already subscribed\n }\n\n this.subscriptions.set(filterId, filter);\n\n if (this.state === 'connected') {\n this.sendCommand('Subscribe', filter);\n }\n }\n\n /**\n * Unsubscribe from events matching a filter.\n *\n * Fire-and-forget, like {@link subscribe} — the server sends no ack.\n */\n async unsubscribe(filter: SubscriptionFilter): Promise<void> {\n const filterId = this.filterToId(filter);\n\n if (!this.subscriptions.has(filterId)) {\n return; // Not subscribed\n }\n\n this.subscriptions.delete(filterId);\n\n if (this.state === 'connected') {\n this.sendCommand('Unsubscribe', filter);\n }\n }\n\n /**\n * Add an event listener for a specific event type\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n if (!this.eventHandlers.has(type)) {\n this.eventHandlers.set(type, new Set());\n }\n this.eventHandlers.get(type)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n const handlers = this.eventHandlers.get(type);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n\n /**\n * Add a listener for all events\n */\n onEvent(handler: GenericEventHandler): () => void {\n this.allEventsHandlers.add(handler);\n return () => this.allEventsHandlers.delete(handler);\n }\n\n /**\n * Add a listener for state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => this.stateChangeHandlers.delete(handler);\n }\n\n // Private methods\n\n private async buildWsUrl(): Promise<string> {\n // wsUrl should already be ws:// or wss://\n const wsBase = this.options.wsUrl;\n // Reuse the provider's cached JWT unless the previous attempt was rejected\n // for auth (401/403 on the upgrade), in which case force a fresh token so a\n // stale/revoked one can't block recovery. Clear the flag either way.\n const forceRefresh = this.authFailure;\n this.authFailure = false;\n const token = await this.options.tokenProvider(forceRefresh);\n return `${wsBase}/api/v1/ws?token=${encodeURIComponent(token)}`;\n }\n\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.stateChangeHandlers.forEach((handler) => handler(state));\n }\n }\n\n private handleMessage(data: string): void {\n try {\n // Backend emits snake_case; convert to camelCase to match the typed\n // event shapes (jobId, queueName, durationMs, ...). User blobs like\n // `result`/`payload` are preserved via SKIP_CONVERSION_KEYS.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const message = convertResponse(JSON.parse(data)) as any;\n\n // The backend tags events with the PascalCase enum variant name\n // (`JobCompleted`, `QueueStats`, ...); the SDK's public API dispatches by\n // dotted name (`job.completed`, `queue.stats`). Translate before dispatch\n // so `on('job.completed', ...)` fires. Unknown/pre-dotted names pass\n // through unchanged.\n const eventType = mapEventType(String(message.type));\n message.type = eventType;\n const event = message as RealtimeEvent;\n this.options.debug(`Received event: ${eventType}`, event);\n\n // Emit to specific handlers\n const handlers = this.eventHandlers.get(eventType as RealtimeEventType);\n if (handlers) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventData = (event as any).data;\n handlers.forEach((handler) => {\n try {\n handler(eventData);\n } catch (error) {\n this.options.debug('Event handler error', error);\n }\n });\n }\n\n // Emit to all-events handlers\n this.allEventsHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n this.options.debug('Event handler error', error);\n }\n });\n } catch (error) {\n this.options.debug('Failed to parse message', { data, error });\n }\n }\n\n private handleDisconnect(): void {\n this.ws = null;\n\n if (this.options.autoReconnect && this.reconnectAttempts < this.options.maxReconnectAttempts) {\n this.scheduleReconnect();\n } else {\n this.setState('disconnected');\n }\n }\n\n private scheduleReconnect(): void {\n this.setState('reconnecting');\n this.reconnectAttempts++;\n\n const baseDelay = Math.min(\n this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n this.options.maxReconnectDelay\n );\n // Add randomized jitter (up to +25%) to avoid a thundering-herd reconnect\n // storm when many clients drop at the same moment. Matches utils/retry.ts.\n const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);\n\n this.options.debug(`Scheduling reconnect attempt ${this.reconnectAttempts} in ${delay}ms`);\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await this.connect();\n } catch (error) {\n this.options.debug('Reconnect failed', error);\n // handleDisconnect will schedule another attempt if needed\n }\n }, delay);\n }\n\n private resubscribeAll(): void {\n for (const filter of this.subscriptions.values()) {\n try {\n this.sendCommand('Subscribe', filter);\n } catch (error) {\n this.options.debug('Failed to resubscribe', { filter, error });\n }\n }\n }\n\n /**\n * Send a subscribe/unsubscribe command to the server.\n *\n * The backend `ClientCommand` shape is `{ cmd, queue, job_id }` and it sends\n * no acknowledgement, so this is fire-and-forget — it writes to the socket\n * and returns. The `SubscriptionFilter`'s `workerId`/`scheduleId` have no\n * server-side equivalent and are ignored.\n */\n private sendCommand(cmd: 'Subscribe' | 'Unsubscribe', filter: SubscriptionFilter): void {\n if (!this.ws || this.state !== 'connected') {\n throw new Error('WebSocket not connected');\n }\n\n const command: WebSocketCommand = {\n cmd,\n queue: filter.queueName,\n job_id: filter.jobId,\n };\n this.ws.send(JSON.stringify(command));\n }\n\n private filterToId(filter: SubscriptionFilter): string {\n return JSON.stringify(filter);\n }\n}\n\n/**\n * Redact sensitive auth query params (token/api_key) from a URL for logging.\n */\nexport function redactToken(url: string): string {\n return url.replace(/([?&](?:token|api_key)=)[^&]*/gi, '$1***');\n}\n\n/**\n * Detect whether a WebSocket error event represents an auth rejection on the\n * upgrade (HTTP 401/403). The Node `ws` package reports these as an error whose\n * message is like \"Unexpected server response: 401\"; different runtimes may put\n * the text on `message`, `error.message`, or `reason`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isAuthFailureEvent(event: any): boolean {\n if (!event) {\n return false;\n }\n const status = event.status ?? event.statusCode ?? event.error?.status;\n if (status === 401 || status === 403) {\n return true;\n }\n const text = String(event.message ?? event.error?.message ?? event.reason ?? '');\n return /\\b(401|403)\\b/.test(text);\n}\n","/**\n * SSE Realtime Client\n *\n * Provides real-time event streaming over Server-Sent Events.\n */\n\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n} from './types.js';\nimport { convertResponse } from '../utils/casing.js';\nimport { mapEventType } from './event-map.js';\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * SSE Realtime Client\n *\n * Connects to the Spooled API SSE endpoint and emits typed events.\n * SSE is unidirectional - subscriptions must be set at connection time.\n */\nexport class SseRealtimeClient {\n private readonly options: Required<RealtimeConnectionOptions>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private eventSource: any = null;\n private state: ConnectionState = 'disconnected';\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private filter: SubscriptionFilter | null = null;\n\n // Event handlers\n private eventHandlers: Map<RealtimeEventType, Set<EventHandler>> = new Map();\n private allEventsHandlers: Set<GenericEventHandler> = new Set();\n private stateChangeHandlers: Set<(state: ConnectionState) => void> = new Set();\n\n constructor(options: RealtimeConnectionOptions) {\n // Defaults applied AFTER the spread — a pre-spread default is clobbered by an\n // explicit `undefined` forwarded from SpooledRealtime (e.g. autoReconnect would\n // resolve to undefined/falsy, silently disabling reconnect despite the\n // documented default `true`).\n this.options = {\n ...options,\n autoReconnect: options.autoReconnect ?? true,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n // Always resolve to a provider so reconnects can mint a fresh token.\n // Falls back to the static token when no provider is supplied.\n tokenProvider: options.tokenProvider ?? (async () => options.token),\n // Coalesce debug to a no-op AFTER the spread. A caller that omits debug\n // still passes `debug: undefined` explicitly (e.g. via SpooledRealtime),\n // and spreading that would overwrite a pre-spread default with undefined,\n // making connect() call `this.options.debug(...)` on undefined and throw\n // \"this.options.debug is not a function\". Guarding here keeps it callable\n // regardless of what the caller passes.\n debug: options.debug ?? (() => {}),\n };\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Connect to the SSE server with a subscription filter\n */\n async connect(filter?: SubscriptionFilter): Promise<void> {\n if (this.state === 'connected' || this.state === 'connecting') {\n return;\n }\n\n this.filter = filter || null;\n\n this.setState('connecting');\n\n const sseUrl = this.buildSseUrl(filter);\n this.options.debug(`Connecting to SSE: ${sseUrl}`);\n\n // Use eventsource package in Node.js, native EventSource in browser\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let EventSourceImpl: any;\n if (typeof EventSource !== 'undefined') {\n EventSourceImpl = EventSource;\n } else {\n // Dynamic import for ESM compatibility\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = await import('eventsource') as any;\n EventSourceImpl = mod.default || mod.EventSource || mod;\n } catch {\n this.setState('disconnected');\n throw new Error('eventsource package is required for SSE in Node.js. Install it with: npm install eventsource');\n }\n }\n\n // Mint a fresh token on every (re)connect so a stale token never blocks recovery.\n let token: string;\n try {\n token = await this.options.tokenProvider();\n } catch (error) {\n this.setState('disconnected');\n throw new Error(`Failed to acquire realtime token: ${error}`);\n }\n\n return new Promise((resolve, reject) => {\n try {\n // Create EventSource with authorization header\n // Note: eventsource v4 changed API - headers are now passed via custom fetch\n this.eventSource = new EventSourceImpl(sseUrl, {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fetch: (input: any, init: any) =>\n fetch(input, {\n ...init,\n headers: {\n ...init?.headers,\n Authorization: `Bearer ${token}`,\n },\n }),\n });\n\n this.eventSource.onopen = () => {\n this.options.debug('SSE connected');\n this.setState('connected');\n this.reconnectAttempts = 0;\n resolve();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.eventSource.onmessage = (event: any) => {\n this.handleMessage(event.data);\n };\n\n this.eventSource.onerror = () => {\n this.options.debug('SSE error');\n\n if (this.state === 'connecting') {\n this.setState('disconnected');\n // Close the abandoned EventSource so it doesn't keep auto-reconnecting\n // in the background after we reject the initial connect promise.\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n reject(new Error('SSE connection failed'));\n return;\n }\n\n this.handleDisconnect();\n };\n } catch (error) {\n this.setState('disconnected');\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the SSE server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n\n this.setState('disconnected');\n this.filter = null;\n }\n\n /**\n * Reconnect with a new filter (SSE requires reconnection to change subscriptions)\n */\n async reconnect(filter?: SubscriptionFilter): Promise<void> {\n this.disconnect();\n await this.connect(filter);\n }\n\n /**\n * Add an event listener for a specific event type\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n if (!this.eventHandlers.has(type)) {\n this.eventHandlers.set(type, new Set());\n }\n this.eventHandlers.get(type)!.add(handler);\n\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n const handlers = this.eventHandlers.get(type);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n\n /**\n * Add a listener for all events\n */\n onEvent(handler: GenericEventHandler): () => void {\n this.allEventsHandlers.add(handler);\n return () => this.allEventsHandlers.delete(handler);\n }\n\n /**\n * Add a listener for state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => this.stateChangeHandlers.delete(handler);\n }\n\n // Private methods\n\n private buildSseUrl(filter?: SubscriptionFilter): string {\n // Backend SSE endpoints:\n // - GET /api/v1/events (all events)\n // - GET /api/v1/events/jobs/{id} (single job polling stream)\n // - GET /api/v1/events/queues/{name} (queue stats polling stream)\n //\n // Note: SSE in the backend is unidirectional and subscriptions are effectively set by endpoint.\n if (filter?.jobId) {\n return `${this.options.baseUrl}/api/v1/events/jobs/${encodeURIComponent(filter.jobId)}`;\n }\n if (filter?.queueName) {\n return `${this.options.baseUrl}/api/v1/events/queues/${encodeURIComponent(filter.queueName)}`;\n }\n return `${this.options.baseUrl}/api/v1/events`;\n }\n\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.stateChangeHandlers.forEach((handler) => handler(state));\n }\n }\n\n private handleMessage(data: string): void {\n try {\n // Backend emits snake_case; convert to camelCase to match the typed\n // event shapes. User blobs (`result`/`payload`) are preserved via\n // SKIP_CONVERSION_KEYS.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const parsed = convertResponse(JSON.parse(data)) as any;\n // Translate the backend's PascalCase variant name (`JobCompleted`) to the\n // SDK's dotted event name (`job.completed`) before dispatch, matching the\n // WebSocket client. Unknown/pre-dotted names pass through unchanged.\n const eventType = mapEventType(String(parsed.type));\n parsed.type = eventType;\n const event = parsed as RealtimeEvent;\n this.options.debug(`Received SSE event: ${eventType}`, event);\n\n // Emit to specific handlers\n const handlers = this.eventHandlers.get(eventType as RealtimeEventType);\n if (handlers) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventData = (event as any).data;\n handlers.forEach((handler) => {\n try {\n handler(eventData);\n } catch (error) {\n this.options.debug('Event handler error', error);\n }\n });\n }\n\n // Emit to all-events handlers\n this.allEventsHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n this.options.debug('Event handler error', error);\n }\n });\n } catch (error) {\n this.options.debug('Failed to parse SSE message', { data, error });\n }\n }\n\n private handleDisconnect(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n\n if (this.options.autoReconnect && this.reconnectAttempts < this.options.maxReconnectAttempts) {\n this.scheduleReconnect();\n } else {\n this.setState('disconnected');\n }\n }\n\n private scheduleReconnect(): void {\n this.setState('reconnecting');\n this.reconnectAttempts++;\n\n const baseDelay = Math.min(\n this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n this.options.maxReconnectDelay\n );\n // Add randomized jitter (up to +25%) to avoid synchronized reconnect\n // storms across clients. Matches utils/retry.ts.\n const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);\n\n this.options.debug(`Scheduling SSE reconnect attempt ${this.reconnectAttempts} in ${delay}ms`);\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await this.connect(this.filter || undefined);\n } catch (error) {\n this.options.debug('SSE reconnect failed', error);\n }\n }, delay);\n }\n}\n","/**\n * Realtime Module\n *\n * Provides WebSocket and SSE clients for real-time event streaming.\n */\n\nexport * from './types.js';\nexport { WebSocketRealtimeClient } from './websocket.js';\nexport { SseRealtimeClient } from './sse.js';\n\nimport { WebSocketRealtimeClient } from './websocket.js';\nimport { SseRealtimeClient } from './sse.js';\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n} from './types.js';\n\n/** Options for creating a SpooledRealtime instance */\nexport interface SpooledRealtimeOptions {\n /**\n * Connection type: 'websocket' or 'sse' (default: 'websocket').\n *\n * Default is WebSocket because it’s typically the lowest server load:\n * - WebSocket uses push/pubsub in the backend\n * - SSE job/queue endpoints poll the database periodically\n */\n type?: 'websocket' | 'sse';\n /** Auto-reconnect on disconnect (default: true) */\n autoReconnect?: boolean;\n /** Maximum reconnect attempts (default: 10) */\n maxReconnectAttempts?: number;\n /** Initial reconnect delay in ms (default: 1000) */\n reconnectDelay?: number;\n /** Maximum reconnect delay in ms (default: 30000) */\n maxReconnectDelay?: number;\n}\n\n/** Full options including internal fields */\ninterface FullRealtimeOptions extends SpooledRealtimeOptions {\n baseUrl: string;\n wsUrl: string;\n token: string;\n /** Async provider that supplies a valid JWT for each (re)connect */\n tokenProvider?: (forceRefresh?: boolean) => Promise<string>;\n debug?: (message: string, meta?: unknown) => void;\n}\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * Unified Realtime Client\n *\n * Wraps WebSocket and SSE clients with a common interface.\n */\nexport class SpooledRealtime {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly client: any;\n\n constructor(options: FullRealtimeOptions) {\n const connectionOptions: RealtimeConnectionOptions = {\n baseUrl: options.baseUrl,\n wsUrl: options.wsUrl,\n token: options.token,\n tokenProvider: options.tokenProvider,\n autoReconnect: options.autoReconnect,\n maxReconnectAttempts: options.maxReconnectAttempts,\n reconnectDelay: options.reconnectDelay,\n maxReconnectDelay: options.maxReconnectDelay,\n debug: options.debug,\n };\n\n if (options.type === 'sse') {\n this.client = new SseRealtimeClient(connectionOptions);\n } else {\n this.client = new WebSocketRealtimeClient(connectionOptions);\n }\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.client.getState();\n }\n\n /**\n * Connect to the realtime server\n */\n async connect(): Promise<void> {\n return this.client.connect();\n }\n\n /**\n * Disconnect from the realtime server\n */\n disconnect(): void {\n this.client.disconnect();\n }\n\n /**\n * Subscribe to events matching a filter\n *\n * @example\n * ```typescript\n * // Subscribe to all events from a queue\n * await realtime.subscribe({ queueName: 'my-queue' });\n *\n * // Subscribe to events for a specific job\n * await realtime.subscribe({ jobId: 'job-123' });\n * ```\n */\n async subscribe(filter: SubscriptionFilter): Promise<void> {\n // SSE subscriptions are effectively endpoint-based; change requires reconnect.\n if (typeof this.client.subscribe === 'function') {\n return this.client.subscribe(filter);\n }\n return this.client.reconnect(filter);\n }\n\n /**\n * Unsubscribe from events matching a filter\n */\n async unsubscribe(filter: SubscriptionFilter): Promise<void> {\n if (typeof this.client.unsubscribe === 'function') {\n return this.client.unsubscribe(filter);\n }\n // For SSE, unsubscribing means disconnecting if the filter matches current connection.\n this.client.disconnect();\n }\n\n /**\n * Add an event listener for a specific event type\n *\n * @example\n * ```typescript\n * realtime.on('job.completed', (data) => {\n * console.log('Job completed:', data.jobId);\n * });\n *\n * realtime.on('job.failed', (data) => {\n * console.error('Job failed:', data.error);\n * });\n * ```\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n return this.client.on(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n this.client.off(type, handler);\n }\n\n /**\n * Add a listener for all events\n *\n * @example\n * ```typescript\n * realtime.onEvent((event) => {\n * console.log(`Event: ${event.type}`, event.data);\n * });\n * ```\n */\n onEvent(handler: GenericEventHandler): () => void {\n return this.client.onEvent(handler);\n }\n\n /**\n * Add a listener for connection state changes\n *\n * @example\n * ```typescript\n * realtime.onStateChange((state) => {\n * console.log('Connection state:', state);\n * });\n * ```\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n return this.client.onStateChange(handler);\n }\n}\n","/**\n * Proto Loader Utility\n *\n * Dynamically loads the Spooled proto file for gRPC communication.\n */\n\n/* global __dirname */\n\nimport * as grpc from '@grpc/grpc-js';\nimport * as protoLoader from '@grpc/proto-loader';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport type { ServiceClientConstructor } from '@grpc/grpc-js';\n\n/** Proto loader options for consistent parsing */\nexport const PROTO_LOADER_OPTIONS: protoLoader.Options = {\n keepCase: false, // Convert snake_case to camelCase\n longs: String, // Represent int64 as strings\n enums: String, // Represent enums as strings\n defaults: true, // Include default values\n oneofs: true, // Support oneofs\n};\n\nexport interface SpooledProtoDefinition {\n spooled: {\n v1: {\n QueueService: ServiceClientConstructor;\n WorkerService: ServiceClientConstructor;\n };\n };\n}\n\nlet cachedDefinition: SpooledProtoDefinition | null = null;\n\n/**\n * Get the path to the proto file.\n * Supports both ESM and CJS environments.\n */\nfunction getProtoPath(): string {\n // In ESM, use import.meta.url\n if (typeof import.meta?.url !== 'undefined') {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n return join(__dirname, '../../proto/spooled.proto');\n }\n\n // Fallback for CJS (when bundled)\n return join(__dirname, '../../proto/spooled.proto');\n}\n\n/**\n * Load the Spooled proto definition synchronously.\n * Caches the result for subsequent calls.\n */\nexport function loadProtoDefinition(): SpooledProtoDefinition {\n if (cachedDefinition) {\n return cachedDefinition;\n }\n\n const protoPath = getProtoPath();\n\n const packageDefinition = protoLoader.loadSync(protoPath, PROTO_LOADER_OPTIONS);\n const grpcObject = grpc.loadPackageDefinition(packageDefinition);\n\n cachedDefinition = grpcObject as unknown as SpooledProtoDefinition;\n return cachedDefinition;\n}\n\n/**\n * Load the Spooled proto definition asynchronously.\n */\nexport async function loadProtoDefinitionAsync(): Promise<SpooledProtoDefinition> {\n if (cachedDefinition) {\n return cachedDefinition;\n }\n\n const protoPath = getProtoPath();\n\n const packageDefinition = await protoLoader.load(protoPath, PROTO_LOADER_OPTIONS);\n const grpcObject = grpc.loadPackageDefinition(packageDefinition);\n\n cachedDefinition = grpcObject as unknown as SpooledProtoDefinition;\n return cachedDefinition;\n}\n\n/**\n * Clear the cached proto definition (mainly for testing).\n */\nexport function clearProtoCache(): void {\n cachedDefinition = null;\n}\n","/**\n * gRPC Streaming Helpers\n *\n * Utilities for working with gRPC streaming in a TypeScript-friendly way.\n */\n\nimport type * as grpc from '@grpc/grpc-js';\nimport type { GrpcJob, GrpcProcessRequest, GrpcProcessResponse } from './types.js';\n\n/**\n * Options for streaming operations\n */\nexport interface StreamOptions {\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Called when connection is established */\n onConnected?: () => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n /** Called when the stream ends */\n onEnd?: () => void;\n}\n\n/**\n * Async iterable wrapper for gRPC readable streams (server streaming).\n */\nexport async function* asyncIterableFromStream<T>(\n stream: grpc.ClientReadableStream<T>,\n options?: StreamOptions\n): AsyncGenerator<T, void, undefined> {\n const { signal, onConnected, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener('abort', () => {\n stream.cancel();\n });\n }\n\n return yield* new AsyncIterableStream(stream, { onConnected, onError, onEnd });\n}\n\n/**\n * AsyncIterable wrapper for grpc.ClientReadableStream\n */\nclass AsyncIterableStream<T> implements AsyncIterable<T> {\n private stream: grpc.ClientReadableStream<T>;\n private options: Omit<StreamOptions, 'signal'>;\n\n constructor(\n stream: grpc.ClientReadableStream<T>,\n options: Omit<StreamOptions, 'signal'> = {}\n ) {\n this.stream = stream;\n this.options = options;\n }\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T, void, undefined> {\n const { onConnected, onError, onEnd } = this.options;\n const queue: T[] = [];\n let error: Error | null = null;\n let ended = false;\n let resolve: (() => void) | null = null;\n\n this.stream.on('data', (data: T) => {\n queue.push(data);\n resolve?.();\n });\n\n this.stream.on('error', (err: Error) => {\n error = err;\n onError?.(err);\n resolve?.();\n });\n\n this.stream.on('end', () => {\n ended = true;\n onEnd?.();\n resolve?.();\n });\n\n this.stream.on('status', (status: grpc.StatusObject) => {\n if (status.code === 0) {\n onConnected?.();\n }\n });\n\n while (true) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n\n if (error) {\n throw error;\n }\n\n if (ended) {\n return;\n }\n\n // Wait for next event\n await new Promise<void>((r) => {\n resolve = r;\n });\n }\n }\n}\n\n/**\n * Bidirectional stream wrapper for ProcessJobs\n */\nexport interface ProcessJobsStream {\n /** Send a request to the server */\n send(request: GrpcProcessRequest): void;\n /** Get async iterable for receiving responses */\n receive(): AsyncIterable<GrpcProcessResponse>;\n /** Signal that no more requests will be sent */\n end(): void;\n /** Cancel the stream */\n cancel(): void;\n}\n\n/**\n * Create a ProcessJobsStream from a gRPC duplex stream\n */\nexport function createProcessJobsStream(\n call: grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>,\n options?: StreamOptions\n): ProcessJobsStream {\n const { signal, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener('abort', () => {\n call.cancel();\n });\n }\n\n return {\n send(request: GrpcProcessRequest): void {\n call.write(request);\n },\n\n receive(): AsyncIterable<GrpcProcessResponse> {\n return new AsyncIterableStream(call, { onError, onEnd });\n },\n\n end(): void {\n call.end();\n },\n\n cancel(): void {\n call.cancel();\n },\n };\n}\n\n/**\n * Job stream for server-side streaming (StreamJobs)\n */\nexport interface JobStream extends AsyncIterable<GrpcJob> {\n /** Cancel the stream */\n cancel(): void;\n}\n\n/**\n * Create a JobStream from a gRPC server stream\n */\nexport function createJobStream(\n call: grpc.ClientReadableStream<GrpcJob>,\n options?: StreamOptions\n): JobStream {\n const { signal, onConnected, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener('abort', () => {\n call.cancel();\n });\n }\n\n const iterable = new AsyncIterableStream<GrpcJob>(call, {\n onConnected,\n onError,\n onEnd,\n });\n\n return {\n [Symbol.asyncIterator]() {\n return iterable[Symbol.asyncIterator]();\n },\n cancel() {\n call.cancel();\n },\n };\n}\n","/**\n * gRPC Client\n *\n * Real gRPC client using @grpc/grpc-js for HTTP/2 + Protobuf communication.\n * Supports unary calls, server streaming, and bidirectional streaming.\n */\n\nimport * as grpc from '@grpc/grpc-js';\nimport { loadProtoDefinition } from './loader.js';\nimport {\n createJobStream,\n createProcessJobsStream,\n type JobStream,\n type ProcessJobsStream,\n type StreamOptions,\n} from './streaming.js';\nimport type {\n GrpcClientOptions,\n GrpcEnqueueRequest,\n GrpcEnqueueResponse,\n GrpcDequeueRequest,\n GrpcDequeueResponse,\n GrpcCompleteRequest,\n GrpcCompleteResponse,\n GrpcFailRequest,\n GrpcFailResponse,\n GrpcRenewLeaseRequest,\n GrpcRenewLeaseResponse,\n GrpcGetJobRequest,\n GrpcGetJobResponse,\n GrpcGetQueueStatsRequest,\n GrpcGetQueueStatsResponse,\n GrpcStreamJobsRequest,\n GrpcRegisterWorkerRequest,\n GrpcRegisterWorkerResponse,\n GrpcHeartbeatRequest,\n GrpcHeartbeatResponse,\n GrpcDeregisterRequest,\n GrpcDeregisterResponse,\n GrpcProcessRequest,\n GrpcProcessResponse,\n GrpcJob,\n} from './types.js';\n\n// Type definitions for dynamic gRPC clients\ntype UnaryCallback<T> = (error: grpc.ServiceError | null, response: T) => void;\n\ninterface QueueServiceClient extends grpc.Client {\n Enqueue(request: GrpcEnqueueRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcEnqueueResponse>): void;\n Dequeue(request: GrpcDequeueRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcDequeueResponse>): void;\n Complete(request: GrpcCompleteRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcCompleteResponse>): void;\n Fail(request: GrpcFailRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcFailResponse>): void;\n RenewLease(request: GrpcRenewLeaseRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcRenewLeaseResponse>): void;\n GetJob(request: GrpcGetJobRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcGetJobResponse>): void;\n GetQueueStats(request: GrpcGetQueueStatsRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcGetQueueStatsResponse>): void;\n StreamJobs(request: GrpcStreamJobsRequest, metadata: grpc.Metadata): grpc.ClientReadableStream<GrpcJob>;\n ProcessJobs(metadata: grpc.Metadata): grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>;\n}\n\ninterface WorkerServiceClient extends grpc.Client {\n Register(request: GrpcRegisterWorkerRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcRegisterWorkerResponse>): void;\n Heartbeat(request: GrpcHeartbeatRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcHeartbeatResponse>): void;\n Deregister(request: GrpcDeregisterRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcDeregisterResponse>): void;\n}\n\n/**\n * Wrap a callback-based gRPC call in a Promise\n */\nfunction promisify<TReq, TRes>(\n client: grpc.Client,\n method: (request: TReq, metadata: grpc.Metadata, callback: UnaryCallback<TRes>) => void,\n request: TReq,\n metadata: grpc.Metadata\n): Promise<TRes> {\n return new Promise((resolve, reject) => {\n method.call(client, request, metadata, (error, response) => {\n if (error) {\n reject(error);\n } else {\n resolve(response);\n }\n });\n });\n}\n\n/**\n * Determine if TLS should be used based on address\n */\nfunction shouldUseTls(address: string, explicitTls?: boolean): boolean {\n if (explicitTls !== undefined) {\n return explicitTls;\n }\n // Default to insecure for localhost/127.0.0.1\n const host = address.split(':')[0].toLowerCase();\n return host !== 'localhost' && host !== '127.0.0.1' && !host.startsWith('[::1]');\n}\n\n/**\n * Queue operations for the gRPC client\n */\nexport class GrpcQueueOperations {\n constructor(\n private readonly client: QueueServiceClient,\n private readonly metadata: grpc.Metadata\n ) {}\n\n /**\n * Enqueue a new job\n */\n async enqueue(params: GrpcEnqueueRequest): Promise<GrpcEnqueueResponse> {\n return promisify(this.client, this.client.Enqueue, params, this.metadata);\n }\n\n /**\n * Dequeue a job (for workers)\n */\n async dequeue(params: GrpcDequeueRequest): Promise<GrpcDequeueResponse> {\n return promisify(this.client, this.client.Dequeue, params, this.metadata);\n }\n\n /**\n * Complete a job successfully\n */\n async complete(params: GrpcCompleteRequest): Promise<GrpcCompleteResponse> {\n return promisify(this.client, this.client.Complete, params, this.metadata);\n }\n\n /**\n * Fail a job\n */\n async fail(params: GrpcFailRequest): Promise<GrpcFailResponse> {\n return promisify(this.client, this.client.Fail, params, this.metadata);\n}\n\n /**\n * Renew a job's lease\n */\n async renewLease(params: GrpcRenewLeaseRequest): Promise<GrpcRenewLeaseResponse> {\n return promisify(this.client, this.client.RenewLease, params, this.metadata);\n }\n\n /**\n * Get a job by ID\n */\n async getJob(jobId: string): Promise<GrpcGetJobResponse> {\n return promisify(this.client, this.client.GetJob, { jobId }, this.metadata);\n }\n\n /**\n * Get queue statistics\n */\n async getQueueStats(queueName: string): Promise<GrpcGetQueueStatsResponse> {\n return promisify(this.client, this.client.GetQueueStats, { queueName }, this.metadata);\n }\n\n /**\n * Stream jobs from a queue (server-side streaming)\n *\n * @example\n * ```typescript\n * const stream = client.grpc.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * });\n *\n * for await (const job of stream) {\n * console.log('Received job:', job.id);\n * }\n * ```\n */\n streamJobs(params: GrpcStreamJobsRequest, options?: StreamOptions): JobStream {\n const call = this.client.StreamJobs(params, this.metadata);\n return createJobStream(call, options);\n }\n\n /**\n * Open a bidirectional stream for processing jobs\n *\n * @example\n * ```typescript\n * const stream = client.grpc.queue.processJobs();\n *\n * // Request jobs\n * stream.send({ dequeue: { queueName: 'my-queue', workerId: 'worker-1' } });\n *\n * // Process responses\n * for await (const response of stream.receive()) {\n * if (response.job) {\n * // Process the job\n * stream.send({ complete: { jobId: response.job.id, workerId: 'worker-1' } });\n * }\n * }\n *\n * stream.end();\n * ```\n */\n processJobs(options?: StreamOptions): ProcessJobsStream {\n const call = this.client.ProcessJobs(this.metadata);\n return createProcessJobsStream(call, options);\n }\n}\n\n/**\n * Worker operations for the gRPC client\n */\nexport class GrpcWorkerOperations {\n constructor(\n private readonly client: WorkerServiceClient,\n private readonly metadata: grpc.Metadata\n ) {}\n\n /**\n * Register a new worker\n */\n async register(params: GrpcRegisterWorkerRequest): Promise<GrpcRegisterWorkerResponse> {\n return promisify(this.client, this.client.Register, params, this.metadata);\n }\n\n /**\n * Send heartbeat\n */\n async heartbeat(params: GrpcHeartbeatRequest): Promise<GrpcHeartbeatResponse> {\n return promisify(this.client, this.client.Heartbeat, params, this.metadata);\n }\n\n /**\n * Deregister a worker\n */\n async deregister(workerId: string): Promise<GrpcDeregisterResponse> {\n return promisify(this.client, this.client.Deregister, { workerId }, this.metadata);\n }\n}\n\n/**\n * Spooled gRPC Client\n *\n * Real gRPC client for high-performance job queue operations.\n *\n * @example\n * ```typescript\n * const client = new SpooledGrpcClient({\n * address: 'grpc.spooled.cloud:443',\n * apiKey: 'sk_live_...',\n * });\n *\n * // Enqueue a job\n * const { jobId } = await client.queue.enqueue({\n * queueName: 'my-queue',\n * payload: { message: 'Hello!' },\n * });\n *\n * // Stream jobs\n * for await (const job of client.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * })) {\n * console.log('Job:', job);\n * }\n * ```\n */\nexport class SpooledGrpcClient {\n private readonly queueClient: QueueServiceClient;\n private readonly workerClient: WorkerServiceClient;\n private readonly metadata: grpc.Metadata;\n\n /** Queue operations */\n readonly queue: GrpcQueueOperations;\n\n /** Worker operations */\n readonly workers: GrpcWorkerOperations;\n\n constructor(options: GrpcClientOptions) {\n const { address, apiKey, useTls, credentials, channelOptions } = options;\n\n // Create credentials\n const creds = credentials ?? (shouldUseTls(address, useTls)\n ? grpc.credentials.createSsl()\n : grpc.credentials.createInsecure());\n\n // Create metadata with API key\n this.metadata = new grpc.Metadata();\n this.metadata.add('x-api-key', apiKey);\n\n // Load proto definition\n const proto = loadProtoDefinition();\n\n // Create service clients\n this.queueClient = new proto.spooled.v1.QueueService(\n address,\n creds,\n channelOptions\n ) as unknown as QueueServiceClient;\n\n this.workerClient = new proto.spooled.v1.WorkerService(\n address,\n creds,\n channelOptions\n ) as unknown as WorkerServiceClient;\n\n // Initialize operation namespaces\n this.queue = new GrpcQueueOperations(this.queueClient, this.metadata);\n this.workers = new GrpcWorkerOperations(this.workerClient, this.metadata);\n }\n\n /**\n * Close all gRPC connections\n */\n close(): void {\n this.queueClient.close();\n this.workerClient.close();\n }\n\n /**\n * Wait for the clients to be ready\n */\n async waitForReady(deadline?: Date): Promise<void> {\n const d = deadline ?? new Date(Date.now() + 10000);\n await Promise.all([\n new Promise<void>((resolve, reject) => {\n this.queueClient.waitForReady(d, (error) => {\n if (error) reject(error);\n else resolve();\n });\n }),\n new Promise<void>((resolve, reject) => {\n this.workerClient.waitForReady(d, (error) => {\n if (error) reject(error);\n else resolve();\n });\n }),\n ]);\n }\n\n /**\n * Get the current connection state\n */\n getState(tryToConnect?: boolean): grpc.connectivityState {\n return this.queueClient.getChannel().getConnectivityState(tryToConnect ?? false);\n }\n}\n","/**\n * Spooled Client\n *\n * Main entry point for the Spooled SDK.\n */\n\nimport {\n type SpooledClientConfig,\n type ResolvedConfig,\n resolveConfig,\n validateConfig,\n} from './config.js';\nimport { AuthenticationError } from './errors.js';\nimport { HttpClient, createHttpClient } from './utils/http.js';\nimport { CircuitBreaker, createCircuitBreaker } from './utils/circuit-breaker.js';\nimport {\n AuthResource,\n JobsResource,\n QueuesResource,\n WorkersResource,\n SchedulesResource,\n WorkflowsResource,\n WebhooksResource,\n ApiKeysResource,\n OrganizationsResource,\n BillingResource,\n DashboardResource,\n HealthResource,\n MetricsResource,\n AdminResource,\n WebhookIngestionResource,\n} from './resources/index.js';\nimport { SpooledRealtime } from './realtime/index.js';\nimport type { SpooledRealtimeOptions } from './realtime/index.js';\nimport { SpooledGrpcClient } from './grpc/client.js';\n\n/**\n * Spooled Cloud SDK Client\n *\n * @example\n * ```typescript\n * const client = new SpooledClient({\n * apiKey: 'sk_live_...'\n * });\n *\n * // Create a job\n * const result = await client.jobs.create({\n * queueName: 'my-queue',\n * payload: { message: 'Hello, World!' }\n * });\n *\n * // List queues\n * const queues = await client.queues.list();\n * ```\n */\nexport class SpooledClient {\n private readonly config: ResolvedConfig;\n private readonly http: HttpClient;\n private readonly circuitBreaker: CircuitBreaker;\n private _grpc: SpooledGrpcClient | null = null;\n\n /** Authentication operations */\n readonly auth: AuthResource;\n\n /** Job operations */\n readonly jobs: JobsResource;\n\n /** Queue operations */\n readonly queues: QueuesResource;\n\n /** Worker operations */\n readonly workers: WorkersResource;\n\n /** Schedule operations */\n readonly schedules: SchedulesResource;\n\n /** Workflow operations */\n readonly workflows: WorkflowsResource;\n\n /** Outgoing webhook operations */\n readonly webhooks: WebhooksResource;\n\n /** API key operations */\n readonly apiKeys: ApiKeysResource;\n\n /** Organization operations */\n readonly organizations: OrganizationsResource;\n\n /** Billing operations */\n readonly billing: BillingResource;\n\n /** Dashboard operations */\n readonly dashboard: DashboardResource;\n\n /** Health endpoints (public) */\n readonly health: HealthResource;\n\n /** Metrics endpoint (public) */\n readonly metrics: MetricsResource;\n\n /** Admin endpoints (requires adminKey) */\n readonly admin: AdminResource;\n\n /** Webhook ingestion endpoints (signature-based) */\n readonly ingest: WebhookIngestionResource;\n\n /** Token refresh state */\n private refreshPromise: Promise<string> | null = null;\n private tokenExpiresAt: number | null = null;\n\n /**\n * Cached JWT for realtime connections (API-key auth path).\n *\n * The realtime layer requests a token on every (re)connect. Minting a brand\n * new JWT via POST /auth/login each time trips the login rate limit (429)\n * under a reconnect storm, after which realtime can never recover. We cache\n * the token here — at the client level, shared across reconnects — and reuse\n * it until it nears expiry.\n */\n private cachedJwt: string | null = null;\n /** Deduplicates concurrent logins (e.g. WS + SSE reconnecting together). */\n private jwtLoginPromise: Promise<string> | null = null;\n\n constructor(options: SpooledClientConfig) {\n // Resolve and validate configuration\n this.config = resolveConfig(options);\n validateConfig(this.config);\n\n // Create circuit breaker\n this.circuitBreaker = createCircuitBreaker(this.config.circuitBreaker);\n\n // Create HTTP client\n this.http = createHttpClient(this.config, this.circuitBreaker);\n\n // Set up token refresh if using JWT\n if (this.config.accessToken && this.config.refreshToken && this.config.autoRefreshToken) {\n this.http.setRefreshTokenFn(this.refreshAccessToken.bind(this));\n }\n\n // Create resource instances\n this.auth = new AuthResource(this.http, () => this.config.refreshToken);\n this.jobs = new JobsResource(this.http);\n this.queues = new QueuesResource(this.http);\n this.workers = new WorkersResource(this.http);\n this.schedules = new SchedulesResource(this.http);\n this.workflows = new WorkflowsResource(this.http);\n this.webhooks = new WebhooksResource(this.http);\n this.apiKeys = new ApiKeysResource(this.http);\n this.organizations = new OrganizationsResource(this.http);\n this.billing = new BillingResource(this.http);\n this.dashboard = new DashboardResource(this.http);\n this.health = new HealthResource(this.http);\n this.metrics = new MetricsResource(this.http);\n this.admin = new AdminResource(this.http, this.config.adminKey);\n this.ingest = new WebhookIngestionResource(this.http);\n\n this.config.debug?.('SpooledClient initialized', {\n baseUrl: this.config.baseUrl,\n hasApiKey: !!this.config.apiKey,\n hasAccessToken: !!this.config.accessToken,\n });\n }\n\n /**\n * Real gRPC client for high-performance operations (HTTP/2 + Protobuf)\n *\n * The gRPC client is created lazily on first access to avoid\n * loading the proto file unless it's actually needed.\n *\n * @example\n * ```typescript\n * // Enqueue via gRPC\n * const { jobId } = await client.grpc.queue.enqueue({\n * queueName: 'my-queue',\n * payload: { message: 'Hello!' },\n * });\n *\n * // Stream jobs\n * for await (const job of client.grpc.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * })) {\n * console.log('Job:', job);\n * }\n * ```\n */\n get grpc(): SpooledGrpcClient {\n if (!this._grpc) {\n const grpcAddress = this.resolveGrpcAddress();\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new AuthenticationError('gRPC client requires an API key');\n }\n\n this._grpc = new SpooledGrpcClient({\n address: grpcAddress,\n apiKey,\n });\n }\n return this._grpc;\n }\n\n /**\n * Create a realtime connection for WebSocket or SSE events\n *\n * @example\n * ```typescript\n * const realtime = await client.realtime();\n *\n * realtime.on('job.created', (event) => {\n * console.log('New job:', event.jobId);\n * });\n *\n * await realtime.connect();\n * await realtime.subscribe({ queueName: 'my-queue' });\n * ```\n */\n async realtime(options?: SpooledRealtimeOptions): Promise<SpooledRealtime> {\n // Get an initial JWT (fails fast on auth errors at call time).\n const token = await this.getJwtToken();\n\n return new SpooledRealtime({\n baseUrl: this.config.baseUrl,\n wsUrl: this.config.wsUrl,\n token,\n // Provider the realtime layer calls on every (re)connect. It returns a\n // cached JWT and only re-logs-in when the token is absent, near expiry,\n // or the transport asks to force a refresh (e.g. after a 401 upgrade).\n tokenProvider: (forceRefresh) => this.getJwtToken(forceRefresh),\n ...options,\n // Only forward debug when the client actually has a logger, so we never\n // hand the realtime layer an explicit `debug: undefined`. The WS/SSE\n // constructors also guard against this, but keeping the undefined out of\n // the option object makes the intent clear at the call site.\n ...(this.config.debug ? { debug: this.config.debug } : {}),\n });\n }\n\n /**\n * Get or acquire a JWT token for realtime connections.\n *\n * The realtime layer calls this on every (re)connect. We cache the JWT and\n * reuse it until it nears expiry so a reconnect storm doesn't hammer\n * /auth/login and trip its rate limit. A fresh login happens only when the\n * cached token is absent, within ~60s of its `exp`, or a refresh is forced.\n *\n * @param forceRefresh Bypass the cache and mint a new token. Set by the\n * transport when the server rejected the current token (e.g. a 401 on the\n * WebSocket upgrade), so a stale/revoked token is replaced without waiting\n * for it to expire.\n */\n private async getJwtToken(forceRefresh = false): Promise<string> {\n // A JWT access token supplied directly: reuse it, refreshing via the\n // refresh token when it nears expiry (or when a refresh is forced).\n if (this.config.accessToken) {\n if (forceRefresh || this.shouldRefreshToken()) {\n return this.refreshAccessToken();\n }\n return this.config.accessToken;\n }\n\n // API-key auth: exchange the key for a JWT once, then reuse the cached JWT\n // across (re)connects until it nears expiry. Only then log in again.\n if (this.config.apiKey) {\n if (forceRefresh) {\n this.cachedJwt = null;\n }\n if (this.cachedJwt && !isJwtNearExpiry(this.cachedJwt)) {\n return this.cachedJwt;\n }\n return this.loginForJwt();\n }\n\n throw new AuthenticationError('No authentication method available for realtime connection');\n }\n\n /**\n * Exchange the API key for a JWT via /auth/login and cache the result.\n *\n * Concurrent callers share a single in-flight login so a burst of reconnects\n * (e.g. WebSocket and SSE at once) issues just one request.\n */\n private async loginForJwt(): Promise<string> {\n if (this.jwtLoginPromise) {\n return this.jwtLoginPromise;\n }\n\n this.jwtLoginPromise = (async () => {\n const response = await this.auth.login({ apiKey: this.config.apiKey! });\n\n // Update internal state and cache the token for future (re)connects.\n this.http.setAuthToken(response.accessToken);\n this.tokenExpiresAt = Date.now() + response.expiresIn * 1000;\n (this.config as ResolvedConfig).refreshToken = response.refreshToken;\n this.cachedJwt = response.accessToken;\n\n return response.accessToken;\n })();\n\n try {\n return await this.jwtLoginPromise;\n } finally {\n this.jwtLoginPromise = null;\n }\n }\n\n /**\n * Check if token should be refreshed\n */\n private shouldRefreshToken(): boolean {\n if (!this.tokenExpiresAt) {\n return false;\n }\n // Refresh 5 minutes before expiry\n const bufferMs = 5 * 60 * 1000;\n return Date.now() >= this.tokenExpiresAt - bufferMs;\n }\n\n /**\n * Refresh the access token\n */\n private async refreshAccessToken(): Promise<string> {\n // Deduplicate concurrent refresh requests\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n if (!this.config.refreshToken) {\n throw new AuthenticationError('No refresh token available');\n }\n\n this.refreshPromise = this.doRefreshToken();\n\n try {\n return await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n /**\n * Actually perform the token refresh\n */\n private async doRefreshToken(): Promise<string> {\n const response = await this.auth.refresh({\n refreshToken: this.config.refreshToken!,\n });\n\n // Update state\n this.http.setAuthToken(response.accessToken);\n this.tokenExpiresAt = Date.now() + response.expiresIn * 1000;\n (this.config as ResolvedConfig).accessToken = response.accessToken;\n\n this.config.debug?.('Token refreshed successfully');\n\n return response.accessToken;\n }\n\n /**\n * Get current configuration (read-only)\n */\n getConfig(): Readonly<ResolvedConfig> {\n return this.config;\n }\n\n /**\n * Get circuit breaker statistics\n */\n getCircuitBreakerStats() {\n return this.circuitBreaker.getStats();\n }\n\n /**\n * Reset the circuit breaker\n */\n resetCircuitBreaker(): void {\n this.circuitBreaker.reset();\n }\n\n /**\n * Create a new client with different options\n */\n withOptions(options: Partial<SpooledClientConfig>): SpooledClient {\n return new SpooledClient({\n apiKey: this.config.apiKey,\n accessToken: this.config.accessToken,\n refreshToken: this.config.refreshToken,\n adminKey: this.config.adminKey,\n grpcAddress: this.config.grpcAddress,\n baseUrl: this.config.baseUrl,\n timeout: this.config.timeout,\n retry: this.config.retry,\n circuitBreaker: this.config.circuitBreaker,\n headers: this.config.headers,\n fetch: this.config.fetch,\n userAgent: this.config.userAgent,\n debug: this.config.debug ?? undefined,\n autoRefreshToken: this.config.autoRefreshToken,\n ...options,\n });\n }\n\n /**\n * Resolve gRPC address (host:port format)\n */\n private resolveGrpcAddress(): string {\n return this.config.grpcAddress;\n }\n\n /**\n * Close all connections including gRPC\n */\n close(): void {\n if (this._grpc) {\n this._grpc.close();\n this._grpc = null;\n }\n }\n}\n\n/**\n * Create a new SpooledClient instance\n *\n * @example\n * ```typescript\n * const client = createClient({\n * apiKey: process.env.SPOOLED_API_KEY\n * });\n * ```\n */\nexport function createClient(options: SpooledClientConfig): SpooledClient {\n return new SpooledClient(options);\n}\n\n/**\n * Decode a JWT's `exp` claim (seconds since epoch) without verifying the\n * signature — we only need the expiry to decide when to refresh, not to trust\n * the token. Returns null for a malformed token or one with no numeric `exp`.\n */\nexport function decodeJwtExp(token: string): number | null {\n const parts = token.split('.');\n if (parts.length < 2) {\n return null;\n }\n try {\n const payload = JSON.parse(base64UrlDecode(parts[1])) as { exp?: unknown };\n return typeof payload.exp === 'number' ? payload.exp : null;\n } catch {\n return null;\n }\n}\n\n/**\n * True when a token is missing an `exp` we can read or is within `skewMs` of it.\n * A token whose expiry can't be decoded is treated as expiring, so we fall back\n * to a fresh login rather than reuse a token we can't reason about.\n */\nexport function isJwtNearExpiry(token: string, skewMs = 60_000): boolean {\n const exp = decodeJwtExp(token);\n if (exp === null) {\n return true;\n }\n return Date.now() >= exp * 1000 - skewMs;\n}\n\n/** Base64url-decode a JWT segment to a UTF-8 string, across Node and browsers. */\nfunction base64UrlDecode(segment: string): string {\n const b64 = segment.replace(/-/g, '+').replace(/_/g, '/');\n // Prefer Node's Buffer; fall back to atob for browsers / non-Node runtimes.\n // Referenced via globalThis so neither global is a hard dependency.\n if (typeof globalThis.Buffer !== 'undefined') {\n return globalThis.Buffer.from(b64, 'base64').toString('utf8');\n }\n const binary = globalThis.atob(b64);\n const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));\n return new globalThis.TextDecoder().decode(bytes);\n}\n","/**\n * Common Types\n *\n * Shared types used across the SDK.\n */\n\n/** JSON primitive types */\nexport type JsonPrimitive = string | number | boolean | null;\n\n/** JSON value type */\nexport type JsonValue = JsonPrimitive | JsonObject | JsonArray;\n\n/** JSON object type */\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\n/** JSON array type */\nexport type JsonArray = JsonValue[];\n\n/** Job status enum values */\nexport type JobStatus =\n | 'pending'\n | 'scheduled'\n | 'processing'\n | 'completed'\n | 'failed'\n | 'deadletter'\n | 'cancelled';\n\n/** Worker status enum values */\nexport type WorkerStatus = 'healthy' | 'degraded' | 'offline' | 'draining';\n\n/** Workflow status enum values */\nexport type WorkflowStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';\n\n/** Plan tier enum values */\nexport type PlanTier = 'free' | 'starter' | 'pro' | 'enterprise';\n\n/** Schedule run status */\nexport type ScheduleRunStatus = 'pending' | 'running' | 'completed' | 'failed';\n\n/** Webhook delivery status */\nexport type WebhookDeliveryStatus = 'pending' | 'success' | 'failed';\n\n/** Webhook event types */\nexport type WebhookEventType =\n | 'job.created'\n | 'job.started'\n | 'job.completed'\n | 'job.failed'\n | 'job.cancelled'\n | 'queue.paused'\n | 'queue.resumed'\n | 'worker.registered'\n | 'worker.deregistered'\n | 'schedule.triggered';\n\n/** Dependency mode for workflows */\nexport type DependencyMode = 'all' | 'any';\n\n/** Pagination parameters */\nexport interface PaginationParams {\n /** Maximum number of results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\n/** List parameters with optional sorting */\nexport interface ListParams extends PaginationParams {\n /** Field to order by */\n orderBy?: string;\n /** Sort direction */\n orderDir?: 'asc' | 'desc';\n}\n\n/** Paginated response wrapper */\nexport interface PaginatedResponse<T> {\n /** Items in current page */\n data: T[];\n /** Total count (if available) */\n total?: number;\n /** Current page offset */\n offset: number;\n /** Page size limit */\n limit: number;\n /** Whether there are more results */\n hasMore: boolean;\n}\n\n/**\n * Helper to create a paginated response from an array\n */\nexport function createPaginatedResponse<T>(\n items: T[],\n limit: number,\n offset: number = 0,\n total?: number\n): PaginatedResponse<T> {\n return {\n data: items,\n total,\n offset,\n limit,\n hasMore: items.length === limit,\n };\n}\n","/**\n * gRPC Types\n *\n * Types that mirror the protobuf definitions in spooled.proto.\n * Uses proper enum names matching the proto (JOB_STATUS_PENDING, etc.)\n */\n\nimport type * as grpc from '@grpc/grpc-js';\n\n// ============================================================================\n// Job Status Enum\n// ============================================================================\n\n/** Job status enum values (proto-style naming) */\nexport enum GrpcJobStatus {\n JOB_STATUS_UNSPECIFIED = 'JOB_STATUS_UNSPECIFIED',\n JOB_STATUS_PENDING = 'JOB_STATUS_PENDING',\n JOB_STATUS_SCHEDULED = 'JOB_STATUS_SCHEDULED',\n JOB_STATUS_PROCESSING = 'JOB_STATUS_PROCESSING',\n JOB_STATUS_COMPLETED = 'JOB_STATUS_COMPLETED',\n JOB_STATUS_FAILED = 'JOB_STATUS_FAILED',\n JOB_STATUS_DEADLETTER = 'JOB_STATUS_DEADLETTER',\n JOB_STATUS_CANCELLED = 'JOB_STATUS_CANCELLED',\n}\n\n/** Numeric job status values (for backward compatibility) */\nexport const GrpcJobStatusNumber = {\n UNSPECIFIED: 0,\n PENDING: 1,\n SCHEDULED: 2,\n PROCESSING: 3,\n COMPLETED: 4,\n FAILED: 5,\n DEADLETTER: 6,\n CANCELLED: 7,\n} as const;\n\n// ============================================================================\n// Timestamp handling\n// ============================================================================\n\n/** Timestamp as returned by gRPC (can be object or ISO string) */\nexport interface GrpcTimestamp {\n seconds?: string | number;\n nanos?: number;\n}\n\n/** Convert timestamp to Date */\nexport function timestampToDate(ts: GrpcTimestamp | string | undefined | null): Date | null {\n if (!ts) return null;\n\n if (typeof ts === 'string') {\n return new Date(ts);\n }\n\n const seconds = typeof ts.seconds === 'string' ? parseInt(ts.seconds, 10) : (ts.seconds ?? 0);\n const nanos = ts.nanos ?? 0;\n return new Date(seconds * 1000 + Math.floor(nanos / 1_000_000));\n}\n\n/** Convert Date to timestamp object */\nexport function dateToTimestamp(date: Date | string): GrpcTimestamp {\n const d = typeof date === 'string' ? new Date(date) : date;\n const ms = d.getTime();\n return {\n seconds: Math.floor(ms / 1000).toString(),\n nanos: (ms % 1000) * 1_000_000,\n };\n}\n\n// ============================================================================\n// Job Message\n// ============================================================================\n\n/** Job message as returned by gRPC */\nexport interface GrpcJob {\n id: string;\n organizationId: string;\n queueName: string;\n status: GrpcJobStatus | string;\n /** Payload as google.protobuf.Struct (object) */\n payload?: Record<string, unknown> | null;\n /** Result as google.protobuf.Struct (object) */\n result?: Record<string, unknown> | null;\n retryCount: number;\n maxRetries: number;\n lastError?: string | null;\n priority: number;\n timeoutSeconds: number;\n createdAt?: GrpcTimestamp | string | null;\n scheduledAt?: GrpcTimestamp | string | null;\n startedAt?: GrpcTimestamp | string | null;\n completedAt?: GrpcTimestamp | string | null;\n leaseExpiresAt?: GrpcTimestamp | string | null;\n assignedWorkerId?: string | null;\n idempotencyKey?: string | null;\n /**\n * Lease fencing token (proto `lease_id`). Returned on dequeue; echo it back\n * in Complete/Fail/RenewLease so the operation applies only to the lease\n * this worker actually holds (empty = legacy worker_id fence).\n */\n leaseId?: string;\n}\n\n// ============================================================================\n// Queue Service - Request/Response Types\n// ============================================================================\n\n/** Enqueue request */\nexport interface GrpcEnqueueRequest {\n queueName: string;\n /** Payload as object (will be converted to google.protobuf.Struct) */\n payload?: Record<string, unknown>;\n priority?: number;\n maxRetries?: number;\n timeoutSeconds?: number;\n scheduledAt?: GrpcTimestamp | string;\n idempotencyKey?: string;\n tags?: Record<string, string>;\n}\n\n/** Enqueue response */\nexport interface GrpcEnqueueResponse {\n jobId: string;\n created: boolean;\n}\n\n/** Dequeue request */\nexport interface GrpcDequeueRequest {\n queueName: string;\n workerId: string;\n leaseDurationSecs?: number;\n batchSize?: number;\n}\n\n/** Dequeue response */\nexport interface GrpcDequeueResponse {\n jobs: GrpcJob[];\n}\n\n/** Complete request */\nexport interface GrpcCompleteRequest {\n jobId: string;\n workerId: string;\n /** Result as object (will be converted to google.protobuf.Struct) */\n result?: Record<string, unknown>;\n /** Lease fencing token from the dequeued job (proto `lease_id`) */\n leaseId?: string;\n}\n\n/** Complete response */\nexport interface GrpcCompleteResponse {\n success: boolean;\n}\n\n/** Fail request */\nexport interface GrpcFailRequest {\n jobId: string;\n workerId: string;\n error: string;\n retry?: boolean;\n /** Lease fencing token from the dequeued job (proto `lease_id`) */\n leaseId?: string;\n}\n\n/** Fail response */\nexport interface GrpcFailResponse {\n success: boolean;\n willRetry?: boolean;\n nextRetryDelaySecs?: number;\n}\n\n/** Renew lease request */\nexport interface GrpcRenewLeaseRequest {\n jobId: string;\n workerId: string;\n extensionSecs: number;\n /** Lease fencing token from the dequeued job (proto `lease_id`) */\n leaseId?: string;\n}\n\n/** Renew lease response */\nexport interface GrpcRenewLeaseResponse {\n success: boolean;\n newExpiresAt?: GrpcTimestamp | string | null;\n}\n\n/** Get job request */\nexport interface GrpcGetJobRequest {\n jobId: string;\n}\n\n/** Get job response */\nexport interface GrpcGetJobResponse {\n job?: GrpcJob | null;\n}\n\n/** Get queue stats request */\nexport interface GrpcGetQueueStatsRequest {\n queueName: string;\n}\n\n/** Get queue stats response */\nexport interface GrpcGetQueueStatsResponse {\n queueName: string;\n pending: number | string;\n scheduled: number | string;\n processing: number | string;\n completed: number | string;\n failed: number | string;\n deadletter: number | string;\n total: number | string;\n maxAgeMs?: number | string | null;\n}\n\n/** Stream jobs request (server streaming) */\nexport interface GrpcStreamJobsRequest {\n queueName: string;\n workerId: string;\n leaseDurationSecs?: number;\n}\n\n// ============================================================================\n// Bidirectional Streaming Types\n// ============================================================================\n\n/** Process request (for bidirectional streaming) */\nexport interface GrpcProcessRequest {\n dequeue?: GrpcDequeueRequest;\n complete?: GrpcCompleteRequest;\n fail?: GrpcFailRequest;\n renewLease?: GrpcRenewLeaseRequest;\n}\n\n/** Error response */\nexport interface GrpcErrorResponse {\n code: string;\n message: string;\n}\n\n/** Process response (for bidirectional streaming) */\nexport interface GrpcProcessResponse {\n job?: GrpcJob;\n complete?: GrpcCompleteResponse;\n fail?: GrpcFailResponse;\n renewLease?: GrpcRenewLeaseResponse;\n error?: GrpcErrorResponse;\n}\n\n// ============================================================================\n// Worker Service Types\n// ============================================================================\n\n/** Register worker request */\nexport interface GrpcRegisterWorkerRequest {\n queueName: string;\n hostname?: string;\n workerType?: string;\n maxConcurrency?: number;\n version?: string;\n metadata?: Record<string, string>;\n}\n\n/** Register worker response */\nexport interface GrpcRegisterWorkerResponse {\n workerId: string;\n leaseDurationSecs: number;\n heartbeatIntervalSecs: number;\n}\n\n/** Heartbeat request */\nexport interface GrpcHeartbeatRequest {\n workerId: string;\n currentJobs?: number;\n status?: string;\n metadata?: Record<string, string>;\n}\n\n/** Heartbeat response */\nexport interface GrpcHeartbeatResponse {\n acknowledged: boolean;\n shouldDrain?: boolean;\n}\n\n/** Deregister request */\nexport interface GrpcDeregisterRequest {\n workerId: string;\n}\n\n/** Deregister response */\nexport interface GrpcDeregisterResponse {\n success: boolean;\n}\n\n// ============================================================================\n// gRPC Client Options\n// ============================================================================\n\n/** Options for creating a gRPC client */\nexport interface GrpcClientOptions {\n /** gRPC server address (host:port) */\n address: string;\n /** API key for authentication */\n apiKey: string;\n /** Use TLS (default: true for production, false for localhost) */\n useTls?: boolean;\n /** Custom channel credentials */\n credentials?: grpc.ChannelCredentials;\n /** Channel options */\n channelOptions?: grpc.ChannelOptions;\n}\n\n// ============================================================================\n// Legacy types (backward compatibility)\n// ============================================================================\n\n/** @deprecated Use GrpcEnqueueRequest */\nexport type GrpcEnqueueJobParams = GrpcEnqueueRequest & {\n organizationId?: string;\n};\n\n/** @deprecated Use GrpcEnqueueResponse */\nexport type GrpcEnqueueJobResponse = GrpcEnqueueResponse;\n\n/** @deprecated Use GrpcDequeueRequest */\nexport type GrpcDequeueJobParams = GrpcDequeueRequest & {\n organizationId?: string;\n leaseDurationSeconds?: number;\n};\n\n/** @deprecated Use GrpcDequeueResponse */\nexport interface GrpcDequeueJobResponse {\n job?: GrpcJob | null;\n}\n\n/** @deprecated Use GrpcCompleteRequest */\nexport type GrpcCompleteJobParams = GrpcCompleteRequest;\n\n/** @deprecated Use GrpcCompleteResponse */\nexport type GrpcCompleteJobResponse = GrpcCompleteResponse;\n\n/** @deprecated Use GrpcFailRequest */\nexport interface GrpcFailJobParams {\n jobId: string;\n workerId: string;\n errorMessage: string;\n}\n\n/** @deprecated Use GrpcFailResponse */\nexport type GrpcFailJobResponse = GrpcFailResponse;\n\n/** @deprecated Use GrpcRenewLeaseRequest */\nexport interface GrpcRenewLeaseParams {\n jobId: string;\n workerId: string;\n leaseDurationSeconds: number;\n}\n\n/** @deprecated Use GrpcRenewLeaseResponse */\nexport interface GrpcRenewLeaseResponse_Legacy {\n renewed: boolean;\n newLeaseExpiresAt?: string | null;\n}\n\n/** @deprecated Use GrpcGetQueueStatsResponse */\nexport interface GrpcGetQueueStatsResponse_Legacy {\n queueName: string;\n pending: number;\n scheduled: number;\n processing: number;\n completed: number;\n failed: number;\n deadletter: number;\n total: number;\n maxAgeMs?: number | null;\n}\n\n/** @deprecated Use GrpcRegisterWorkerRequest */\nexport interface GrpcRegisterWorkerParams {\n workerId: string;\n organizationId?: string;\n queueNames: string[];\n maxConcurrentJobs?: number;\n hostname?: string;\n metadata?: Record<string, unknown> | string;\n}\n\n/** @deprecated Use GrpcRegisterWorkerResponse */\nexport interface GrpcRegisterWorkerResponse_Legacy {\n registered: boolean;\n heartbeatIntervalSeconds: number;\n}\n\n/** @deprecated Use GrpcHeartbeatRequest */\nexport interface GrpcHeartbeatParams {\n workerId: string;\n currentJobIds: string[];\n status: string;\n}\n\n/** @deprecated Use GrpcHeartbeatResponse */\nexport type GrpcHeartbeatResponse_Legacy = GrpcHeartbeatResponse;\n","/**\n * Spooled Worker\n *\n * Worker runtime for processing jobs from a queue.\n */\n\nimport type { SpooledClient } from '../client.js';\nimport type { JsonObject } from '../types/common.js';\nimport type { ClaimedJob } from '../types/jobs.js';\nimport type {\n SpooledWorkerOptions,\n WorkerState,\n JobHandler,\n JobContext,\n WorkerEvent,\n WorkerEventData,\n ActiveJob,\n} from './types.js';\nimport { hostname as osHostname } from 'os';\n\n/** Default options */\nconst DEFAULT_OPTIONS = {\n concurrency: 5,\n pollInterval: 1000,\n leaseDuration: 30,\n heartbeatFraction: 0.5,\n autoStart: false,\n shutdownTimeout: 30000,\n} as const;\n\n/** Event handler type */\ntype EventHandler<E extends WorkerEvent> = (data: WorkerEventData[E]) => void;\n\n/**\n * Spooled Worker\n *\n * @example\n * ```typescript\n * const worker = new SpooledWorker(client, {\n * queueName: 'my-queue',\n * concurrency: 10,\n * });\n *\n * worker.process(async (ctx) => {\n * console.log('Processing job:', ctx.jobId);\n * await doSomeWork(ctx.payload);\n * return { success: true };\n * });\n *\n * await worker.start();\n *\n * // Graceful shutdown\n * process.on('SIGTERM', () => worker.stop());\n * ```\n */\nexport class SpooledWorker {\n private readonly client: SpooledClient;\n private readonly options: Required<SpooledWorkerOptions>;\n private readonly debug: (msg: string, meta?: unknown) => void;\n\n private state: WorkerState = 'idle';\n private workerId: string | null = null;\n private handler: JobHandler | null = null;\n private activeJobs: Map<string, ActiveJob> = new Map();\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private workerHeartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private shutdownPromise: Promise<void> | null = null;\n\n // Event handlers\n private eventHandlers: Map<WorkerEvent, Set<EventHandler<WorkerEvent>>> = new Map();\n\n constructor(client: SpooledClient, options: SpooledWorkerOptions) {\n this.client = client;\n this.options = {\n ...DEFAULT_OPTIONS,\n hostname: osHostname(),\n workerType: 'nodejs',\n version: '1.0.34',\n metadata: {},\n ...options,\n } as Required<SpooledWorkerOptions>;\n\n // Get debug from client config\n const config = client.getConfig();\n this.debug = config.debug ?? (() => {});\n\n if (this.options.autoStart) {\n // Defer to next tick to allow process() to be called\n setImmediate(() => this.start());\n }\n }\n\n /**\n * Get current worker state\n */\n getState(): WorkerState {\n return this.state;\n }\n\n /**\n * Get worker ID (available after start)\n */\n getWorkerId(): string | null {\n return this.workerId;\n }\n\n /**\n * Get number of active jobs\n */\n getActiveJobCount(): number {\n return this.activeJobs.size;\n }\n\n /**\n * Register job handler\n */\n process(handler: JobHandler): void {\n if (this.state !== 'idle') {\n throw new Error('Cannot set handler after worker has started');\n }\n this.handler = handler;\n }\n\n /**\n * Start the worker\n */\n async start(): Promise<void> {\n if (this.state !== 'idle') {\n throw new Error(`Cannot start worker in state: ${this.state}`);\n }\n\n if (!this.handler) {\n throw new Error('No job handler registered. Call process() first.');\n }\n\n this.state = 'starting';\n this.debug(`Starting worker for queue: ${this.options.queueName}`);\n\n try {\n // Register with the API\n const registration = await this.client.workers.register({\n queueName: this.options.queueName,\n hostname: this.options.hostname,\n workerType: this.options.workerType,\n maxConcurrency: this.options.concurrency,\n metadata: this.options.metadata,\n version: this.options.version,\n });\n\n this.workerId = registration.id;\n this.debug(`Worker registered: ${this.workerId}`, registration);\n\n // Start worker heartbeat\n const heartbeatInterval = registration.heartbeatIntervalSecs * 1000;\n this.workerHeartbeatTimer = setInterval(() => {\n this.sendWorkerHeartbeat();\n }, heartbeatInterval);\n\n // Start polling\n this.state = 'running';\n this.emit('started', { workerId: this.workerId, queueName: this.options.queueName });\n this.schedulePoll();\n } catch (error) {\n this.state = 'error';\n this.emit('error', { error: error as Error });\n throw error;\n }\n }\n\n /**\n * Stop the worker gracefully\n */\n async stop(): Promise<void> {\n if (this.state !== 'running') {\n return;\n }\n\n // Deduplicate concurrent stop calls\n if (this.shutdownPromise) {\n return this.shutdownPromise;\n }\n\n this.shutdownPromise = this.doStop();\n return this.shutdownPromise;\n }\n\n private async doStop(): Promise<void> {\n this.state = 'stopping';\n this.debug('Stopping worker...');\n\n // Stop polling\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n\n // Stop worker heartbeat\n if (this.workerHeartbeatTimer) {\n clearInterval(this.workerHeartbeatTimer);\n this.workerHeartbeatTimer = null;\n }\n\n // Signal all active jobs to stop\n for (const active of this.activeJobs.values()) {\n active.abortController.abort();\n }\n\n // Wait for active jobs to complete (with timeout)\n if (this.activeJobs.size > 0) {\n this.debug(`Waiting for ${this.activeJobs.size} active jobs to complete...`);\n\n await Promise.race([\n this.waitForActiveJobs(),\n this.sleep(this.options.shutdownTimeout),\n ]);\n\n // Force-fail any remaining jobs. Snapshot the entries first because\n // cleanupJob() mutates the activeJobs map as we go.\n const remaining = Array.from(this.activeJobs.entries());\n for (const [jobId, active] of remaining) {\n this.debug(`Force-failing job ${jobId} due to shutdown timeout`);\n await this.failJob(active.job, 'Worker shutdown timeout');\n // Clear the per-job heartbeat interval and drop the job from the map.\n // The handler's finally (which normally does this) may never run if\n // user code ignores the abort signal, so the timer would leak forever.\n this.cleanupJob(jobId);\n }\n }\n\n // Deregister worker\n if (this.workerId) {\n try {\n await this.client.workers.deregister(this.workerId);\n this.debug('Worker deregistered');\n } catch (error) {\n this.debug('Failed to deregister worker', error);\n }\n }\n\n this.state = 'stopped';\n this.workerId = null;\n this.emit('stopped', { workerId: this.workerId ?? '', reason: 'graceful' });\n this.shutdownPromise = null;\n }\n\n /**\n * Add event listener\n */\n on<E extends WorkerEvent>(event: E, handler: EventHandler<E>): () => void {\n if (!this.eventHandlers.has(event)) {\n this.eventHandlers.set(event, new Set());\n }\n this.eventHandlers.get(event)!.add(handler as EventHandler<WorkerEvent>);\n return () => this.off(event, handler);\n }\n\n /**\n * Remove event listener\n */\n off<E extends WorkerEvent>(event: E, handler: EventHandler<E>): void {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler as EventHandler<WorkerEvent>);\n }\n }\n\n // Private methods\n\n private emit<E extends WorkerEvent>(event: E, data: WorkerEventData[E]): void {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n this.debug('Event handler error', { event, error });\n }\n });\n }\n }\n\n private schedulePoll(): void {\n if (this.state !== 'running') {\n return;\n }\n\n this.pollTimer = setTimeout(() => this.poll(), this.options.pollInterval);\n }\n\n private async poll(): Promise<void> {\n if (this.state !== 'running' || !this.workerId) {\n return;\n }\n\n // Check if we have capacity\n const availableSlots = this.options.concurrency - this.activeJobs.size;\n if (availableSlots <= 0) {\n this.schedulePoll();\n return;\n }\n\n try {\n // Claim jobs\n const result = await this.client.jobs.claim({\n queueName: this.options.queueName,\n workerId: this.workerId,\n limit: availableSlots,\n leaseDurationSecs: this.options.leaseDuration,\n });\n\n // Process claimed jobs\n for (const job of result.jobs) {\n this.processJob(job);\n }\n } catch (error) {\n this.debug('Poll failed', error);\n this.emit('error', { error: error as Error });\n }\n\n // Schedule next poll\n this.schedulePoll();\n }\n\n private processJob(job: ClaimedJob): void {\n this.emit('job:claimed', { jobId: job.id, queueName: job.queueName });\n\n const abortController = new AbortController();\n const activeJob: ActiveJob = {\n job,\n startedAt: new Date(),\n abortController,\n };\n\n this.activeJobs.set(job.id, activeJob);\n\n // Start per-job heartbeat\n const heartbeatInterval = this.options.leaseDuration * this.options.heartbeatFraction * 1000;\n activeJob.heartbeatTimer = setInterval(() => {\n this.sendJobHeartbeat(job.id);\n }, heartbeatInterval);\n\n // Execute handler\n this.executeHandler(activeJob);\n }\n\n private async executeHandler(activeJob: ActiveJob): Promise<void> {\n const { job, abortController } = activeJob;\n const { signal } = abortController;\n\n this.emit('job:started', { jobId: job.id, queueName: job.queueName });\n\n const context: JobContext = {\n jobId: job.id,\n queueName: job.queueName,\n payload: job.payload,\n retryCount: job.retryCount,\n maxRetries: job.maxRetries,\n signal,\n progress: async (_percent: number, _message?: string) => {\n // Progress tracking could be implemented via heartbeat metadata\n // For now, this is a no-op\n },\n log: (level, message, meta) => {\n this.debug(`[${job.id}] [${level}] ${message}`, meta);\n },\n };\n\n try {\n const result = await this.handler!(context);\n\n // Check if aborted\n if (signal.aborted) {\n this.debug(`Job ${job.id} was aborted`);\n return;\n }\n\n // Complete the job\n await this.completeJob(job, result ?? undefined);\n } catch (error) {\n // Check if aborted\n if (signal.aborted) {\n this.debug(`Job ${job.id} was aborted`);\n return;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n await this.failJob(job, errorMessage);\n } finally {\n this.cleanupJob(job.id);\n }\n }\n\n private async completeJob(job: ClaimedJob, result?: JsonObject): Promise<void> {\n if (!this.workerId) return;\n\n try {\n await this.client.jobs.complete(job.id, {\n workerId: this.workerId,\n result,\n ...(job.leaseId !== undefined && { leaseId: job.leaseId }),\n });\n\n this.emit('job:completed', {\n jobId: job.id,\n queueName: job.queueName,\n result,\n });\n } catch (error) {\n this.debug(`Failed to complete job ${job.id}`, error);\n }\n }\n\n private async failJob(job: ClaimedJob, errorMessage: string): Promise<void> {\n if (!this.workerId) return;\n\n const willRetry = job.retryCount < job.maxRetries;\n\n try {\n await this.client.jobs.fail(job.id, {\n workerId: this.workerId,\n error: errorMessage,\n ...(job.leaseId !== undefined && { leaseId: job.leaseId }),\n });\n\n this.emit('job:failed', {\n jobId: job.id,\n queueName: job.queueName,\n error: errorMessage,\n willRetry,\n });\n } catch (error) {\n this.debug(`Failed to fail job ${job.id}`, error);\n }\n }\n\n private cleanupJob(jobId: string): void {\n const activeJob = this.activeJobs.get(jobId);\n if (activeJob?.heartbeatTimer) {\n clearInterval(activeJob.heartbeatTimer);\n }\n this.activeJobs.delete(jobId);\n }\n\n private async sendJobHeartbeat(jobId: string): Promise<void> {\n if (!this.workerId) return;\n\n const leaseId = this.activeJobs.get(jobId)?.job.leaseId;\n\n try {\n await this.client.jobs.heartbeat(jobId, {\n workerId: this.workerId,\n leaseDurationSecs: this.options.leaseDuration,\n ...(leaseId !== undefined && { leaseId }),\n });\n } catch (error) {\n this.debug(`Job heartbeat failed for ${jobId}`, error);\n }\n }\n\n private async sendWorkerHeartbeat(): Promise<void> {\n if (!this.workerId || this.state !== 'running') return;\n\n try {\n await this.client.workers.heartbeat(this.workerId, {\n currentJobs: this.activeJobs.size,\n status: 'healthy',\n });\n } catch (error) {\n this.debug('Worker heartbeat failed', error);\n }\n }\n\n private async waitForActiveJobs(): Promise<void> {\n while (this.activeJobs.size > 0) {\n await this.sleep(100);\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n"]}
|