@dispatchtickets/sdk 0.3.0 → 0.5.0
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/README.md +57 -9
- package/dist/index.cjs +397 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +509 -15
- package/dist/index.d.ts +509 -15
- package/dist/index.js +389 -67
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/utils/http.ts","../src/resources/base.ts","../src/resources/accounts.ts","../src/resources/brands.ts","../src/resources/tickets.ts","../src/resources/comments.ts","../src/resources/attachments.ts","../src/resources/webhooks.ts","../src/resources/categories.ts","../src/resources/tags.ts","../src/resources/customers.ts","../src/resources/fields.ts","../src/utils/webhooks.ts","../src/client.ts","../src/types/events.ts","../src/utils/pagination.ts"],"names":["createHmac","timingSafeEqual"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Base error class for all Dispatch Tickets SDK errors\n */\nexport class DispatchTicketsError extends Error {\n readonly code: string;\n readonly statusCode?: number;\n readonly details?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'DispatchTicketsError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when API key is missing or invalid\n */\nexport class AuthenticationError extends DispatchTicketsError {\n constructor(message = 'Invalid or missing API key') {\n super(message, 'authentication_error', 401);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown when rate limit is exceeded\n */\nexport class RateLimitError extends DispatchTicketsError {\n readonly retryAfter?: number;\n\n constructor(message = 'Rate limit exceeded', retryAfter?: number) {\n super(message, 'rate_limit_error', 429);\n this.name = 'RateLimitError';\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Thrown when request validation fails\n */\nexport class ValidationError extends DispatchTicketsError {\n readonly errors?: Array<{ field: string; message: string }>;\n\n constructor(\n message = 'Validation failed',\n errors?: Array<{ field: string; message: string }>\n ) {\n super(message, 'validation_error', 400, { errors });\n this.name = 'ValidationError';\n this.errors = errors;\n }\n}\n\n/**\n * Thrown when a resource is not found\n */\nexport class NotFoundError extends DispatchTicketsError {\n readonly resourceType?: string;\n readonly resourceId?: string;\n\n constructor(message = 'Resource not found', resourceType?: string, resourceId?: string) {\n super(message, 'not_found', 404, { resourceType, resourceId });\n this.name = 'NotFoundError';\n this.resourceType = resourceType;\n this.resourceId = resourceId;\n }\n}\n\n/**\n * Thrown when there's a conflict (e.g., duplicate resource)\n */\nexport class ConflictError extends DispatchTicketsError {\n constructor(message = 'Resource conflict') {\n super(message, 'conflict', 409);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Thrown when the server returns an unexpected error\n */\nexport class ServerError extends DispatchTicketsError {\n constructor(message = 'Internal server error', statusCode = 500) {\n super(message, 'server_error', statusCode);\n this.name = 'ServerError';\n }\n}\n\n/**\n * Thrown when request times out\n */\nexport class TimeoutError extends DispatchTicketsError {\n constructor(message = 'Request timed out') {\n super(message, 'timeout_error');\n this.name = 'TimeoutError';\n }\n}\n\n/**\n * Thrown when network connection fails\n */\nexport class NetworkError extends DispatchTicketsError {\n constructor(message = 'Network error') {\n super(message, 'network_error');\n this.name = 'NetworkError';\n }\n}\n","import {\n DispatchTicketsError,\n AuthenticationError,\n RateLimitError,\n ValidationError,\n NotFoundError,\n ConflictError,\n ServerError,\n TimeoutError,\n NetworkError,\n} from '../errors.js';\n\n/**\n * Custom fetch function type\n */\nexport type FetchFunction = typeof fetch;\n\nexport interface HttpClientConfig {\n baseUrl: string;\n apiKey: string;\n timeout: number;\n maxRetries: number;\n debug?: boolean;\n /**\n * Custom fetch implementation for testing/mocking\n */\n fetch?: FetchFunction;\n}\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n path: string;\n body?: unknown;\n query?: Record<string, string | number | boolean | undefined>;\n headers?: Record<string, string>;\n idempotencyKey?: string;\n}\n\ninterface ApiErrorResponse {\n message?: string;\n error?: string;\n errors?: Array<{ field: string; message: string }>;\n code?: string;\n}\n\n/**\n * HTTP client with retry logic and error handling\n */\nexport class HttpClient {\n private readonly config: HttpClientConfig;\n private readonly fetchFn: FetchFunction;\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n this.fetchFn = config.fetch ?? fetch;\n }\n\n /**\n * Execute an HTTP request with retry logic\n */\n async request<T>(options: RequestOptions): Promise<T> {\n const url = this.buildUrl(options.path, options.query);\n const headers = this.buildHeaders(options.headers, options.idempotencyKey);\n\n let lastError: Error | undefined;\n let attempt = 0;\n\n while (attempt <= this.config.maxRetries) {\n try {\n const response = await this.executeRequest(url, options.method, headers, options.body);\n return await this.handleResponse<T>(response);\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on client errors (except rate limits)\n if (error instanceof DispatchTicketsError) {\n if (\n error instanceof AuthenticationError ||\n error instanceof ValidationError ||\n error instanceof NotFoundError ||\n error instanceof ConflictError\n ) {\n throw error;\n }\n\n // Retry on rate limit with backoff\n if (error instanceof RateLimitError && error.retryAfter) {\n if (attempt < this.config.maxRetries) {\n await this.sleep(error.retryAfter * 1000);\n attempt++;\n continue;\n }\n }\n\n // Retry on server errors\n if (error instanceof ServerError) {\n if (attempt < this.config.maxRetries) {\n await this.sleep(this.calculateBackoff(attempt));\n attempt++;\n continue;\n }\n }\n }\n\n // Retry on network/timeout errors\n if (error instanceof NetworkError || error instanceof TimeoutError) {\n if (attempt < this.config.maxRetries) {\n await this.sleep(this.calculateBackoff(attempt));\n attempt++;\n continue;\n }\n }\n\n throw error;\n }\n }\n\n throw lastError || new NetworkError('Request failed after retries');\n }\n\n private buildUrl(path: string, query?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(path, this.config.baseUrl);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n return url.toString();\n }\n\n private buildHeaders(\n customHeaders?: Record<string, string>,\n idempotencyKey?: string\n ): Record<string, string> {\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...customHeaders,\n };\n\n if (idempotencyKey) {\n headers['X-Idempotency-Key'] = idempotencyKey;\n }\n\n return headers;\n }\n\n private async executeRequest(\n url: string,\n method: string,\n headers: Record<string, string>,\n body?: unknown\n ): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n if (this.config.debug) {\n console.log(`[DispatchTickets] ${method} ${url}`);\n if (body) {\n console.log('[DispatchTickets] Body:', JSON.stringify(body, null, 2));\n }\n }\n\n const response = await this.fetchFn(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n return response;\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new TimeoutError(`Request timed out after ${this.config.timeout}ms`);\n }\n throw new NetworkError(error.message);\n }\n throw new NetworkError('Unknown network error');\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n private async handleResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n if (response.ok) {\n if (response.status === 204 || !isJson) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n // Handle error responses\n let errorData: ApiErrorResponse = {};\n if (isJson) {\n try {\n errorData = (await response.json()) as ApiErrorResponse;\n } catch {\n // Ignore JSON parse errors for error responses\n }\n }\n\n const message = errorData.message || errorData.error || response.statusText;\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message);\n case 400:\n case 422:\n throw new ValidationError(message, errorData.errors);\n case 404:\n throw new NotFoundError(message);\n case 409:\n throw new ConflictError(message);\n case 429: {\n const retryAfter = response.headers.get('retry-after');\n throw new RateLimitError(message, retryAfter ? parseInt(retryAfter, 10) : undefined);\n }\n default:\n if (response.status >= 500) {\n throw new ServerError(message, response.status);\n }\n throw new DispatchTicketsError(message, 'api_error', response.status, errorData as Record<string, unknown>);\n }\n }\n\n private calculateBackoff(attempt: number): number {\n // Exponential backoff: 1s, 2s, 4s, ...\n const baseDelay = 1000;\n const maxDelay = 30000;\n const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);\n // Add jitter (0-25% of delay)\n return delay + Math.random() * delay * 0.25;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient, RequestOptions } from '../utils/http.js';\n\n/**\n * Base class for all resource classes\n */\nexport abstract class BaseResource {\n protected readonly http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n protected async _get<T>(path: string, query?: RequestOptions['query']): Promise<T> {\n return this.http.request<T>({\n method: 'GET',\n path,\n query,\n });\n }\n\n protected async _post<T>(\n path: string,\n body?: unknown,\n options?: { idempotencyKey?: string; query?: RequestOptions['query'] }\n ): Promise<T> {\n return this.http.request<T>({\n method: 'POST',\n path,\n body,\n idempotencyKey: options?.idempotencyKey,\n query: options?.query,\n });\n }\n\n protected async _patch<T>(path: string, body?: unknown): Promise<T> {\n return this.http.request<T>({\n method: 'PATCH',\n path,\n body,\n });\n }\n\n protected async _put<T>(path: string, body?: unknown): Promise<T> {\n return this.http.request<T>({\n method: 'PUT',\n path,\n body,\n });\n }\n\n protected async _delete<T>(path: string, query?: RequestOptions['query']): Promise<T> {\n return this.http.request<T>({\n method: 'DELETE',\n path,\n query,\n });\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Account,\n AccountUsage,\n ApiKey,\n ApiKeyWithSecret,\n CreateApiKeyInput,\n UpdateApiKeyScopeInput,\n} from '../types/account.js';\n\n/**\n * Accounts resource for managing the current account\n */\nexport class AccountsResource extends BaseResource {\n /**\n * Get the current account\n */\n async me(): Promise<Account> {\n return this._get<Account>('/accounts/me');\n }\n\n /**\n * Get usage statistics for the current account\n */\n async getUsage(): Promise<AccountUsage> {\n return this._get<AccountUsage>('/accounts/me/usage');\n }\n\n /**\n * List all API keys for the current account\n */\n async listApiKeys(): Promise<ApiKey[]> {\n return this._get<ApiKey[]>('/accounts/me/api-keys');\n }\n\n /**\n * Create a new API key\n *\n * Note: The full key value is only returned once on creation.\n * Store it securely as it cannot be retrieved again.\n */\n async createApiKey(data: CreateApiKeyInput): Promise<ApiKeyWithSecret> {\n return this._post<ApiKeyWithSecret>('/accounts/me/api-keys', data);\n }\n\n /**\n * Update the brand scope for an API key\n */\n async updateApiKeyScope(\n keyId: string,\n data: UpdateApiKeyScopeInput\n ): Promise<{ success: boolean }> {\n return this._patch<{ success: boolean }>(\n `/accounts/me/api-keys/${keyId}/scope`,\n data\n );\n }\n\n /**\n * Revoke an API key\n */\n async revokeApiKey(keyId: string): Promise<void> {\n await this._delete<void>(`/accounts/me/api-keys/${keyId}`);\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Brand, CreateBrandInput, UpdateBrandInput, DeleteBrandPreview } from '../types/brand.js';\n\n/**\n * Brands resource for managing workspaces\n */\nexport class BrandsResource extends BaseResource {\n /**\n * Create a new brand\n */\n async create(data: CreateBrandInput): Promise<Brand> {\n return this._post<Brand>('/brands', data);\n }\n\n /**\n * List all brands\n */\n async list(): Promise<Brand[]> {\n return this._get<Brand[]>('/brands');\n }\n\n /**\n * Get a brand by ID\n */\n async get(brandId: string): Promise<Brand> {\n return this._get<Brand>(`/brands/${brandId}`);\n }\n\n /**\n * Update a brand\n */\n async update(brandId: string, data: UpdateBrandInput): Promise<Brand> {\n return this._patch<Brand>(`/brands/${brandId}`, data);\n }\n\n /**\n * Delete a brand\n * @param brandId - The brand ID\n * @param confirm - Set to true to actually delete; false to preview what would be deleted\n */\n async delete(brandId: string, confirm = true): Promise<void | DeleteBrandPreview> {\n if (confirm) {\n await this._delete<void>(`/brands/${brandId}`, { confirm: true });\n return;\n }\n return this._delete<DeleteBrandPreview>(`/brands/${brandId}`);\n }\n\n /**\n * Get the ticket schema for a brand\n */\n async getSchema(brandId: string): Promise<Record<string, unknown>> {\n return this._get<Record<string, unknown>>(`/brands/${brandId}/schema`);\n }\n\n /**\n * Update the ticket schema for a brand\n */\n async updateSchema(brandId: string, schema: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this._put<Record<string, unknown>>(`/brands/${brandId}/schema`, schema);\n }\n\n /**\n * Get the inbound email address for a brand\n *\n * Emails sent to this address will automatically create tickets.\n *\n * @param brandId - The brand ID\n * @param domain - Optional custom inbound domain (default: inbound.dispatchtickets.com)\n * @returns The inbound email address\n *\n * @example\n * ```typescript\n * const email = client.brands.getInboundEmail('br_abc123');\n * // Returns: br_abc123@inbound.dispatchtickets.com\n *\n * // With custom domain:\n * const customEmail = client.brands.getInboundEmail('br_abc123', 'support.mycompany.com');\n * // Returns: br_abc123@support.mycompany.com\n * ```\n */\n getInboundEmail(brandId: string, domain = 'inbound.dispatchtickets.com'): string {\n return `${brandId}@${domain}`;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Ticket,\n CreateTicketInput,\n UpdateTicketInput,\n ListTicketsFilters,\n CreateTicketOptions,\n MergeTicketsInput,\n BulkActionResult,\n} from '../types/ticket.js';\nimport type { PaginatedResponse, BulkAction } from '../types/common.js';\n\n/**\n * Tickets resource\n */\nexport class TicketsResource extends BaseResource {\n /**\n * Create a new ticket\n */\n async create(\n brandId: string,\n data: CreateTicketInput,\n options?: CreateTicketOptions\n ): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets`, data, {\n idempotencyKey: options?.idempotencyKey,\n });\n }\n\n /**\n * List tickets with pagination (async iterator)\n * Automatically fetches all pages\n */\n async *list(\n brandId: string,\n filters?: Omit<ListTicketsFilters, 'cursor'>\n ): AsyncIterable<Ticket> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const page = await this.listPage(brandId, { ...filters, cursor });\n for (const ticket of page.data) {\n yield ticket;\n }\n cursor = page.pagination.cursor;\n hasMore = page.pagination.hasMore;\n }\n }\n\n /**\n * List a single page of tickets\n */\n async listPage(\n brandId: string,\n filters?: ListTicketsFilters\n ): Promise<PaginatedResponse<Ticket>> {\n const query = this.buildListQuery(filters);\n return this._get<PaginatedResponse<Ticket>>(`/brands/${brandId}/tickets`, query);\n }\n\n /**\n * Get a ticket by ID\n */\n async get(brandId: string, ticketId: string): Promise<Ticket> {\n return this._get<Ticket>(`/brands/${brandId}/tickets/${ticketId}`);\n }\n\n /**\n * Update a ticket\n */\n async update(\n brandId: string,\n ticketId: string,\n data: UpdateTicketInput\n ): Promise<Ticket> {\n return this._patch<Ticket>(`/brands/${brandId}/tickets/${ticketId}`, data);\n }\n\n /**\n * Delete a ticket\n */\n async delete(brandId: string, ticketId: string): Promise<Ticket> {\n return this._delete<Ticket>(`/brands/${brandId}/tickets/${ticketId}`);\n }\n\n /**\n * Mark a ticket as spam or not spam\n */\n async markAsSpam(brandId: string, ticketId: string, isSpam: boolean): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets/${ticketId}/spam`, { isSpam });\n }\n\n /**\n * Merge tickets into a target ticket\n */\n async merge(\n brandId: string,\n targetTicketId: string,\n sourceTicketIds: string[]\n ): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets/${targetTicketId}/merge`, {\n sourceTicketIds,\n } satisfies MergeTicketsInput);\n }\n\n /**\n * Perform a bulk action on multiple tickets\n */\n async bulk(\n brandId: string,\n action: BulkAction,\n ticketIds: string[],\n options?: {\n assigneeId?: string | null;\n categoryId?: string | null;\n tags?: string[];\n }\n ): Promise<BulkActionResult> {\n return this._post<BulkActionResult>(`/brands/${brandId}/tickets/bulk`, {\n action,\n ticketIds,\n ...options,\n });\n }\n\n private buildListQuery(\n filters?: ListTicketsFilters\n ): Record<string, string | number | boolean | undefined> {\n if (!filters) return {};\n\n const query: Record<string, string | number | boolean | undefined> = {};\n\n if (filters.status) {\n query.status = Array.isArray(filters.status)\n ? filters.status.join(',')\n : filters.status;\n }\n if (filters.priority) query.priority = filters.priority;\n if (filters.assigneeId) query.assigneeId = filters.assigneeId;\n if (filters.customerId) query.customerId = filters.customerId;\n if (filters.customerEmail) query.customerEmail = filters.customerEmail;\n if (filters.createdBy) query.createdBy = filters.createdBy;\n if (filters.createdAfter) query.createdAfter = filters.createdAfter;\n if (filters.createdBefore) query.createdBefore = filters.createdBefore;\n if (filters.hasAttachments !== undefined) query.hasAttachments = filters.hasAttachments;\n if (filters.isSpam !== undefined) query.isSpam = filters.isSpam;\n if (filters.search) query.search = filters.search;\n if (filters.categoryId) query.categoryId = filters.categoryId;\n if (filters.tagIds) query.tagIds = filters.tagIds.join(',');\n if (filters.source) query.source = filters.source;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n\n return query;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Comment,\n CreateCommentInput,\n UpdateCommentInput,\n CreateCommentOptions,\n} from '../types/comment.js';\n\n/**\n * Comments resource\n */\nexport class CommentsResource extends BaseResource {\n /**\n * Create a new comment on a ticket\n */\n async create(\n brandId: string,\n ticketId: string,\n data: CreateCommentInput,\n options?: CreateCommentOptions\n ): Promise<Comment> {\n return this._post<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments`,\n data,\n { idempotencyKey: options?.idempotencyKey }\n );\n }\n\n /**\n * List all comments on a ticket\n */\n async list(brandId: string, ticketId: string): Promise<Comment[]> {\n return this._get<Comment[]>(`/brands/${brandId}/tickets/${ticketId}/comments`);\n }\n\n /**\n * Get a comment by ID\n */\n async get(brandId: string, ticketId: string, commentId: string): Promise<Comment> {\n return this._get<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`\n );\n }\n\n /**\n * Update a comment\n */\n async update(\n brandId: string,\n ticketId: string,\n commentId: string,\n data: UpdateCommentInput\n ): Promise<Comment> {\n return this._patch<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`,\n data\n );\n }\n\n /**\n * Delete a comment\n */\n async delete(brandId: string, ticketId: string, commentId: string): Promise<Comment> {\n return this._delete<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`\n );\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Attachment,\n AttachmentWithUrl,\n InitiateUploadInput,\n InitiateUploadResponse,\n} from '../types/attachment.js';\n\n/**\n * Attachments resource\n */\nexport class AttachmentsResource extends BaseResource {\n /**\n * Initiate an upload and get a presigned URL\n */\n async initiateUpload(\n brandId: string,\n ticketId: string,\n data: InitiateUploadInput\n ): Promise<InitiateUploadResponse> {\n return this._post<InitiateUploadResponse>(\n `/brands/${brandId}/tickets/${ticketId}/attachments`,\n data\n );\n }\n\n /**\n * Confirm that an upload has completed\n */\n async confirmUpload(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<Attachment> {\n return this._post<Attachment>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}/confirm`\n );\n }\n\n /**\n * List all attachments on a ticket\n */\n async list(brandId: string, ticketId: string): Promise<Attachment[]> {\n return this._get<Attachment[]>(`/brands/${brandId}/tickets/${ticketId}/attachments`);\n }\n\n /**\n * Get an attachment with its download URL\n */\n async get(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<AttachmentWithUrl> {\n return this._get<AttachmentWithUrl>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}`\n );\n }\n\n /**\n * Delete an attachment\n */\n async delete(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<void> {\n await this._delete<void>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}`\n );\n }\n\n /**\n * Convenience method: Upload a file in one step\n * Handles: initiate -> upload to presigned URL -> confirm\n */\n async upload(\n brandId: string,\n ticketId: string,\n file: Blob | Buffer | ArrayBuffer,\n filename: string,\n contentType: string\n ): Promise<Attachment> {\n // Get file size\n let size: number;\n if (file instanceof Blob) {\n size = file.size;\n } else if (Buffer.isBuffer(file)) {\n size = file.length;\n } else {\n size = file.byteLength;\n }\n\n // Initiate upload\n const { uploadUrl, attachmentId } = await this.initiateUpload(brandId, ticketId, {\n filename,\n contentType,\n size,\n });\n\n // Upload to presigned URL\n const uploadResponse = await fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': contentType,\n 'Content-Length': String(size),\n },\n body: file,\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n }\n\n // Confirm upload\n return this.confirmUpload(brandId, ticketId, attachmentId);\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Webhook, CreateWebhookInput, WebhookDelivery } from '../types/webhook.js';\n\n/**\n * Webhooks resource\n */\nexport class WebhooksResource extends BaseResource {\n /**\n * Create a new webhook\n */\n async create(brandId: string, data: CreateWebhookInput): Promise<Webhook> {\n return this._post<Webhook>(`/brands/${brandId}/webhooks`, data);\n }\n\n /**\n * List all webhooks for a brand\n */\n async list(brandId: string): Promise<Webhook[]> {\n return this._get<Webhook[]>(`/brands/${brandId}/webhooks`);\n }\n\n /**\n * Get a webhook by ID\n */\n async get(brandId: string, webhookId: string): Promise<Webhook> {\n return this._get<Webhook>(`/brands/${brandId}/webhooks/${webhookId}`);\n }\n\n /**\n * Delete a webhook\n */\n async delete(brandId: string, webhookId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/webhooks/${webhookId}`);\n }\n\n /**\n * Get webhook delivery history\n */\n async getDeliveries(brandId: string, webhookId: string): Promise<WebhookDelivery[]> {\n return this._get<WebhookDelivery[]>(\n `/brands/${brandId}/webhooks/${webhookId}/deliveries`\n );\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Category,\n CreateCategoryInput,\n UpdateCategoryInput,\n CategoryStats,\n} from '../types/category.js';\n\n/**\n * Categories resource\n */\nexport class CategoriesResource extends BaseResource {\n /**\n * Create a new category\n */\n async create(brandId: string, data: CreateCategoryInput): Promise<Category> {\n return this._post<Category>(`/brands/${brandId}/categories`, data);\n }\n\n /**\n * List all categories for a brand\n */\n async list(brandId: string): Promise<Category[]> {\n return this._get<Category[]>(`/brands/${brandId}/categories`);\n }\n\n /**\n * Get a category by ID\n */\n async get(brandId: string, categoryId: string): Promise<Category> {\n return this._get<Category>(`/brands/${brandId}/categories/${categoryId}`);\n }\n\n /**\n * Update a category\n */\n async update(\n brandId: string,\n categoryId: string,\n data: UpdateCategoryInput\n ): Promise<Category> {\n return this._patch<Category>(`/brands/${brandId}/categories/${categoryId}`, data);\n }\n\n /**\n * Delete a category\n */\n async delete(brandId: string, categoryId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/categories/${categoryId}`);\n }\n\n /**\n * Get category statistics (ticket counts)\n */\n async getStats(brandId: string): Promise<CategoryStats> {\n return this._get<CategoryStats>(`/brands/${brandId}/categories/stats`);\n }\n\n /**\n * Reorder categories\n */\n async reorder(brandId: string, categoryIds: string[]): Promise<void> {\n await this._post<void>(`/brands/${brandId}/categories/reorder`, { categoryIds });\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Tag, CreateTagInput, UpdateTagInput } from '../types/tag.js';\n\n/**\n * Tags resource\n */\nexport class TagsResource extends BaseResource {\n /**\n * Create a new tag\n */\n async create(brandId: string, data: CreateTagInput): Promise<Tag> {\n return this._post<Tag>(`/brands/${brandId}/tags`, data);\n }\n\n /**\n * List all tags for a brand\n */\n async list(brandId: string): Promise<Tag[]> {\n return this._get<Tag[]>(`/brands/${brandId}/tags`);\n }\n\n /**\n * Update a tag\n */\n async update(brandId: string, tagId: string, data: UpdateTagInput): Promise<Tag> {\n return this._patch<Tag>(`/brands/${brandId}/tags/${tagId}`, data);\n }\n\n /**\n * Delete a tag\n */\n async delete(brandId: string, tagId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/tags/${tagId}`);\n }\n\n /**\n * Merge tags into a target tag\n */\n async merge(brandId: string, targetTagId: string, sourceTagIds: string[]): Promise<Tag> {\n return this._post<Tag>(`/brands/${brandId}/tags/${targetTagId}/merge`, {\n sourceTagIds,\n });\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Customer,\n CreateCustomerInput,\n UpdateCustomerInput,\n ListCustomersFilters,\n} from '../types/customer.js';\nimport type { PaginatedResponse } from '../types/common.js';\n\n/**\n * Customers resource\n */\nexport class CustomersResource extends BaseResource {\n /**\n * Create a new customer\n */\n async create(brandId: string, data: CreateCustomerInput): Promise<Customer> {\n return this._post<Customer>(`/brands/${brandId}/customers`, data);\n }\n\n /**\n * List customers with pagination (async iterator)\n */\n async *list(\n brandId: string,\n filters?: Omit<ListCustomersFilters, 'cursor'>\n ): AsyncIterable<Customer> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const page = await this.listPage(brandId, { ...filters, cursor });\n for (const customer of page.data) {\n yield customer;\n }\n cursor = page.pagination.cursor;\n hasMore = page.pagination.hasMore;\n }\n }\n\n /**\n * List a single page of customers\n */\n async listPage(\n brandId: string,\n filters?: ListCustomersFilters\n ): Promise<PaginatedResponse<Customer>> {\n const query = this.buildListQuery(filters);\n return this._get<PaginatedResponse<Customer>>(`/brands/${brandId}/customers`, query);\n }\n\n /**\n * Search customers (autocomplete)\n */\n async search(brandId: string, query: string): Promise<Customer[]> {\n return this._get<Customer[]>(`/brands/${brandId}/customers/search`, { q: query });\n }\n\n /**\n * Get a customer by ID\n */\n async get(brandId: string, customerId: string): Promise<Customer> {\n return this._get<Customer>(`/brands/${brandId}/customers/${customerId}`);\n }\n\n /**\n * Update a customer\n */\n async update(\n brandId: string,\n customerId: string,\n data: UpdateCustomerInput\n ): Promise<Customer> {\n return this._patch<Customer>(`/brands/${brandId}/customers/${customerId}`, data);\n }\n\n /**\n * Delete a customer\n */\n async delete(brandId: string, customerId: string): Promise<Customer> {\n return this._delete<Customer>(`/brands/${brandId}/customers/${customerId}`);\n }\n\n private buildListQuery(\n filters?: ListCustomersFilters\n ): Record<string, string | number | boolean | undefined> {\n if (!filters) return {};\n\n const query: Record<string, string | number | boolean | undefined> = {};\n\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n\n return query;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n FieldDefinition,\n FieldDefinitions,\n CreateFieldInput,\n UpdateFieldInput,\n EntityType,\n} from '../types/field.js';\n\n/**\n * Custom fields resource\n */\nexport class FieldsResource extends BaseResource {\n /**\n * Get all field definitions for a brand\n */\n async getAll(brandId: string): Promise<FieldDefinitions> {\n return this._get<FieldDefinitions>(`/brands/${brandId}/fields`);\n }\n\n /**\n * Get field definitions for a specific entity type\n */\n async list(brandId: string, entityType: EntityType): Promise<FieldDefinition[]> {\n return this._get<FieldDefinition[]>(`/brands/${brandId}/fields/${entityType}`);\n }\n\n /**\n * Create a new field definition\n */\n async create(\n brandId: string,\n entityType: EntityType,\n data: CreateFieldInput\n ): Promise<FieldDefinition> {\n return this._post<FieldDefinition>(`/brands/${brandId}/fields/${entityType}`, data);\n }\n\n /**\n * Update a field definition\n */\n async update(\n brandId: string,\n entityType: EntityType,\n key: string,\n data: UpdateFieldInput\n ): Promise<FieldDefinition> {\n return this._patch<FieldDefinition>(\n `/brands/${brandId}/fields/${entityType}/${key}`,\n data\n );\n }\n\n /**\n * Delete a field definition\n */\n async delete(brandId: string, entityType: EntityType, key: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/fields/${entityType}/${key}`);\n }\n\n /**\n * Reorder field definitions\n */\n async reorder(brandId: string, entityType: EntityType, keys: string[]): Promise<void> {\n await this._post<void>(`/brands/${brandId}/fields/${entityType}/reorder`, { keys });\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto';\n\n/**\n * Webhook signature verification utilities\n */\nexport const webhookUtils = {\n /**\n * Verify a webhook signature\n *\n * @param payload - The raw request body as a string\n * @param signature - The X-Dispatch-Signature header value\n * @param secret - Your webhook secret\n * @returns true if the signature is valid\n *\n * @example\n * ```typescript\n * import { DispatchTickets } from '@dispatchtickets/sdk';\n *\n * app.post('/webhooks', (req, res) => {\n * const signature = req.headers['x-dispatch-signature'];\n * const isValid = DispatchTickets.webhooks.verifySignature(\n * req.rawBody,\n * signature,\n * process.env.WEBHOOK_SECRET\n * );\n *\n * if (!isValid) {\n * return res.status(401).send('Invalid signature');\n * }\n *\n * // Process webhook...\n * });\n * ```\n */\n verifySignature(payload: string, signature: string, secret: string): boolean {\n if (!signature || !secret) {\n return false;\n }\n\n // Signature format: sha256=<hex>\n const parts = signature.split('=');\n if (parts.length !== 2 || parts[0] !== 'sha256') {\n return false;\n }\n\n const receivedSignature = parts[1];\n const expectedSignature = createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n\n // Use timing-safe comparison to prevent timing attacks\n try {\n const receivedBuffer = Buffer.from(receivedSignature, 'hex');\n const expectedBuffer = Buffer.from(expectedSignature, 'hex');\n\n if (receivedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return timingSafeEqual(receivedBuffer, expectedBuffer);\n } catch {\n return false;\n }\n },\n\n /**\n * Generate a signature for testing purposes\n *\n * @param payload - The payload to sign\n * @param secret - The secret to sign with\n * @returns The signature in the format sha256=<hex>\n */\n generateSignature(payload: string, secret: string): string {\n const signature = createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n return `sha256=${signature}`;\n },\n};\n","import { HttpClient, HttpClientConfig, FetchFunction } from './utils/http.js';\nimport { AccountsResource } from './resources/accounts.js';\nimport { BrandsResource } from './resources/brands.js';\nimport { TicketsResource } from './resources/tickets.js';\nimport { CommentsResource } from './resources/comments.js';\nimport { AttachmentsResource } from './resources/attachments.js';\nimport { WebhooksResource } from './resources/webhooks.js';\nimport { CategoriesResource } from './resources/categories.js';\nimport { TagsResource } from './resources/tags.js';\nimport { CustomersResource } from './resources/customers.js';\nimport { FieldsResource } from './resources/fields.js';\nimport { webhookUtils } from './utils/webhooks.js';\n\n/**\n * Configuration options for the Dispatch Tickets client\n */\nexport interface DispatchTicketsConfig {\n /**\n * Your API key (required)\n */\n apiKey: string;\n\n /**\n * Base URL for the API\n * @default 'https://dispatch-tickets-api.onrender.com/v1'\n */\n baseUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Maximum number of retries for failed requests\n * @default 3\n */\n maxRetries?: number;\n\n /**\n * Enable debug logging\n * @default false\n */\n debug?: boolean;\n\n /**\n * Custom fetch implementation for testing/mocking\n */\n fetch?: FetchFunction;\n}\n\n/**\n * Dispatch Tickets SDK client\n *\n * @example\n * ```typescript\n * import { DispatchTickets } from '@dispatchtickets/sdk';\n *\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * });\n *\n * // List brands\n * const brands = await client.brands.list();\n *\n * // Create a ticket\n * const ticket = await client.tickets.create('ws_abc123', {\n * title: 'Help with login',\n * body: 'I cannot log in to my account',\n * });\n *\n * // Iterate through all tickets\n * for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {\n * console.log(ticket.title);\n * }\n * ```\n */\nexport class DispatchTickets {\n private readonly http: HttpClient;\n\n /**\n * Accounts resource for managing the current account and API keys\n */\n readonly accounts: AccountsResource;\n\n /**\n * Brands (workspaces) resource\n */\n readonly brands: BrandsResource;\n\n /**\n * Tickets resource\n */\n readonly tickets: TicketsResource;\n\n /**\n * Comments resource\n */\n readonly comments: CommentsResource;\n\n /**\n * Attachments resource\n */\n readonly attachments: AttachmentsResource;\n\n /**\n * Webhooks resource\n */\n readonly webhooks: WebhooksResource;\n\n /**\n * Categories resource\n */\n readonly categories: CategoriesResource;\n\n /**\n * Tags resource\n */\n readonly tags: TagsResource;\n\n /**\n * Customers resource\n */\n readonly customers: CustomersResource;\n\n /**\n * Custom fields resource\n */\n readonly fields: FieldsResource;\n\n /**\n * Static webhook utilities\n */\n static readonly webhooks = webhookUtils;\n\n constructor(config: DispatchTicketsConfig) {\n if (!config.apiKey) {\n throw new Error('API key is required');\n }\n\n const httpConfig: HttpClientConfig = {\n baseUrl: config.baseUrl || 'https://dispatch-tickets-api.onrender.com/v1',\n apiKey: config.apiKey,\n timeout: config.timeout ?? 30000,\n maxRetries: config.maxRetries ?? 3,\n debug: config.debug ?? false,\n fetch: config.fetch,\n };\n\n this.http = new HttpClient(httpConfig);\n\n // Initialize resources\n this.accounts = new AccountsResource(this.http);\n this.brands = new BrandsResource(this.http);\n this.tickets = new TicketsResource(this.http);\n this.comments = new CommentsResource(this.http);\n this.attachments = new AttachmentsResource(this.http);\n this.webhooks = new WebhooksResource(this.http);\n this.categories = new CategoriesResource(this.http);\n this.tags = new TagsResource(this.http);\n this.customers = new CustomersResource(this.http);\n this.fields = new FieldsResource(this.http);\n }\n}\n","import type { TicketStatus, TicketPriority, TicketSource, AuthorType } from './common.js';\n\n/**\n * All supported webhook event types\n */\nexport type WebhookEventType =\n | 'ticket.created'\n | 'ticket.updated'\n | 'ticket.comment.created';\n\n/**\n * Base webhook event envelope\n */\nexport interface WebhookEventEnvelope<T extends WebhookEventType, D> {\n /** Unique event ID */\n id: string;\n /** Event type */\n event: T;\n /** Brand ID that triggered the event */\n brand_id: string;\n /** Event data */\n data: D;\n /** ISO timestamp when event was created */\n timestamp: string;\n}\n\n/**\n * Customer info included in events\n */\nexport interface EventCustomerInfo {\n customerId: string | null;\n customerEmail: string | null;\n customerName: string | null;\n}\n\n/**\n * Payload for ticket.created event\n */\nexport interface TicketCreatedData extends EventCustomerInfo {\n id: string;\n ticketNumber: number;\n title: string;\n status: TicketStatus;\n priority: TicketPriority;\n source: TicketSource;\n createdAt: string;\n}\n\n/**\n * Payload for ticket.updated event\n */\nexport interface TicketUpdatedData extends EventCustomerInfo {\n id: string;\n ticketNumber: number;\n title: string;\n status: TicketStatus;\n priority: TicketPriority;\n assigneeId: string | null;\n updatedAt: string;\n /** List of field names that were changed */\n changes: string[];\n}\n\n/**\n * Comment data in ticket.comment.created event\n */\nexport interface EventCommentData {\n id: string;\n body: string;\n authorId: string | null;\n authorType: AuthorType;\n createdAt: string;\n}\n\n/**\n * Payload for ticket.comment.created event\n */\nexport interface CommentCreatedData extends EventCustomerInfo {\n ticketId: string;\n /** Formatted ticket number (e.g., \"ACME-123\") */\n ticketNumber: string;\n comment: EventCommentData;\n}\n\n/**\n * Ticket created webhook event\n */\nexport type TicketCreatedEvent = WebhookEventEnvelope<'ticket.created', TicketCreatedData>;\n\n/**\n * Ticket updated webhook event\n */\nexport type TicketUpdatedEvent = WebhookEventEnvelope<'ticket.updated', TicketUpdatedData>;\n\n/**\n * Comment created webhook event\n */\nexport type CommentCreatedEvent = WebhookEventEnvelope<'ticket.comment.created', CommentCreatedData>;\n\n/**\n * Union of all webhook events\n */\nexport type WebhookEvent = TicketCreatedEvent | TicketUpdatedEvent | CommentCreatedEvent;\n\n/**\n * Map of event types to their data types\n */\nexport interface WebhookEventMap {\n 'ticket.created': TicketCreatedEvent;\n 'ticket.updated': TicketUpdatedEvent;\n 'ticket.comment.created': CommentCreatedEvent;\n}\n\n/**\n * Type guard to check if event is a ticket.created event\n */\nexport function isTicketCreatedEvent(event: WebhookEvent): event is TicketCreatedEvent {\n return event.event === 'ticket.created';\n}\n\n/**\n * Type guard to check if event is a ticket.updated event\n */\nexport function isTicketUpdatedEvent(event: WebhookEvent): event is TicketUpdatedEvent {\n return event.event === 'ticket.updated';\n}\n\n/**\n * Type guard to check if event is a ticket.comment.created event\n */\nexport function isCommentCreatedEvent(event: WebhookEvent): event is CommentCreatedEvent {\n return event.event === 'ticket.comment.created';\n}\n\n/**\n * Parse and validate a webhook payload\n *\n * @param payload - Raw JSON payload string or parsed object\n * @returns Typed webhook event\n * @throws Error if payload is invalid\n *\n * @example\n * ```typescript\n * import { parseWebhookEvent, isTicketCreatedEvent } from '@dispatchtickets/sdk';\n *\n * app.post('/webhooks', (req, res) => {\n * const event = parseWebhookEvent(req.body);\n *\n * if (isTicketCreatedEvent(event)) {\n * console.log('New ticket:', event.data.title);\n * }\n * });\n * ```\n */\nexport function parseWebhookEvent(payload: string | object): WebhookEvent {\n const event = typeof payload === 'string' ? JSON.parse(payload) : payload;\n\n if (!event || typeof event !== 'object') {\n throw new Error('Invalid webhook payload: expected object');\n }\n\n if (!event.event || typeof event.event !== 'string') {\n throw new Error('Invalid webhook payload: missing event type');\n }\n\n if (!event.id || typeof event.id !== 'string') {\n throw new Error('Invalid webhook payload: missing event id');\n }\n\n if (!event.data || typeof event.data !== 'object') {\n throw new Error('Invalid webhook payload: missing data');\n }\n\n const validEvents: WebhookEventType[] = ['ticket.created', 'ticket.updated', 'ticket.comment.created'];\n if (!validEvents.includes(event.event)) {\n throw new Error(`Invalid webhook payload: unknown event type \"${event.event}\"`);\n }\n\n return event as WebhookEvent;\n}\n","import type { PaginatedResponse } from '../types/common.js';\n\n/**\n * Options for paginated requests\n */\nexport interface PaginationOptions {\n limit?: number;\n cursor?: string;\n}\n\n/**\n * Create an async iterator from a paginated API endpoint\n */\nexport function createPaginatedIterator<T>(\n fetchPage: (cursor?: string) => Promise<PaginatedResponse<T>>\n): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n let cursor: string | undefined;\n let hasMore = true;\n let currentPage: T[] = [];\n let currentIndex = 0;\n\n return {\n async next(): Promise<IteratorResult<T>> {\n // If we have items in the current page, return the next one\n if (currentIndex < currentPage.length) {\n return { value: currentPage[currentIndex++], done: false };\n }\n\n // If no more pages, we're done\n if (!hasMore) {\n return { value: undefined, done: true };\n }\n\n // Fetch the next page\n const response = await fetchPage(cursor);\n currentPage = response.data;\n currentIndex = 0;\n cursor = response.pagination.cursor;\n hasMore = response.pagination.hasMore;\n\n // If the page is empty, we're done\n if (currentPage.length === 0) {\n return { value: undefined, done: true };\n }\n\n return { value: currentPage[currentIndex++], done: false };\n },\n };\n },\n };\n}\n\n/**\n * Collect all items from an async iterable into an array\n */\nexport async function collectAll<T>(iterable: AsyncIterable<T>): Promise<T[]> {\n const items: T[] = [];\n for await (const item of iterable) {\n items.push(item);\n }\n return items;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/utils/http.ts","../src/resources/base.ts","../src/resources/accounts.ts","../src/resources/brands.ts","../src/resources/tickets.ts","../src/resources/comments.ts","../src/resources/attachments.ts","../src/resources/webhooks.ts","../src/resources/categories.ts","../src/resources/tags.ts","../src/resources/customers.ts","../src/resources/fields.ts","../src/utils/webhooks.ts","../src/client.ts","../src/types/events.ts","../src/utils/pagination.ts"],"names":["createHmac","timingSafeEqual"],"mappings":";;;;;AAGO,IAAM,oBAAA,GAAN,cAAmC,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA;AAAA,EAEA,SAAA;AAAA,EAET,WAAA,CACE,OAAA,EACA,IAAA,EACA,UAAA,EACA,SACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAKO,IAAM,mBAAA,GAAN,cAAkC,oBAAA,CAAqB;AAAA,EAC5D,WAAA,CAAY,OAAA,GAAU,4BAAA,EAA8B,SAAA,EAAoB;AACtE,IAAA,KAAA,CAAM,OAAA,EAAS,sBAAA,EAAwB,GAAA,EAAK,MAAA,EAAW,SAAS,CAAA;AAChE,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF;AAKO,IAAM,cAAA,GAAN,cAA6B,oBAAA,CAAqB;AAAA,EAC9C,UAAA;AAAA;AAAA,EAEA,KAAA;AAAA;AAAA,EAEA,SAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EAET,WAAA,CACE,OAAA,GAAU,qBAAA,EACV,UAAA,EACA,WACA,aAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,kBAAA,EAAoB,GAAA,EAAK,MAAA,EAAW,SAAS,CAAA;AAC5D,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,QAAQ,aAAA,EAAe,KAAA;AAC5B,IAAA,IAAA,CAAK,YAAY,aAAA,EAAe,SAAA;AAChC,IAAA,IAAA,CAAK,QAAQ,aAAA,EAAe,KAAA;AAAA,EAC9B;AACF;AAKO,IAAM,eAAA,GAAN,cAA8B,oBAAA,CAAqB;AAAA,EAC/C,MAAA;AAAA,EAET,WAAA,CACE,OAAA,GAAU,mBAAA,EACV,MAAA,EACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,SAAS,kBAAA,EAAoB,GAAA,EAAK,EAAE,MAAA,IAAU,SAAS,CAAA;AAC7D,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AACF;AAKO,IAAM,aAAA,GAAN,cAA4B,oBAAA,CAAqB;AAAA,EAC7C,YAAA;AAAA,EACA,UAAA;AAAA,EAET,WAAA,CACE,OAAA,GAAU,oBAAA,EACV,YAAA,EACA,YACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,SAAS,WAAA,EAAa,GAAA,EAAK,EAAE,YAAA,EAAc,UAAA,IAAc,SAAS,CAAA;AACxE,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AACpB,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAAA,EACpB;AACF;AAKO,IAAM,aAAA,GAAN,cAA4B,oBAAA,CAAqB;AAAA,EACtD,WAAA,CAAY,OAAA,GAAU,mBAAA,EAAqB,SAAA,EAAoB;AAC7D,IAAA,KAAA,CAAM,OAAA,EAAS,UAAA,EAAY,GAAA,EAAK,MAAA,EAAW,SAAS,CAAA;AACpD,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AACF;AAKO,IAAM,WAAA,GAAN,cAA0B,oBAAA,CAAqB;AAAA,EACpD,WAAA,CAAY,OAAA,GAAU,uBAAA,EAAyB,UAAA,GAAa,KAAK,SAAA,EAAoB;AACnF,IAAA,KAAA,CAAM,OAAA,EAAS,cAAA,EAAgB,UAAA,EAAY,MAAA,EAAW,SAAS,CAAA;AAC/D,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AAAA,EACd;AACF;AAKO,IAAM,YAAA,GAAN,cAA2B,oBAAA,CAAqB;AAAA,EACrD,WAAA,CAAY,UAAU,mBAAA,EAAqB;AACzC,IAAA,KAAA,CAAM,SAAS,eAAe,CAAA;AAC9B,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AAAA,EACd;AACF;AAKO,IAAM,YAAA,GAAN,cAA2B,oBAAA,CAAqB;AAAA,EACrD,WAAA,CAAY,UAAU,eAAA,EAAiB;AACrC,IAAA,KAAA,CAAM,SAAS,eAAe,CAAA;AAC9B,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AAAA,EACd;AACF;AASO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,OAAO,KAAA,YAAiB,oBAAA;AAC1B;AAKO,SAAS,sBAAsB,KAAA,EAA8C;AAClF,EAAA,OAAO,KAAA,YAAiB,mBAAA;AAC1B;AAKO,SAAS,iBAAiB,KAAA,EAAyC;AACxE,EAAA,OAAO,KAAA,YAAiB,cAAA;AAC1B;AAKO,SAAS,kBAAkB,KAAA,EAA0C;AAC1E,EAAA,OAAO,KAAA,YAAiB,eAAA;AAC1B;AAKO,SAAS,gBAAgB,KAAA,EAAwC;AACtE,EAAA,OAAO,KAAA,YAAiB,aAAA;AAC1B;AAKO,SAAS,gBAAgB,KAAA,EAAwC;AACtE,EAAA,OAAO,KAAA,YAAiB,aAAA;AAC1B;AAKO,SAAS,cAAc,KAAA,EAAsC;AAClE,EAAA,OAAO,KAAA,YAAiB,WAAA;AAC1B;AAKO,SAAS,eAAe,KAAA,EAAuC;AACpE,EAAA,OAAO,KAAA,YAAiB,YAAA;AAC1B;AAKO,SAAS,eAAe,KAAA,EAAuC;AACpE,EAAA,OAAO,KAAA,YAAiB,YAAA;AAC1B;;;ACZO,IAAM,aAAN,MAAiB;AAAA,EACL,MAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA;AAAA,EAGT,cAAA;AAAA;AAAA,EAEA,cAAA;AAAA,EAER,YAAY,MAAA,EAA0B;AACpC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,KAAA,IAAS,KAAA;AAG/B,IAAA,IAAA,CAAK,WAAA,GAAc;AAAA,MACjB,UAAA,EAAY,MAAA,CAAO,KAAA,EAAO,UAAA,IAAc,MAAA,CAAO,UAAA;AAAA,MAC/C,iBAAA,EAAmB,OAAO,KAAA,EAAO,iBAAA,IAAqB,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAAA,MAC9E,mBAAA,EAAqB,MAAA,CAAO,KAAA,EAAO,mBAAA,IAAuB,IAAA;AAAA,MAC1D,cAAA,EAAgB,MAAA,CAAO,KAAA,EAAO,cAAA,IAAkB,IAAA;AAAA,MAChD,cAAA,EAAgB,MAAA,CAAO,KAAA,EAAO,cAAA,IAAkB,GAAA;AAAA,MAChD,UAAA,EAAY,MAAA,CAAO,KAAA,EAAO,UAAA,IAAc,GAAA;AAAA,MACxC,iBAAA,EAAmB,MAAA,CAAO,KAAA,EAAO,iBAAA,IAAqB,CAAA;AAAA,MACtD,MAAA,EAAQ,MAAA,CAAO,KAAA,EAAO,MAAA,IAAU;AAAA,KAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAA,GAA2C;AAC7C,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAA,GAAoC;AACtC,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAW,OAAA,EAAqC;AACpD,IAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,IAAA,EAAM,QAAQ,KAAK,CAAA;AACrD,IAAA,MAAM,UAAU,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,OAAA,EAAS,QAAQ,cAAc,CAAA;AAEzE,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI,OAAA,GAAU,CAAA;AAEd,IAAA,OAAO,OAAA,IAAW,IAAA,CAAK,WAAA,CAAY,UAAA,EAAY;AAC7C,MAAA,MAAM,cAAA,GAAiC;AAAA,QACrC,QAAQ,OAAA,CAAQ,MAAA;AAAA,QAChB,GAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd;AAAA,OACF;AAEA,MAAA,IAAI;AAEF,QAAA,IAAI,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,SAAA,EAAW;AAChC,UAAA,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,cAAc,CAAA;AAAA,QAClD;AAEA,QAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,QAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,cAAA;AAAA,UAC1B,GAAA;AAAA,UACA,OAAA,CAAQ,MAAA;AAAA,UACR,OAAA;AAAA,UACA,OAAA,CAAQ,IAAA;AAAA,UACR,OAAA,CAAQ;AAAA,SACV;AACA,QAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAEhC,QAAA,MAAM,SAAS,MAAM,IAAA,CAAK,cAAA,CAAkB,QAAA,EAAU,gBAAgB,UAAU,CAAA;AAChF,QAAA,OAAO,MAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,SAAA,GAAY,KAAA;AAGZ,QAAA,IAAI,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,OAAA,EAAS;AAC9B,UAAA,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,OAAA,CAAQ,WAAW,cAAc,CAAA;AAAA,QAC3D;AAGA,QAAA,IAAI,UAAU,IAAA,CAAK,WAAA,CAAY,cAAc,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA,EAAG;AACxE,UAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,cAAA,CAAe,SAAA,EAAW,OAAO,CAAA;AAGpD,UAAA,IAAI,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,OAAA,EAAS;AAC9B,YAAA,MAAM,KAAK,MAAA,CAAO,KAAA,CAAM,OAAA,CAAQ,cAAA,EAAgB,WAAW,KAAK,CAAA;AAAA,UAClE;AAEA,UAAA,MAAM,IAAA,CAAK,MAAM,KAAK,CAAA;AACtB,UAAA,OAAA,EAAA;AACA,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,SAAA;AAAA,MACR;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,IAAa,IAAI,YAAA,CAAa,8BAA8B,CAAA;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAwB,OAAA,EAA4D;AACxF,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA,CAAW,OAAO,CAAA;AAC1C,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,WAAW,IAAA,CAAK,cAAA;AAAA,MAChB,WAAW,IAAA,CAAK;AAAA,KAClB;AAAA,EACF;AAAA,EAEQ,YAAY,KAAA,EAAuB;AAEzC,IAAA,IACE,iBAAiB,mBAAA,IACjB,KAAA,YAAiB,mBACjB,KAAA,YAAiB,aAAA,IACjB,iBAAiB,aAAA,EACjB;AACA,MAAA,OAAO,KAAA;AAAA,IACT;AAGA,IAAA,IAAI,iBAAiB,cAAA,EAAgB;AACnC,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,KAAA,YAAiB,WAAA,IAAe,KAAA,CAAM,UAAA,EAAY;AACpD,MAAA,OAAO,IAAA,CAAK,WAAA,CAAY,iBAAA,CAAkB,QAAA,CAAS,MAAM,UAAU,CAAA;AAAA,IACrE;AAGA,IAAA,IAAI,iBAAiB,YAAA,EAAc;AACjC,MAAA,OAAO,KAAK,WAAA,CAAY,mBAAA;AAAA,IAC1B;AAGA,IAAA,IAAI,iBAAiB,YAAA,EAAc;AACjC,MAAA,OAAO,KAAK,WAAA,CAAY,cAAA;AAAA,IAC1B;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,cAAA,CAAe,OAAc,OAAA,EAAyB;AAE5D,IAAA,IAAI,KAAA,YAAiB,cAAA,IAAkB,KAAA,CAAM,UAAA,EAAY;AACvD,MAAA,OAAO,MAAM,UAAA,GAAa,GAAA;AAAA,IAC5B;AAGA,IAAA,MAAM,SAAA,GAAY,KAAK,WAAA,CAAY,cAAA;AACnC,IAAA,MAAM,QAAQ,IAAA,CAAK,GAAA;AAAA,MACjB,YAAY,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,mBAAmB,OAAO,CAAA;AAAA,MAChE,KAAK,WAAA,CAAY;AAAA,KACnB;AAGA,IAAA,MAAM,SAAS,KAAA,GAAQ,IAAA,CAAK,WAAA,CAAY,MAAA,GAAS,KAAK,MAAA,EAAO;AAC7D,IAAA,OAAO,KAAA,GAAQ,MAAA;AAAA,EACjB;AAAA,EAEQ,QAAA,CAAS,MAAc,KAAA,EAAuE;AACpG,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,IAAA,EAAM,IAAA,CAAK,OAAO,OAAO,CAAA;AAE7C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAChD,QAAA,IAAI,UAAU,MAAA,EAAW;AACvB,UAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAAA,EAEQ,YAAA,CACN,eACA,cAAA,EACwB;AACxB,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,eAAA,EAAiB,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,MAC7C,cAAA,EAAgB,kBAAA;AAAA,MAChB,QAAA,EAAU,kBAAA;AAAA,MACV,GAAG;AAAA,KACL;AAEA,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,OAAA,CAAQ,mBAAmB,CAAA,GAAI,cAAA;AAAA,IACjC;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAc,cAAA,CACZ,GAAA,EACA,MAAA,EACA,OAAA,EACA,MACA,UAAA,EACmB;AACnB,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,SAAA,GAAY,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,IAAA,CAAK,OAAO,OAAO,CAAA;AAG1E,IAAA,MAAM,YAAA,GAAe,MAAM,UAAA,CAAW,KAAA,EAAM;AAC5C,IAAA,UAAA,EAAY,gBAAA,CAAiB,SAAS,YAAY,CAAA;AAElD,IAAA,IAAI;AACF,MAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,QAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAA;AAChD,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,OAAA,CAAQ,IAAI,yBAAA,EAA2B,IAAA,CAAK,UAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,QACtE;AAAA,MACF;AAGA,MAAA,IAAI,YAAY,OAAA,EAAS;AACvB,QAAA,MAAM,IAAI,MAAM,iBAAiB,CAAA;AAAA,MACnC;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK;AAAA,QACvC,MAAA;AAAA,QACA,OAAA;AAAA,QACA,IAAA,EAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,GAAI,KAAA,CAAA;AAAA,QACpC,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAED,MAAA,OAAO,QAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiB,KAAA,EAAO;AAE1B,QAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,UAAA,IAAI,YAAY,OAAA,EAAS;AACvB,YAAA,MAAM,IAAI,aAAa,yBAAyB,CAAA;AAAA,UAClD;AACA,UAAA,MAAM,IAAI,YAAA,CAAa,CAAA,wBAAA,EAA2B,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAA,CAAI,CAAA;AAAA,QAC3E;AACA,QAAA,MAAM,IAAI,YAAA,CAAa,KAAA,CAAM,OAAO,CAAA;AAAA,MACtC;AACA,MAAA,MAAM,IAAI,aAAa,uBAAuB,CAAA;AAAA,IAChD,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,SAAS,CAAA;AACtB,MAAA,UAAA,EAAY,mBAAA,CAAoB,SAAS,YAAY,CAAA;AAAA,IACvD;AAAA,EACF;AAAA,EAEQ,qBAAqB,QAAA,EAA+C;AAC1E,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AACtD,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,uBAAuB,CAAA;AAC9D,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AAEtD,IAAA,IAAI,KAAA,IAAS,aAAa,KAAA,EAAO;AAC/B,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,QAAA,CAAS,KAAA,EAAO,EAAE,CAAA;AAAA,QACzB,SAAA,EAAW,QAAA,CAAS,SAAA,EAAW,EAAE,CAAA;AAAA,QACjC,KAAA,EAAO,QAAA,CAAS,KAAA,EAAO,EAAE;AAAA,OAC3B;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAc,cAAA,CACZ,QAAA,EACA,cAAA,EACA,UAAA,EACY;AACZ,IAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA;AACvD,IAAA,MAAM,MAAA,GAAS,WAAA,EAAa,QAAA,CAAS,kBAAkB,CAAA;AAGvD,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,MAAA;AAC1D,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,oBAAA,CAAqB,QAAQ,CAAA;AAGxD,IAAA,IAAA,CAAK,cAAA,GAAiB,SAAA;AACtB,IAAA,IAAA,CAAK,cAAA,GAAiB,aAAA;AAEtB,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,KAAA,IAAS,SAAA,EAAW;AAClC,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,8BAAA,EAAiC,SAAS,CAAA,CAAE,CAAA;AAAA,IAC1D;AAGA,IAAA,IAAI,QAAA,CAAS,EAAA,IAAM,IAAA,CAAK,MAAA,CAAO,OAAO,UAAA,EAAY;AAChD,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,UAAA,CAAW;AAAA,QACjC,OAAA,EAAS,cAAA;AAAA,QACT,QAAQ,QAAA,CAAS,MAAA;AAAA,QACjB,SAAS,QAAA,CAAS,OAAA;AAAA,QAClB,SAAA;AAAA,QACA,SAAA,EAAW,aAAA;AAAA,QACX;AAAA,OACD,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,SAAS,EAAA,EAAI;AACf,MAAA,IAAI,QAAA,CAAS,MAAA,KAAW,GAAA,IAAO,CAAC,MAAA,EAAQ;AACtC,QAAA,OAAO,MAAA;AAAA,MACT;AACA,MAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,IAC9B;AAGA,IAAA,IAAI,YAA8B,EAAC;AACnC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAI;AACF,QAAA,SAAA,GAAa,MAAM,SAAS,IAAA,EAAK;AAAA,MACnC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,SAAA,CAAU,OAAA,IAAW,SAAA,CAAU,SAAS,QAAA,CAAS,UAAA;AAEjE,IAAA,QAAQ,SAAS,MAAA;AAAQ,MACvB,KAAK,GAAA;AACH,QAAA,MAAM,IAAI,mBAAA,CAAoB,OAAA,EAAS,SAAS,CAAA;AAAA,MAClD,KAAK,GAAA;AAAA,MACL,KAAK,GAAA;AACH,QAAA,MAAM,IAAI,eAAA,CAAgB,OAAA,EAAS,SAAA,CAAU,QAAQ,SAAS,CAAA;AAAA,MAChE,KAAK,GAAA;AACH,QAAA,MAAM,IAAI,aAAA,CAAc,OAAA,EAAS,MAAA,EAAW,QAAW,SAAS,CAAA;AAAA,MAClE,KAAK,GAAA;AACH,QAAA,MAAM,IAAI,aAAA,CAAc,OAAA,EAAS,SAAS,CAAA;AAAA,MAC5C,KAAK,GAAA,EAAK;AACR,QAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AACrD,QAAA,MAAM,IAAI,cAAA;AAAA,UACR,OAAA;AAAA,UACA,UAAA,GAAa,QAAA,CAAS,UAAA,EAAY,EAAE,CAAA,GAAI,MAAA;AAAA,UACxC,SAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,MACA;AACE,QAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,UAAA,MAAM,IAAI,WAAA,CAAY,OAAA,EAAS,QAAA,CAAS,QAAQ,SAAS,CAAA;AAAA,QAC3D;AACA,QAAA,MAAM,IAAI,oBAAA;AAAA,UACR,OAAA;AAAA,UACA,WAAA;AAAA,UACA,QAAA,CAAS,MAAA;AAAA,UACT,SAAA;AAAA,UACA;AAAA,SACF;AAAA;AACJ,EACF;AAAA,EAEQ,MAAM,EAAA,EAA2B;AACvC,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AAAA,EACzD;AACF,CAAA;;;AC/gBO,IAAe,eAAf,MAA4B;AAAA,EACd,IAAA;AAAA,EAEnB,YAAY,IAAA,EAAkB;AAC5B,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AAAA,EAEA,MAAgB,IAAA,CACd,IAAA,EACA,KAAA,EACA,OAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,KAAK,OAAA,CAAW;AAAA,MAC1B,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA;AAAA,MACA,KAAA;AAAA,MACA,QAAQ,OAAA,EAAS;AAAA,KAClB,CAAA;AAAA,EACH;AAAA,EAEA,MAAgB,KAAA,CACd,IAAA,EACA,IAAA,EACA,OAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,KAAK,OAAA,CAAW;AAAA,MAC1B,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA;AAAA,MACA,IAAA;AAAA,MACA,gBAAgB,OAAA,EAAS,cAAA;AAAA,MACzB,OAAO,OAAA,EAAS,KAAA;AAAA,MAChB,QAAQ,OAAA,EAAS;AAAA,KAClB,CAAA;AAAA,EACH;AAAA,EAEA,MAAgB,MAAA,CACd,IAAA,EACA,IAAA,EACA,OAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,KAAK,OAAA,CAAW;AAAA,MAC1B,MAAA,EAAQ,OAAA;AAAA,MACR,IAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAQ,OAAA,EAAS;AAAA,KAClB,CAAA;AAAA,EACH;AAAA,EAEA,MAAgB,IAAA,CACd,IAAA,EACA,IAAA,EACA,OAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,KAAK,OAAA,CAAW;AAAA,MAC1B,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAQ,OAAA,EAAS;AAAA,KAClB,CAAA;AAAA,EACH;AAAA,EAEA,MAAgB,OAAA,CACd,IAAA,EACA,KAAA,EACA,OAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,KAAK,OAAA,CAAW;AAAA,MAC1B,MAAA,EAAQ,QAAA;AAAA,MACR,IAAA;AAAA,MACA,KAAA;AAAA,MACA,QAAQ,OAAA,EAAS;AAAA,KAClB,CAAA;AAAA,EACH;AACF,CAAA;;;ACtFO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAIjD,MAAM,EAAA,GAAuB;AAC3B,IAAA,OAAO,IAAA,CAAK,KAAc,cAAc,CAAA;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,GAAkC;AACtC,IAAA,OAAO,IAAA,CAAK,KAAmB,oBAAoB,CAAA;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAA,GAAiC;AACrC,IAAA,OAAO,IAAA,CAAK,KAAe,uBAAuB,CAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,IAAA,EAAoD;AACrE,IAAA,OAAO,IAAA,CAAK,KAAA,CAAwB,uBAAA,EAAyB,IAAI,CAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAA,CACJ,KAAA,EACA,IAAA,EAC+B;AAC/B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,MACV,yBAAyB,KAAK,CAAA,MAAA,CAAA;AAAA,MAC9B;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,KAAA,EAA8B;AAC/C,IAAA,MAAM,IAAA,CAAK,OAAA,CAAc,CAAA,sBAAA,EAAyB,KAAK,CAAA,CAAE,CAAA;AAAA,EAC3D;AACF,CAAA;;;AC1DO,IAAM,cAAA,GAAN,cAA6B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAI/C,MAAM,OAAO,IAAA,EAAwC;AACnD,IAAA,OAAO,IAAA,CAAK,KAAA,CAAa,SAAA,EAAW,IAAI,CAAA;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,GAAyB;AAC7B,IAAA,OAAO,IAAA,CAAK,KAAc,SAAS,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,OAAA,EAAiC;AACzC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAY,CAAA,QAAA,EAAW,OAAO,CAAA,CAAE,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,IAAA,EAAwC;AACpE,IAAA,OAAO,IAAA,CAAK,MAAA,CAAc,CAAA,QAAA,EAAW,OAAO,IAAI,IAAI,CAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAA,CAAO,OAAA,EAAiB,OAAA,GAAU,IAAA,EAA0C;AAChF,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,IAAA,CAAK,QAAc,CAAA,QAAA,EAAW,OAAO,IAAI,EAAE,OAAA,EAAS,MAAM,CAAA;AAChE,MAAA;AAAA,IACF;AACA,IAAA,OAAO,IAAA,CAAK,OAAA,CAA4B,CAAA,QAAA,EAAW,OAAO,CAAA,CAAE,CAAA;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,OAAA,EAAmD;AACjE,IAAA,OAAO,IAAA,CAAK,IAAA,CAA8B,CAAA,QAAA,EAAW,OAAO,CAAA,OAAA,CAAS,CAAA;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAA,CAAa,OAAA,EAAiB,MAAA,EAAmE;AACrG,IAAA,OAAO,IAAA,CAAK,IAAA,CAA8B,CAAA,QAAA,EAAW,OAAO,WAAW,MAAM,CAAA;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,eAAA,CAAgB,OAAA,EAAiB,MAAA,GAAS,6BAAA,EAAuC;AAC/E,IAAA,OAAO,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAAA,EAC7B;AACF,CAAA;;;ACrEO,IAAM,eAAA,GAAN,cAA8B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAIhD,MAAM,MAAA,CACJ,OAAA,EACA,IAAA,EACA,OAAA,EACiB;AACjB,IAAA,OAAO,IAAA,CAAK,KAAA,CAAc,CAAA,QAAA,EAAW,OAAO,YAAY,IAAA,EAAM;AAAA,MAC5D,gBAAgB,OAAA,EAAS;AAAA,KAC1B,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,IAAA,CACL,OAAA,EACA,OAAA,EACuB;AACvB,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,OAAO,OAAA,EAAS;AACd,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,QAAA,CAAS,SAAS,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,CAAA;AAChE,MAAA,KAAA,MAAW,MAAA,IAAU,KAAK,IAAA,EAAM;AAC9B,QAAA,MAAM,MAAA;AAAA,MACR;AACA,MAAA,MAAA,GAAS,KAAK,UAAA,CAAW,MAAA;AACzB,MAAA,OAAA,GAAU,KAAK,UAAA,CAAW,OAAA;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,CACJ,OAAA,EACA,OAAA,EACoC;AACpC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,cAAA,CAAe,OAAO,CAAA;AACzC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAgC,CAAA,QAAA,EAAW,OAAO,YAAY,KAAK,CAAA;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CAAI,OAAA,EAAiB,QAAA,EAAmC;AAC5D,IAAA,OAAO,KAAK,IAAA,CAAa,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,CAAA,CAAE,CAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,QAAA,EACA,IAAA,EACiB;AACjB,IAAA,OAAO,KAAK,MAAA,CAAe,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,IAAI,IAAI,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,QAAA,EAAmC;AAC/D,IAAA,OAAO,KAAK,OAAA,CAAgB,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,CAAA,CAAE,CAAA;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,CAAW,OAAA,EAAiB,QAAA,EAAkB,MAAA,EAAkC;AACpF,IAAA,OAAO,IAAA,CAAK,MAAc,CAAA,QAAA,EAAW,OAAO,YAAY,QAAQ,CAAA,KAAA,CAAA,EAAS,EAAE,MAAA,EAAQ,CAAA;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,CACJ,OAAA,EACA,cAAA,EACA,eAAA,EACiB;AACjB,IAAA,OAAO,KAAK,KAAA,CAAc,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,cAAc,CAAA,MAAA,CAAA,EAAU;AAAA,MAC9E;AAAA,KAC2B,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,CACJ,OAAA,EACA,MAAA,EACA,WACA,OAAA,EAK2B;AAC3B,IAAA,OAAO,IAAA,CAAK,KAAA,CAAwB,CAAA,QAAA,EAAW,OAAO,CAAA,aAAA,CAAA,EAAiB;AAAA,MACrE,MAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAG;AAAA,KACJ,CAAA;AAAA,EACH;AAAA,EAEQ,eACN,OAAA,EACuD;AACvD,IAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAC;AAEtB,IAAA,MAAM,QAA+D,EAAC;AAEtE,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,KAAA,CAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,GACvC,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,GACvB,OAAA,CAAQ,MAAA;AAAA,IACd;AACA,IAAA,IAAI,OAAA,CAAQ,QAAA,EAAU,KAAA,CAAM,QAAA,GAAW,OAAA,CAAQ,QAAA;AAC/C,IAAA,IAAI,OAAA,CAAQ,UAAA,EAAY,KAAA,CAAM,UAAA,GAAa,OAAA,CAAQ,UAAA;AACnD,IAAA,IAAI,OAAA,CAAQ,UAAA,EAAY,KAAA,CAAM,UAAA,GAAa,OAAA,CAAQ,UAAA;AACnD,IAAA,IAAI,OAAA,CAAQ,aAAA,EAAe,KAAA,CAAM,aAAA,GAAgB,OAAA,CAAQ,aAAA;AACzD,IAAA,IAAI,OAAA,CAAQ,SAAA,EAAW,KAAA,CAAM,SAAA,GAAY,OAAA,CAAQ,SAAA;AACjD,IAAA,IAAI,OAAA,CAAQ,YAAA,EAAc,KAAA,CAAM,YAAA,GAAe,OAAA,CAAQ,YAAA;AACvD,IAAA,IAAI,OAAA,CAAQ,aAAA,EAAe,KAAA,CAAM,aAAA,GAAgB,OAAA,CAAQ,aAAA;AACzD,IAAA,IAAI,OAAA,CAAQ,cAAA,KAAmB,MAAA,EAAW,KAAA,CAAM,iBAAiB,OAAA,CAAQ,cAAA;AACzE,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,IAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,KAAA,CAAM,MAAA,GAAS,OAAA,CAAQ,MAAA;AAC3C,IAAA,IAAI,OAAA,CAAQ,UAAA,EAAY,KAAA,CAAM,UAAA,GAAa,OAAA,CAAQ,UAAA;AACnD,IAAA,IAAI,QAAQ,MAAA,EAAQ,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA,CAAO,KAAK,GAAG,CAAA;AAC1D,IAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,KAAA,CAAM,MAAA,GAAS,OAAA,CAAQ,MAAA;AAC3C,IAAA,IAAI,OAAA,CAAQ,IAAA,EAAM,KAAA,CAAM,IAAA,GAAO,OAAA,CAAQ,IAAA;AACvC,IAAA,IAAI,OAAA,CAAQ,KAAA,EAAO,KAAA,CAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA;AACzC,IAAA,IAAI,OAAA,CAAQ,KAAA,EAAO,KAAA,CAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA;AACzC,IAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,KAAA,CAAM,MAAA,GAAS,OAAA,CAAQ,MAAA;AAE3C,IAAA,OAAO,KAAA;AAAA,EACT;AACF,CAAA;;;ACnJO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAIjD,MAAM,MAAA,CACJ,OAAA,EACA,QAAA,EACA,MACA,OAAA,EACkB;AAClB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,CAAA,SAAA,CAAA;AAAA,MACtC,IAAA;AAAA,MACA,EAAE,cAAA,EAAgB,OAAA,EAAS,cAAA;AAAe,KAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,CAAK,OAAA,EAAiB,QAAA,EAAsC;AAChE,IAAA,OAAO,KAAK,IAAA,CAAgB,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,CAAA,SAAA,CAAW,CAAA;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CAAI,OAAA,EAAiB,QAAA,EAAkB,SAAA,EAAqC;AAChF,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,aAAa,SAAS,CAAA;AAAA,KAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,QAAA,EACA,WACA,IAAA,EACkB;AAClB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,aAAa,SAAS,CAAA,CAAA;AAAA,MAC5D;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,QAAA,EAAkB,SAAA,EAAqC;AACnF,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,aAAa,SAAS,CAAA;AAAA,KAC9D;AAAA,EACF;AACF,CAAA;;;ACxDO,IAAM,mBAAA,GAAN,cAAkC,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAIpD,MAAM,cAAA,CACJ,OAAA,EACA,QAAA,EACA,IAAA,EACiC;AACjC,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,CAAA,YAAA,CAAA;AAAA,MACtC;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CACJ,OAAA,EACA,QAAA,EACA,YAAA,EACqB;AACrB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,gBAAgB,YAAY,CAAA,QAAA;AAAA,KACpE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,CAAK,OAAA,EAAiB,QAAA,EAAyC;AACnE,IAAA,OAAO,KAAK,IAAA,CAAmB,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,CAAA,YAAA,CAAc,CAAA;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CACJ,OAAA,EACA,QAAA,EACA,YAAA,EAC4B;AAC5B,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,gBAAgB,YAAY,CAAA;AAAA,KACpE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,QAAA,EACA,YAAA,EACe;AACf,IAAA,MAAM,IAAA,CAAK,OAAA;AAAA,MACT,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,EAAY,QAAQ,gBAAgB,YAAY,CAAA;AAAA,KACpE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CACJ,OAAA,EACA,QAAA,EACA,IAAA,EACA,UACA,WAAA,EACqB;AAErB,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,MAAA,IAAA,GAAO,IAAA,CAAK,IAAA;AAAA,IACd,CAAA,MAAA,IAAW,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,EAAG;AAChC,MAAA,IAAA,GAAO,IAAA,CAAK,MAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,IAAA,GAAO,IAAA,CAAK,UAAA;AAAA,IACd;AAGA,IAAA,MAAM,EAAE,WAAW,YAAA,EAAa,GAAI,MAAM,IAAA,CAAK,cAAA,CAAe,SAAS,QAAA,EAAU;AAAA,MAC/E,QAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACD,CAAA;AAGD,IAAA,MAAM,cAAA,GAAiB,MAAM,KAAA,CAAM,SAAA,EAAW;AAAA,MAC5C,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,WAAA;AAAA,QAChB,gBAAA,EAAkB,OAAO,IAAI;AAAA,OAC/B;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAED,IAAA,IAAI,CAAC,eAAe,EAAA,EAAI;AACtB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,cAAA,CAAe,UAAU,CAAA,CAAE,CAAA;AAAA,IAC/D;AAGA,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,OAAA,EAAS,QAAA,EAAU,YAAY,CAAA;AAAA,EAC3D;AACF,CAAA;;;AC/GO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAIjD,MAAM,MAAA,CAAO,OAAA,EAAiB,IAAA,EAA4C;AACxE,IAAA,OAAO,IAAA,CAAK,KAAA,CAAe,CAAA,QAAA,EAAW,OAAO,aAAa,IAAI,CAAA;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,OAAA,EAAqC;AAC9C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAgB,CAAA,QAAA,EAAW,OAAO,CAAA,SAAA,CAAW,CAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CAAI,OAAA,EAAiB,SAAA,EAAqC;AAC9D,IAAA,OAAO,KAAK,IAAA,CAAc,CAAA,QAAA,EAAW,OAAO,CAAA,UAAA,EAAa,SAAS,CAAA,CAAE,CAAA;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,SAAA,EAAkC;AAC9D,IAAA,MAAM,KAAK,OAAA,CAAc,CAAA,QAAA,EAAW,OAAO,CAAA,UAAA,EAAa,SAAS,CAAA,CAAE,CAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CAAc,OAAA,EAAiB,SAAA,EAA+C;AAClF,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,UAAA,EAAa,SAAS,CAAA,WAAA;AAAA,KAC1C;AAAA,EACF;AACF,CAAA;;;AChCO,IAAM,kBAAA,GAAN,cAAiC,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAInD,MAAM,MAAA,CAAO,OAAA,EAAiB,IAAA,EAA8C;AAC1E,IAAA,OAAO,IAAA,CAAK,KAAA,CAAgB,CAAA,QAAA,EAAW,OAAO,eAAe,IAAI,CAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,OAAA,EAAsC;AAC/C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAiB,CAAA,QAAA,EAAW,OAAO,CAAA,WAAA,CAAa,CAAA;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CAAI,OAAA,EAAiB,UAAA,EAAuC;AAChE,IAAA,OAAO,KAAK,IAAA,CAAe,CAAA,QAAA,EAAW,OAAO,CAAA,YAAA,EAAe,UAAU,CAAA,CAAE,CAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,UAAA,EACA,IAAA,EACmB;AACnB,IAAA,OAAO,KAAK,MAAA,CAAiB,CAAA,QAAA,EAAW,OAAO,CAAA,YAAA,EAAe,UAAU,IAAI,IAAI,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,UAAA,EAAmC;AAC/D,IAAA,MAAM,KAAK,OAAA,CAAc,CAAA,QAAA,EAAW,OAAO,CAAA,YAAA,EAAe,UAAU,CAAA,CAAE,CAAA;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,OAAA,EAAyC;AACtD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAoB,CAAA,QAAA,EAAW,OAAO,CAAA,iBAAA,CAAmB,CAAA;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,CAAQ,OAAA,EAAiB,WAAA,EAAsC;AACnE,IAAA,MAAM,KAAK,KAAA,CAAY,CAAA,QAAA,EAAW,OAAO,CAAA,mBAAA,CAAA,EAAuB,EAAE,aAAa,CAAA;AAAA,EACjF;AACF,CAAA;;;AC1DO,IAAM,YAAA,GAAN,cAA2B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAI7C,MAAM,MAAA,CAAO,OAAA,EAAiB,IAAA,EAAoC;AAChE,IAAA,OAAO,IAAA,CAAK,KAAA,CAAW,CAAA,QAAA,EAAW,OAAO,SAAS,IAAI,CAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,OAAA,EAAiC;AAC1C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAY,CAAA,QAAA,EAAW,OAAO,CAAA,KAAA,CAAO,CAAA;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,KAAA,EAAe,IAAA,EAAoC;AAC/E,IAAA,OAAO,KAAK,MAAA,CAAY,CAAA,QAAA,EAAW,OAAO,CAAA,MAAA,EAAS,KAAK,IAAI,IAAI,CAAA;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,KAAA,EAA8B;AAC1D,IAAA,MAAM,KAAK,OAAA,CAAc,CAAA,QAAA,EAAW,OAAO,CAAA,MAAA,EAAS,KAAK,CAAA,CAAE,CAAA;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,CAAM,OAAA,EAAiB,WAAA,EAAqB,YAAA,EAAsC;AACtF,IAAA,OAAO,KAAK,KAAA,CAAW,CAAA,QAAA,EAAW,OAAO,CAAA,MAAA,EAAS,WAAW,CAAA,MAAA,CAAA,EAAU;AAAA,MACrE;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAA;;;AC/BO,IAAM,iBAAA,GAAN,cAAgC,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAIlD,MAAM,MAAA,CAAO,OAAA,EAAiB,IAAA,EAA8C;AAC1E,IAAA,OAAO,IAAA,CAAK,KAAA,CAAgB,CAAA,QAAA,EAAW,OAAO,cAAc,IAAI,CAAA;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,IAAA,CACL,OAAA,EACA,OAAA,EACyB;AACzB,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,OAAO,OAAA,EAAS;AACd,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,QAAA,CAAS,SAAS,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,CAAA;AAChE,MAAA,KAAA,MAAW,QAAA,IAAY,KAAK,IAAA,EAAM;AAChC,QAAA,MAAM,QAAA;AAAA,MACR;AACA,MAAA,MAAA,GAAS,KAAK,UAAA,CAAW,MAAA;AACzB,MAAA,OAAA,GAAU,KAAK,UAAA,CAAW,OAAA;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,CACJ,OAAA,EACA,OAAA,EACsC;AACtC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,cAAA,CAAe,OAAO,CAAA;AACzC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAkC,CAAA,QAAA,EAAW,OAAO,cAAc,KAAK,CAAA;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,KAAA,EAAoC;AAChE,IAAA,OAAO,IAAA,CAAK,KAAiB,CAAA,QAAA,EAAW,OAAO,qBAAqB,EAAE,CAAA,EAAG,OAAO,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CAAI,OAAA,EAAiB,UAAA,EAAuC;AAChE,IAAA,OAAO,KAAK,IAAA,CAAe,CAAA,QAAA,EAAW,OAAO,CAAA,WAAA,EAAc,UAAU,CAAA,CAAE,CAAA;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,UAAA,EACA,IAAA,EACmB;AACnB,IAAA,OAAO,KAAK,MAAA,CAAiB,CAAA,QAAA,EAAW,OAAO,CAAA,WAAA,EAAc,UAAU,IAAI,IAAI,CAAA;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,UAAA,EAAuC;AACnE,IAAA,OAAO,KAAK,OAAA,CAAkB,CAAA,QAAA,EAAW,OAAO,CAAA,WAAA,EAAc,UAAU,CAAA,CAAE,CAAA;AAAA,EAC5E;AAAA,EAEQ,eACN,OAAA,EACuD;AACvD,IAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAC;AAEtB,IAAA,MAAM,QAA+D,EAAC;AAEtE,IAAA,IAAI,OAAA,CAAQ,KAAA,EAAO,KAAA,CAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA;AACzC,IAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,KAAA,CAAM,MAAA,GAAS,OAAA,CAAQ,MAAA;AAC3C,IAAA,IAAI,OAAA,CAAQ,IAAA,EAAM,KAAA,CAAM,IAAA,GAAO,OAAA,CAAQ,IAAA;AACvC,IAAA,IAAI,OAAA,CAAQ,KAAA,EAAO,KAAA,CAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA;AAEzC,IAAA,OAAO,KAAA;AAAA,EACT;AACF,CAAA;;;ACrFO,IAAM,cAAA,GAAN,cAA6B,YAAA,CAAa;AAAA;AAAA;AAAA;AAAA,EAI/C,MAAM,OAAO,OAAA,EAA4C;AACvD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAuB,CAAA,QAAA,EAAW,OAAO,CAAA,OAAA,CAAS,CAAA;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,CAAK,OAAA,EAAiB,UAAA,EAAoD;AAC9E,IAAA,OAAO,KAAK,IAAA,CAAwB,CAAA,QAAA,EAAW,OAAO,CAAA,QAAA,EAAW,UAAU,CAAA,CAAE,CAAA;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,UAAA,EACA,IAAA,EAC0B;AAC1B,IAAA,OAAO,KAAK,KAAA,CAAuB,CAAA,QAAA,EAAW,OAAO,CAAA,QAAA,EAAW,UAAU,IAAI,IAAI,CAAA;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,UAAA,EACA,KACA,IAAA,EAC0B;AAC1B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,MACV,CAAA,QAAA,EAAW,OAAO,CAAA,QAAA,EAAW,UAAU,IAAI,GAAG,CAAA,CAAA;AAAA,MAC9C;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CAAO,OAAA,EAAiB,UAAA,EAAwB,GAAA,EAA4B;AAChF,IAAA,MAAM,IAAA,CAAK,QAAc,CAAA,QAAA,EAAW,OAAO,WAAW,UAAU,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,CAAQ,OAAA,EAAiB,UAAA,EAAwB,IAAA,EAA+B;AACpF,IAAA,MAAM,IAAA,CAAK,MAAY,CAAA,QAAA,EAAW,OAAO,WAAW,UAAU,CAAA,QAAA,CAAA,EAAY,EAAE,IAAA,EAAM,CAAA;AAAA,EACpF;AACF,CAAA;AC7DO,IAAM,YAAA,GAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6B1B,eAAA,CAAgB,OAAA,EAAiB,SAAA,EAAmB,MAAA,EAAyB;AAC3E,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,MAAA,EAAQ;AACzB,MAAA,OAAO,KAAA;AAAA,IACT;AAGA,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA;AACjC,IAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,CAAC,MAAM,QAAA,EAAU;AAC/C,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,iBAAA,GAAoB,MAAM,CAAC,CAAA;AACjC,IAAA,MAAM,iBAAA,GAAoBA,kBAAW,QAAA,EAAU,MAAM,EAClD,MAAA,CAAO,OAAO,CAAA,CACd,MAAA,CAAO,KAAK,CAAA;AAGf,IAAA,IAAI;AACF,MAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,iBAAA,EAAmB,KAAK,CAAA;AAC3D,MAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,iBAAA,EAAmB,KAAK,CAAA;AAE3D,MAAA,IAAI,cAAA,CAAe,MAAA,KAAW,cAAA,CAAe,MAAA,EAAQ;AACnD,QAAA,OAAO,KAAA;AAAA,MACT;AAEA,MAAA,OAAOC,sBAAA,CAAgB,gBAAgB,cAAc,CAAA;AAAA,IACvD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,iBAAA,CAAkB,SAAiB,MAAA,EAAwB;AACzD,IAAA,MAAM,SAAA,GAAYD,kBAAW,QAAA,EAAU,MAAM,EAC1C,MAAA,CAAO,OAAO,CAAA,CACd,MAAA,CAAO,KAAK,CAAA;AACf,IAAA,OAAO,UAAU,SAAS,CAAA,CAAA;AAAA,EAC5B;AACF;;;AC6HO,IAAM,kBAAN,MAAsB;AAAA,EACV,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBR,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,WAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,UAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBT,OAAgB,QAAA,GAAW,YAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAe3B,YAAY,MAAA,EAA+B;AACzC,IAAA,IAAI,CAAC,OAAO,MAAA,EAAQ;AAClB,MAAA,MAAM,IAAI,MAAM,qBAAqB,CAAA;AAAA,IACvC;AAEA,IAAA,MAAM,UAAA,GAA+B;AAAA,MACnC,OAAA,EAAS,OAAO,OAAA,IAAW,8CAAA;AAAA,MAC3B,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,OAAA,EAAS,OAAO,OAAA,IAAW,GAAA;AAAA,MAC3B,UAAA,EAAY,MAAA,CAAO,UAAA,IAAc,MAAA,CAAO,OAAO,UAAA,IAAc,CAAA;AAAA,MAC7D,KAAA,EAAO,OAAO,KAAA,IAAS,KAAA;AAAA,MACvB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,OAAO,MAAA,CAAO;AAAA,KAChB;AAEA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,UAAA,CAAW,UAAU,CAAA;AAGrC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AAC9C,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,QAAA,GAAW,IAAI,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AAC9C,IAAA,IAAA,CAAK,WAAA,GAAc,IAAI,mBAAA,CAAoB,IAAA,CAAK,IAAI,CAAA;AACpD,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AAC9C,IAAA,IAAA,CAAK,UAAA,GAAa,IAAI,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA;AAClD,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AACtC,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;AAAA,EAC5C;AACF;;;AC9UO,SAAS,qBAAqB,KAAA,EAAkD;AACrF,EAAA,OAAO,MAAM,KAAA,KAAU,gBAAA;AACzB;AAKO,SAAS,qBAAqB,KAAA,EAAkD;AACrF,EAAA,OAAO,MAAM,KAAA,KAAU,gBAAA;AACzB;AAKO,SAAS,sBAAsB,KAAA,EAAmD;AACvF,EAAA,OAAO,MAAM,KAAA,KAAU,wBAAA;AACzB;AAsBO,SAAS,kBAAkB,OAAA,EAAwC;AACxE,EAAA,MAAM,QAAQ,OAAO,OAAA,KAAY,WAAW,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA,GAAI,OAAA;AAElE,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA,MAAM,IAAI,MAAM,0CAA0C,CAAA;AAAA,EAC5D;AAEA,EAAA,IAAI,CAAC,KAAA,CAAM,KAAA,IAAS,OAAO,KAAA,CAAM,UAAU,QAAA,EAAU;AACnD,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC/D;AAEA,EAAA,IAAI,CAAC,KAAA,CAAM,EAAA,IAAM,OAAO,KAAA,CAAM,OAAO,QAAA,EAAU;AAC7C,IAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,EAC7D;AAEA,EAAA,IAAI,CAAC,KAAA,CAAM,IAAA,IAAQ,OAAO,KAAA,CAAM,SAAS,QAAA,EAAU;AACjD,IAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,EACzD;AAEA,EAAA,MAAM,WAAA,GAAkC,CAAC,gBAAA,EAAkB,gBAAA,EAAkB,wBAAwB,CAAA;AACrG,EAAA,IAAI,CAAC,WAAA,CAAY,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA,EAAG;AACtC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgD,KAAA,CAAM,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,EAChF;AAEA,EAAA,OAAO,KAAA;AACT;;;AC1HA,eAAsB,WAAc,QAAA,EAA0C;AAC5E,EAAA,MAAM,QAAa,EAAC;AACpB,EAAA,WAAA,MAAiB,QAAQ,QAAA,EAAU;AACjC,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EACjB;AACA,EAAA,OAAO,KAAA;AACT","file":"index.cjs","sourcesContent":["/**\n * Base error class for all Dispatch Tickets SDK errors\n */\nexport class DispatchTicketsError extends Error {\n readonly code: string;\n readonly statusCode?: number;\n readonly details?: Record<string, unknown>;\n /** Request ID for debugging with support */\n readonly requestId?: string;\n\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message);\n this.name = 'DispatchTicketsError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n this.requestId = requestId;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when API key is missing or invalid\n */\nexport class AuthenticationError extends DispatchTicketsError {\n constructor(message = 'Invalid or missing API key', requestId?: string) {\n super(message, 'authentication_error', 401, undefined, requestId);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown when rate limit is exceeded\n */\nexport class RateLimitError extends DispatchTicketsError {\n readonly retryAfter?: number;\n /** Rate limit ceiling */\n readonly limit?: number;\n /** Remaining requests in current window */\n readonly remaining?: number;\n /** Unix timestamp when rate limit resets */\n readonly reset?: number;\n\n constructor(\n message = 'Rate limit exceeded',\n retryAfter?: number,\n requestId?: string,\n rateLimitInfo?: { limit?: number; remaining?: number; reset?: number }\n ) {\n super(message, 'rate_limit_error', 429, undefined, requestId);\n this.name = 'RateLimitError';\n this.retryAfter = retryAfter;\n this.limit = rateLimitInfo?.limit;\n this.remaining = rateLimitInfo?.remaining;\n this.reset = rateLimitInfo?.reset;\n }\n}\n\n/**\n * Thrown when request validation fails\n */\nexport class ValidationError extends DispatchTicketsError {\n readonly errors?: Array<{ field: string; message: string }>;\n\n constructor(\n message = 'Validation failed',\n errors?: Array<{ field: string; message: string }>,\n requestId?: string\n ) {\n super(message, 'validation_error', 400, { errors }, requestId);\n this.name = 'ValidationError';\n this.errors = errors;\n }\n}\n\n/**\n * Thrown when a resource is not found\n */\nexport class NotFoundError extends DispatchTicketsError {\n readonly resourceType?: string;\n readonly resourceId?: string;\n\n constructor(\n message = 'Resource not found',\n resourceType?: string,\n resourceId?: string,\n requestId?: string\n ) {\n super(message, 'not_found', 404, { resourceType, resourceId }, requestId);\n this.name = 'NotFoundError';\n this.resourceType = resourceType;\n this.resourceId = resourceId;\n }\n}\n\n/**\n * Thrown when there's a conflict (e.g., duplicate resource)\n */\nexport class ConflictError extends DispatchTicketsError {\n constructor(message = 'Resource conflict', requestId?: string) {\n super(message, 'conflict', 409, undefined, requestId);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Thrown when the server returns an unexpected error\n */\nexport class ServerError extends DispatchTicketsError {\n constructor(message = 'Internal server error', statusCode = 500, requestId?: string) {\n super(message, 'server_error', statusCode, undefined, requestId);\n this.name = 'ServerError';\n }\n}\n\n/**\n * Thrown when request times out\n */\nexport class TimeoutError extends DispatchTicketsError {\n constructor(message = 'Request timed out') {\n super(message, 'timeout_error');\n this.name = 'TimeoutError';\n }\n}\n\n/**\n * Thrown when network connection fails\n */\nexport class NetworkError extends DispatchTicketsError {\n constructor(message = 'Network error') {\n super(message, 'network_error');\n this.name = 'NetworkError';\n }\n}\n\n// ============================================\n// Type Guards\n// ============================================\n\n/**\n * Check if an error is a DispatchTicketsError\n */\nexport function isDispatchTicketsError(error: unknown): error is DispatchTicketsError {\n return error instanceof DispatchTicketsError;\n}\n\n/**\n * Check if an error is an AuthenticationError\n */\nexport function isAuthenticationError(error: unknown): error is AuthenticationError {\n return error instanceof AuthenticationError;\n}\n\n/**\n * Check if an error is a RateLimitError\n */\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return error instanceof RateLimitError;\n}\n\n/**\n * Check if an error is a ValidationError\n */\nexport function isValidationError(error: unknown): error is ValidationError {\n return error instanceof ValidationError;\n}\n\n/**\n * Check if an error is a NotFoundError\n */\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return error instanceof NotFoundError;\n}\n\n/**\n * Check if an error is a ConflictError\n */\nexport function isConflictError(error: unknown): error is ConflictError {\n return error instanceof ConflictError;\n}\n\n/**\n * Check if an error is a ServerError\n */\nexport function isServerError(error: unknown): error is ServerError {\n return error instanceof ServerError;\n}\n\n/**\n * Check if an error is a TimeoutError\n */\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError;\n}\n\n/**\n * Check if an error is a NetworkError\n */\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError;\n}\n","import {\n DispatchTicketsError,\n AuthenticationError,\n RateLimitError,\n ValidationError,\n NotFoundError,\n ConflictError,\n ServerError,\n TimeoutError,\n NetworkError,\n} from '../errors.js';\n\n/**\n * Custom fetch function type\n */\nexport type FetchFunction = typeof fetch;\n\n/**\n * Request context passed to hooks\n */\nexport interface RequestContext {\n /** HTTP method */\n method: string;\n /** Full URL being requested */\n url: string;\n /** Request headers */\n headers: Record<string, string>;\n /** Request body (if any) */\n body?: unknown;\n /** Retry attempt number (0 = first attempt) */\n attempt: number;\n}\n\n/**\n * Response context passed to hooks\n */\nexport interface ResponseContext {\n /** The request that was made */\n request: RequestContext;\n /** HTTP status code */\n status: number;\n /** Response headers */\n headers: Headers;\n /** Request ID from server */\n requestId?: string;\n /** Rate limit info from server */\n rateLimit?: RateLimitInfo;\n /** Duration of the request in milliseconds */\n durationMs: number;\n}\n\n/**\n * Retry configuration options\n */\nexport interface RetryConfig {\n /**\n * Maximum number of retry attempts\n * @default 3\n */\n maxRetries?: number;\n\n /**\n * HTTP status codes that should trigger a retry\n * @default [429, 500, 502, 503, 504]\n */\n retryableStatuses?: number[];\n\n /**\n * Whether to retry on network errors\n * @default true\n */\n retryOnNetworkError?: boolean;\n\n /**\n * Whether to retry on timeout errors\n * @default true\n */\n retryOnTimeout?: boolean;\n\n /**\n * Initial delay between retries in milliseconds\n * @default 1000\n */\n initialDelayMs?: number;\n\n /**\n * Maximum delay between retries in milliseconds\n * @default 30000\n */\n maxDelayMs?: number;\n\n /**\n * Multiplier for exponential backoff\n * @default 2\n */\n backoffMultiplier?: number;\n\n /**\n * Jitter factor (0-1) to add randomness to delays\n * @default 0.25\n */\n jitter?: number;\n}\n\n/**\n * Hooks for observability and customization\n */\nexport interface Hooks {\n /**\n * Called before each request is sent\n * Can modify the request or throw to abort\n */\n onRequest?: (context: RequestContext) => void | Promise<void>;\n\n /**\n * Called after each successful response\n */\n onResponse?: (context: ResponseContext) => void | Promise<void>;\n\n /**\n * Called when an error occurs (before retry)\n */\n onError?: (error: Error, context: RequestContext) => void | Promise<void>;\n\n /**\n * Called before each retry attempt\n */\n onRetry?: (context: RequestContext, error: Error, delayMs: number) => void | Promise<void>;\n}\n\nexport interface HttpClientConfig {\n baseUrl: string;\n apiKey: string;\n timeout: number;\n maxRetries: number;\n debug?: boolean;\n /**\n * Custom fetch implementation for testing/mocking\n */\n fetch?: FetchFunction;\n /**\n * Fine-grained retry configuration\n */\n retry?: RetryConfig;\n /**\n * Hooks for observability\n */\n hooks?: Hooks;\n}\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n path: string;\n body?: unknown;\n query?: Record<string, string | number | boolean | undefined>;\n headers?: Record<string, string>;\n idempotencyKey?: string;\n /**\n * AbortSignal to cancel the request\n */\n signal?: AbortSignal;\n}\n\ninterface ApiErrorResponse {\n message?: string;\n error?: string;\n errors?: Array<{ field: string; message: string }>;\n code?: string;\n}\n\n/**\n * Rate limit information from response headers\n */\nexport interface RateLimitInfo {\n /** Maximum requests allowed in the current window */\n limit: number;\n /** Remaining requests in the current window */\n remaining: number;\n /** Unix timestamp (seconds) when the rate limit resets */\n reset: number;\n}\n\n/**\n * Response wrapper with rate limit info\n */\nexport interface ResponseWithRateLimit<T> {\n data: T;\n rateLimit?: RateLimitInfo;\n requestId?: string;\n}\n\n/**\n * HTTP client with retry logic, hooks, and error handling\n */\nexport class HttpClient {\n private readonly config: HttpClientConfig;\n private readonly fetchFn: FetchFunction;\n private readonly retryConfig: Required<RetryConfig>;\n\n /** Rate limit info from the last response */\n private _lastRateLimit?: RateLimitInfo;\n /** Request ID from the last response */\n private _lastRequestId?: string;\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n this.fetchFn = config.fetch ?? fetch;\n\n // Merge retry config with defaults\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? config.maxRetries,\n retryableStatuses: config.retry?.retryableStatuses ?? [429, 500, 502, 503, 504],\n retryOnNetworkError: config.retry?.retryOnNetworkError ?? true,\n retryOnTimeout: config.retry?.retryOnTimeout ?? true,\n initialDelayMs: config.retry?.initialDelayMs ?? 1000,\n maxDelayMs: config.retry?.maxDelayMs ?? 30000,\n backoffMultiplier: config.retry?.backoffMultiplier ?? 2,\n jitter: config.retry?.jitter ?? 0.25,\n };\n }\n\n /**\n * Get rate limit info from the last response\n */\n get lastRateLimit(): RateLimitInfo | undefined {\n return this._lastRateLimit;\n }\n\n /**\n * Get request ID from the last response\n */\n get lastRequestId(): string | undefined {\n return this._lastRequestId;\n }\n\n /**\n * Execute an HTTP request with retry logic\n */\n async request<T>(options: RequestOptions): Promise<T> {\n const url = this.buildUrl(options.path, options.query);\n const headers = this.buildHeaders(options.headers, options.idempotencyKey);\n\n let lastError: Error | undefined;\n let attempt = 0;\n\n while (attempt <= this.retryConfig.maxRetries) {\n const requestContext: RequestContext = {\n method: options.method,\n url,\n headers,\n body: options.body,\n attempt,\n };\n\n try {\n // Call onRequest hook\n if (this.config.hooks?.onRequest) {\n await this.config.hooks.onRequest(requestContext);\n }\n\n const startTime = Date.now();\n const response = await this.executeRequest(\n url,\n options.method,\n headers,\n options.body,\n options.signal\n );\n const durationMs = Date.now() - startTime;\n\n const result = await this.handleResponse<T>(response, requestContext, durationMs);\n return result;\n } catch (error) {\n lastError = error as Error;\n\n // Call onError hook\n if (this.config.hooks?.onError) {\n await this.config.hooks.onError(lastError, requestContext);\n }\n\n // Check if we should retry\n if (attempt < this.retryConfig.maxRetries && this.shouldRetry(lastError)) {\n const delay = this.calculateDelay(lastError, attempt);\n\n // Call onRetry hook\n if (this.config.hooks?.onRetry) {\n await this.config.hooks.onRetry(requestContext, lastError, delay);\n }\n\n await this.sleep(delay);\n attempt++;\n continue;\n }\n\n throw lastError;\n }\n }\n\n throw lastError || new NetworkError('Request failed after retries');\n }\n\n /**\n * Execute request and return response with rate limit info\n */\n async requestWithRateLimit<T>(options: RequestOptions): Promise<ResponseWithRateLimit<T>> {\n const data = await this.request<T>(options);\n return {\n data,\n rateLimit: this._lastRateLimit,\n requestId: this._lastRequestId,\n };\n }\n\n private shouldRetry(error: Error): boolean {\n // Never retry client errors (except rate limits handled specially)\n if (\n error instanceof AuthenticationError ||\n error instanceof ValidationError ||\n error instanceof NotFoundError ||\n error instanceof ConflictError\n ) {\n return false;\n }\n\n // Retry on rate limit (uses retry-after header for delay)\n if (error instanceof RateLimitError) {\n return true;\n }\n\n // Retry on configured status codes (ServerError)\n if (error instanceof ServerError && error.statusCode) {\n return this.retryConfig.retryableStatuses.includes(error.statusCode);\n }\n\n // Retry on network errors if configured\n if (error instanceof NetworkError) {\n return this.retryConfig.retryOnNetworkError;\n }\n\n // Retry on timeout if configured\n if (error instanceof TimeoutError) {\n return this.retryConfig.retryOnTimeout;\n }\n\n return false;\n }\n\n private calculateDelay(error: Error, attempt: number): number {\n // Use retry-after header for rate limits\n if (error instanceof RateLimitError && error.retryAfter) {\n return error.retryAfter * 1000;\n }\n\n // Exponential backoff with jitter\n const baseDelay = this.retryConfig.initialDelayMs;\n const delay = Math.min(\n baseDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt),\n this.retryConfig.maxDelayMs\n );\n\n // Add jitter\n const jitter = delay * this.retryConfig.jitter * Math.random();\n return delay + jitter;\n }\n\n private buildUrl(path: string, query?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(path, this.config.baseUrl);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n return url.toString();\n }\n\n private buildHeaders(\n customHeaders?: Record<string, string>,\n idempotencyKey?: string\n ): Record<string, string> {\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...customHeaders,\n };\n\n if (idempotencyKey) {\n headers['X-Idempotency-Key'] = idempotencyKey;\n }\n\n return headers;\n }\n\n private async executeRequest(\n url: string,\n method: string,\n headers: Record<string, string>,\n body?: unknown,\n userSignal?: AbortSignal\n ): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n // Create a combined signal that aborts on either timeout or user signal\n const abortHandler = () => controller.abort();\n userSignal?.addEventListener('abort', abortHandler);\n\n try {\n if (this.config.debug) {\n console.log(`[DispatchTickets] ${method} ${url}`);\n if (body) {\n console.log('[DispatchTickets] Body:', JSON.stringify(body, null, 2));\n }\n }\n\n // Check if user already aborted\n if (userSignal?.aborted) {\n throw new Error('Request aborted');\n }\n\n const response = await this.fetchFn(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n return response;\n } catch (error) {\n if (error instanceof Error) {\n // Check if it was a user abort vs timeout\n if (error.name === 'AbortError') {\n if (userSignal?.aborted) {\n throw new NetworkError('Request aborted by user');\n }\n throw new TimeoutError(`Request timed out after ${this.config.timeout}ms`);\n }\n throw new NetworkError(error.message);\n }\n throw new NetworkError('Unknown network error');\n } finally {\n clearTimeout(timeoutId);\n userSignal?.removeEventListener('abort', abortHandler);\n }\n }\n\n private extractRateLimitInfo(response: Response): RateLimitInfo | undefined {\n const limit = response.headers.get('x-ratelimit-limit');\n const remaining = response.headers.get('x-ratelimit-remaining');\n const reset = response.headers.get('x-ratelimit-reset');\n\n if (limit && remaining && reset) {\n return {\n limit: parseInt(limit, 10),\n remaining: parseInt(remaining, 10),\n reset: parseInt(reset, 10),\n };\n }\n\n return undefined;\n }\n\n private async handleResponse<T>(\n response: Response,\n requestContext: RequestContext,\n durationMs: number\n ): Promise<T> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n // Extract request ID and rate limit info\n const requestId = response.headers.get('x-request-id') ?? undefined;\n const rateLimitInfo = this.extractRateLimitInfo(response);\n\n // Store for access via getters\n this._lastRequestId = requestId;\n this._lastRateLimit = rateLimitInfo;\n\n if (this.config.debug && requestId) {\n console.log(`[DispatchTickets] Request ID: ${requestId}`);\n }\n\n // Call onResponse hook for successful responses\n if (response.ok && this.config.hooks?.onResponse) {\n await this.config.hooks.onResponse({\n request: requestContext,\n status: response.status,\n headers: response.headers,\n requestId,\n rateLimit: rateLimitInfo,\n durationMs,\n });\n }\n\n if (response.ok) {\n if (response.status === 204 || !isJson) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n // Handle error responses\n let errorData: ApiErrorResponse = {};\n if (isJson) {\n try {\n errorData = (await response.json()) as ApiErrorResponse;\n } catch {\n // Ignore JSON parse errors for error responses\n }\n }\n\n const message = errorData.message || errorData.error || response.statusText;\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message, requestId);\n case 400:\n case 422:\n throw new ValidationError(message, errorData.errors, requestId);\n case 404:\n throw new NotFoundError(message, undefined, undefined, requestId);\n case 409:\n throw new ConflictError(message, requestId);\n case 429: {\n const retryAfter = response.headers.get('retry-after');\n throw new RateLimitError(\n message,\n retryAfter ? parseInt(retryAfter, 10) : undefined,\n requestId,\n rateLimitInfo\n );\n }\n default:\n if (response.status >= 500) {\n throw new ServerError(message, response.status, requestId);\n }\n throw new DispatchTicketsError(\n message,\n 'api_error',\n response.status,\n errorData as Record<string, unknown>,\n requestId\n );\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient, RequestOptions } from '../utils/http.js';\n\n/**\n * Options for API requests\n */\nexport interface ApiRequestOptions {\n /**\n * AbortSignal to cancel the request\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 5000);\n *\n * const ticket = await client.tickets.get('ws_abc', 'tkt_xyz', {\n * signal: controller.signal,\n * });\n * ```\n */\n signal?: AbortSignal;\n}\n\n/**\n * Base class for all resource classes\n * @internal\n */\nexport abstract class BaseResource {\n protected readonly http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n protected async _get<T>(\n path: string,\n query?: RequestOptions['query'],\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'GET',\n path,\n query,\n signal: options?.signal,\n });\n }\n\n protected async _post<T>(\n path: string,\n body?: unknown,\n options?: { idempotencyKey?: string; query?: RequestOptions['query']; signal?: AbortSignal }\n ): Promise<T> {\n return this.http.request<T>({\n method: 'POST',\n path,\n body,\n idempotencyKey: options?.idempotencyKey,\n query: options?.query,\n signal: options?.signal,\n });\n }\n\n protected async _patch<T>(\n path: string,\n body?: unknown,\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'PATCH',\n path,\n body,\n signal: options?.signal,\n });\n }\n\n protected async _put<T>(\n path: string,\n body?: unknown,\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'PUT',\n path,\n body,\n signal: options?.signal,\n });\n }\n\n protected async _delete<T>(\n path: string,\n query?: RequestOptions['query'],\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'DELETE',\n path,\n query,\n signal: options?.signal,\n });\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Account,\n AccountUsage,\n ApiKey,\n ApiKeyWithSecret,\n CreateApiKeyInput,\n UpdateApiKeyScopeInput,\n} from '../types/account.js';\n\n/**\n * Accounts resource for managing the current account\n */\nexport class AccountsResource extends BaseResource {\n /**\n * Get the current account\n */\n async me(): Promise<Account> {\n return this._get<Account>('/accounts/me');\n }\n\n /**\n * Get usage statistics for the current account\n */\n async getUsage(): Promise<AccountUsage> {\n return this._get<AccountUsage>('/accounts/me/usage');\n }\n\n /**\n * List all API keys for the current account\n */\n async listApiKeys(): Promise<ApiKey[]> {\n return this._get<ApiKey[]>('/accounts/me/api-keys');\n }\n\n /**\n * Create a new API key\n *\n * Note: The full key value is only returned once on creation.\n * Store it securely as it cannot be retrieved again.\n */\n async createApiKey(data: CreateApiKeyInput): Promise<ApiKeyWithSecret> {\n return this._post<ApiKeyWithSecret>('/accounts/me/api-keys', data);\n }\n\n /**\n * Update the brand scope for an API key\n */\n async updateApiKeyScope(\n keyId: string,\n data: UpdateApiKeyScopeInput\n ): Promise<{ success: boolean }> {\n return this._patch<{ success: boolean }>(\n `/accounts/me/api-keys/${keyId}/scope`,\n data\n );\n }\n\n /**\n * Revoke an API key\n */\n async revokeApiKey(keyId: string): Promise<void> {\n await this._delete<void>(`/accounts/me/api-keys/${keyId}`);\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Brand, CreateBrandInput, UpdateBrandInput, DeleteBrandPreview } from '../types/brand.js';\n\n/**\n * Brands resource for managing workspaces\n */\nexport class BrandsResource extends BaseResource {\n /**\n * Create a new brand\n */\n async create(data: CreateBrandInput): Promise<Brand> {\n return this._post<Brand>('/brands', data);\n }\n\n /**\n * List all brands\n */\n async list(): Promise<Brand[]> {\n return this._get<Brand[]>('/brands');\n }\n\n /**\n * Get a brand by ID\n */\n async get(brandId: string): Promise<Brand> {\n return this._get<Brand>(`/brands/${brandId}`);\n }\n\n /**\n * Update a brand\n */\n async update(brandId: string, data: UpdateBrandInput): Promise<Brand> {\n return this._patch<Brand>(`/brands/${brandId}`, data);\n }\n\n /**\n * Delete a brand\n * @param brandId - The brand ID\n * @param confirm - Set to true to actually delete; false to preview what would be deleted\n */\n async delete(brandId: string, confirm = true): Promise<void | DeleteBrandPreview> {\n if (confirm) {\n await this._delete<void>(`/brands/${brandId}`, { confirm: true });\n return;\n }\n return this._delete<DeleteBrandPreview>(`/brands/${brandId}`);\n }\n\n /**\n * Get the ticket schema for a brand\n */\n async getSchema(brandId: string): Promise<Record<string, unknown>> {\n return this._get<Record<string, unknown>>(`/brands/${brandId}/schema`);\n }\n\n /**\n * Update the ticket schema for a brand\n */\n async updateSchema(brandId: string, schema: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this._put<Record<string, unknown>>(`/brands/${brandId}/schema`, schema);\n }\n\n /**\n * Get the inbound email address for a brand\n *\n * Emails sent to this address will automatically create tickets.\n *\n * @param brandId - The brand ID\n * @param domain - Optional custom inbound domain (default: inbound.dispatchtickets.com)\n * @returns The inbound email address\n *\n * @example\n * ```typescript\n * const email = client.brands.getInboundEmail('br_abc123');\n * // Returns: br_abc123@inbound.dispatchtickets.com\n *\n * // With custom domain:\n * const customEmail = client.brands.getInboundEmail('br_abc123', 'support.mycompany.com');\n * // Returns: br_abc123@support.mycompany.com\n * ```\n */\n getInboundEmail(brandId: string, domain = 'inbound.dispatchtickets.com'): string {\n return `${brandId}@${domain}`;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Ticket,\n CreateTicketInput,\n UpdateTicketInput,\n ListTicketsFilters,\n CreateTicketOptions,\n MergeTicketsInput,\n BulkActionResult,\n} from '../types/ticket.js';\nimport type { PaginatedResponse, BulkAction } from '../types/common.js';\n\n/**\n * Tickets resource\n */\nexport class TicketsResource extends BaseResource {\n /**\n * Create a new ticket\n */\n async create(\n brandId: string,\n data: CreateTicketInput,\n options?: CreateTicketOptions\n ): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets`, data, {\n idempotencyKey: options?.idempotencyKey,\n });\n }\n\n /**\n * List tickets with pagination (async iterator)\n * Automatically fetches all pages\n */\n async *list(\n brandId: string,\n filters?: Omit<ListTicketsFilters, 'cursor'>\n ): AsyncIterable<Ticket> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const page = await this.listPage(brandId, { ...filters, cursor });\n for (const ticket of page.data) {\n yield ticket;\n }\n cursor = page.pagination.cursor;\n hasMore = page.pagination.hasMore;\n }\n }\n\n /**\n * List a single page of tickets\n */\n async listPage(\n brandId: string,\n filters?: ListTicketsFilters\n ): Promise<PaginatedResponse<Ticket>> {\n const query = this.buildListQuery(filters);\n return this._get<PaginatedResponse<Ticket>>(`/brands/${brandId}/tickets`, query);\n }\n\n /**\n * Get a ticket by ID\n */\n async get(brandId: string, ticketId: string): Promise<Ticket> {\n return this._get<Ticket>(`/brands/${brandId}/tickets/${ticketId}`);\n }\n\n /**\n * Update a ticket\n */\n async update(\n brandId: string,\n ticketId: string,\n data: UpdateTicketInput\n ): Promise<Ticket> {\n return this._patch<Ticket>(`/brands/${brandId}/tickets/${ticketId}`, data);\n }\n\n /**\n * Delete a ticket\n */\n async delete(brandId: string, ticketId: string): Promise<Ticket> {\n return this._delete<Ticket>(`/brands/${brandId}/tickets/${ticketId}`);\n }\n\n /**\n * Mark a ticket as spam or not spam\n */\n async markAsSpam(brandId: string, ticketId: string, isSpam: boolean): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets/${ticketId}/spam`, { isSpam });\n }\n\n /**\n * Merge tickets into a target ticket\n */\n async merge(\n brandId: string,\n targetTicketId: string,\n sourceTicketIds: string[]\n ): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets/${targetTicketId}/merge`, {\n sourceTicketIds,\n } satisfies MergeTicketsInput);\n }\n\n /**\n * Perform a bulk action on multiple tickets\n */\n async bulk(\n brandId: string,\n action: BulkAction,\n ticketIds: string[],\n options?: {\n assigneeId?: string | null;\n categoryId?: string | null;\n tags?: string[];\n }\n ): Promise<BulkActionResult> {\n return this._post<BulkActionResult>(`/brands/${brandId}/tickets/bulk`, {\n action,\n ticketIds,\n ...options,\n });\n }\n\n private buildListQuery(\n filters?: ListTicketsFilters\n ): Record<string, string | number | boolean | undefined> {\n if (!filters) return {};\n\n const query: Record<string, string | number | boolean | undefined> = {};\n\n if (filters.status) {\n query.status = Array.isArray(filters.status)\n ? filters.status.join(',')\n : filters.status;\n }\n if (filters.priority) query.priority = filters.priority;\n if (filters.assigneeId) query.assigneeId = filters.assigneeId;\n if (filters.customerId) query.customerId = filters.customerId;\n if (filters.customerEmail) query.customerEmail = filters.customerEmail;\n if (filters.createdBy) query.createdBy = filters.createdBy;\n if (filters.createdAfter) query.createdAfter = filters.createdAfter;\n if (filters.createdBefore) query.createdBefore = filters.createdBefore;\n if (filters.hasAttachments !== undefined) query.hasAttachments = filters.hasAttachments;\n if (filters.isSpam !== undefined) query.isSpam = filters.isSpam;\n if (filters.search) query.search = filters.search;\n if (filters.categoryId) query.categoryId = filters.categoryId;\n if (filters.tagIds) query.tagIds = filters.tagIds.join(',');\n if (filters.source) query.source = filters.source;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n\n return query;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Comment,\n CreateCommentInput,\n UpdateCommentInput,\n CreateCommentOptions,\n} from '../types/comment.js';\n\n/**\n * Comments resource\n */\nexport class CommentsResource extends BaseResource {\n /**\n * Create a new comment on a ticket\n */\n async create(\n brandId: string,\n ticketId: string,\n data: CreateCommentInput,\n options?: CreateCommentOptions\n ): Promise<Comment> {\n return this._post<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments`,\n data,\n { idempotencyKey: options?.idempotencyKey }\n );\n }\n\n /**\n * List all comments on a ticket\n */\n async list(brandId: string, ticketId: string): Promise<Comment[]> {\n return this._get<Comment[]>(`/brands/${brandId}/tickets/${ticketId}/comments`);\n }\n\n /**\n * Get a comment by ID\n */\n async get(brandId: string, ticketId: string, commentId: string): Promise<Comment> {\n return this._get<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`\n );\n }\n\n /**\n * Update a comment\n */\n async update(\n brandId: string,\n ticketId: string,\n commentId: string,\n data: UpdateCommentInput\n ): Promise<Comment> {\n return this._patch<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`,\n data\n );\n }\n\n /**\n * Delete a comment\n */\n async delete(brandId: string, ticketId: string, commentId: string): Promise<Comment> {\n return this._delete<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`\n );\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Attachment,\n AttachmentWithUrl,\n InitiateUploadInput,\n InitiateUploadResponse,\n} from '../types/attachment.js';\n\n/**\n * Attachments resource\n */\nexport class AttachmentsResource extends BaseResource {\n /**\n * Initiate an upload and get a presigned URL\n */\n async initiateUpload(\n brandId: string,\n ticketId: string,\n data: InitiateUploadInput\n ): Promise<InitiateUploadResponse> {\n return this._post<InitiateUploadResponse>(\n `/brands/${brandId}/tickets/${ticketId}/attachments`,\n data\n );\n }\n\n /**\n * Confirm that an upload has completed\n */\n async confirmUpload(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<Attachment> {\n return this._post<Attachment>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}/confirm`\n );\n }\n\n /**\n * List all attachments on a ticket\n */\n async list(brandId: string, ticketId: string): Promise<Attachment[]> {\n return this._get<Attachment[]>(`/brands/${brandId}/tickets/${ticketId}/attachments`);\n }\n\n /**\n * Get an attachment with its download URL\n */\n async get(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<AttachmentWithUrl> {\n return this._get<AttachmentWithUrl>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}`\n );\n }\n\n /**\n * Delete an attachment\n */\n async delete(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<void> {\n await this._delete<void>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}`\n );\n }\n\n /**\n * Convenience method: Upload a file in one step\n * Handles: initiate -> upload to presigned URL -> confirm\n */\n async upload(\n brandId: string,\n ticketId: string,\n file: Blob | Buffer | ArrayBuffer,\n filename: string,\n contentType: string\n ): Promise<Attachment> {\n // Get file size\n let size: number;\n if (file instanceof Blob) {\n size = file.size;\n } else if (Buffer.isBuffer(file)) {\n size = file.length;\n } else {\n size = file.byteLength;\n }\n\n // Initiate upload\n const { uploadUrl, attachmentId } = await this.initiateUpload(brandId, ticketId, {\n filename,\n contentType,\n size,\n });\n\n // Upload to presigned URL\n const uploadResponse = await fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': contentType,\n 'Content-Length': String(size),\n },\n body: file,\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n }\n\n // Confirm upload\n return this.confirmUpload(brandId, ticketId, attachmentId);\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Webhook, CreateWebhookInput, WebhookDelivery } from '../types/webhook.js';\n\n/**\n * Webhooks resource\n */\nexport class WebhooksResource extends BaseResource {\n /**\n * Create a new webhook\n */\n async create(brandId: string, data: CreateWebhookInput): Promise<Webhook> {\n return this._post<Webhook>(`/brands/${brandId}/webhooks`, data);\n }\n\n /**\n * List all webhooks for a brand\n */\n async list(brandId: string): Promise<Webhook[]> {\n return this._get<Webhook[]>(`/brands/${brandId}/webhooks`);\n }\n\n /**\n * Get a webhook by ID\n */\n async get(brandId: string, webhookId: string): Promise<Webhook> {\n return this._get<Webhook>(`/brands/${brandId}/webhooks/${webhookId}`);\n }\n\n /**\n * Delete a webhook\n */\n async delete(brandId: string, webhookId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/webhooks/${webhookId}`);\n }\n\n /**\n * Get webhook delivery history\n */\n async getDeliveries(brandId: string, webhookId: string): Promise<WebhookDelivery[]> {\n return this._get<WebhookDelivery[]>(\n `/brands/${brandId}/webhooks/${webhookId}/deliveries`\n );\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Category,\n CreateCategoryInput,\n UpdateCategoryInput,\n CategoryStats,\n} from '../types/category.js';\n\n/**\n * Categories resource\n */\nexport class CategoriesResource extends BaseResource {\n /**\n * Create a new category\n */\n async create(brandId: string, data: CreateCategoryInput): Promise<Category> {\n return this._post<Category>(`/brands/${brandId}/categories`, data);\n }\n\n /**\n * List all categories for a brand\n */\n async list(brandId: string): Promise<Category[]> {\n return this._get<Category[]>(`/brands/${brandId}/categories`);\n }\n\n /**\n * Get a category by ID\n */\n async get(brandId: string, categoryId: string): Promise<Category> {\n return this._get<Category>(`/brands/${brandId}/categories/${categoryId}`);\n }\n\n /**\n * Update a category\n */\n async update(\n brandId: string,\n categoryId: string,\n data: UpdateCategoryInput\n ): Promise<Category> {\n return this._patch<Category>(`/brands/${brandId}/categories/${categoryId}`, data);\n }\n\n /**\n * Delete a category\n */\n async delete(brandId: string, categoryId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/categories/${categoryId}`);\n }\n\n /**\n * Get category statistics (ticket counts)\n */\n async getStats(brandId: string): Promise<CategoryStats> {\n return this._get<CategoryStats>(`/brands/${brandId}/categories/stats`);\n }\n\n /**\n * Reorder categories\n */\n async reorder(brandId: string, categoryIds: string[]): Promise<void> {\n await this._post<void>(`/brands/${brandId}/categories/reorder`, { categoryIds });\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Tag, CreateTagInput, UpdateTagInput } from '../types/tag.js';\n\n/**\n * Tags resource\n */\nexport class TagsResource extends BaseResource {\n /**\n * Create a new tag\n */\n async create(brandId: string, data: CreateTagInput): Promise<Tag> {\n return this._post<Tag>(`/brands/${brandId}/tags`, data);\n }\n\n /**\n * List all tags for a brand\n */\n async list(brandId: string): Promise<Tag[]> {\n return this._get<Tag[]>(`/brands/${brandId}/tags`);\n }\n\n /**\n * Update a tag\n */\n async update(brandId: string, tagId: string, data: UpdateTagInput): Promise<Tag> {\n return this._patch<Tag>(`/brands/${brandId}/tags/${tagId}`, data);\n }\n\n /**\n * Delete a tag\n */\n async delete(brandId: string, tagId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/tags/${tagId}`);\n }\n\n /**\n * Merge tags into a target tag\n */\n async merge(brandId: string, targetTagId: string, sourceTagIds: string[]): Promise<Tag> {\n return this._post<Tag>(`/brands/${brandId}/tags/${targetTagId}/merge`, {\n sourceTagIds,\n });\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Customer,\n CreateCustomerInput,\n UpdateCustomerInput,\n ListCustomersFilters,\n} from '../types/customer.js';\nimport type { PaginatedResponse } from '../types/common.js';\n\n/**\n * Customers resource\n */\nexport class CustomersResource extends BaseResource {\n /**\n * Create a new customer\n */\n async create(brandId: string, data: CreateCustomerInput): Promise<Customer> {\n return this._post<Customer>(`/brands/${brandId}/customers`, data);\n }\n\n /**\n * List customers with pagination (async iterator)\n */\n async *list(\n brandId: string,\n filters?: Omit<ListCustomersFilters, 'cursor'>\n ): AsyncIterable<Customer> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const page = await this.listPage(brandId, { ...filters, cursor });\n for (const customer of page.data) {\n yield customer;\n }\n cursor = page.pagination.cursor;\n hasMore = page.pagination.hasMore;\n }\n }\n\n /**\n * List a single page of customers\n */\n async listPage(\n brandId: string,\n filters?: ListCustomersFilters\n ): Promise<PaginatedResponse<Customer>> {\n const query = this.buildListQuery(filters);\n return this._get<PaginatedResponse<Customer>>(`/brands/${brandId}/customers`, query);\n }\n\n /**\n * Search customers (autocomplete)\n */\n async search(brandId: string, query: string): Promise<Customer[]> {\n return this._get<Customer[]>(`/brands/${brandId}/customers/search`, { q: query });\n }\n\n /**\n * Get a customer by ID\n */\n async get(brandId: string, customerId: string): Promise<Customer> {\n return this._get<Customer>(`/brands/${brandId}/customers/${customerId}`);\n }\n\n /**\n * Update a customer\n */\n async update(\n brandId: string,\n customerId: string,\n data: UpdateCustomerInput\n ): Promise<Customer> {\n return this._patch<Customer>(`/brands/${brandId}/customers/${customerId}`, data);\n }\n\n /**\n * Delete a customer\n */\n async delete(brandId: string, customerId: string): Promise<Customer> {\n return this._delete<Customer>(`/brands/${brandId}/customers/${customerId}`);\n }\n\n private buildListQuery(\n filters?: ListCustomersFilters\n ): Record<string, string | number | boolean | undefined> {\n if (!filters) return {};\n\n const query: Record<string, string | number | boolean | undefined> = {};\n\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n\n return query;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n FieldDefinition,\n FieldDefinitions,\n CreateFieldInput,\n UpdateFieldInput,\n EntityType,\n} from '../types/field.js';\n\n/**\n * Custom fields resource\n */\nexport class FieldsResource extends BaseResource {\n /**\n * Get all field definitions for a brand\n */\n async getAll(brandId: string): Promise<FieldDefinitions> {\n return this._get<FieldDefinitions>(`/brands/${brandId}/fields`);\n }\n\n /**\n * Get field definitions for a specific entity type\n */\n async list(brandId: string, entityType: EntityType): Promise<FieldDefinition[]> {\n return this._get<FieldDefinition[]>(`/brands/${brandId}/fields/${entityType}`);\n }\n\n /**\n * Create a new field definition\n */\n async create(\n brandId: string,\n entityType: EntityType,\n data: CreateFieldInput\n ): Promise<FieldDefinition> {\n return this._post<FieldDefinition>(`/brands/${brandId}/fields/${entityType}`, data);\n }\n\n /**\n * Update a field definition\n */\n async update(\n brandId: string,\n entityType: EntityType,\n key: string,\n data: UpdateFieldInput\n ): Promise<FieldDefinition> {\n return this._patch<FieldDefinition>(\n `/brands/${brandId}/fields/${entityType}/${key}`,\n data\n );\n }\n\n /**\n * Delete a field definition\n */\n async delete(brandId: string, entityType: EntityType, key: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/fields/${entityType}/${key}`);\n }\n\n /**\n * Reorder field definitions\n */\n async reorder(brandId: string, entityType: EntityType, keys: string[]): Promise<void> {\n await this._post<void>(`/brands/${brandId}/fields/${entityType}/reorder`, { keys });\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto';\n\n/**\n * Webhook signature verification utilities\n */\nexport const webhookUtils = {\n /**\n * Verify a webhook signature\n *\n * @param payload - The raw request body as a string\n * @param signature - The X-Dispatch-Signature header value\n * @param secret - Your webhook secret\n * @returns true if the signature is valid\n *\n * @example\n * ```typescript\n * import { DispatchTickets } from '@dispatchtickets/sdk';\n *\n * app.post('/webhooks', (req, res) => {\n * const signature = req.headers['x-dispatch-signature'];\n * const isValid = DispatchTickets.webhooks.verifySignature(\n * req.rawBody,\n * signature,\n * process.env.WEBHOOK_SECRET\n * );\n *\n * if (!isValid) {\n * return res.status(401).send('Invalid signature');\n * }\n *\n * // Process webhook...\n * });\n * ```\n */\n verifySignature(payload: string, signature: string, secret: string): boolean {\n if (!signature || !secret) {\n return false;\n }\n\n // Signature format: sha256=<hex>\n const parts = signature.split('=');\n if (parts.length !== 2 || parts[0] !== 'sha256') {\n return false;\n }\n\n const receivedSignature = parts[1];\n const expectedSignature = createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n\n // Use timing-safe comparison to prevent timing attacks\n try {\n const receivedBuffer = Buffer.from(receivedSignature, 'hex');\n const expectedBuffer = Buffer.from(expectedSignature, 'hex');\n\n if (receivedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return timingSafeEqual(receivedBuffer, expectedBuffer);\n } catch {\n return false;\n }\n },\n\n /**\n * Generate a signature for testing purposes\n *\n * @param payload - The payload to sign\n * @param secret - The secret to sign with\n * @returns The signature in the format sha256=<hex>\n */\n generateSignature(payload: string, secret: string): string {\n const signature = createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n return `sha256=${signature}`;\n },\n};\n","import {\n HttpClient,\n HttpClientConfig,\n FetchFunction,\n RetryConfig,\n Hooks,\n} from './utils/http.js';\nimport { AccountsResource } from './resources/accounts.js';\nimport { BrandsResource } from './resources/brands.js';\nimport { TicketsResource } from './resources/tickets.js';\nimport { CommentsResource } from './resources/comments.js';\nimport { AttachmentsResource } from './resources/attachments.js';\nimport { WebhooksResource } from './resources/webhooks.js';\nimport { CategoriesResource } from './resources/categories.js';\nimport { TagsResource } from './resources/tags.js';\nimport { CustomersResource } from './resources/customers.js';\nimport { FieldsResource } from './resources/fields.js';\nimport { webhookUtils } from './utils/webhooks.js';\n\n/**\n * Configuration options for the Dispatch Tickets client\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * timeout: 30000,\n * retry: {\n * maxRetries: 5,\n * retryableStatuses: [429, 500, 502, 503, 504],\n * },\n * hooks: {\n * onRequest: (ctx) => console.log(`${ctx.method} ${ctx.url}`),\n * onResponse: (ctx) => console.log(`${ctx.status} in ${ctx.durationMs}ms`),\n * },\n * });\n * ```\n */\nexport interface DispatchTicketsConfig {\n /**\n * Your API key (required)\n *\n * Get your API key from the Dispatch Tickets dashboard.\n * Keys starting with `sk_live_` are production keys.\n * Keys starting with `sk_test_` are test keys.\n */\n apiKey: string;\n\n /**\n * Base URL for the API\n * @default 'https://dispatch-tickets-api.onrender.com/v1'\n */\n baseUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Maximum number of retries for failed requests\n * @default 3\n * @deprecated Use `retry.maxRetries` instead for fine-grained control\n */\n maxRetries?: number;\n\n /**\n * Enable debug logging\n *\n * When enabled, logs all requests, responses, and request IDs to console.\n * @default false\n */\n debug?: boolean;\n\n /**\n * Custom fetch implementation for testing/mocking\n *\n * @example\n * ```typescript\n * const mockFetch = vi.fn().mockResolvedValue({\n * ok: true,\n * status: 200,\n * headers: { get: () => 'application/json' },\n * json: () => Promise.resolve({ id: 'test' }),\n * });\n *\n * const client = new DispatchTickets({\n * apiKey: 'sk_test_...',\n * fetch: mockFetch,\n * });\n * ```\n */\n fetch?: FetchFunction;\n\n /**\n * Fine-grained retry configuration\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * retry: {\n * maxRetries: 5,\n * retryableStatuses: [429, 500, 502, 503, 504],\n * initialDelayMs: 500,\n * maxDelayMs: 60000,\n * backoffMultiplier: 2,\n * jitter: 0.25,\n * },\n * });\n * ```\n */\n retry?: RetryConfig;\n\n /**\n * Hooks for observability and customization\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * hooks: {\n * onRequest: (ctx) => {\n * console.log(`[${new Date().toISOString()}] ${ctx.method} ${ctx.url}`);\n * },\n * onResponse: (ctx) => {\n * console.log(`[${ctx.requestId}] ${ctx.status} in ${ctx.durationMs}ms`);\n * },\n * onError: (error, ctx) => {\n * console.error(`Request failed: ${error.message}`);\n * // Send to error tracking service\n * Sentry.captureException(error);\n * },\n * onRetry: (ctx, error, delayMs) => {\n * console.log(`Retrying in ${delayMs}ms (attempt ${ctx.attempt + 1})`);\n * },\n * },\n * });\n * ```\n */\n hooks?: Hooks;\n}\n\n/**\n * Dispatch Tickets SDK client\n *\n * The main entry point for interacting with the Dispatch Tickets API.\n * Create a client instance with your API key and use the resource methods\n * to manage tickets, comments, attachments, and more.\n *\n * @example Basic usage\n * ```typescript\n * import { DispatchTickets } from '@dispatchtickets/sdk';\n *\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * });\n *\n * // List brands\n * const brands = await client.brands.list();\n *\n * // Create a ticket\n * const ticket = await client.tickets.create('ws_abc123', {\n * title: 'Help with login',\n * body: 'I cannot log in to my account',\n * });\n *\n * // Iterate through all tickets\n * for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {\n * console.log(ticket.title);\n * }\n * ```\n *\n * @example With request cancellation\n * ```typescript\n * const controller = new AbortController();\n *\n * // Cancel after 5 seconds\n * setTimeout(() => controller.abort(), 5000);\n *\n * try {\n * const tickets = await client.tickets.listPage('ws_abc123', {}, {\n * signal: controller.signal,\n * });\n * } catch (error) {\n * if (error.message === 'Request aborted by user') {\n * console.log('Request was cancelled');\n * }\n * }\n * ```\n *\n * @example With hooks for logging\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * hooks: {\n * onRequest: (ctx) => console.log(`→ ${ctx.method} ${ctx.url}`),\n * onResponse: (ctx) => console.log(`← ${ctx.status} (${ctx.durationMs}ms)`),\n * },\n * });\n * ```\n */\nexport class DispatchTickets {\n private readonly http: HttpClient;\n\n /**\n * Accounts resource for managing the current account and API keys\n *\n * @example\n * ```typescript\n * // Get current account\n * const account = await client.accounts.me();\n *\n * // Get usage statistics\n * const usage = await client.accounts.getUsage();\n *\n * // Create a new API key\n * const newKey = await client.accounts.createApiKey({\n * name: 'Production',\n * allBrands: true,\n * });\n * ```\n */\n readonly accounts: AccountsResource;\n\n /**\n * Brands (workspaces) resource\n *\n * Brands are isolated containers for tickets. Each brand can have its own\n * email address, categories, tags, and settings.\n *\n * @example\n * ```typescript\n * // List all brands\n * const brands = await client.brands.list();\n *\n * // Create a new brand\n * const brand = await client.brands.create({\n * name: 'Acme Support',\n * slug: 'acme',\n * });\n *\n * // Get inbound email address\n * const email = client.brands.getInboundEmail('br_abc123');\n * // Returns: br_abc123@inbound.dispatchtickets.com\n * ```\n */\n readonly brands: BrandsResource;\n\n /**\n * Tickets resource\n *\n * @example\n * ```typescript\n * // Create a ticket\n * const ticket = await client.tickets.create('ws_abc123', {\n * title: 'Issue with billing',\n * body: 'I was charged twice...',\n * priority: 'high',\n * });\n *\n * // Iterate through all tickets\n * for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {\n * console.log(ticket.title);\n * }\n * ```\n */\n readonly tickets: TicketsResource;\n\n /**\n * Comments resource\n *\n * @example\n * ```typescript\n * // Add a comment\n * const comment = await client.comments.create('ws_abc123', 'tkt_xyz', {\n * body: 'Thanks for your patience!',\n * authorType: 'AGENT',\n * });\n *\n * // List comments\n * const comments = await client.comments.list('ws_abc123', 'tkt_xyz');\n * ```\n */\n readonly comments: CommentsResource;\n\n /**\n * Attachments resource\n *\n * @example\n * ```typescript\n * // Simple upload\n * const attachment = await client.attachments.upload(\n * 'ws_abc123',\n * 'tkt_xyz',\n * fileBuffer,\n * 'document.pdf',\n * 'application/pdf'\n * );\n *\n * // Get download URL\n * const { downloadUrl } = await client.attachments.get('ws_abc123', 'tkt_xyz', 'att_abc');\n * ```\n */\n readonly attachments: AttachmentsResource;\n\n /**\n * Webhooks resource\n *\n * @example\n * ```typescript\n * // Create a webhook\n * const webhook = await client.webhooks.create('ws_abc123', {\n * url: 'https://example.com/webhook',\n * secret: 'your-secret',\n * events: ['ticket.created', 'ticket.updated'],\n * });\n * ```\n */\n readonly webhooks: WebhooksResource;\n\n /**\n * Categories resource\n *\n * @example\n * ```typescript\n * // Create a category\n * await client.categories.create('ws_abc123', { name: 'Billing', color: '#ef4444' });\n *\n * // Get category stats\n * const stats = await client.categories.getStats('ws_abc123');\n * ```\n */\n readonly categories: CategoriesResource;\n\n /**\n * Tags resource\n *\n * @example\n * ```typescript\n * // Create a tag\n * await client.tags.create('ws_abc123', { name: 'urgent', color: '#f59e0b' });\n *\n * // Merge tags\n * await client.tags.merge('ws_abc123', 'tag_target', ['tag_source1', 'tag_source2']);\n * ```\n */\n readonly tags: TagsResource;\n\n /**\n * Customers resource\n *\n * @example\n * ```typescript\n * // Create a customer\n * const customer = await client.customers.create('ws_abc123', {\n * email: 'user@example.com',\n * name: 'Jane Doe',\n * });\n *\n * // Search customers\n * const results = await client.customers.search('ws_abc123', 'jane');\n * ```\n */\n readonly customers: CustomersResource;\n\n /**\n * Custom fields resource\n *\n * @example\n * ```typescript\n * // Get all field definitions\n * const fields = await client.fields.getAll('ws_abc123');\n *\n * // Create a field\n * await client.fields.create('ws_abc123', 'ticket', {\n * key: 'order_id',\n * label: 'Order ID',\n * type: 'text',\n * required: true,\n * });\n * ```\n */\n readonly fields: FieldsResource;\n\n /**\n * Static webhook utilities\n *\n * @example\n * ```typescript\n * // Verify webhook signature\n * const isValid = DispatchTickets.webhooks.verifySignature(\n * rawBody,\n * req.headers['x-dispatch-signature'],\n * 'your-secret'\n * );\n *\n * // Generate signature for testing\n * const signature = DispatchTickets.webhooks.generateSignature(\n * JSON.stringify(payload),\n * 'your-secret'\n * );\n * ```\n */\n static readonly webhooks = webhookUtils;\n\n /**\n * Create a new Dispatch Tickets client\n *\n * @param config - Client configuration options\n * @throws Error if API key is not provided\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * });\n * ```\n */\n constructor(config: DispatchTicketsConfig) {\n if (!config.apiKey) {\n throw new Error('API key is required');\n }\n\n const httpConfig: HttpClientConfig = {\n baseUrl: config.baseUrl || 'https://dispatch-tickets-api.onrender.com/v1',\n apiKey: config.apiKey,\n timeout: config.timeout ?? 30000,\n maxRetries: config.maxRetries ?? config.retry?.maxRetries ?? 3,\n debug: config.debug ?? false,\n fetch: config.fetch,\n retry: config.retry,\n hooks: config.hooks,\n };\n\n this.http = new HttpClient(httpConfig);\n\n // Initialize resources\n this.accounts = new AccountsResource(this.http);\n this.brands = new BrandsResource(this.http);\n this.tickets = new TicketsResource(this.http);\n this.comments = new CommentsResource(this.http);\n this.attachments = new AttachmentsResource(this.http);\n this.webhooks = new WebhooksResource(this.http);\n this.categories = new CategoriesResource(this.http);\n this.tags = new TagsResource(this.http);\n this.customers = new CustomersResource(this.http);\n this.fields = new FieldsResource(this.http);\n }\n}\n","import type { TicketStatus, TicketPriority, TicketSource, AuthorType } from './common.js';\n\n/**\n * All supported webhook event types\n */\nexport type WebhookEventType =\n | 'ticket.created'\n | 'ticket.updated'\n | 'ticket.comment.created';\n\n/**\n * Base webhook event envelope\n */\nexport interface WebhookEventEnvelope<T extends WebhookEventType, D> {\n /** Unique event ID */\n id: string;\n /** Event type */\n event: T;\n /** Brand ID that triggered the event */\n brand_id: string;\n /** Event data */\n data: D;\n /** ISO timestamp when event was created */\n timestamp: string;\n}\n\n/**\n * Customer info included in events\n */\nexport interface EventCustomerInfo {\n customerId: string | null;\n customerEmail: string | null;\n customerName: string | null;\n}\n\n/**\n * Payload for ticket.created event\n */\nexport interface TicketCreatedData extends EventCustomerInfo {\n id: string;\n ticketNumber: number;\n title: string;\n status: TicketStatus;\n priority: TicketPriority;\n source: TicketSource;\n createdAt: string;\n}\n\n/**\n * Payload for ticket.updated event\n */\nexport interface TicketUpdatedData extends EventCustomerInfo {\n id: string;\n ticketNumber: number;\n title: string;\n status: TicketStatus;\n priority: TicketPriority;\n assigneeId: string | null;\n updatedAt: string;\n /** List of field names that were changed */\n changes: string[];\n}\n\n/**\n * Comment data in ticket.comment.created event\n */\nexport interface EventCommentData {\n id: string;\n body: string;\n authorId: string | null;\n authorType: AuthorType;\n createdAt: string;\n}\n\n/**\n * Payload for ticket.comment.created event\n */\nexport interface CommentCreatedData extends EventCustomerInfo {\n ticketId: string;\n /** Formatted ticket number (e.g., \"ACME-123\") */\n ticketNumber: string;\n comment: EventCommentData;\n}\n\n/**\n * Ticket created webhook event\n */\nexport type TicketCreatedEvent = WebhookEventEnvelope<'ticket.created', TicketCreatedData>;\n\n/**\n * Ticket updated webhook event\n */\nexport type TicketUpdatedEvent = WebhookEventEnvelope<'ticket.updated', TicketUpdatedData>;\n\n/**\n * Comment created webhook event\n */\nexport type CommentCreatedEvent = WebhookEventEnvelope<'ticket.comment.created', CommentCreatedData>;\n\n/**\n * Union of all webhook events\n */\nexport type WebhookEvent = TicketCreatedEvent | TicketUpdatedEvent | CommentCreatedEvent;\n\n/**\n * Map of event types to their data types\n */\nexport interface WebhookEventMap {\n 'ticket.created': TicketCreatedEvent;\n 'ticket.updated': TicketUpdatedEvent;\n 'ticket.comment.created': CommentCreatedEvent;\n}\n\n/**\n * Type guard to check if event is a ticket.created event\n */\nexport function isTicketCreatedEvent(event: WebhookEvent): event is TicketCreatedEvent {\n return event.event === 'ticket.created';\n}\n\n/**\n * Type guard to check if event is a ticket.updated event\n */\nexport function isTicketUpdatedEvent(event: WebhookEvent): event is TicketUpdatedEvent {\n return event.event === 'ticket.updated';\n}\n\n/**\n * Type guard to check if event is a ticket.comment.created event\n */\nexport function isCommentCreatedEvent(event: WebhookEvent): event is CommentCreatedEvent {\n return event.event === 'ticket.comment.created';\n}\n\n/**\n * Parse and validate a webhook payload\n *\n * @param payload - Raw JSON payload string or parsed object\n * @returns Typed webhook event\n * @throws Error if payload is invalid\n *\n * @example\n * ```typescript\n * import { parseWebhookEvent, isTicketCreatedEvent } from '@dispatchtickets/sdk';\n *\n * app.post('/webhooks', (req, res) => {\n * const event = parseWebhookEvent(req.body);\n *\n * if (isTicketCreatedEvent(event)) {\n * console.log('New ticket:', event.data.title);\n * }\n * });\n * ```\n */\nexport function parseWebhookEvent(payload: string | object): WebhookEvent {\n const event = typeof payload === 'string' ? JSON.parse(payload) : payload;\n\n if (!event || typeof event !== 'object') {\n throw new Error('Invalid webhook payload: expected object');\n }\n\n if (!event.event || typeof event.event !== 'string') {\n throw new Error('Invalid webhook payload: missing event type');\n }\n\n if (!event.id || typeof event.id !== 'string') {\n throw new Error('Invalid webhook payload: missing event id');\n }\n\n if (!event.data || typeof event.data !== 'object') {\n throw new Error('Invalid webhook payload: missing data');\n }\n\n const validEvents: WebhookEventType[] = ['ticket.created', 'ticket.updated', 'ticket.comment.created'];\n if (!validEvents.includes(event.event)) {\n throw new Error(`Invalid webhook payload: unknown event type \"${event.event}\"`);\n }\n\n return event as WebhookEvent;\n}\n","import type { PaginatedResponse } from '../types/common.js';\n\n/**\n * Options for paginated requests\n */\nexport interface PaginationOptions {\n limit?: number;\n cursor?: string;\n}\n\n/**\n * Create an async iterator from a paginated API endpoint\n */\nexport function createPaginatedIterator<T>(\n fetchPage: (cursor?: string) => Promise<PaginatedResponse<T>>\n): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n let cursor: string | undefined;\n let hasMore = true;\n let currentPage: T[] = [];\n let currentIndex = 0;\n\n return {\n async next(): Promise<IteratorResult<T>> {\n // If we have items in the current page, return the next one\n if (currentIndex < currentPage.length) {\n return { value: currentPage[currentIndex++], done: false };\n }\n\n // If no more pages, we're done\n if (!hasMore) {\n return { value: undefined, done: true };\n }\n\n // Fetch the next page\n const response = await fetchPage(cursor);\n currentPage = response.data;\n currentIndex = 0;\n cursor = response.pagination.cursor;\n hasMore = response.pagination.hasMore;\n\n // If the page is empty, we're done\n if (currentPage.length === 0) {\n return { value: undefined, done: true };\n }\n\n return { value: currentPage[currentIndex++], done: false };\n },\n };\n },\n };\n}\n\n/**\n * Collect all items from an async iterable into an array\n */\nexport async function collectAll<T>(iterable: AsyncIterable<T>): Promise<T[]> {\n const items: T[] = [];\n for await (const item of iterable) {\n items.push(item);\n }\n return items;\n}\n"]}
|