@getmicdrop/venue-calendar 3.8.3 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +700 -661
  2. package/dist/AirbnbSplitMain-BfddFqOQ.js +2201 -0
  3. package/dist/AirbnbSplitMain-BfddFqOQ.js.map +1 -0
  4. package/dist/{CarouselView.legacy-BED9P-az.js → CarouselView.legacy-BKXwmB2P.js} +11 -10
  5. package/dist/CarouselView.legacy-BKXwmB2P.js.map +1 -0
  6. package/dist/CartView-iIEjDwFN.js +1667 -0
  7. package/dist/CartView-iIEjDwFN.js.map +1 -0
  8. package/dist/Checkout-Cu0D8mFn.js +743 -0
  9. package/dist/Checkout-Cu0D8mFn.js.map +1 -0
  10. package/dist/{Checkout.legacy-B1Ui4zZN.js → Checkout.legacy-C6V9HmUZ.js} +374 -359
  11. package/dist/Checkout.legacy-C6V9HmUZ.js.map +1 -0
  12. package/dist/CheckoutMain-B17znLe0.js +1403 -0
  13. package/dist/CheckoutMain-B17znLe0.js.map +1 -0
  14. package/dist/CheckoutTimer-BsI1r6lY.js +34 -0
  15. package/dist/CheckoutTimer-BsI1r6lY.js.map +1 -0
  16. package/dist/CollectionView-CQgKWQHT.js +142 -0
  17. package/dist/CollectionView-CQgKWQHT.js.map +1 -0
  18. package/dist/{CollectionView.legacy-CXv5mTUk.js → CollectionView.legacy-B8SDspBL.js} +25 -24
  19. package/dist/CollectionView.legacy-B8SDspBL.js.map +1 -0
  20. package/dist/EventDetailsView-XXl8aQJ9.js +1187 -0
  21. package/dist/EventDetailsView-XXl8aQJ9.js.map +1 -0
  22. package/dist/{FeaturedView.legacy-C5yztREl.js → FeaturedView.legacy-Dse2jnrt.js} +15 -15
  23. package/dist/FeaturedView.legacy-Dse2jnrt.js.map +1 -0
  24. package/dist/GalleryCard-CDaYD8XI.js +92 -0
  25. package/dist/GalleryCard-CDaYD8XI.js.map +1 -0
  26. package/dist/{GalleryView.legacy-DoM4NcPc.js → GalleryView.legacy-U_ripo22.js} +18 -17
  27. package/dist/GalleryView.legacy-U_ripo22.js.map +1 -0
  28. package/dist/{GroupedListView.legacy-Dmm_z1rM.js → GroupedListView.legacy-BrickaeB.js} +25 -25
  29. package/dist/GroupedListView.legacy-BrickaeB.js.map +1 -0
  30. package/dist/Heading-AFd3o0xt.js +44 -0
  31. package/dist/Heading-AFd3o0xt.js.map +1 -0
  32. package/dist/OrderSummarySkeleton-dDKUH741.js +16 -0
  33. package/dist/OrderSummarySkeleton-dDKUH741.js.map +1 -0
  34. package/dist/SeriesPage-CNoI4R4M.js +56 -0
  35. package/dist/SeriesPage-CNoI4R4M.js.map +1 -0
  36. package/dist/SeriesPage.legacy-Cugebbf0.js +195 -0
  37. package/dist/SeriesPage.legacy-Cugebbf0.js.map +1 -0
  38. package/dist/Success-BQAu7uZn.js +715 -0
  39. package/dist/Success-BQAu7uZn.js.map +1 -0
  40. package/dist/Success.legacy-DSmTsdB_.js +195 -0
  41. package/dist/Success.legacy-DSmTsdB_.js.map +1 -0
  42. package/dist/Text-CXR2fhx6.js +54 -0
  43. package/dist/Text-CXR2fhx6.js.map +1 -0
  44. package/dist/{VenueCalendar-DIQ8H0q7.js → VenueCalendar-DzTrcN8J.js} +11242 -21624
  45. package/dist/VenueCalendar-DzTrcN8J.js.map +1 -0
  46. package/dist/ViewTicketsEmbed-DOTq6kSz.js +2038 -0
  47. package/dist/ViewTicketsEmbed-DOTq6kSz.js.map +1 -0
  48. package/dist/__SKIP_NAVIGATION__-CJ96TTPE.js +7 -0
  49. package/dist/__SKIP_NAVIGATION__-CJ96TTPE.js.map +1 -0
  50. package/dist/api/api.cjs +1 -1
  51. package/dist/api/api.cjs.map +1 -1
  52. package/dist/api/api.mjs +511 -279
  53. package/dist/api/api.mjs.map +1 -1
  54. package/dist/api/client.d.ts +3 -33
  55. package/dist/api/cta.d.ts +38 -0
  56. package/dist/api/events.d.ts +3 -1
  57. package/dist/api/gift-cards.d.ts +88 -0
  58. package/dist/api/index.d.ts +6 -0
  59. package/dist/api/types.d.ts +353 -349
  60. package/dist/api/waitlist.d.ts +23 -0
  61. package/dist/colors-BZoMuXdh.js.map +1 -1
  62. package/dist/labels-BPzDu-3y.js +1351 -0
  63. package/dist/labels-BPzDu-3y.js.map +1 -0
  64. package/dist/seo/HostSeoController.d.ts +9 -1
  65. package/dist/seo/seo.cjs +1 -1
  66. package/dist/seo/seo.cjs.map +1 -1
  67. package/dist/seo/seo.mjs +53 -50
  68. package/dist/seo/seo.mjs.map +1 -1
  69. package/dist/seo/types.d.ts +137 -136
  70. package/dist/transform-CZI_M7Wk.js +218 -0
  71. package/dist/transform-CZI_M7Wk.js.map +1 -0
  72. package/dist/types/index.d.ts +387 -387
  73. package/dist/venue-calendar.css +1 -1
  74. package/dist/venue-calendar.es.js +36 -28
  75. package/dist/venue-calendar.es.js.map +1 -1
  76. package/dist/venue-calendar.iife.js +43 -43
  77. package/dist/venue-calendar.iife.js.map +1 -1
  78. package/dist/venue-calendar.umd.js +40 -40
  79. package/dist/venue-calendar.umd.js.map +1 -1
  80. package/package.json +44 -6
  81. package/src/lib/theme.js +13 -0
  82. package/dist/CarouselView.legacy-BED9P-az.js.map +0 -1
  83. package/dist/Checkout.legacy-B1Ui4zZN.js.map +0 -1
  84. package/dist/CollectionView.legacy-CXv5mTUk.js.map +0 -1
  85. package/dist/FeaturedView.legacy-C5yztREl.js.map +0 -1
  86. package/dist/GalleryView.legacy-DoM4NcPc.js.map +0 -1
  87. package/dist/GroupedListView.legacy-Dmm_z1rM.js.map +0 -1
  88. package/dist/SeriesPage.legacy-Cgtr6qB_.js +0 -190
  89. package/dist/SeriesPage.legacy-Cgtr6qB_.js.map +0 -1
  90. package/dist/Success.legacy-DHG9NwIq.js +0 -194
  91. package/dist/Success.legacy-DHG9NwIq.js.map +0 -1
  92. package/dist/VenueCalendar-DIQ8H0q7.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"api.cjs","sources":["../../node_modules/@getmicdrop/svelte-components/dist/utils/logger.js","../../src/lib/api/client.ts","../../src/lib/api/orders.ts","../../src/lib/api/promo.ts","../../src/lib/api/events.ts","../../src/lib/api/venues.ts","../../src/lib/api/transformers/order.ts","../../src/lib/api/transformers/event.ts","../../src/lib/api/transformers/venue.ts"],"sourcesContent":["/**\n * Centralized logger utility for MicDrop applications\n * Can be disabled in production or configured for different log levels\n *\n * Usage (factory — recommended for consuming apps):\n * import { createLogger } from '@getmicdrop/svelte-components/utils/logger';\n * const log = createLogger('MF');\n * log.info('booting'); // → [MF] [INFO] booting\n *\n * Usage (singleton — legacy, still works):\n * import { logger, configureLogger } from '@getmicdrop/svelte-components/utils/logger';\n * configureLogger({ prefix: '[MF]' });\n * logger.info('booting');\n */\nconst LOG_LEVELS = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\nconst isEnabled = () => typeof window !== 'undefined' &&\n (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production');\n/**\n * Create an independent logger instance with its own config.\n *\n * @param prefix - Tag shown in log output, e.g. 'MF' produces `[MF]`\n * @param options - Optional overrides for enabled/level\n */\nexport function createLogger(prefix, options = {}) {\n let config = {\n enabled: options.enabled ?? isEnabled(),\n level: options.level ?? 'debug',\n prefix: prefix.startsWith('[') ? prefix : `[${prefix}]`,\n };\n function shouldLog(level) {\n return config.enabled && LOG_LEVELS[level] >= LOG_LEVELS[config.level];\n }\n function formatMessage(level, message) {\n return `${config.prefix} [${level.toUpperCase()}] ${message}`;\n }\n return {\n debug(message, ...args) {\n if (shouldLog('debug')) {\n console.log(formatMessage('debug', message), ...args);\n }\n },\n info(message, ...args) {\n if (shouldLog('info')) {\n console.info(formatMessage('info', message), ...args);\n }\n },\n warn(message, ...args) {\n if (shouldLog('warn')) {\n console.warn(formatMessage('warn', message), ...args);\n }\n },\n error(message, ...args) {\n if (shouldLog('error')) {\n console.error(formatMessage('error', message), ...args);\n }\n },\n configure(opts) {\n config = { ...config, ...opts };\n },\n };\n}\n// ---------------------------------------------------------------------------\n// Singleton (backward-compatible) — uses the factory internally\n// ---------------------------------------------------------------------------\nlet config = {\n enabled: isEnabled(),\n level: 'debug',\n prefix: '[MicDrop]',\n};\nexport function configureLogger(options) {\n config = { ...config, ...options };\n}\nfunction shouldLog(level) {\n return config.enabled && LOG_LEVELS[level] >= LOG_LEVELS[config.level];\n}\nfunction formatMessage(level, message) {\n return `${config.prefix} [${level.toUpperCase()}] ${message}`;\n}\nexport const logger = {\n debug: (message, ...args) => {\n if (shouldLog('debug')) {\n console.log(formatMessage('debug', message), ...args);\n }\n },\n info: (message, ...args) => {\n if (shouldLog('info')) {\n console.info(formatMessage('info', message), ...args);\n }\n },\n warn: (message, ...args) => {\n if (shouldLog('warn')) {\n console.warn(formatMessage('warn', message), ...args);\n }\n },\n error: (message, ...args) => {\n if (shouldLog('error')) {\n console.error(formatMessage('error', message), ...args);\n }\n },\n};\nexport default logger;\n","/**\r\n * API Client for MicDrop Public Checkout API\r\n *\r\n * Provides a centralized HTTP client with:\r\n * - Configurable base URL\r\n * - Error handling and logging\r\n * - Request/response typing\r\n * - IP address capture for payment intents\r\n */\r\n\r\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\r\nconst logger = createLogger('VC');\r\nimport type { ApiConfig, ApiResponse } from './types.js';\r\n\r\n// Default API configuration\r\nconst DEFAULT_CONFIG: Required<ApiConfig> = {\r\n baseUrl: 'https://get-micdrop.com',\r\n timeout: 30000,\r\n onError: (error: Error) => logger.error('API Error:', error),\r\n};\r\n\r\n// Global configuration (can be overridden)\r\nlet globalConfig: Required<ApiConfig> = { ...DEFAULT_CONFIG };\r\n\r\n/**\r\n * Configure the API client\r\n */\r\nexport function configureApi(config: Partial<ApiConfig>): void {\r\n globalConfig = { ...globalConfig, ...config };\r\n}\r\n\r\n/**\r\n * Get the current API configuration\r\n */\r\nexport function getApiConfig(): Required<ApiConfig> {\r\n return { ...globalConfig };\r\n}\r\n\r\n/**\r\n * Get the public API base URL for v2 endpoints\r\n */\r\nexport function getPublicBaseUrl(): string {\r\n return `${globalConfig.baseUrl}/api/v2/public`;\r\n}\r\n\r\n/**\r\n * Get the legacy public API base URL\r\n */\r\nexport function getLegacyPublicUrl(): string {\r\n return `${globalConfig.baseUrl}/api/public`;\r\n}\r\n\r\n/**\r\n * Get the orders V2 API base URL\r\n */\r\nexport function getOrdersV2Url(): string {\r\n return `${globalConfig.baseUrl}/api/orders/v2/public`;\r\n}\r\n\r\n/**\r\n * Get the user's IP address for payment intents\r\n * @deprecated IP is now resolved server-side via request headers\r\n */\r\nexport async function getClientIP(): Promise<string> {\r\n return '';\r\n}\r\n\r\n/**\r\n * Make a GET request to the API\r\n */\r\nexport async function apiGet<T>(\r\n endpoint: string,\r\n options?: RequestInit\r\n): Promise<ApiResponse<T>> {\r\n return apiRequest<T>('GET', endpoint, undefined, options);\r\n}\r\n\r\n/**\r\n * Make a POST request to the API\r\n */\r\nexport async function apiPost<T>(\r\n endpoint: string,\r\n body?: unknown,\r\n options?: RequestInit\r\n): Promise<ApiResponse<T>> {\r\n return apiRequest<T>('POST', endpoint, body, options);\r\n}\r\n\r\n/**\r\n * Make a PUT request to the API\r\n */\r\nexport async function apiPut<T>(\r\n endpoint: string,\r\n body?: unknown,\r\n options?: RequestInit\r\n): Promise<ApiResponse<T>> {\r\n return apiRequest<T>('PUT', endpoint, body, options);\r\n}\r\n\r\n/**\r\n * Make a DELETE request to the API\r\n */\r\nexport async function apiDelete<T>(\r\n endpoint: string,\r\n options?: RequestInit\r\n): Promise<ApiResponse<T>> {\r\n return apiRequest<T>('DELETE', endpoint, undefined, options);\r\n}\r\n\r\n/**\r\n * Core API request function\r\n */\r\nasync function apiRequest<T>(\r\n method: string,\r\n endpoint: string,\r\n body?: unknown,\r\n options?: RequestInit\r\n): Promise<ApiResponse<T>> {\r\n const url = endpoint.startsWith('http')\r\n ? endpoint\r\n : `${getPublicBaseUrl()}${endpoint}`;\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), globalConfig.timeout);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...options?.headers,\r\n },\r\n body: body ? JSON.stringify(body) : undefined,\r\n credentials: 'include',\r\n signal: controller.signal,\r\n ...options,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n const error = new Error(\r\n errorData.error || errorData.message || `HTTP ${response.status}`\r\n );\r\n globalConfig.onError(error);\r\n\r\n return {\r\n success: false,\r\n error: errorData.error || errorData.message || `HTTP ${response.status}`,\r\n statusCode: response.status,\r\n };\r\n }\r\n\r\n const data = await response.json();\r\n return {\r\n success: true,\r\n data: data as T,\r\n statusCode: response.status,\r\n };\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n\r\n const errorMessage =\r\n error instanceof Error\r\n ? error.name === 'AbortError'\r\n ? 'Request timed out'\r\n : error.message\r\n : 'Unknown error';\r\n\r\n globalConfig.onError(error instanceof Error ? error : new Error(errorMessage));\r\n\r\n return {\r\n success: false,\r\n error: errorMessage,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Simple fetch wrapper for backwards compatibility\r\n * Returns data directly or null on error\r\n */\r\nexport async function simpleFetch<T>(\r\n url: string,\r\n options?: RequestInit\r\n): Promise<T | null> {\r\n try {\r\n const response = await fetch(url, {\r\n credentials: 'include',\r\n ...options,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n logger.error(`API request failed: ${response.status}`, errorData);\r\n return null;\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('API request error:', error);\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Orders API\r\n *\r\n * Functions for managing orders, payments, and reservations\r\n * in the public checkout flow.\r\n */\r\n\r\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\r\nconst logger = createLogger('VC');\r\nimport {\r\n getPublicBaseUrl,\r\n getOrdersV2Url,\r\n simpleFetch,\r\n} from './client.js';\r\nimport type {\r\n PaymentIntentResponse,\r\n CompleteReservationResponse,\r\n CancelReservationResponse,\r\n CreateOrderResponse,\r\n ValidatePaymentRequest,\r\n ValidatePaymentResponse,\r\n ExtendSessionResponse,\r\n SessionStatus,\r\n Order,\r\n} from './types.js';\r\n\r\n/**\r\n * Create a payment intent for the cart\r\n *\r\n * This initiates the Stripe payment flow by creating a PaymentIntent\r\n * on the backend. The response includes the client_secret needed\r\n * for Stripe Elements.\r\n *\r\n * @param cartId - The cart/order UUID\r\n * @param quantities - Map of ticketId -> quantity\r\n * @param donationAmounts - Map of ticketId -> donation amount in dollars (for type=2 tickets)\r\n * @returns Payment intent data including client_secret, or null on error\r\n */\r\nexport async function createPaymentIntent(\r\n cartId: string,\r\n quantities: Record<string | number, number>,\r\n donationAmounts?: Record<string | number, number>\r\n): Promise<PaymentIntentResponse | null> {\r\n try {\r\n const response = await fetch(\r\n `${getOrdersV2Url()}/cart/${cartId}/payment-intent`,\r\n {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n credentials: 'include',\r\n body: JSON.stringify({\r\n productQuantities: quantities,\r\n ...(donationAmounts && Object.keys(donationAmounts).length > 0\r\n ? { donationAmounts }\r\n : {}),\r\n }),\r\n }\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n logger.error('Payment intent creation failed:', errorData);\r\n throw new Error(errorData.error || 'Failed to create payment intent');\r\n }\r\n\r\n const data = await response.json();\r\n logger.debug('Payment intent created:', data);\r\n return data;\r\n } catch (error) {\r\n logger.error('createPaymentIntent error:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Complete reservation after successful payment\r\n *\r\n * Called after Stripe confirms the payment to finalize the order\r\n * and generate tickets.\r\n *\r\n * @param orderUuid - The order UUID\r\n * @returns Success status and message\r\n */\r\nexport async function completeReservation(\r\n orderUuid: string\r\n): Promise<CompleteReservationResponse> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/orders/complete/${orderUuid}`,\r\n {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n }\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n return {\r\n success: false,\r\n error: errorData.error || 'Failed to complete reservation',\r\n };\r\n }\r\n\r\n const result = await response.json();\r\n return {\r\n success: true,\r\n message: result.message,\r\n };\r\n } catch (error) {\r\n logger.error('Error completing reservation:', error);\r\n return { success: false, error: 'Network error completing reservation' };\r\n }\r\n}\r\n\r\n/**\r\n * Cancel reservation and release tickets back to inventory\r\n *\r\n * Called when user abandons checkout or session expires.\r\n *\r\n * @param orderUuid - The order UUID\r\n * @returns Success status and message\r\n */\r\nexport async function cancelReservation(\r\n orderUuid: string\r\n): Promise<CancelReservationResponse> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/orders/cancel/${orderUuid}`,\r\n {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n }\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n return {\r\n success: false,\r\n error: errorData.error || 'Failed to cancel reservation',\r\n };\r\n }\r\n\r\n const result = await response.json();\r\n return {\r\n success: true,\r\n message: result.message,\r\n };\r\n } catch (error) {\r\n logger.error('Error cancelling reservation:', error);\r\n return { success: false, error: 'Network error cancelling reservation' };\r\n }\r\n}\r\n\r\n/**\r\n * Create a new order/cart\r\n *\r\n * This creates an empty order that can be used for checkout.\r\n * The order UUID is used for all subsequent operations.\r\n *\r\n * @param eventId - The event ID\r\n * @param promoCode - Optional promo code to apply\r\n * @returns The order UUID, or null on error\r\n */\r\nexport async function createOrder(\r\n eventId: string | number,\r\n promoCode?: string\r\n): Promise<CreateOrderResponse | null> {\r\n try {\r\n const response = await fetch(`${getPublicBaseUrl()}/orders/create`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n eventID: eventId,\r\n promoCode,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n logger.error('Create order failed:', errorData);\r\n return null;\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('createOrder error:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get order details (public, no auth required)\r\n *\r\n * Fetches the order details for displaying on the success page.\r\n *\r\n * @param orderId - The order UUID or ID\r\n * @returns The order details, or null on error\r\n */\r\nexport async function getOrder(orderId: string): Promise<Order | null> {\r\n return simpleFetch<Order>(`${getPublicBaseUrl()}/orders/${orderId}`);\r\n}\r\n\r\n/**\r\n * Validate payment intent and complete the order\r\n *\r\n * This is an alternative to completeReservation that accepts\r\n * additional payment details. Used by micdrop-frontend.\r\n *\r\n * @param cartId - The cart/order UUID\r\n * @param payload - Payment validation payload\r\n * @returns Validation result\r\n */\r\nexport async function validatePaymentIntent(\r\n cartId: string,\r\n payload: ValidatePaymentRequest\r\n): Promise<ValidatePaymentResponse | null> {\r\n try {\r\n const response = await fetch(\r\n `${getOrdersV2Url()}/validatePaymentIntent/${cartId}`,\r\n {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify(payload),\r\n }\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n logger.error('Payment validation failed:', errorData);\r\n return {\r\n success: false,\r\n status: 'failed',\r\n error: errorData.error || 'Payment validation failed',\r\n };\r\n }\r\n\r\n const result = await response.json();\r\n return {\r\n success: true,\r\n status: result.status || 'Payment succeeded',\r\n orderUUID: result.orderUUID || result.uuid,\r\n };\r\n } catch (error) {\r\n logger.error('validatePaymentIntent error:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Extend the checkout session by 15 minutes\r\n *\r\n * Users get a limited number of extensions (typically 2-3).\r\n *\r\n * @param orderUuid - The order UUID\r\n * @returns Extension result with new expiry time\r\n */\r\nexport async function extendCheckoutSession(\r\n orderUuid: string\r\n): Promise<ExtendSessionResponse> {\r\n try {\r\n const response = await fetch(`${getPublicBaseUrl()}/orders/extend-session`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({ orderUuid }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n return {\r\n success: false,\r\n error: errorData.error || 'Failed to extend session',\r\n };\r\n }\r\n\r\n const result = await response.json();\r\n return {\r\n success: true,\r\n newExpiryTime: result.newExpiryTime,\r\n remainingExtensions: result.remainingExtensions,\r\n };\r\n } catch (error) {\r\n logger.error('Error extending checkout session:', error);\r\n return { success: false, error: 'Network error extending session' };\r\n }\r\n}\r\n\r\n/**\r\n * Get current session status including expiry time\r\n *\r\n * Used to display countdown timer and check if extensions are available.\r\n *\r\n * @param orderUuid - The order UUID\r\n * @returns Session status including expiry time\r\n */\r\nexport async function getSessionStatus(orderUuid: string): Promise<SessionStatus> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/orders/session/${orderUuid}`\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n return { error: errorData.error || 'No active session found' };\r\n }\r\n\r\n const result = await response.json();\r\n return {\r\n expiresAt: result.expiresAt,\r\n extensionCount: result.extensionCount,\r\n remainingExtensions: result.remainingExtensions,\r\n canExtend: result.canExtend,\r\n reservationCount: result.reservationCount,\r\n };\r\n } catch (error) {\r\n logger.error('Error getting session status:', error);\r\n return { error: 'Network error getting session status' };\r\n }\r\n}\r\n\r\n/**\r\n * Initiate a new order (alias for createOrder)\r\n *\r\n * This function provides backwards compatibility with micdrop-frontend.\r\n * It accepts the same parameters as the legacy initiateOrder function.\r\n *\r\n * @param cartData - Object containing eventID and optional quantities/promoCode\r\n * @returns The order UUID, or null on error\r\n */\r\nexport async function initiateOrder(\r\n cartData: { eventID: string | number; promoCode?: string; quantities?: Record<string | number, number> } = {} as any\r\n): Promise<string | null> {\r\n try {\r\n const response = await fetch(`${getPublicBaseUrl()}/orders/create`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify(cartData),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n logger.error('Order initiation failed:', errorData);\r\n return null;\r\n }\r\n\r\n const data = await response.json();\r\n return data.uuid;\r\n } catch (error) {\r\n logger.error('initiateOrder error:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Track UTM source for analytics\r\n *\r\n * Records the traffic source (utm_source parameter) for marketing analytics.\r\n *\r\n * @param venueId - The venue ID\r\n * @returns Promise that resolves when tracking is complete\r\n */\r\nexport async function trackUTMSource(venueId: string | number): Promise<void> {\r\n if (typeof window === 'undefined') return;\r\n\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const utmSource = urlParams.get('utm_source') || 'Direct';\r\n\r\n try {\r\n await fetch(\r\n `${getPublicBaseUrl()}/utm/${venueId}/${encodeURIComponent(utmSource)}`\r\n );\r\n } catch (error) {\r\n logger.error('UTM tracking failed:', error);\r\n }\r\n}\r\n","/**\r\n * Promo Codes API\r\n *\r\n * Functions for validating and checking promo codes\r\n * in the public checkout flow.\r\n */\r\n\r\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\r\nconst logger = createLogger('VC');\r\nimport { getPublicBaseUrl } from './client.js';\r\nimport type { PromoValidationResponse, HasPromoCodesResponse } from './types.js';\r\n\r\n/**\r\n * Validate a promo code for an event\r\n *\r\n * Checks if a promo code is valid and returns its effects:\r\n * - Discount amount and type\r\n * - Hidden ticket reveal\r\n *\r\n * @param eventId - The event ID\r\n * @param code - The promo code to validate\r\n * @returns Validation result with discount info\r\n */\r\nexport async function validatePromoCode(\r\n eventId: string | number,\r\n code: string\r\n): Promise<PromoValidationResponse> {\r\n try {\r\n if (!code || !code.trim()) {\r\n return { valid: false, error: 'Promo code is required' };\r\n }\r\n\r\n // API uses GET with code in URL path\r\n const encodedCode = encodeURIComponent(code.trim());\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/promo-codes/validate/${eventId}/${encodedCode}`\r\n );\r\n\r\n if (!response.ok) {\r\n // 404 = invalid code, other errors are server issues\r\n if (response.status === 404) {\r\n return { valid: false, error: 'Invalid promo code' };\r\n }\r\n const errorData = await response.json().catch(() => ({}));\r\n return { valid: false, error: errorData.error || 'Failed to validate code' };\r\n }\r\n\r\n const result = await response.json();\r\n return {\r\n valid: result.valid ?? true,\r\n revealHiddenTickets: result.revealHiddenTickets,\r\n revealTicketIds: result.revealTicketIds,\r\n provideDiscount: result.provideDiscount,\r\n discountType: result.discountType,\r\n amount: result.amount,\r\n code: result.code || code,\r\n };\r\n } catch (error) {\r\n logger.error('Error validating promo code:', error);\r\n return { valid: false, error: 'Network error validating code' };\r\n }\r\n}\r\n\r\n/**\r\n * Check if promo codes are available for an event\r\n *\r\n * Used to conditionally show/hide the promo code input field.\r\n *\r\n * @param eventId - The event ID\r\n * @returns Whether promo codes exist for this event\r\n */\r\nexport async function hasPromoCodes(eventId: string | number): Promise<boolean> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/promo-codes/check/${eventId}`\r\n );\r\n\r\n if (!response.ok) {\r\n // If endpoint doesn't exist or errors, default to showing the input\r\n return true;\r\n }\r\n\r\n const result: HasPromoCodesResponse = await response.json();\r\n return result.hasPromoCodes === true;\r\n } catch (error) {\r\n logger.error('Error checking promo codes availability:', error);\r\n // Default to showing promo input if we can't check\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * Apply a promo code to a cart\r\n *\r\n * This updates the cart with the promo code discount.\r\n *\r\n * @param cartId - The cart UUID\r\n * @param code - The promo code to apply\r\n * @returns Success status\r\n */\r\nexport async function applyPromoCode(\r\n cartId: string,\r\n code: string\r\n): Promise<{ success: boolean; error?: string }> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/orders/${cartId}/apply-promo`,\r\n {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({ code }),\r\n }\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n return {\r\n success: false,\r\n error: errorData.error || 'Failed to apply promo code',\r\n };\r\n }\r\n\r\n return { success: true };\r\n } catch (error) {\r\n logger.error('Error applying promo code:', error);\r\n return { success: false, error: 'Network error applying code' };\r\n }\r\n}\r\n\r\n/**\r\n * Remove a promo code from a cart\r\n *\r\n * @param cartId - The cart UUID\r\n * @returns Success status\r\n */\r\nexport async function removePromoCode(\r\n cartId: string\r\n): Promise<{ success: boolean; error?: string }> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/orders/${cartId}/remove-promo`,\r\n {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n }\r\n );\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n return {\r\n success: false,\r\n error: errorData.error || 'Failed to remove promo code',\r\n };\r\n }\r\n\r\n return { success: true };\r\n } catch (error) {\r\n logger.error('Error removing promo code:', error);\r\n return { success: false, error: 'Network error removing code' };\r\n }\r\n}\r\n","/**\r\n * Events API\r\n *\r\n * Functions for fetching event data, tickets, and performers\r\n * in the public checkout flow.\r\n */\r\n\r\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\r\nconst logger = createLogger('VC');\r\nimport { getPublicBaseUrl, simpleFetch } from './client.js';\r\nimport type {\r\n Event,\r\n AvailableTicket,\r\n EventPerformersResponse,\r\n SeriesOccurrencesResponse,\r\n SeriesPageData,\r\n PublicCollectionData,\r\n} from './types.js';\r\n\r\n/**\r\n * Fetch event details\r\n *\r\n * Gets full event information including venue and ticket data.\r\n *\r\n * @param eventId - The event ID\r\n * @param customFetch - Optional custom fetch function (for SSR)\r\n * @returns Event details or null on error\r\n */\r\nexport async function fetchEventDetails(\r\n eventId: string | number,\r\n customFetch: typeof fetch = fetch\r\n): Promise<Event | null> {\r\n try {\r\n const response = await customFetch(`${getPublicBaseUrl()}/events/${eventId}`);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch event details: ${response.status}`);\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('Error fetching event details:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Fetch available tickets for an event\r\n *\r\n * Returns all ticket types that are currently available for sale.\r\n *\r\n * @param eventId - The event ID\r\n * @returns Array of available tickets\r\n */\r\nexport async function fetchEventTickets(\r\n eventId: string | number\r\n): Promise<AvailableTicket[]> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/tickets/event/${eventId}`\r\n );\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch tickets: ${response.status}`);\r\n }\r\n\r\n const tickets = await response.json();\r\n return Array.isArray(tickets) ? tickets : [];\r\n } catch (error) {\r\n logger.error('Error fetching tickets:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Fetch performers for an event\r\n *\r\n * Returns the lineup with pre-resolved avatar URLs.\r\n *\r\n * @param eventId - The event ID\r\n * @returns Performers list and visibility flag\r\n */\r\nexport async function fetchEventPerformers(\r\n eventId: string | number\r\n): Promise<EventPerformersResponse> {\r\n try {\r\n if (!eventId) {\r\n logger.warn('fetchEventPerformers called without eventId');\r\n return { performers: [], showPerformers: false };\r\n }\r\n\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/events/${eventId}/performers`\r\n );\r\n\r\n if (!response.ok) {\r\n logger.error(\r\n `Failed to fetch performers: ${response.status} ${response.statusText}`\r\n );\r\n return { performers: [], showPerformers: false };\r\n }\r\n\r\n const data = await response.json();\r\n return {\r\n performers: Array.isArray(data.performers) ? data.performers : [],\r\n showPerformers: data.showPerformers === true,\r\n };\r\n } catch (error) {\r\n logger.error('Error fetching event performers:', error);\r\n return { performers: [], showPerformers: false };\r\n }\r\n}\r\n\r\n/**\r\n * Fetch all venues for an organization\r\n *\r\n * @param orgId - The organization ID\r\n * @returns Array of venues\r\n */\r\nexport async function fetchAllVenues(orgId: string | number): Promise<any[]> {\r\n try {\r\n if (!orgId) {\r\n logger.warn('fetchAllVenues called without orgId');\r\n return [];\r\n }\r\n\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/venues/organization/${orgId}`\r\n );\r\n\r\n if (!response.ok) {\r\n logger.error(\r\n `Failed to fetch venues: ${response.status} ${response.statusText}`\r\n );\r\n return [];\r\n }\r\n\r\n const venues = await response.json();\r\n return Array.isArray(venues) ? venues : [];\r\n } catch (error) {\r\n logger.error('Error fetching venues:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Fetch events for a venue\r\n *\r\n * @param venueId - The venue ID\r\n * @returns Array of events\r\n */\r\nexport async function fetchVenueEvents(venueId: string | number): Promise<Event[]> {\r\n try {\r\n if (!venueId) {\r\n logger.warn('fetchVenueEvents called without venueId');\r\n return [];\r\n }\r\n\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/events/venue/${venueId}`\r\n );\r\n\r\n if (!response.ok) {\r\n logger.error(\r\n `Failed to fetch venue events: ${response.status} ${response.statusText}`\r\n );\r\n return [];\r\n }\r\n\r\n const events = await response.json();\r\n return Array.isArray(events) ? events : [];\r\n } catch (error) {\r\n logger.error('Error fetching venue events:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get events for a specific month\r\n *\r\n * Used for calendar views to efficiently load events.\r\n *\r\n * @param venueId - The venue ID\r\n * @param year - The year (e.g., 2024)\r\n * @param month - The month (1-12)\r\n * @returns Array of events for the month\r\n */\r\nexport async function getMonthEvents(\r\n venueId: string | number,\r\n year: number,\r\n month: number\r\n): Promise<Event[]> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/events/venue/${venueId}/month/${year}/${month}`\r\n );\r\n\r\n if (!response.ok) {\r\n logger.error(`Failed to fetch month events: ${response.status}`);\r\n return [];\r\n }\r\n\r\n const data = await response.json();\r\n return Array.isArray(data.events) ? data.events : Array.isArray(data) ? data : [];\r\n } catch (error) {\r\n logger.error('Error fetching month events:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get events for an organization for a specific month\r\n *\r\n * @param orgId - The organization ID\r\n * @param year - The year (e.g., 2024)\r\n * @param month - The month (1-12)\r\n * @returns Array of events for the month\r\n */\r\nexport async function getOrgMonthEvents(\r\n orgId: string | number,\r\n year: number,\r\n month: number\r\n): Promise<Event[]> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/events/organization/${orgId}/month/${year}/${month}`\r\n );\r\n\r\n if (!response.ok) {\r\n logger.error(`Failed to fetch org month events: ${response.status}`);\r\n return [];\r\n }\r\n\r\n const data = await response.json();\r\n return Array.isArray(data.events) ? data.events : Array.isArray(data) ? data : [];\r\n } catch (error) {\r\n logger.error('Error fetching org month events:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get series occurrences for date selector\r\n *\r\n * Returns all instances of a recurring event series.\r\n *\r\n * @param eventSeriesId - The series ID\r\n * @returns Series occurrences\r\n */\r\nexport async function getSeriesOccurrences(\r\n eventSeriesId: number\r\n): Promise<SeriesOccurrencesResponse | null> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/series/${eventSeriesId}/occurrences`\r\n );\r\n\r\n if (!response.ok) {\r\n logger.error(`Failed to fetch series occurrences: ${response.status}`);\r\n return null;\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('Error fetching series occurrences:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Fetch series occurrences with CTA state\r\n *\r\n * Returns full series data including availability status.\r\n *\r\n * @param eventSeriesId - The series ID\r\n * @param venueId - The venue ID\r\n * @returns Series occurrences with CTA state\r\n */\r\nexport async function fetchSeriesOccurrences(\r\n eventSeriesId: number,\r\n venueId: string | number\r\n): Promise<SeriesOccurrencesResponse | null> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/series/${eventSeriesId}/occurrences?venueId=${venueId}`\r\n );\r\n\r\n if (!response.ok) {\r\n logger.error(`Failed to fetch series with CTA: ${response.status}`);\r\n return null;\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('Error fetching series occurrences:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Fetch series page data\r\n *\r\n * Returns full series information including occurrences, venue, and performers.\r\n *\r\n * @param seriesId - The series ID\r\n * @returns Series page data or null on error\r\n */\r\nexport async function fetchSeriesPage(\r\n seriesId: string | number\r\n): Promise<SeriesPageData | null> {\r\n try {\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/series/${seriesId}/page`\r\n );\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch series page: ${response.status}`);\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('Error fetching series page:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Fetch public collection data\r\n *\r\n * Returns collection info including events list.\r\n * For password-protected collections, pass the password to authenticate.\r\n *\r\n * @param collectionId - The collection ID\r\n * @param password - Optional password for protected collections\r\n * @returns Collection data or null on error\r\n */\r\nexport async function fetchPublicCollection(\r\n collectionId: string | number,\r\n password?: string\r\n): Promise<PublicCollectionData | null> {\r\n try {\r\n const url = password\r\n ? `${getPublicBaseUrl()}/collections/${collectionId}/public?password=${encodeURIComponent(password)}`\r\n : `${getPublicBaseUrl()}/collections/${collectionId}/public`;\r\n\r\n const response = await fetch(url);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch collection: ${response.status}`);\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('Error fetching collection:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Check collection password\r\n *\r\n * Validates password for password-protected collections.\r\n *\r\n * @param collectionId - The collection ID\r\n * @param password - The password to check\r\n * @returns Whether the password is valid\r\n */\r\nexport async function checkCollectionPassword(\r\n collectionId: string | number,\r\n password: string\r\n): Promise<boolean> {\r\n try {\r\n const encodedPassword = encodeURIComponent(password);\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/collections/${collectionId}/check-password/${encodedPassword}`\r\n );\r\n\r\n if (!response.ok) {\r\n return false;\r\n }\r\n\r\n const result = await response.json();\r\n return result.valid === true;\r\n } catch (error) {\r\n logger.error('Error checking collection password:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check event password\r\n *\r\n * Validates password for password-protected events.\r\n *\r\n * @param eventId - The event ID\r\n * @param password - The password to check\r\n * @returns Whether the password is valid\r\n */\r\nexport async function checkEventPassword(\r\n eventId: string | number,\r\n password: string\r\n): Promise<boolean> {\r\n try {\r\n const encodedPassword = encodeURIComponent(password);\r\n const response = await fetch(\r\n `${getPublicBaseUrl()}/events/${eventId}/check-password/${encodedPassword}`\r\n );\r\n\r\n if (!response.ok) {\r\n return false;\r\n }\r\n\r\n const result = await response.json();\r\n return result.valid === true;\r\n } catch (error) {\r\n logger.error('Error checking event password:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Test network connection\r\n *\r\n * Health check endpoint for connectivity testing.\r\n *\r\n * @param orgId - Optional org ID\r\n * @param venueId - Optional venue ID\r\n * @returns Whether the connection is working\r\n */\r\nexport async function testNetworkConnection(\r\n orgId?: string | number,\r\n venueId?: string | number\r\n): Promise<boolean> {\r\n try {\r\n // Use a simple endpoint to test connectivity\r\n const url = venueId\r\n ? `${getPublicBaseUrl()}/events/venue/${venueId}`\r\n : orgId\r\n ? `${getPublicBaseUrl()}/venues/organization/${orgId}`\r\n : `${getPublicBaseUrl()}/health`;\r\n\r\n const response = await fetch(url, {\r\n method: 'HEAD',\r\n });\r\n\r\n return response.ok;\r\n } catch (error) {\r\n logger.error('Network connection test failed:', error);\r\n return false;\r\n }\r\n}\r\n","/**\r\n * Venues API\r\n *\r\n * Functions for fetching venue data including\r\n * service fees and tax configuration.\r\n */\r\n\r\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\r\nconst logger = createLogger('VC');\r\nimport { getPublicBaseUrl, simpleFetch } from './client.js';\r\nimport type { Venue } from './types.js';\r\n\r\n/**\r\n * Get venue details (public, no auth required)\r\n *\r\n * Fetches venue information including service fees and taxes\r\n * needed for checkout calculations.\r\n *\r\n * @param venueId - The venue ID\r\n * @returns Venue details or null on error\r\n */\r\nexport async function getVenue(venueId: string | number): Promise<Venue | null> {\r\n try {\r\n if (!venueId) {\r\n logger.warn('getVenue called without venueId');\r\n return null;\r\n }\r\n\r\n const response = await fetch(`${getPublicBaseUrl()}/venues/${venueId}`);\r\n\r\n if (!response.ok) {\r\n logger.error(`Failed to fetch venue: ${response.status}`);\r\n return null;\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('Error fetching venue:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get venue service fee configuration\r\n *\r\n * Returns just the fee-related fields for checkout calculations.\r\n *\r\n * @param venueId - The venue ID\r\n * @returns Fee configuration or null on error\r\n */\r\nexport async function getVenueFees(\r\n venueId: string | number\r\n): Promise<{\r\n serviceFeePercentage: number;\r\n serviceFeeCents: number;\r\n taxPercentage: number;\r\n} | null> {\r\n const venue = await getVenue(venueId);\r\n\r\n if (!venue) {\r\n return null;\r\n }\r\n\r\n return {\r\n serviceFeePercentage: venue.serviceFeePercentage ?? 0,\r\n serviceFeeCents: venue.serviceFeeCents ?? 0,\r\n taxPercentage: venue.taxPercentage ?? 0,\r\n };\r\n}\r\n\r\n/**\r\n * Get venue by slug\r\n *\r\n * Fetches venue using its URL-friendly slug.\r\n *\r\n * @param slug - The venue slug\r\n * @returns Venue details or null on error\r\n */\r\nexport async function getVenueBySlug(slug: string): Promise<Venue | null> {\r\n try {\r\n if (!slug) {\r\n logger.warn('getVenueBySlug called without slug');\r\n return null;\r\n }\r\n\r\n const encodedSlug = encodeURIComponent(slug);\r\n const response = await fetch(`${getPublicBaseUrl()}/venues/slug/${encodedSlug}`);\r\n\r\n if (!response.ok) {\r\n logger.error(`Failed to fetch venue by slug: ${response.status}`);\r\n return null;\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n logger.error('Error fetching venue by slug:', error);\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Order Transformer\r\n *\r\n * Normalizes API order responses to a consistent format.\r\n * Handles variations in field names between different API versions.\r\n */\r\n\r\nimport type { Order, PurchasedTicket } from '../types.js';\r\n\r\n/**\r\n * Raw API order response (may have varying field names)\r\n */\r\ninterface ApiOrder {\r\n uuid?: string;\r\n id?: number;\r\n ID?: number;\r\n customerEmail?: string;\r\n email?: string;\r\n customer_email?: string;\r\n customerFirstName?: string;\r\n firstName?: string;\r\n first_name?: string;\r\n customerLastName?: string;\r\n lastName?: string;\r\n last_name?: string;\r\n status?: string;\r\n totalAmount?: number;\r\n total?: number;\r\n total_amount?: number;\r\n subtotal?: number;\r\n serviceFeesAmount?: number;\r\n serviceFee?: number;\r\n service_fee?: number;\r\n service_fees_amount?: number;\r\n taxAmount?: number;\r\n tax?: number;\r\n tax_amount?: number;\r\n discount?: number;\r\n paymentIntentId?: string;\r\n payment_intent_id?: string;\r\n paymentMethod?: string;\r\n payment_method?: string;\r\n purchasedTickets?: any[];\r\n tickets?: any[];\r\n purchased_tickets?: any[];\r\n createdAt?: string;\r\n created_at?: string;\r\n updatedAt?: string;\r\n updated_at?: string;\r\n}\r\n\r\n/**\r\n * Raw API ticket response\r\n */\r\ninterface ApiTicket {\r\n uuid?: string;\r\n id?: number;\r\n ID?: number;\r\n ticketNumber?: string;\r\n ticket_number?: string;\r\n orderId?: string | number;\r\n order_id?: string | number;\r\n attendeeFirstName?: string;\r\n attendee_first_name?: string;\r\n firstName?: string;\r\n attendeeLastName?: string;\r\n attendee_last_name?: string;\r\n lastName?: string;\r\n attendeeEmail?: string;\r\n attendee_email?: string;\r\n email?: string;\r\n ticketName?: string;\r\n ticket_name?: string;\r\n name?: string;\r\n ticketTypeId?: number;\r\n ticket_type_id?: number;\r\n purchasePrice?: number;\r\n purchase_price?: number;\r\n price?: number;\r\n status?: string;\r\n checkedIn?: boolean;\r\n checked_in?: boolean;\r\n checkedInAt?: string;\r\n checked_in_at?: string;\r\n}\r\n\r\n/**\r\n * Transform a raw API ticket to normalized PurchasedTicket\r\n */\r\nexport function transformTicket(apiTicket: ApiTicket): PurchasedTicket {\r\n return {\r\n uuid: apiTicket.uuid || String(apiTicket.id || apiTicket.ID || ''),\r\n id: apiTicket.id || apiTicket.ID,\r\n ticketNumber: apiTicket.ticketNumber || apiTicket.ticket_number,\r\n orderId: apiTicket.orderId || apiTicket.order_id,\r\n attendeeFirstName:\r\n apiTicket.attendeeFirstName ||\r\n apiTicket.attendee_first_name ||\r\n apiTicket.firstName,\r\n attendeeLastName:\r\n apiTicket.attendeeLastName ||\r\n apiTicket.attendee_last_name ||\r\n apiTicket.lastName,\r\n attendeeEmail:\r\n apiTicket.attendeeEmail || apiTicket.attendee_email || apiTicket.email,\r\n ticketName:\r\n apiTicket.ticketName || apiTicket.ticket_name || apiTicket.name || '',\r\n ticketTypeId: apiTicket.ticketTypeId || apiTicket.ticket_type_id,\r\n purchasePrice:\r\n apiTicket.purchasePrice ||\r\n apiTicket.purchase_price ||\r\n apiTicket.price ||\r\n 0,\r\n status: apiTicket.status,\r\n checkedIn: apiTicket.checkedIn || apiTicket.checked_in,\r\n checkedInAt: apiTicket.checkedInAt || apiTicket.checked_in_at,\r\n };\r\n}\r\n\r\n/**\r\n * Transform a raw API order to normalized Order\r\n *\r\n * Handles various field name patterns:\r\n * - camelCase (customerEmail)\r\n * - snake_case (customer_email)\r\n * - Shortened names (email)\r\n */\r\nexport function transformOrder(apiOrder: ApiOrder): Order {\r\n // Extract tickets array from various possible field names\r\n const rawTickets =\r\n apiOrder.purchasedTickets ||\r\n apiOrder.tickets ||\r\n apiOrder.purchased_tickets ||\r\n [];\r\n\r\n return {\r\n uuid: apiOrder.uuid || String(apiOrder.id || apiOrder.ID || ''),\r\n id: apiOrder.id || apiOrder.ID,\r\n customerEmail:\r\n apiOrder.customerEmail ||\r\n apiOrder.email ||\r\n apiOrder.customer_email ||\r\n '',\r\n customerFirstName:\r\n apiOrder.customerFirstName ||\r\n apiOrder.firstName ||\r\n apiOrder.first_name,\r\n customerLastName:\r\n apiOrder.customerLastName ||\r\n apiOrder.lastName ||\r\n apiOrder.last_name,\r\n status: apiOrder.status || 'unknown',\r\n totalAmount:\r\n apiOrder.totalAmount ||\r\n apiOrder.total ||\r\n apiOrder.total_amount ||\r\n 0,\r\n subtotal: apiOrder.subtotal,\r\n serviceFeesAmount:\r\n apiOrder.serviceFeesAmount ||\r\n apiOrder.serviceFee ||\r\n apiOrder.service_fee ||\r\n apiOrder.service_fees_amount ||\r\n 0,\r\n taxAmount:\r\n apiOrder.taxAmount || apiOrder.tax || apiOrder.tax_amount || 0,\r\n discount: apiOrder.discount || 0,\r\n paymentIntentId:\r\n apiOrder.paymentIntentId || apiOrder.payment_intent_id,\r\n paymentMethod: apiOrder.paymentMethod || apiOrder.payment_method,\r\n purchasedTickets: rawTickets.map(transformTicket),\r\n createdAt: apiOrder.createdAt || apiOrder.created_at,\r\n updatedAt: apiOrder.updatedAt || apiOrder.updated_at,\r\n };\r\n}\r\n\r\n/**\r\n * Transform order for display on success page\r\n *\r\n * Returns a simplified object with display-ready values.\r\n */\r\nexport function transformOrderForDisplay(apiOrder: ApiOrder): {\r\n orderId: string;\r\n displayOrderId: string;\r\n email: string;\r\n customerName: string;\r\n total: number;\r\n formattedTotal: string;\r\n ticketCount: number;\r\n status: string;\r\n} {\r\n const order = transformOrder(apiOrder);\r\n const displayId = order.uuid.split('-')[0] || order.uuid;\r\n\r\n return {\r\n orderId: order.uuid,\r\n displayOrderId: displayId,\r\n email: order.customerEmail,\r\n customerName: [order.customerFirstName, order.customerLastName]\r\n .filter(Boolean)\r\n .join(' '),\r\n total: order.totalAmount,\r\n formattedTotal: `$${(order.totalAmount / 100).toFixed(2)}`,\r\n ticketCount: order.purchasedTickets.length,\r\n status: order.status,\r\n };\r\n}\r\n","/**\r\n * Event Transformer\r\n *\r\n * Normalizes API event responses to a consistent format.\r\n * Handles image URL resolution and CTA state calculation.\r\n */\r\n\r\nimport type { Event, AvailableTicket } from '../types.js';\r\n\r\n// CDN base URL for images\r\nconst CDN_BASE_URL = 'https://micdrop-images.sfo3.digitaloceanspaces.com';\r\n\r\n/**\r\n * Raw API event response (may have varying field names)\r\n */\r\ninterface ApiEvent {\r\n eventID?: number;\r\n id?: number;\r\n ID?: number;\r\n name?: string;\r\n title?: string;\r\n slug?: string;\r\n description?: string;\r\n date?: string;\r\n startDateTime?: string;\r\n start_date_time?: string;\r\n endDateTime?: string;\r\n end_date_time?: string;\r\n doorsOpenTime?: string;\r\n doors_open_time?: string;\r\n timezone?: string;\r\n time_zone?: string;\r\n venueId?: number;\r\n venue_id?: number;\r\n venueName?: string;\r\n venue_name?: string;\r\n venueAddress?: string;\r\n venue_address?: string;\r\n location?: string;\r\n imageUrl?: string;\r\n imageURL?: string;\r\n image_url?: string;\r\n image?: string;\r\n status?: string;\r\n isPublished?: boolean;\r\n is_published?: boolean;\r\n isCancelled?: boolean;\r\n is_cancelled?: boolean;\r\n availableTickets?: any[];\r\n available_tickets?: any[];\r\n tickets?: any[];\r\n ticketsAvailable?: number;\r\n tickets_available?: number;\r\n ticketsSold?: number;\r\n tickets_sold?: number;\r\n minPrice?: number;\r\n min_price?: number;\r\n maxPrice?: number;\r\n max_price?: number;\r\n ctaText?: string;\r\n cta_text?: string;\r\n ctaState?: string;\r\n cta_state?: string;\r\n showPerformers?: boolean;\r\n show_performers?: boolean;\r\n eventSeriesId?: number;\r\n event_series_id?: number;\r\n seriesInstanceNumber?: number;\r\n series_instance_number?: number;\r\n}\r\n\r\n/**\r\n * Get CDN image URL\r\n *\r\n * Prepends the CDN base URL if the path is relative.\r\n */\r\nexport function getCDNImageUrl(path: string | undefined): string {\r\n if (!path) return '';\r\n if (path.startsWith('http')) return path;\r\n return `${CDN_BASE_URL}/${path.replace(/^\\//, '')}`;\r\n}\r\n\r\n/**\r\n * Extract image URL from event with fallbacks\r\n */\r\nexport function getEventImageUrl(apiEvent: ApiEvent): string {\r\n const rawUrl =\r\n apiEvent.imageUrl ||\r\n apiEvent.imageURL ||\r\n apiEvent.image_url ||\r\n apiEvent.image ||\r\n '';\r\n\r\n return getCDNImageUrl(rawUrl);\r\n}\r\n\r\n/**\r\n * Calculate CTA state based on ticket availability\r\n */\r\nexport function calculateCtaState(\r\n apiEvent: ApiEvent\r\n): 'available' | 'sold_out' | 'coming_soon' | 'ended' {\r\n // Check explicit CTA state first\r\n const explicitState = apiEvent.ctaState || apiEvent.cta_state;\r\n if (explicitState) {\r\n return explicitState as any;\r\n }\r\n\r\n // Check if event is cancelled or ended\r\n if (apiEvent.isCancelled || apiEvent.is_cancelled) {\r\n return 'ended';\r\n }\r\n\r\n // Check event date\r\n const eventDate = apiEvent.startDateTime || apiEvent.start_date_time || apiEvent.date;\r\n if (eventDate) {\r\n const eventTime = new Date(eventDate).getTime();\r\n const now = Date.now();\r\n\r\n if (eventTime < now) {\r\n return 'ended';\r\n }\r\n }\r\n\r\n // Check ticket availability\r\n const availableCount =\r\n apiEvent.ticketsAvailable ?? apiEvent.tickets_available;\r\n\r\n if (availableCount !== undefined) {\r\n if (availableCount <= 0) {\r\n return 'sold_out';\r\n }\r\n return 'available';\r\n }\r\n\r\n // Check tickets array\r\n const tickets =\r\n apiEvent.availableTickets ||\r\n apiEvent.available_tickets ||\r\n apiEvent.tickets ||\r\n [];\r\n\r\n if (tickets.length === 0) {\r\n return 'coming_soon';\r\n }\r\n\r\n const totalAvailable = tickets.reduce((sum: number, t: any) => {\r\n const qty =\r\n t.quantityAvailable ?? t.quantity_available ?? t.quantity ?? 0;\r\n const sold = t.quantitySold ?? t.quantity_sold ?? 0;\r\n return sum + Math.max(0, qty - sold);\r\n }, 0);\r\n\r\n if (totalAvailable <= 0) {\r\n return 'sold_out';\r\n }\r\n\r\n return 'available';\r\n}\r\n\r\n/**\r\n * Transform a raw API ticket to normalized AvailableTicket\r\n */\r\nexport function transformTicket(apiTicket: any): AvailableTicket {\r\n return {\r\n id: apiTicket.id || apiTicket.ID,\r\n name: apiTicket.name || apiTicket.ticketName || '',\r\n description: apiTicket.description,\r\n price: apiTicket.price || 0,\r\n quantity: apiTicket.quantity || apiTicket.totalQuantity || 0,\r\n quantitySold: apiTicket.quantitySold || apiTicket.quantity_sold || 0,\r\n quantityAvailable:\r\n apiTicket.quantityAvailable ||\r\n apiTicket.quantity_available ||\r\n (apiTicket.quantity || 0) - (apiTicket.quantitySold || 0),\r\n minPerOrder: apiTicket.minPerOrder || apiTicket.min_per_order || 1,\r\n maxPerOrder: apiTicket.maxPerOrder || apiTicket.max_per_order || 10,\r\n saleStartDate: apiTicket.saleStartDate || apiTicket.sale_start_date,\r\n saleEndDate: apiTicket.saleEndDate || apiTicket.sale_end_date,\r\n isHidden: apiTicket.isHidden || apiTicket.is_hidden || false,\r\n revealWithPromoCode:\r\n apiTicket.revealWithPromoCode || apiTicket.reveal_with_promo_code,\r\n ticketType: apiTicket.ticketType || apiTicket.ticket_type || 0,\r\n sectionId: apiTicket.sectionId || apiTicket.section_id,\r\n sortOrder: apiTicket.sortOrder || apiTicket.sort_order || 0,\r\n };\r\n}\r\n\r\n/**\r\n * Transform a raw API event to normalized Event\r\n */\r\nexport function transformEvent(apiEvent: ApiEvent): Event {\r\n // Extract tickets array from various possible field names\r\n const rawTickets =\r\n apiEvent.availableTickets ||\r\n apiEvent.available_tickets ||\r\n apiEvent.tickets ||\r\n [];\r\n\r\n const tickets = rawTickets.map(transformTicket);\r\n\r\n // Calculate min/max prices from tickets\r\n const prices = tickets.map((t) => t.price).filter((p) => p > 0);\r\n const minPrice = prices.length > 0 ? Math.min(...prices) : undefined;\r\n const maxPrice = prices.length > 0 ? Math.max(...prices) : undefined;\r\n\r\n return {\r\n eventID: apiEvent.eventID || apiEvent.id || apiEvent.ID || 0,\r\n id: apiEvent.id || apiEvent.ID,\r\n name: apiEvent.name || apiEvent.title || '',\r\n title: apiEvent.title || apiEvent.name,\r\n slug: apiEvent.slug,\r\n description: apiEvent.description,\r\n date: apiEvent.date || apiEvent.startDateTime || apiEvent.start_date_time || '',\r\n startDateTime: apiEvent.startDateTime || apiEvent.start_date_time,\r\n endDateTime: apiEvent.endDateTime || apiEvent.end_date_time,\r\n doorsOpenTime: apiEvent.doorsOpenTime || apiEvent.doors_open_time,\r\n timezone: apiEvent.timezone || apiEvent.time_zone,\r\n venueId: apiEvent.venueId || apiEvent.venue_id,\r\n venueName: apiEvent.venueName || apiEvent.venue_name,\r\n venueAddress: apiEvent.venueAddress || apiEvent.venue_address,\r\n location: apiEvent.location || apiEvent.venueAddress || apiEvent.venue_address,\r\n imageUrl: getEventImageUrl(apiEvent),\r\n imageURL: getEventImageUrl(apiEvent),\r\n status: apiEvent.status,\r\n isPublished: apiEvent.isPublished ?? apiEvent.is_published,\r\n isCancelled: apiEvent.isCancelled ?? apiEvent.is_cancelled,\r\n availableTickets: tickets,\r\n ticketsAvailable:\r\n apiEvent.ticketsAvailable ??\r\n apiEvent.tickets_available ??\r\n tickets.reduce((sum, t) => sum + (t.quantityAvailable || 0), 0),\r\n ticketsSold: apiEvent.ticketsSold ?? apiEvent.tickets_sold,\r\n minPrice: apiEvent.minPrice ?? apiEvent.min_price ?? minPrice,\r\n maxPrice: apiEvent.maxPrice ?? apiEvent.max_price ?? maxPrice,\r\n ctaText: apiEvent.ctaText || apiEvent.cta_text,\r\n ctaState: calculateCtaState(apiEvent),\r\n showPerformers: apiEvent.showPerformers ?? apiEvent.show_performers,\r\n eventSeriesId: apiEvent.eventSeriesId || apiEvent.event_series_id,\r\n seriesInstanceNumber:\r\n apiEvent.seriesInstanceNumber || apiEvent.series_instance_number,\r\n };\r\n}\r\n\r\n/**\r\n * Legacy transformer name for backwards compatibility\r\n */\r\nexport const transformEventData = transformEvent;\r\n","/**\r\n * Venue Transformer\r\n *\r\n * Normalizes API venue responses to a consistent format.\r\n */\r\n\r\nimport type { Venue } from '../types.js';\r\n\r\n// CDN base URL for images\r\nconst CDN_BASE_URL = 'https://micdrop-images.sfo3.digitaloceanspaces.com';\r\n\r\n/**\r\n * Raw API venue response (may have varying field names)\r\n */\r\ninterface ApiVenue {\r\n id?: number;\r\n ID?: number;\r\n name?: string;\r\n slug?: string;\r\n address?: string;\r\n googleLocationNameCache?: string;\r\n google_location_name_cache?: string;\r\n city?: string;\r\n state?: string;\r\n zipCode?: string;\r\n zip_code?: string;\r\n country?: string;\r\n timezone?: string;\r\n time_zone?: string;\r\n logoUrl?: string;\r\n logo_url?: string;\r\n logo?: string;\r\n serviceFeePercentage?: number;\r\n service_fee_percentage?: number;\r\n serviceFeeCents?: number;\r\n service_fee_cents?: number;\r\n taxPercentage?: number;\r\n tax_percentage?: number;\r\n organizationId?: number;\r\n organization_id?: number;\r\n}\r\n\r\n/**\r\n * Get CDN image URL for venue logo\r\n */\r\nfunction getLogoUrl(path: string | undefined): string {\r\n if (!path) return '';\r\n if (path.startsWith('http')) return path;\r\n return `${CDN_BASE_URL}/${path.replace(/^\\//, '')}`;\r\n}\r\n\r\n/**\r\n * Transform a raw API venue to normalized Venue\r\n */\r\nexport function transformVenue(apiVenue: ApiVenue): Venue {\r\n const logoPath =\r\n apiVenue.logoUrl || apiVenue.logo_url || apiVenue.logo;\r\n\r\n return {\r\n id: apiVenue.id || apiVenue.ID || 0,\r\n name: apiVenue.name || '',\r\n slug: apiVenue.slug,\r\n address: apiVenue.address,\r\n googleLocationNameCache:\r\n apiVenue.googleLocationNameCache ||\r\n apiVenue.google_location_name_cache,\r\n city: apiVenue.city,\r\n state: apiVenue.state,\r\n zipCode: apiVenue.zipCode || apiVenue.zip_code,\r\n country: apiVenue.country,\r\n timezone: apiVenue.timezone || apiVenue.time_zone,\r\n logoUrl: getLogoUrl(logoPath),\r\n serviceFeePercentage:\r\n apiVenue.serviceFeePercentage ??\r\n apiVenue.service_fee_percentage ??\r\n 0,\r\n serviceFeeCents:\r\n apiVenue.serviceFeeCents ?? apiVenue.service_fee_cents ?? 0,\r\n taxPercentage:\r\n apiVenue.taxPercentage ?? apiVenue.tax_percentage ?? 0,\r\n organizationId:\r\n apiVenue.organizationId || apiVenue.organization_id,\r\n };\r\n}\r\n\r\n/**\r\n * Extract fee configuration from venue\r\n */\r\nexport function extractVenueFees(apiVenue: ApiVenue): {\r\n serviceFeePercentage: number;\r\n serviceFeeCents: number;\r\n taxPercentage: number;\r\n} {\r\n return {\r\n serviceFeePercentage:\r\n apiVenue.serviceFeePercentage ??\r\n apiVenue.service_fee_percentage ??\r\n 0,\r\n serviceFeeCents:\r\n apiVenue.serviceFeeCents ?? apiVenue.service_fee_cents ?? 0,\r\n taxPercentage:\r\n apiVenue.taxPercentage ?? apiVenue.tax_percentage ?? 0,\r\n };\r\n}\r\n\r\n/**\r\n * Get formatted venue address\r\n */\r\nexport function formatVenueAddress(venue: Venue): string {\r\n const parts = [\r\n venue.address,\r\n venue.city,\r\n venue.state,\r\n venue.zipCode,\r\n ].filter(Boolean);\r\n\r\n return parts.join(', ');\r\n}\r\n"],"names":["LOG_LEVELS","isEnabled","createLogger","prefix","options","config","shouldLog","level","formatMessage","message","args","opts","logger","DEFAULT_CONFIG","error","globalConfig","configureApi","getApiConfig","getPublicBaseUrl","getLegacyPublicUrl","getOrdersV2Url","getClientIP","apiGet","endpoint","apiRequest","apiPost","body","apiPut","apiDelete","method","url","controller","timeoutId","response","errorData","errorMessage","simpleFetch","createPaymentIntent","cartId","quantities","donationAmounts","data","completeReservation","orderUuid","cancelReservation","createOrder","eventId","promoCode","getOrder","orderId","validatePaymentIntent","payload","result","extendCheckoutSession","getSessionStatus","initiateOrder","cartData","trackUTMSource","venueId","utmSource","validatePromoCode","code","encodedCode","hasPromoCodes","applyPromoCode","removePromoCode","fetchEventDetails","customFetch","fetchEventTickets","tickets","fetchEventPerformers","fetchAllVenues","orgId","venues","fetchVenueEvents","events","getMonthEvents","year","month","getOrgMonthEvents","getSeriesOccurrences","eventSeriesId","fetchSeriesOccurrences","fetchSeriesPage","seriesId","fetchPublicCollection","collectionId","password","checkCollectionPassword","encodedPassword","checkEventPassword","testNetworkConnection","getVenue","getVenueFees","venue","getVenueBySlug","slug","encodedSlug","transformTicket","apiTicket","transformOrder","apiOrder","rawTickets","transformOrderForDisplay","order","displayId","CDN_BASE_URL","getCDNImageUrl","path","getEventImageUrl","apiEvent","rawUrl","calculateCtaState","explicitState","eventDate","eventTime","now","availableCount","sum","t","qty","sold","transformEvent","prices","p","minPrice","maxPrice","transformEventData","getLogoUrl","transformVenue","apiVenue","logoPath","extractVenueFees","formatVenueAddress"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"api.cjs","sources":["../../src/lib/api/client.ts","../../src/lib/api/orders.ts","../../src/lib/api/promo.ts","../../src/lib/api/events.ts","../../src/lib/api/venues.ts","../../src/lib/api/gift-cards.ts","../../src/lib/api/waitlist.ts","../../src/lib/api/cta.ts","../../src/lib/api/transformers/order.ts","../../src/lib/api/transformers/event.ts","../../src/lib/api/transformers/venue.ts"],"sourcesContent":["/**\n * API Client for MicDrop Public Checkout API\n *\n * Provides a centralized HTTP client with:\n * - Configurable base URL\n * - Per-request timeout via AbortController\n * - Exponential-backoff retry on 5xx and network errors (idempotent methods)\n * - Consistent error surfacing\n * - Request/response typing\n */\n\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\nconst logger = createLogger('VC');\nimport type { ApiConfig, ApiResponse } from './types.js';\n\n// Default API configuration\nconst DEFAULT_CONFIG: Required<ApiConfig> = {\n baseUrl: 'https://get-micdrop.com',\n timeout: 30000,\n retries: 2,\n retryDelay: 500,\n onError: (error: Error) => logger.error('API Error:', error),\n};\n\nlet globalConfig: Required<ApiConfig> = { ...DEFAULT_CONFIG };\n\nexport function configureApi(config: Partial<ApiConfig>): void {\n globalConfig = { ...globalConfig, ...config };\n}\n\nexport function getApiConfig(): Required<ApiConfig> {\n return { ...globalConfig };\n}\n\nexport function getPublicBaseUrl(): string {\n return `${globalConfig.baseUrl}/api/v2/public`;\n}\n\nexport function getLegacyPublicUrl(): string {\n return `${globalConfig.baseUrl}/api/public`;\n}\n\nexport function getOrdersV2Url(): string {\n return `${globalConfig.baseUrl}/api/orders/v2/public`;\n}\n\n/** @deprecated IP is now resolved server-side via request headers. */\nexport async function getClientIP(): Promise<string> {\n return '';\n}\n\n/**\n * Sleep utility for retry backoff.\n */\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * fetch with timeout, idempotent retry, and exponential backoff.\n *\n * - Retries on network errors and 5xx (transient) responses.\n * - Never retries non-idempotent methods (POST/PUT/PATCH/DELETE) — those are\n * left to caller-driven retries to avoid duplicate writes.\n * - The supplied AbortSignal (if any) is respected and short-circuits retries.\n */\nasync function fetchWithRetry(\n url: string,\n init: RequestInit,\n cfg: Required<ApiConfig>\n): Promise<Response> {\n const method = (init.method || 'GET').toUpperCase();\n const isIdempotent = method === 'GET' || method === 'HEAD';\n const maxAttempts = isIdempotent ? cfg.retries + 1 : 1;\n\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), cfg.timeout);\n\n // Chain the caller's signal if provided.\n const callerSignal = init.signal;\n let onCallerAbort: (() => void) | undefined;\n if (callerSignal) {\n if (callerSignal.aborted) controller.abort();\n else {\n onCallerAbort = () => controller.abort();\n callerSignal.addEventListener('abort', onCallerAbort, { once: true });\n }\n }\n\n try {\n const response = await fetch(url, { ...init, signal: controller.signal });\n\n // Retry transient server errors.\n if (response.status >= 500 && attempt < maxAttempts) {\n lastError = new Error(`HTTP ${response.status}`);\n } else {\n return response;\n }\n } catch (err) {\n lastError = err;\n // Caller aborted — give up.\n if (callerSignal?.aborted) throw err;\n } finally {\n clearTimeout(timeoutId);\n if (callerSignal && onCallerAbort) {\n callerSignal.removeEventListener('abort', onCallerAbort);\n }\n }\n\n if (attempt < maxAttempts) {\n await sleep(cfg.retryDelay * Math.pow(2, attempt - 1));\n }\n }\n\n throw lastError;\n}\n\nexport async function apiGet<T>(\n endpoint: string,\n options?: RequestInit\n): Promise<ApiResponse<T>> {\n return apiRequest<T>('GET', endpoint, undefined, options);\n}\n\nexport async function apiPost<T>(\n endpoint: string,\n body?: unknown,\n options?: RequestInit\n): Promise<ApiResponse<T>> {\n return apiRequest<T>('POST', endpoint, body, options);\n}\n\nexport async function apiPut<T>(\n endpoint: string,\n body?: unknown,\n options?: RequestInit\n): Promise<ApiResponse<T>> {\n return apiRequest<T>('PUT', endpoint, body, options);\n}\n\nexport async function apiDelete<T>(\n endpoint: string,\n options?: RequestInit\n): Promise<ApiResponse<T>> {\n return apiRequest<T>('DELETE', endpoint, undefined, options);\n}\n\nasync function apiRequest<T>(\n method: string,\n endpoint: string,\n body?: unknown,\n options?: RequestInit\n): Promise<ApiResponse<T>> {\n const url = endpoint.startsWith('http')\n ? endpoint\n : `${getPublicBaseUrl()}${endpoint}`;\n\n try {\n const response = await fetchWithRetry(\n url,\n {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...options?.headers,\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n credentials: 'include',\n ...options,\n },\n globalConfig\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const message =\n errorData.error || errorData.message || `HTTP ${response.status}`;\n globalConfig.onError(new Error(message));\n return { success: false, error: message, statusCode: response.status };\n }\n\n const data = await response.json();\n return { success: true, data: data as T, statusCode: response.status };\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.name === 'AbortError'\n ? 'Request timed out'\n : error.message\n : 'Unknown error';\n\n globalConfig.onError(\n error instanceof Error ? error : new Error(errorMessage)\n );\n return { success: false, error: errorMessage };\n }\n}\n\n/**\n * Simple fetch wrapper that returns parsed JSON or null on error.\n * Inherits the global timeout + retry policy for GETs.\n */\nexport async function simpleFetch<T>(\n url: string,\n options?: RequestInit\n): Promise<T | null> {\n try {\n const response = await fetchWithRetry(\n url,\n { credentials: 'include', ...options },\n globalConfig\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n logger.error(`API request failed: ${response.status}`, errorData);\n return null;\n }\n\n return response.json();\n } catch (error) {\n logger.error('API request error:', error);\n return null;\n }\n}\n","/**\n * Orders API\n *\n * Functions for managing orders, payments, and reservations\n * in the public checkout flow.\n */\n\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\nconst logger = createLogger('VC');\nimport {\n getPublicBaseUrl,\n getOrdersV2Url,\n simpleFetch,\n} from './client.js';\nimport type {\n PaymentIntentResponse,\n CompleteReservationResponse,\n CancelReservationResponse,\n CreateOrderResponse,\n ValidatePaymentRequest,\n ValidatePaymentResponse,\n ExtendSessionResponse,\n SessionStatus,\n Order,\n} from './types.js';\n\n/**\n * Create a payment intent for the cart\n *\n * This initiates the Stripe payment flow by creating a PaymentIntent\n * on the backend. The response includes the client_secret needed\n * for Stripe Elements.\n *\n * @param cartId - The cart/order UUID\n * @param quantities - Map of ticketId -> quantity\n * @param donationAmounts - Map of ticketId -> donation amount in dollars (for type=2 tickets)\n * @returns Payment intent data including client_secret, or null on error\n */\nexport async function createPaymentIntent(\n cartId: string,\n quantities: Record<string | number, number>,\n donationAmounts?: Record<string | number, number>\n): Promise<PaymentIntentResponse | null> {\n try {\n const response = await fetch(\n `${getOrdersV2Url()}/cart/${cartId}/payment-intent`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n credentials: 'include',\n body: JSON.stringify({\n productQuantities: quantities,\n ...(donationAmounts && Object.keys(donationAmounts).length > 0\n ? { donationAmounts }\n : {}),\n }),\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n logger.error('Payment intent creation failed:', errorData);\n throw new Error(errorData.error || 'Failed to create payment intent');\n }\n\n const data = await response.json();\n logger.debug('Payment intent created:', data);\n return data;\n } catch (error) {\n logger.error('createPaymentIntent error:', error);\n return null;\n }\n}\n\n/**\n * Complete reservation after successful payment\n *\n * Called after Stripe confirms the payment to finalize the order\n * and generate tickets.\n *\n * @param orderUuid - The order UUID\n * @returns Success status and message\n */\nexport async function completeReservation(\n orderUuid: string\n): Promise<CompleteReservationResponse> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/orders/complete/${orderUuid}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n error: errorData.error || 'Failed to complete reservation',\n };\n }\n\n const result = await response.json();\n return {\n success: true,\n message: result.message,\n };\n } catch (error) {\n logger.error('Error completing reservation:', error);\n return { success: false, error: 'Network error completing reservation' };\n }\n}\n\n/**\n * Cancel reservation and release tickets back to inventory\n *\n * Called when user abandons checkout or session expires.\n *\n * @param orderUuid - The order UUID\n * @returns Success status and message\n */\nexport async function cancelReservation(\n orderUuid: string\n): Promise<CancelReservationResponse> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/orders/cancel/${orderUuid}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n error: errorData.error || 'Failed to cancel reservation',\n };\n }\n\n const result = await response.json();\n return {\n success: true,\n message: result.message,\n };\n } catch (error) {\n logger.error('Error cancelling reservation:', error);\n return { success: false, error: 'Network error cancelling reservation' };\n }\n}\n\n/**\n * Create a new order/cart\n *\n * This creates an empty order that can be used for checkout.\n * The order UUID is used for all subsequent operations.\n *\n * @param eventId - The event ID\n * @param promoCode - Optional promo code to apply\n * @returns The order UUID, or null on error\n */\nexport async function createOrder(\n eventId: string | number,\n promoCode?: string\n): Promise<CreateOrderResponse | null> {\n try {\n const response = await fetch(`${getPublicBaseUrl()}/orders/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n eventID: eventId,\n promoCode,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n logger.error('Create order failed:', errorData);\n return null;\n }\n\n return response.json();\n } catch (error) {\n logger.error('createOrder error:', error);\n return null;\n }\n}\n\n/**\n * Get order details (public, no auth required)\n *\n * Fetches the order details for displaying on the success page.\n *\n * @param orderId - The order UUID or ID\n * @returns The order details, or null on error\n */\nexport async function getOrder(orderId: string): Promise<Order | null> {\n return simpleFetch<Order>(`${getPublicBaseUrl()}/orders/${orderId}`);\n}\n\n/**\n * Validate payment intent and complete the order\n *\n * This is an alternative to completeReservation that accepts\n * additional payment details. Used by micdrop-frontend.\n *\n * @param cartId - The cart/order UUID\n * @param payload - Payment validation payload\n * @returns Validation result\n */\nexport async function validatePaymentIntent(\n cartId: string,\n payload: ValidatePaymentRequest\n): Promise<ValidatePaymentResponse | null> {\n try {\n const response = await fetch(\n `${getOrdersV2Url()}/validatePaymentIntent/${cartId}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n logger.error('Payment validation failed:', errorData);\n return {\n success: false,\n status: 'failed',\n error: errorData.error || 'Payment validation failed',\n };\n }\n\n const result = await response.json();\n return {\n success: true,\n status: result.status || 'Payment succeeded',\n orderUUID: result.orderUUID || result.uuid,\n };\n } catch (error) {\n logger.error('validatePaymentIntent error:', error);\n return null;\n }\n}\n\n/**\n * Extend the checkout session by 15 minutes\n *\n * Users get a limited number of extensions (typically 2-3).\n *\n * @param orderUuid - The order UUID\n * @returns Extension result with new expiry time\n */\nexport async function extendCheckoutSession(\n orderUuid: string\n): Promise<ExtendSessionResponse> {\n try {\n const response = await fetch(`${getPublicBaseUrl()}/orders/extend-session`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ orderUuid }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n error: errorData.error || 'Failed to extend session',\n };\n }\n\n const result = await response.json();\n return {\n success: true,\n newExpiryTime: result.newExpiryTime,\n remainingExtensions: result.remainingExtensions,\n };\n } catch (error) {\n logger.error('Error extending checkout session:', error);\n return { success: false, error: 'Network error extending session' };\n }\n}\n\n/**\n * Get current session status including expiry time\n *\n * Used to display countdown timer and check if extensions are available.\n *\n * @param orderUuid - The order UUID\n * @returns Session status including expiry time\n */\nexport async function getSessionStatus(orderUuid: string): Promise<SessionStatus> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/orders/session/${orderUuid}`\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return { error: errorData.error || 'No active session found' };\n }\n\n const result = await response.json();\n return {\n expiresAt: result.expiresAt,\n extensionCount: result.extensionCount,\n remainingExtensions: result.remainingExtensions,\n canExtend: result.canExtend,\n reservationCount: result.reservationCount,\n };\n } catch (error) {\n logger.error('Error getting session status:', error);\n return { error: 'Network error getting session status' };\n }\n}\n\n/**\n * Initiate a new order (alias for createOrder)\n *\n * This function provides backwards compatibility with micdrop-frontend.\n * It accepts the same parameters as the legacy initiateOrder function.\n *\n * @param cartData - Object containing eventID and optional quantities/promoCode\n * @returns The order UUID, or null on error\n */\nexport async function initiateOrder(\n cartData: { eventID: string | number; promoCode?: string; quantities?: Record<string | number, number> } = {} as any\n): Promise<string | null> {\n try {\n const response = await fetch(`${getPublicBaseUrl()}/orders/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(cartData),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n logger.error('Order initiation failed:', errorData);\n return null;\n }\n\n const data = await response.json();\n return data.uuid;\n } catch (error) {\n logger.error('initiateOrder error:', error);\n return null;\n }\n}\n\n/**\n * Track UTM source for analytics\n *\n * Records the traffic source (utm_source parameter) for marketing analytics.\n *\n * @param venueId - The venue ID\n * @returns Promise that resolves when tracking is complete\n */\nexport async function trackUTMSource(venueId: string | number): Promise<void> {\n if (typeof window === 'undefined') return;\n\n const urlParams = new URLSearchParams(window.location.search);\n const utmSource = urlParams.get('utm_source') || 'Direct';\n\n try {\n await fetch(\n `${getPublicBaseUrl()}/utm/${venueId}/${encodeURIComponent(utmSource)}`\n );\n } catch (error) {\n logger.error('UTM tracking failed:', error);\n }\n}\n","/**\n * Promo Codes API\n *\n * Functions for validating and checking promo codes\n * in the public checkout flow.\n */\n\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\nconst logger = createLogger('VC');\nimport { getPublicBaseUrl } from './client.js';\nimport type { PromoValidationResponse, HasPromoCodesResponse } from './types.js';\n\n/**\n * Validate a promo code for an event\n *\n * Checks if a promo code is valid and returns its effects:\n * - Discount amount and type\n * - Hidden ticket reveal\n *\n * @param eventId - The event ID\n * @param code - The promo code to validate\n * @returns Validation result with discount info\n */\nexport async function validatePromoCode(\n eventId: string | number,\n code: string\n): Promise<PromoValidationResponse> {\n try {\n if (!code || !code.trim()) {\n return { valid: false, error: 'Promo code is required' };\n }\n\n // API uses GET with code in URL path\n const encodedCode = encodeURIComponent(code.trim());\n const response = await fetch(\n `${getPublicBaseUrl()}/promo-codes/validate/${eventId}/${encodedCode}`\n );\n\n if (!response.ok) {\n // 404 = invalid code, other errors are server issues\n if (response.status === 404) {\n return { valid: false, error: 'Invalid promo code' };\n }\n const errorData = await response.json().catch(() => ({}));\n return { valid: false, error: errorData.error || 'Failed to validate code' };\n }\n\n const result = await response.json();\n return {\n valid: result.valid ?? true,\n revealHiddenTickets: result.revealHiddenTickets,\n revealTicketIds: result.revealTicketIds,\n provideDiscount: result.provideDiscount,\n discountType: result.discountType,\n amount: result.amount,\n code: result.code || code,\n };\n } catch (error) {\n logger.error('Error validating promo code:', error);\n return { valid: false, error: 'Network error validating code' };\n }\n}\n\n/**\n * Check if promo codes are available for an event\n *\n * Used to conditionally show/hide the promo code input field.\n *\n * @param eventId - The event ID\n * @returns Whether promo codes exist for this event\n */\nexport async function hasPromoCodes(eventId: string | number): Promise<boolean> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/promo-codes/check/${eventId}`\n );\n\n if (!response.ok) {\n // If endpoint doesn't exist or errors, default to showing the input\n return true;\n }\n\n const result: HasPromoCodesResponse = await response.json();\n return result.hasPromoCodes === true;\n } catch (error) {\n logger.error('Error checking promo codes availability:', error);\n // Default to showing promo input if we can't check\n return true;\n }\n}\n\n/**\n * Apply a promo code to a cart\n *\n * This updates the cart with the promo code discount.\n *\n * @param cartId - The cart UUID\n * @param code - The promo code to apply\n * @returns Success status\n */\nexport async function applyPromoCode(\n cartId: string,\n code: string\n): Promise<{ success: boolean; error?: string }> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/orders/${cartId}/apply-promo`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ code }),\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n error: errorData.error || 'Failed to apply promo code',\n };\n }\n\n return { success: true };\n } catch (error) {\n logger.error('Error applying promo code:', error);\n return { success: false, error: 'Network error applying code' };\n }\n}\n\n/**\n * Remove a promo code from a cart\n *\n * @param cartId - The cart UUID\n * @returns Success status\n */\nexport async function removePromoCode(\n cartId: string\n): Promise<{ success: boolean; error?: string }> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/orders/${cartId}/remove-promo`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n error: errorData.error || 'Failed to remove promo code',\n };\n }\n\n return { success: true };\n } catch (error) {\n logger.error('Error removing promo code:', error);\n return { success: false, error: 'Network error removing code' };\n }\n}\n","/**\n * Events API\n *\n * Functions for fetching event data, tickets, and performers\n * in the public checkout flow.\n */\n\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\nconst logger = createLogger('VC');\nimport { getPublicBaseUrl, simpleFetch } from './client.js';\nimport type {\n Event,\n AvailableTicket,\n EventPerformersResponse,\n SeriesOccurrencesResponse,\n SeriesPageData,\n PublicCollectionData,\n} from './types.js';\n\n/**\n * In-flight `fetchEventDetails` requests keyed by event ID. Lets\n * concurrent callers (Checkout, CartView, EventDetailsView, +page.js\n * server load — all of which may run during a single navigation) share\n * one HTTP request rather than triggering three.\n *\n * The entry deletes as soon as the underlying promise settles, so this\n * is dedup not cache. For real cache-with-TTL we'd want SWR; that's a\n * future milestone.\n */\nconst _eventDetailsInflight = new Map<string, Promise<Event | null>>();\n\n/**\n * Fetch event details\n *\n * Gets full event information including venue and ticket data.\n *\n * @param eventId - The event ID\n * @param customFetch - Optional custom fetch function (for SSR)\n * @returns Event details or null on error\n */\nexport async function fetchEventDetails(\n eventId: string | number,\n customFetch: typeof fetch = fetch\n): Promise<Event | null> {\n const key = String(eventId);\n // Only dedup when using the default fetch — custom-fetch callers\n // (e.g. SvelteKit server loads) bring their own request context.\n if (customFetch === fetch) {\n const inflight = _eventDetailsInflight.get(key);\n if (inflight) return inflight;\n }\n\n const run = (async () => {\n try {\n const response = await customFetch(`${getPublicBaseUrl()}/events/${eventId}`);\n if (!response.ok) {\n throw new Error(`Failed to fetch event details: ${response.status}`);\n }\n return await response.json();\n } catch (error) {\n logger.error('Error fetching event details:', error);\n return null;\n }\n })();\n\n if (customFetch === fetch) {\n _eventDetailsInflight.set(key, run);\n run.finally(() => {\n // Only clear if this same promise is still the inflight one — a\n // later call may have set up a fresh request after the user\n // triggered an explicit refresh.\n if (_eventDetailsInflight.get(key) === run) {\n _eventDetailsInflight.delete(key);\n }\n });\n }\n return run;\n}\n\n/**\n * Fetch available tickets for an event\n *\n * Returns all ticket types that are currently available for sale.\n *\n * @param eventId - The event ID\n * @returns Array of available tickets\n */\nexport async function fetchEventTickets(\n eventId: string | number\n): Promise<AvailableTicket[]> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/tickets/event/${eventId}`\n );\n\n if (!response.ok) {\n throw new Error(`Failed to fetch tickets: ${response.status}`);\n }\n\n const tickets = await response.json();\n return Array.isArray(tickets) ? tickets : [];\n } catch (error) {\n logger.error('Error fetching tickets:', error);\n return [];\n }\n}\n\n/**\n * Fetch performers for an event\n *\n * Returns the lineup with pre-resolved avatar URLs.\n *\n * @param eventId - The event ID\n * @returns Performers list and visibility flag\n */\nexport async function fetchEventPerformers(\n eventId: string | number\n): Promise<EventPerformersResponse> {\n try {\n if (!eventId) {\n logger.warn('fetchEventPerformers called without eventId');\n return { performers: [], showPerformers: false };\n }\n\n const response = await fetch(\n `${getPublicBaseUrl()}/events/${eventId}/performers`\n );\n\n if (!response.ok) {\n logger.error(\n `Failed to fetch performers: ${response.status} ${response.statusText}`\n );\n return { performers: [], showPerformers: false };\n }\n\n const data = await response.json();\n return {\n performers: Array.isArray(data.performers) ? data.performers : [],\n showPerformers: data.showPerformers === true,\n };\n } catch (error) {\n logger.error('Error fetching event performers:', error);\n return { performers: [], showPerformers: false };\n }\n}\n\n/**\n * Fetch all venues for an organization\n *\n * @param orgId - The organization ID\n * @returns Array of venues\n */\nexport async function fetchAllVenues(orgId: string | number): Promise<any[]> {\n try {\n if (!orgId) {\n logger.warn('fetchAllVenues called without orgId');\n return [];\n }\n\n const response = await fetch(\n `${getPublicBaseUrl()}/venues/organization/${orgId}`\n );\n\n if (!response.ok) {\n logger.error(\n `Failed to fetch venues: ${response.status} ${response.statusText}`\n );\n return [];\n }\n\n const venues = await response.json();\n return Array.isArray(venues) ? venues : [];\n } catch (error) {\n logger.error('Error fetching venues:', error);\n return [];\n }\n}\n\n/**\n * Fetch events for a venue\n *\n * @param venueId - The venue ID\n * @returns Array of events\n */\nexport async function fetchVenueEvents(venueId: string | number): Promise<Event[]> {\n try {\n if (!venueId) {\n logger.warn('fetchVenueEvents called without venueId');\n return [];\n }\n\n const response = await fetch(\n `${getPublicBaseUrl()}/events/venue/${venueId}`\n );\n\n if (!response.ok) {\n logger.error(\n `Failed to fetch venue events: ${response.status} ${response.statusText}`\n );\n return [];\n }\n\n const events = await response.json();\n return Array.isArray(events) ? events : [];\n } catch (error) {\n logger.error('Error fetching venue events:', error);\n return [];\n }\n}\n\n/**\n * Get events for a specific month\n *\n * Used for calendar views to efficiently load events.\n *\n * @param venueId - The venue ID\n * @param year - The year (e.g., 2024)\n * @param month - The month (1-12)\n * @returns Array of events for the month\n */\nexport async function getMonthEvents(\n venueId: string | number,\n year: number,\n month: number\n): Promise<Event[]> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/events/venue/${venueId}/month/${year}/${month}`\n );\n\n if (!response.ok) {\n logger.error(`Failed to fetch month events: ${response.status}`);\n return [];\n }\n\n const data = await response.json();\n return Array.isArray(data.events) ? data.events : Array.isArray(data) ? data : [];\n } catch (error) {\n logger.error('Error fetching month events:', error);\n return [];\n }\n}\n\n/**\n * Get events for an organization for a specific month\n *\n * @param orgId - The organization ID\n * @param year - The year (e.g., 2024)\n * @param month - The month (1-12)\n * @returns Array of events for the month\n */\nexport async function getOrgMonthEvents(\n orgId: string | number,\n year: number,\n month: number\n): Promise<Event[]> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/events/organization/${orgId}/month/${year}/${month}`\n );\n\n if (!response.ok) {\n logger.error(`Failed to fetch org month events: ${response.status}`);\n return [];\n }\n\n const data = await response.json();\n return Array.isArray(data.events) ? data.events : Array.isArray(data) ? data : [];\n } catch (error) {\n logger.error('Error fetching org month events:', error);\n return [];\n }\n}\n\n/**\n * Get series occurrences for date selector\n *\n * Returns all instances of a recurring event series.\n *\n * @param eventSeriesId - The series ID\n * @returns Series occurrences\n */\nexport async function getSeriesOccurrences(\n eventSeriesId: number\n): Promise<SeriesOccurrencesResponse | null> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/series/${eventSeriesId}/occurrences`\n );\n\n if (!response.ok) {\n logger.error(`Failed to fetch series occurrences: ${response.status}`);\n return null;\n }\n\n return response.json();\n } catch (error) {\n logger.error('Error fetching series occurrences:', error);\n return null;\n }\n}\n\n/**\n * Fetch series occurrences with CTA state\n *\n * Returns full series data including availability status.\n *\n * @param eventSeriesId - The series ID\n * @param venueId - The venue ID\n * @returns Series occurrences with CTA state\n */\nexport async function fetchSeriesOccurrences(\n eventSeriesId: number,\n venueId: string | number\n): Promise<SeriesOccurrencesResponse | null> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/series/${eventSeriesId}/occurrences?venueId=${venueId}`\n );\n\n if (!response.ok) {\n logger.error(`Failed to fetch series with CTA: ${response.status}`);\n return null;\n }\n\n return response.json();\n } catch (error) {\n logger.error('Error fetching series occurrences:', error);\n return null;\n }\n}\n\n/**\n * Fetch series page data\n *\n * Returns full series information including occurrences, venue, and performers.\n *\n * @param seriesId - The series ID\n * @returns Series page data or null on error\n */\nexport async function fetchSeriesPage(\n seriesId: string | number\n): Promise<SeriesPageData | null> {\n try {\n const response = await fetch(\n `${getPublicBaseUrl()}/series/${seriesId}/page`\n );\n\n if (!response.ok) {\n throw new Error(`Failed to fetch series page: ${response.status}`);\n }\n\n return response.json();\n } catch (error) {\n logger.error('Error fetching series page:', error);\n return null;\n }\n}\n\n/**\n * Fetch public collection data\n *\n * Returns collection info including events list.\n * For password-protected collections, pass the password to authenticate.\n *\n * @param collectionId - The collection ID\n * @param password - Optional password for protected collections\n * @returns Collection data or null on error\n */\nexport async function fetchPublicCollection(\n collectionId: string | number,\n password?: string\n): Promise<PublicCollectionData | null> {\n try {\n const url = password\n ? `${getPublicBaseUrl()}/collections/${collectionId}/public?password=${encodeURIComponent(password)}`\n : `${getPublicBaseUrl()}/collections/${collectionId}/public`;\n\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch collection: ${response.status}`);\n }\n\n return response.json();\n } catch (error) {\n logger.error('Error fetching collection:', error);\n return null;\n }\n}\n\n/**\n * Check collection password\n *\n * Validates password for password-protected collections.\n *\n * @param collectionId - The collection ID\n * @param password - The password to check\n * @returns Whether the password is valid\n */\nexport async function checkCollectionPassword(\n collectionId: string | number,\n password: string\n): Promise<boolean> {\n try {\n const encodedPassword = encodeURIComponent(password);\n const response = await fetch(\n `${getPublicBaseUrl()}/collections/${collectionId}/check-password/${encodedPassword}`\n );\n\n if (!response.ok) {\n return false;\n }\n\n const result = await response.json();\n return result.valid === true;\n } catch (error) {\n logger.error('Error checking collection password:', error);\n return false;\n }\n}\n\n/**\n * Check event password\n *\n * Validates password for password-protected events.\n *\n * @param eventId - The event ID\n * @param password - The password to check\n * @returns Whether the password is valid\n */\nexport async function checkEventPassword(\n eventId: string | number,\n password: string\n): Promise<{ valid: boolean }> {\n try {\n // POST in the body — never in the URL path, which is captured by\n // access logs, browser history, and Referer headers.\n const response = await fetch(\n `${getPublicBaseUrl()}/events/${eventId}/check-password`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ password }),\n }\n );\n\n if (!response.ok) return { valid: false };\n\n const result = await response.json();\n if (typeof result === 'boolean') return { valid: result };\n return { valid: result.valid === true || result === true };\n } catch (error) {\n logger.error('Error checking event password:', error);\n return { valid: false };\n }\n}\n\n/**\n * Test network connection\n *\n * Health check endpoint for connectivity testing.\n *\n * @param orgId - Optional org ID\n * @param venueId - Optional venue ID\n * @returns Whether the connection is working\n */\nexport async function testNetworkConnection(\n orgId?: string | number,\n venueId?: string | number\n): Promise<boolean> {\n try {\n // Use a simple endpoint to test connectivity\n const url = venueId\n ? `${getPublicBaseUrl()}/events/venue/${venueId}`\n : orgId\n ? `${getPublicBaseUrl()}/venues/organization/${orgId}`\n : `${getPublicBaseUrl()}/health`;\n\n const response = await fetch(url, {\n method: 'HEAD',\n });\n\n return response.ok;\n } catch (error) {\n logger.error('Network connection test failed:', error);\n return false;\n }\n}\n","/**\n * Venues API\n *\n * Functions for fetching venue data including\n * service fees and tax configuration.\n */\n\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\nconst logger = createLogger('VC');\nimport { getPublicBaseUrl, simpleFetch } from './client.js';\nimport type { Venue } from './types.js';\n\n/**\n * Get venue details (public, no auth required)\n *\n * Fetches venue information including service fees and taxes\n * needed for checkout calculations.\n *\n * @param venueId - The venue ID\n * @returns Venue details or null on error\n */\nexport async function getVenue(venueId: string | number): Promise<Venue | null> {\n try {\n if (!venueId) {\n logger.warn('getVenue called without venueId');\n return null;\n }\n\n const response = await fetch(`${getPublicBaseUrl()}/venues/${venueId}`);\n\n if (!response.ok) {\n logger.error(`Failed to fetch venue: ${response.status}`);\n return null;\n }\n\n return response.json();\n } catch (error) {\n logger.error('Error fetching venue:', error);\n return null;\n }\n}\n\n/**\n * Get venue service fee configuration\n *\n * Returns just the fee-related fields for checkout calculations.\n *\n * @param venueId - The venue ID\n * @returns Fee configuration or null on error\n */\nexport async function getVenueFees(\n venueId: string | number\n): Promise<{\n serviceFeePercentage: number;\n serviceFeeCents: number;\n taxPercentage: number;\n} | null> {\n const venue = await getVenue(venueId);\n\n if (!venue) {\n return null;\n }\n\n return {\n serviceFeePercentage: venue.serviceFeePercentage ?? 0,\n serviceFeeCents: venue.serviceFeeCents ?? 0,\n taxPercentage: venue.taxPercentage ?? 0,\n };\n}\n\n/**\n * Get venue by slug\n *\n * Fetches venue using its URL-friendly slug.\n *\n * @param slug - The venue slug\n * @returns Venue details or null on error\n */\nexport async function getVenueBySlug(slug: string): Promise<Venue | null> {\n try {\n if (!slug) {\n logger.warn('getVenueBySlug called without slug');\n return null;\n }\n\n const encodedSlug = encodeURIComponent(slug);\n const response = await fetch(`${getPublicBaseUrl()}/venues/slug/${encodedSlug}`);\n\n if (!response.ok) {\n logger.error(`Failed to fetch venue by slug: ${response.status}`);\n return null;\n }\n\n return response.json();\n } catch (error) {\n logger.error('Error fetching venue by slug:', error);\n return null;\n }\n}\n","/**\n * Gift Card Purchase API Client\n * Handles gift card purchase creation, cart application/removal,\n * and gift-card-only checkout completion.\n */\n\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\nimport { getOrdersV2Url } from './client.js';\nconst logger = createLogger('VC');\n\nconst API_BASE_URL = 'https://get-micdrop.com';\nconst ORDERS_V2_URL = `${API_BASE_URL}/api/orders/v2`;\nconst ORDERS_V2_PUBLIC = () => getOrdersV2Url();\n\n/**\n * Request payload for creating a gift card purchase\n */\nexport interface GiftCardPurchaseRequest {\n venueId: number;\n amount: number; // In cents (e.g., 5000 = $50.00)\n recipientEmail: string;\n recipientName: string;\n personalMessage?: string;\n purchaserEmail: string;\n purchaserName: string;\n scheduledDeliveryAt?: string | null; // ISO date string or null for immediate\n}\n\n/**\n * Response from gift card purchase creation\n */\nexport interface GiftCardPurchaseResponse {\n giftCardUUID: string;\n clientSecret: string;\n amount: number;\n stripePublishableKey: string;\n}\n\n/**\n * Venue information needed for gift card purchase\n */\nexport interface VenueInfo {\n id: number;\n name: string;\n slug: string;\n stripePublishableKey?: string;\n}\n\n/**\n * Create a gift card purchase and get Stripe client secret\n * @param req - Gift card purchase request details\n * @returns Gift card UUID and Stripe client secret, or null on failure\n */\nexport async function createGiftCardPurchase(\n req: GiftCardPurchaseRequest\n): Promise<GiftCardPurchaseResponse | null> {\n try {\n const response = await fetch(\n `${ORDERS_V2_URL}/gift-cards`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n logger.error('Gift card purchase creation failed:', errorData);\n throw new Error(errorData.error || 'Failed to create gift card purchase');\n }\n\n const data = await response.json();\n logger.debug('Gift card purchase created:', data);\n return data;\n } catch (error) {\n logger.error('Gift card purchase creation error:', error);\n return null;\n }\n}\n\nexport interface ApplyGiftCardResult {\n valid: boolean;\n giftCardCode?: string;\n giftCardAmount?: number;\n giftCardBalance?: number;\n paymentType?: string;\n stripeAmount?: number;\n orderTotal?: number;\n requiresStripe?: boolean;\n error?: string;\n}\n\n/**\n * Apply a gift card to a cart.\n */\nexport async function applyGiftCard(\n cartId: string,\n code: string\n): Promise<ApplyGiftCardResult> {\n try {\n const res = await fetch(`${ORDERS_V2_PUBLIC()}/cart/${cartId}/apply-gift-card`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ giftCardCode: code }),\n });\n\n if (!res.ok) {\n if (res.status === 429) {\n return {\n valid: false,\n error: 'Too many attempts. Please wait a moment and try again.',\n };\n }\n const errorData = await res.json().catch(() => ({}));\n logger.error('Apply gift card failed:', errorData);\n return { valid: false, error: errorData.error || 'Invalid gift card code' };\n }\n\n const data = await res.json();\n return {\n valid: true,\n giftCardCode: data.giftCardCode,\n giftCardAmount: data.giftCardAmount,\n giftCardBalance: data.giftCardBalance,\n paymentType: data.paymentType,\n stripeAmount: data.stripeAmount,\n orderTotal: data.orderTotal,\n requiresStripe: data.requiresStripe,\n };\n } catch (err) {\n logger.error('applyGiftCard error:', err);\n return {\n valid: false,\n error: 'Network error. Please check your connection and try again.',\n };\n }\n}\n\nexport interface RemoveGiftCardResult {\n success: boolean;\n error?: string;\n}\n\n/**\n * Remove a gift card from a cart.\n */\nexport async function removeGiftCard(cartId: string): Promise<RemoveGiftCardResult> {\n try {\n const res = await fetch(`${ORDERS_V2_PUBLIC()}/cart/${cartId}/gift-card`, {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!res.ok) {\n const errorData = await res.json().catch(() => ({}));\n logger.error('Remove gift card failed:', errorData);\n return { success: false, error: errorData.error || 'Failed to remove gift card' };\n }\n\n return { success: true };\n } catch (err) {\n logger.error('removeGiftCard error:', err);\n return {\n success: false,\n error: 'Network error. Please check your connection and try again.',\n };\n }\n}\n\nexport interface CompleteGiftCardPaymentInput {\n firstName: string;\n lastName: string;\n email: string;\n phoneNumber?: string | null;\n mailingList?: boolean;\n}\n\nexport interface CompleteGiftCardPaymentResult {\n success: boolean;\n orderId?: string;\n confirmationNumber?: string;\n error?: string;\n}\n\n/**\n * Complete a gift-card-only payment (no Stripe required when balance >= total).\n */\nexport async function completeGiftCardPayment(\n cartId: string,\n customerDetails: CompleteGiftCardPaymentInput\n): Promise<CompleteGiftCardPaymentResult> {\n try {\n const res = await fetch(\n `${ORDERS_V2_PUBLIC()}/cart/${cartId}/complete-gift-card-payment`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n firstName: customerDetails.firstName,\n lastName: customerDetails.lastName,\n email: customerDetails.email,\n phoneNumber: customerDetails.phoneNumber || null,\n mailingList: customerDetails.mailingList || false,\n }),\n }\n );\n\n if (!res.ok) {\n const errorData = await res.json().catch(() => ({}));\n logger.error('Complete gift card payment failed:', errorData);\n return { success: false, error: errorData.error || 'Failed to complete payment' };\n }\n\n const data = await res.json();\n return {\n success: true,\n orderId: data.orderId,\n confirmationNumber: data.confirmationNumber,\n };\n } catch (err) {\n logger.error('completeGiftCardPayment error:', err);\n return {\n success: false,\n error: 'Network error. Please check your connection and try again.',\n };\n }\n}\n\n/**\n * Fetch venue information by slug\n * @param slug - Venue slug\n * @returns Venue info or null on failure\n */\nexport async function getVenueBySlug(\n slug: string,\n customFetch: typeof fetch = fetch\n): Promise<VenueInfo | null> {\n try {\n const response = await customFetch(\n `${API_BASE_URL}/api/v2/public/venues/slug/${slug}`\n );\n\n if (!response.ok) {\n logger.error(`Failed to fetch venue by slug: ${response.status}`);\n return null;\n }\n\n const venue = await response.json();\n return {\n id: venue.id,\n name: venue.name,\n slug: venue.slug,\n stripePublishableKey: venue.stripePublishableKey,\n };\n } catch (error) {\n logger.error('Error fetching venue by slug:', error);\n return null;\n }\n}\n","/**\n * Waitlist API\n *\n * Endpoints for the sold-out-event waitlist flow.\n */\n\nimport { createLogger } from '@getmicdrop/svelte-components/utils/logger';\nimport { getPublicBaseUrl } from './client.js';\n\nconst logger = createLogger('VC');\n\nexport interface JoinWaitlistResult {\n success: boolean;\n position?: number;\n updated?: boolean;\n error?: string;\n}\n\nconst WAITLIST_ERROR_MESSAGES: Record<string, string> = {\n waitlist_not_enabled: 'Waitlist is not available for this event',\n event_not_found: 'Event not found',\n invalid_phone: 'Please enter a valid phone number',\n already_purchased: 'You have already purchased tickets for this event',\n phone_already_registered: 'This phone number is already on the waitlist',\n};\n\n/**\n * Join the waitlist for a sold-out event.\n */\nexport async function joinWaitlist(\n eventId: string | number,\n email: string,\n phone: string | null = null,\n smsOptIn = false\n): Promise<JoinWaitlistResult> {\n try {\n const body: Record<string, unknown> = { email };\n if (phone && smsOptIn) {\n body.phone = phone;\n body.smsOptIn = true;\n }\n\n const res = await fetch(`${getPublicBaseUrl()}/events/${eventId}/waitlist`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const errorData = await res.json().catch(() => ({}));\n logger.error('Join waitlist failed:', errorData);\n return {\n success: false,\n error:\n WAITLIST_ERROR_MESSAGES[errorData.error] ||\n 'Failed to join waitlist. Please try again.',\n };\n }\n\n const data = await res.json();\n return {\n success: true,\n position: data.position,\n updated: data.updated,\n };\n } catch (err) {\n logger.error('joinWaitlist error:', err);\n return {\n success: false,\n error: 'Network error. Please check your connection and try again.',\n };\n }\n}\n\nexport interface WaitlistPositionResult {\n position: number | null;\n error?: string;\n}\n\n/**\n * Get a customer's current position in the waitlist (or null if not on it).\n */\nexport async function getWaitlistPosition(\n eventId: string | number,\n email: string\n): Promise<WaitlistPositionResult> {\n try {\n const res = await fetch(\n `${getPublicBaseUrl()}/events/${eventId}/waitlist/position?email=${encodeURIComponent(email)}`\n );\n\n if (!res.ok) {\n if (res.status === 404) return { position: null };\n return { position: null, error: 'Failed to check position' };\n }\n\n const data = await res.json();\n return { position: data.position };\n } catch (err) {\n logger.error('getWaitlistPosition error:', err);\n return { position: null, error: 'Network error' };\n }\n}\n","/**\n * CTA state computation.\n *\n * Pure function (no I/O) — derives the buy-button state from an event and\n * its ticket list. Lives in `api/` because it is the canonical, single\n * source of truth that replaces the duplicate implementations previously\n * scattered across utils/api.js, core/api-client.js, and a few components.\n */\n\n// Import from the specific subpath (not the bare entry) so the api/\n// bundle doesn't pull in the entire SC component graph (Accordion etc.)\n// and break `npm run build:api`.\nimport { formatDateRaw } from '@getmicdrop/svelte-components/utils/formatters';\n\nexport interface CtaStateOptions {\n cancelled?: boolean;\n isRegistration?: boolean;\n waitlistEnabled?: boolean;\n}\n\nexport interface CtaState {\n text: string;\n disabled: boolean;\n reason:\n | 'cancelled'\n | 'event_past'\n | 'no_tickets'\n | 'available'\n | 'coming_soon'\n | 'sold_out_waitlist'\n | 'sold_out'\n | 'sales_ended';\n}\n\ninterface CtaEvent {\n startDateTime?: string | null;\n endDateTime?: string | null;\n}\n\ninterface CtaTicket {\n salesChannel?: number;\n salesBegin?: string | null;\n salesStart?: string | null;\n saleBegin?: string | null;\n onSaleStart?: string | null;\n salesEnd?: string | null;\n saleEnd?: string | null;\n onSaleEnd?: string | null;\n remainingCapacity?: number | null;\n quantityRemaining?: number | null;\n quantity?: number | null;\n soldOut?: boolean;\n}\n\nexport function computeCtaState(\n event: CtaEvent,\n tickets: CtaTicket[] | undefined,\n options: CtaStateOptions = {}\n): CtaState {\n const {\n cancelled = false,\n isRegistration = false,\n waitlistEnabled = false,\n } = options;\n const now = new Date();\n\n if (cancelled)\n return { text: 'Cancelled', disabled: true, reason: 'cancelled' };\n\n const eventEnd = event.endDateTime || event.startDateTime;\n if (eventEnd && new Date(eventEnd) < now) {\n return { text: 'Sales ended', disabled: true, reason: 'event_past' };\n }\n\n const publicTickets = (tickets || []).filter(t => t.salesChannel !== 2);\n if (publicTickets.length === 0) {\n return {\n text: 'No tickets available',\n disabled: true,\n reason: 'no_tickets',\n };\n }\n\n let hasPurchasable = false;\n let allSoldOut = true;\n let allComingSoon = true;\n let earliestSalesStart: Date | null = null;\n\n for (const ticket of publicTickets) {\n const salesBegin =\n ticket.salesBegin ||\n ticket.salesStart ||\n ticket.saleBegin ||\n ticket.onSaleStart;\n const salesEnd = ticket.salesEnd || ticket.saleEnd || ticket.onSaleEnd;\n const remaining =\n ticket.remainingCapacity ?? ticket.quantityRemaining ?? ticket.quantity;\n const isSoldOut =\n ticket.soldOut ||\n (remaining !== null && remaining !== undefined && remaining <= 0);\n\n const isScheduled = salesBegin ? new Date(salesBegin) > now : false;\n const hasSalesEnded = salesEnd ? new Date(salesEnd) < now : false;\n const isPurchasable = !isSoldOut && !isScheduled && !hasSalesEnded;\n\n if (isPurchasable) hasPurchasable = true;\n if (!isSoldOut) allSoldOut = false;\n if (!isScheduled) allComingSoon = false;\n\n if (isScheduled && salesBegin && !isSoldOut && !hasSalesEnded) {\n const startDate = new Date(salesBegin);\n if (!earliestSalesStart || startDate < earliestSalesStart) {\n earliestSalesStart = startDate;\n }\n }\n }\n\n if (hasPurchasable) {\n return {\n text: isRegistration ? 'Reserve a spot' : 'Get tickets',\n disabled: false,\n reason: 'available',\n };\n }\n\n if (allComingSoon && earliestSalesStart) {\n const diffMs = earliestSalesStart.getTime() - now.getTime();\n const diffHours = diffMs / (1000 * 60 * 60);\n const diffDays = diffMs / (1000 * 60 * 60 * 24);\n let dateText: string;\n if (diffHours < 24) {\n dateText = earliestSalesStart.toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n });\n } else if (diffDays <= 7) {\n dateText = formatDateRaw(\n earliestSalesStart,\n { weekday: 'short', hour: 'numeric', minute: '2-digit', hour12: true },\n 'en-US'\n );\n } else {\n const d = formatDateRaw(\n earliestSalesStart,\n { month: 'short', day: 'numeric' },\n 'en-US'\n );\n const t = earliestSalesStart.toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n });\n dateText = `${d} ${t}`;\n }\n return {\n text: `On sale ${dateText}`,\n disabled: true,\n reason: 'coming_soon',\n };\n }\n\n if (allSoldOut) {\n if (waitlistEnabled) {\n return {\n text: 'Join Waitlist',\n disabled: false,\n reason: 'sold_out_waitlist',\n };\n }\n return { text: 'Sold out', disabled: true, reason: 'sold_out' };\n }\n\n return { text: 'Sales ended', disabled: true, reason: 'sales_ended' };\n}\n","import type { USD } from '@getmicdrop/svelte-components/utils/formatters';\nimport { formatCurrency } from '@getmicdrop/svelte-components/utils/formatters';\n/**\n * Order Transformer\n *\n * Normalizes API order responses to a consistent format.\n * Handles variations in field names between different API versions.\n */\n\nimport type { Order, PurchasedTicket } from '../types.js';\n\n/**\n * Raw API order response (may have varying field names)\n */\ninterface ApiOrder {\n uuid?: string;\n id?: number;\n ID?: number;\n customerEmail?: string;\n email?: string;\n customer_email?: string;\n customerFirstName?: string;\n firstName?: string;\n first_name?: string;\n customerLastName?: string;\n lastName?: string;\n last_name?: string;\n status?: string;\n totalAmount?: number;\n total?: number;\n total_amount?: number;\n subtotal?: number;\n serviceFeesAmount?: number;\n serviceFee?: number;\n service_fee?: number;\n service_fees_amount?: number;\n taxAmount?: number;\n tax?: number;\n tax_amount?: number;\n discount?: number;\n paymentIntentId?: string;\n payment_intent_id?: string;\n paymentMethod?: string;\n payment_method?: string;\n purchasedTickets?: any[];\n tickets?: any[];\n purchased_tickets?: any[];\n createdAt?: string;\n created_at?: string;\n updatedAt?: string;\n updated_at?: string;\n}\n\n/**\n * Raw API ticket response\n */\ninterface ApiTicket {\n uuid?: string;\n id?: number;\n ID?: number;\n ticketNumber?: string;\n ticket_number?: string;\n orderId?: string | number;\n order_id?: string | number;\n attendeeFirstName?: string;\n attendee_first_name?: string;\n firstName?: string;\n attendeeLastName?: string;\n attendee_last_name?: string;\n lastName?: string;\n attendeeEmail?: string;\n attendee_email?: string;\n email?: string;\n ticketName?: string;\n ticket_name?: string;\n name?: string;\n ticketTypeId?: number;\n ticket_type_id?: number;\n purchasePrice?: number;\n purchase_price?: number;\n price?: number;\n status?: string;\n checkedIn?: boolean;\n checked_in?: boolean;\n checkedInAt?: string;\n checked_in_at?: string;\n}\n\n/**\n * Transform a raw API ticket to normalized PurchasedTicket\n */\nexport function transformTicket(apiTicket: ApiTicket): PurchasedTicket {\n return {\n uuid: apiTicket.uuid || String(apiTicket.id || apiTicket.ID || ''),\n id: apiTicket.id || apiTicket.ID,\n ticketNumber: apiTicket.ticketNumber || apiTicket.ticket_number,\n orderId: apiTicket.orderId || apiTicket.order_id,\n attendeeFirstName:\n apiTicket.attendeeFirstName ||\n apiTicket.attendee_first_name ||\n apiTicket.firstName,\n attendeeLastName:\n apiTicket.attendeeLastName ||\n apiTicket.attendee_last_name ||\n apiTicket.lastName,\n attendeeEmail:\n apiTicket.attendeeEmail || apiTicket.attendee_email || apiTicket.email,\n ticketName:\n apiTicket.ticketName || apiTicket.ticket_name || apiTicket.name || '',\n ticketTypeId: apiTicket.ticketTypeId || apiTicket.ticket_type_id,\n purchasePrice:\n apiTicket.purchasePrice ||\n apiTicket.purchase_price ||\n apiTicket.price ||\n 0,\n status: apiTicket.status,\n checkedIn: apiTicket.checkedIn || apiTicket.checked_in,\n checkedInAt: apiTicket.checkedInAt || apiTicket.checked_in_at,\n };\n}\n\n/**\n * Transform a raw API order to normalized Order\n *\n * Handles various field name patterns:\n * - camelCase (customerEmail)\n * - snake_case (customer_email)\n * - Shortened names (email)\n */\nexport function transformOrder(apiOrder: ApiOrder): Order {\n // Extract tickets array from various possible field names\n const rawTickets =\n apiOrder.purchasedTickets ||\n apiOrder.tickets ||\n apiOrder.purchased_tickets ||\n [];\n\n return {\n uuid: apiOrder.uuid || String(apiOrder.id || apiOrder.ID || ''),\n id: apiOrder.id || apiOrder.ID,\n customerEmail:\n apiOrder.customerEmail ||\n apiOrder.email ||\n apiOrder.customer_email ||\n '',\n customerFirstName:\n apiOrder.customerFirstName ||\n apiOrder.firstName ||\n apiOrder.first_name,\n customerLastName:\n apiOrder.customerLastName ||\n apiOrder.lastName ||\n apiOrder.last_name,\n status: apiOrder.status || 'unknown',\n totalAmount:\n apiOrder.totalAmount ||\n apiOrder.total ||\n apiOrder.total_amount ||\n 0,\n subtotal: apiOrder.subtotal,\n serviceFeesAmount:\n apiOrder.serviceFeesAmount ||\n apiOrder.serviceFee ||\n apiOrder.service_fee ||\n apiOrder.service_fees_amount ||\n 0,\n taxAmount:\n apiOrder.taxAmount || apiOrder.tax || apiOrder.tax_amount || 0,\n discount: apiOrder.discount || 0,\n paymentIntentId:\n apiOrder.paymentIntentId || apiOrder.payment_intent_id,\n paymentMethod: apiOrder.paymentMethod || apiOrder.payment_method,\n purchasedTickets: rawTickets.map(transformTicket),\n createdAt: apiOrder.createdAt || apiOrder.created_at,\n updatedAt: apiOrder.updatedAt || apiOrder.updated_at,\n };\n}\n\n/**\n * Transform order for display on success page\n *\n * Returns a simplified object with display-ready values.\n */\nexport function transformOrderForDisplay(apiOrder: ApiOrder): {\n orderId: string;\n displayOrderId: string;\n email: string;\n customerName: string;\n total: number;\n formattedTotal: string;\n ticketCount: number;\n status: string;\n} {\n const order = transformOrder(apiOrder);\n const displayId = order.uuid.split('-')[0] || order.uuid;\n\n return {\n orderId: order.uuid,\n displayOrderId: displayId,\n email: order.customerEmail,\n customerName: [order.customerFirstName, order.customerLastName]\n .filter(Boolean)\n .join(' '),\n total: order.totalAmount,\n formattedTotal: `${formatCurrency((order.totalAmount / 100) as USD /* FIXME(canonical-cleanup:toFixed): this cast bypasses the brand boundary; replace with toCents/toUSD at the API-response-transform layer. */)}`,\n ticketCount: order.purchasedTickets.length,\n status: order.status,\n };\n}\n","/**\n * Event Transformer\n *\n * Normalizes API event responses to a consistent format.\n * Handles image URL resolution and CTA state calculation.\n */\n\nimport type { Event, AvailableTicket } from '../types.js';\n\n// CDN base URL for images\nconst CDN_BASE_URL = 'https://micdrop-images.sfo3.digitaloceanspaces.com';\n\n/**\n * Raw API event response (may have varying field names)\n */\ninterface ApiEvent {\n eventID?: number;\n id?: number;\n ID?: number;\n name?: string;\n title?: string;\n slug?: string;\n description?: string;\n date?: string;\n startDateTime?: string;\n start_date_time?: string;\n endDateTime?: string;\n end_date_time?: string;\n doorsOpenTime?: string;\n doors_open_time?: string;\n timezone?: string;\n time_zone?: string;\n venueId?: number;\n venue_id?: number;\n venueName?: string;\n venue_name?: string;\n venueAddress?: string;\n venue_address?: string;\n location?: string;\n imageUrl?: string;\n imageURL?: string;\n image_url?: string;\n image?: string;\n status?: string;\n isPublished?: boolean;\n is_published?: boolean;\n isCancelled?: boolean;\n is_cancelled?: boolean;\n availableTickets?: any[];\n available_tickets?: any[];\n tickets?: any[];\n ticketsAvailable?: number;\n tickets_available?: number;\n ticketsSold?: number;\n tickets_sold?: number;\n minPrice?: number;\n min_price?: number;\n maxPrice?: number;\n max_price?: number;\n ctaText?: string;\n cta_text?: string;\n ctaState?: string;\n cta_state?: string;\n showPerformers?: boolean;\n show_performers?: boolean;\n eventSeriesId?: number;\n event_series_id?: number;\n seriesInstanceNumber?: number;\n series_instance_number?: number;\n}\n\n/**\n * Get CDN image URL\n *\n * Prepends the CDN base URL if the path is relative.\n */\nexport function getCDNImageUrl(path: string | undefined): string {\n if (!path) return '';\n if (path.startsWith('http')) return path;\n return `${CDN_BASE_URL}/${path.replace(/^\\//, '')}`;\n}\n\n/**\n * Extract image URL from event with fallbacks\n */\nexport function getEventImageUrl(apiEvent: ApiEvent): string {\n const rawUrl =\n apiEvent.imageUrl ||\n apiEvent.imageURL ||\n apiEvent.image_url ||\n apiEvent.image ||\n '';\n\n return getCDNImageUrl(rawUrl);\n}\n\n/**\n * Calculate CTA state based on ticket availability\n */\nexport function calculateCtaState(\n apiEvent: ApiEvent\n): 'available' | 'sold_out' | 'coming_soon' | 'ended' {\n // Check explicit CTA state first\n const explicitState = apiEvent.ctaState || apiEvent.cta_state;\n if (explicitState) {\n return explicitState as any;\n }\n\n // Check if event is cancelled or ended\n if (apiEvent.isCancelled || apiEvent.is_cancelled) {\n return 'ended';\n }\n\n // Check event date\n const eventDate = apiEvent.startDateTime || apiEvent.start_date_time || apiEvent.date;\n if (eventDate) {\n const eventTime = new Date(eventDate).getTime();\n const now = Date.now();\n\n if (eventTime < now) {\n return 'ended';\n }\n }\n\n // Check ticket availability\n const availableCount =\n apiEvent.ticketsAvailable ?? apiEvent.tickets_available;\n\n if (availableCount !== undefined) {\n if (availableCount <= 0) {\n return 'sold_out';\n }\n return 'available';\n }\n\n // Check tickets array\n const tickets =\n apiEvent.availableTickets ||\n apiEvent.available_tickets ||\n apiEvent.tickets ||\n [];\n\n if (tickets.length === 0) {\n return 'coming_soon';\n }\n\n const totalAvailable = tickets.reduce((sum: number, t: any) => {\n const qty =\n t.quantityAvailable ?? t.quantity_available ?? t.quantity ?? 0;\n const sold = t.quantitySold ?? t.quantity_sold ?? 0;\n return sum + Math.max(0, qty - sold);\n }, 0);\n\n if (totalAvailable <= 0) {\n return 'sold_out';\n }\n\n return 'available';\n}\n\n/**\n * Transform a raw API ticket to normalized AvailableTicket\n */\nexport function transformTicket(apiTicket: any): AvailableTicket {\n return {\n id: apiTicket.id || apiTicket.ID,\n name: apiTicket.name || apiTicket.ticketName || '',\n description: apiTicket.description,\n price: apiTicket.price || 0,\n quantity: apiTicket.quantity || apiTicket.totalQuantity || 0,\n quantitySold: apiTicket.quantitySold || apiTicket.quantity_sold || 0,\n quantityAvailable:\n apiTicket.quantityAvailable ||\n apiTicket.quantity_available ||\n (apiTicket.quantity || 0) - (apiTicket.quantitySold || 0),\n minPerOrder: apiTicket.minPerOrder || apiTicket.min_per_order || 1,\n maxPerOrder: apiTicket.maxPerOrder || apiTicket.max_per_order || 10,\n saleStartDate: apiTicket.saleStartDate || apiTicket.sale_start_date,\n saleEndDate: apiTicket.saleEndDate || apiTicket.sale_end_date,\n isHidden: apiTicket.isHidden || apiTicket.is_hidden || false,\n revealWithPromoCode:\n apiTicket.revealWithPromoCode || apiTicket.reveal_with_promo_code,\n ticketType: apiTicket.ticketType || apiTicket.ticket_type || 0,\n sectionId: apiTicket.sectionId || apiTicket.section_id,\n sortOrder: apiTicket.sortOrder || apiTicket.sort_order || 0,\n };\n}\n\n/**\n * Transform a raw API event to normalized Event\n */\nexport function transformEvent(apiEvent: ApiEvent): Event {\n // Extract tickets array from various possible field names\n const rawTickets =\n apiEvent.availableTickets ||\n apiEvent.available_tickets ||\n apiEvent.tickets ||\n [];\n\n const tickets = rawTickets.map(transformTicket);\n\n // Calculate min/max prices from tickets\n const prices = tickets.map((t) => t.price).filter((p) => p > 0);\n const minPrice = prices.length > 0 ? Math.min(...prices) : undefined;\n const maxPrice = prices.length > 0 ? Math.max(...prices) : undefined;\n\n return {\n eventID: apiEvent.eventID || apiEvent.id || apiEvent.ID || 0,\n id: apiEvent.id || apiEvent.ID,\n name: apiEvent.name || apiEvent.title || '',\n title: apiEvent.title || apiEvent.name,\n slug: apiEvent.slug,\n description: apiEvent.description,\n date: apiEvent.date || apiEvent.startDateTime || apiEvent.start_date_time || '',\n startDateTime: apiEvent.startDateTime || apiEvent.start_date_time,\n endDateTime: apiEvent.endDateTime || apiEvent.end_date_time,\n doorsOpenTime: apiEvent.doorsOpenTime || apiEvent.doors_open_time,\n timezone: apiEvent.timezone || apiEvent.time_zone,\n venueId: apiEvent.venueId || apiEvent.venue_id,\n venueName: apiEvent.venueName || apiEvent.venue_name,\n venueAddress: apiEvent.venueAddress || apiEvent.venue_address,\n location: apiEvent.location || apiEvent.venueAddress || apiEvent.venue_address,\n imageUrl: getEventImageUrl(apiEvent),\n imageURL: getEventImageUrl(apiEvent),\n status: apiEvent.status,\n isPublished: apiEvent.isPublished ?? apiEvent.is_published,\n isCancelled: apiEvent.isCancelled ?? apiEvent.is_cancelled,\n availableTickets: tickets,\n ticketsAvailable:\n apiEvent.ticketsAvailable ??\n apiEvent.tickets_available ??\n tickets.reduce((sum, t) => sum + (t.quantityAvailable || 0), 0),\n ticketsSold: apiEvent.ticketsSold ?? apiEvent.tickets_sold,\n minPrice: apiEvent.minPrice ?? apiEvent.min_price ?? minPrice,\n maxPrice: apiEvent.maxPrice ?? apiEvent.max_price ?? maxPrice,\n ctaText: apiEvent.ctaText || apiEvent.cta_text,\n ctaState: calculateCtaState(apiEvent),\n showPerformers: apiEvent.showPerformers ?? apiEvent.show_performers,\n eventSeriesId: apiEvent.eventSeriesId || apiEvent.event_series_id,\n seriesInstanceNumber:\n apiEvent.seriesInstanceNumber || apiEvent.series_instance_number,\n };\n}\n\n/**\n * Legacy transformer name for backwards compatibility\n */\nexport const transformEventData = transformEvent;\n","/**\n * Venue Transformer\n *\n * Normalizes API venue responses to a consistent format.\n */\n\nimport type { Venue } from '../types.js';\n\n// CDN base URL for images\nconst CDN_BASE_URL = 'https://micdrop-images.sfo3.digitaloceanspaces.com';\n\n/**\n * Raw API venue response (may have varying field names)\n */\ninterface ApiVenue {\n id?: number;\n ID?: number;\n name?: string;\n slug?: string;\n address?: string;\n googleLocationNameCache?: string;\n google_location_name_cache?: string;\n city?: string;\n state?: string;\n zipCode?: string;\n zip_code?: string;\n country?: string;\n timezone?: string;\n time_zone?: string;\n logoUrl?: string;\n logo_url?: string;\n logo?: string;\n serviceFeePercentage?: number;\n service_fee_percentage?: number;\n serviceFeeCents?: number;\n service_fee_cents?: number;\n taxPercentage?: number;\n tax_percentage?: number;\n organizationId?: number;\n organization_id?: number;\n}\n\n/**\n * Get CDN image URL for venue logo\n */\nfunction getLogoUrl(path: string | undefined): string {\n if (!path) return '';\n if (path.startsWith('http')) return path;\n return `${CDN_BASE_URL}/${path.replace(/^\\//, '')}`;\n}\n\n/**\n * Transform a raw API venue to normalized Venue\n */\nexport function transformVenue(apiVenue: ApiVenue): Venue {\n const logoPath =\n apiVenue.logoUrl || apiVenue.logo_url || apiVenue.logo;\n\n return {\n id: apiVenue.id || apiVenue.ID || 0,\n name: apiVenue.name || '',\n slug: apiVenue.slug,\n address: apiVenue.address,\n googleLocationNameCache:\n apiVenue.googleLocationNameCache ||\n apiVenue.google_location_name_cache,\n city: apiVenue.city,\n state: apiVenue.state,\n zipCode: apiVenue.zipCode || apiVenue.zip_code,\n country: apiVenue.country,\n timezone: apiVenue.timezone || apiVenue.time_zone,\n logoUrl: getLogoUrl(logoPath),\n serviceFeePercentage:\n apiVenue.serviceFeePercentage ??\n apiVenue.service_fee_percentage ??\n 0,\n serviceFeeCents:\n apiVenue.serviceFeeCents ?? apiVenue.service_fee_cents ?? 0,\n taxPercentage:\n apiVenue.taxPercentage ?? apiVenue.tax_percentage ?? 0,\n organizationId:\n apiVenue.organizationId || apiVenue.organization_id,\n };\n}\n\n/**\n * Extract fee configuration from venue\n */\nexport function extractVenueFees(apiVenue: ApiVenue): {\n serviceFeePercentage: number;\n serviceFeeCents: number;\n taxPercentage: number;\n} {\n return {\n serviceFeePercentage:\n apiVenue.serviceFeePercentage ??\n apiVenue.service_fee_percentage ??\n 0,\n serviceFeeCents:\n apiVenue.serviceFeeCents ?? apiVenue.service_fee_cents ?? 0,\n taxPercentage:\n apiVenue.taxPercentage ?? apiVenue.tax_percentage ?? 0,\n };\n}\n\n/**\n * Get formatted venue address\n */\nexport function formatVenueAddress(venue: Venue): string {\n const parts = [\n venue.address,\n venue.city,\n venue.state,\n venue.zipCode,\n ].filter(Boolean);\n\n return parts.join(', ');\n}\n"],"names":["logger","createLogger","DEFAULT_CONFIG","error","globalConfig","configureApi","config","getApiConfig","getPublicBaseUrl","getLegacyPublicUrl","getOrdersV2Url","getClientIP","sleep","ms","resolve","fetchWithRetry","url","init","cfg","method","maxAttempts","lastError","attempt","controller","timeoutId","callerSignal","onCallerAbort","response","err","apiGet","endpoint","options","apiRequest","apiPost","body","apiPut","apiDelete","errorData","message","errorMessage","simpleFetch","createPaymentIntent","cartId","quantities","donationAmounts","data","completeReservation","orderUuid","cancelReservation","createOrder","eventId","promoCode","getOrder","orderId","validatePaymentIntent","payload","result","extendCheckoutSession","getSessionStatus","initiateOrder","cartData","trackUTMSource","venueId","utmSource","validatePromoCode","code","encodedCode","hasPromoCodes","applyPromoCode","removePromoCode","_eventDetailsInflight","fetchEventDetails","customFetch","key","inflight","run","fetchEventTickets","tickets","fetchEventPerformers","fetchAllVenues","orgId","venues","fetchVenueEvents","events","getMonthEvents","year","month","getOrgMonthEvents","getSeriesOccurrences","eventSeriesId","fetchSeriesOccurrences","fetchSeriesPage","seriesId","fetchPublicCollection","collectionId","password","checkCollectionPassword","encodedPassword","checkEventPassword","testNetworkConnection","getVenue","getVenueFees","venue","getVenueBySlug","slug","encodedSlug","API_BASE_URL","ORDERS_V2_URL","ORDERS_V2_PUBLIC","createGiftCardPurchase","req","applyGiftCard","res","removeGiftCard","completeGiftCardPayment","customerDetails","WAITLIST_ERROR_MESSAGES","joinWaitlist","email","phone","smsOptIn","getWaitlistPosition","computeCtaState","event","cancelled","isRegistration","waitlistEnabled","now","eventEnd","publicTickets","t","hasPurchasable","allSoldOut","allComingSoon","earliestSalesStart","ticket","salesBegin","salesEnd","remaining","isSoldOut","isScheduled","hasSalesEnded","startDate","diffMs","diffHours","diffDays","dateText","formatDateRaw","d","transformTicket","apiTicket","transformOrder","apiOrder","rawTickets","transformOrderForDisplay","order","displayId","formatCurrency","CDN_BASE_URL","getCDNImageUrl","path","getEventImageUrl","apiEvent","rawUrl","calculateCtaState","explicitState","eventDate","eventTime","availableCount","sum","qty","sold","transformEvent","prices","p","minPrice","maxPrice","transformEventData","getLogoUrl","transformVenue","apiVenue","logoPath","extractVenueFees","formatVenueAddress"],"mappings":"0MAYMA,EAASC,EAAAA,aAAa,IAAI,EAI1BC,EAAsC,CAC1C,QAAS,0BACT,QAAS,IACT,QAAS,EACT,WAAY,IACZ,QAAUC,GAAiBH,EAAO,MAAM,aAAcG,CAAK,CAC7D,EAEA,IAAIC,EAAoC,CAAE,GAAGF,CAAA,EAEtC,SAASG,EAAaC,EAAkC,CAC7DF,EAAe,CAAE,GAAGA,EAAc,GAAGE,CAAA,CACvC,CAEO,SAASC,GAAoC,CAClD,MAAO,CAAE,GAAGH,CAAA,CACd,CAEO,SAASI,GAA2B,CACzC,MAAO,GAAGJ,EAAa,OAAO,gBAChC,CAEO,SAASK,GAA6B,CAC3C,MAAO,GAAGL,EAAa,OAAO,aAChC,CAEO,SAASM,GAAyB,CACvC,MAAO,GAAGN,EAAa,OAAO,uBAChC,CAGA,eAAsBO,GAA+B,CACnD,MAAO,EACT,CAKA,MAAMC,EAASC,GACb,IAAI,QAASC,GAAY,WAAWA,EAASD,CAAE,CAAC,EAUlD,eAAeE,EACbC,EACAC,EACAC,EACmB,CACnB,MAAMC,GAAUF,EAAK,QAAU,OAAO,YAAA,EAEhCG,EADeD,IAAW,OAASA,IAAW,OACjBD,EAAI,QAAU,EAAI,EAErD,IAAIG,EACJ,QAASC,EAAU,EAAGA,GAAWF,EAAaE,IAAW,CACvD,MAAMC,EAAa,IAAI,gBACjBC,EAAY,WAAW,IAAMD,EAAW,MAAA,EAASL,EAAI,OAAO,EAG5DO,EAAeR,EAAK,OAC1B,IAAIS,EACAD,IACEA,EAAa,QAASF,EAAW,MAAA,GAEnCG,EAAgB,IAAMH,EAAW,MAAA,EACjCE,EAAa,iBAAiB,QAASC,EAAe,CAAE,KAAM,GAAM,IAIxE,GAAI,CACF,MAAMC,EAAW,MAAM,MAAMX,EAAK,CAAE,GAAGC,EAAM,OAAQM,EAAW,OAAQ,EAGxE,GAAII,EAAS,QAAU,KAAOL,EAAUF,EACtCC,EAAY,IAAI,MAAM,QAAQM,EAAS,MAAM,EAAE,MAE/C,QAAOA,CAEX,OAASC,EAAK,CAGZ,GAFAP,EAAYO,EAERH,GAAc,QAAS,MAAMG,CACnC,QAAA,CACE,aAAaJ,CAAS,EAClBC,GAAgBC,GAClBD,EAAa,oBAAoB,QAASC,CAAa,CAE3D,CAEIJ,EAAUF,GACZ,MAAMR,EAAMM,EAAI,WAAa,KAAK,IAAI,EAAGI,EAAU,CAAC,CAAC,CAEzD,CAEA,MAAMD,CACR,CAEA,eAAsBQ,EACpBC,EACAC,EACyB,CACzB,OAAOC,EAAc,MAAOF,EAAU,OAAWC,CAAO,CAC1D,CAEA,eAAsBE,EACpBH,EACAI,EACAH,EACyB,CACzB,OAAOC,EAAc,OAAQF,EAAUI,EAAMH,CAAO,CACtD,CAEA,eAAsBI,EACpBL,EACAI,EACAH,EACyB,CACzB,OAAOC,EAAc,MAAOF,EAAUI,EAAMH,CAAO,CACrD,CAEA,eAAsBK,GACpBN,EACAC,EACyB,CACzB,OAAOC,EAAc,SAAUF,EAAU,OAAWC,CAAO,CAC7D,CAEA,eAAeC,EACbb,EACAW,EACAI,EACAH,EACyB,CACzB,MAAMf,EAAMc,EAAS,WAAW,MAAM,EAClCA,EACA,GAAGtB,EAAA,CAAkB,GAAGsB,CAAQ,GAEpC,GAAI,CACF,MAAMH,EAAW,MAAMZ,EACrBC,EACA,CACE,OAAAG,EACA,QAAS,CACP,eAAgB,mBAChB,GAAGY,GAAS,OAAA,EAEd,KAAMG,IAAS,OAAY,KAAK,UAAUA,CAAI,EAAI,OAClD,YAAa,UACb,GAAGH,CAAA,EAEL3B,CAAA,EAGF,GAAI,CAACuB,EAAS,GAAI,CAChB,MAAMU,EAAY,MAAMV,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EAClDW,EACJD,EAAU,OAASA,EAAU,SAAW,QAAQV,EAAS,MAAM,GACjE,OAAAvB,EAAa,QAAQ,IAAI,MAAMkC,CAAO,CAAC,EAChC,CAAE,QAAS,GAAO,MAAOA,EAAS,WAAYX,EAAS,MAAA,CAChE,CAGA,MAAO,CAAE,QAAS,GAAM,KADX,MAAMA,EAAS,KAAA,EACa,WAAYA,EAAS,MAAA,CAChE,OAASxB,EAAO,CACd,MAAMoC,EACJpC,aAAiB,MACbA,EAAM,OAAS,aACb,oBACAA,EAAM,QACR,gBAEN,OAAAC,EAAa,QACXD,aAAiB,MAAQA,EAAQ,IAAI,MAAMoC,CAAY,CAAA,EAElD,CAAE,QAAS,GAAO,MAAOA,CAAA,CAClC,CACF,CAMA,eAAsBC,GACpBxB,EACAe,EACmB,CACnB,GAAI,CACF,MAAMJ,EAAW,MAAMZ,EACrBC,EACA,CAAE,YAAa,UAAW,GAAGe,CAAA,EAC7B3B,CAAA,EAGF,GAAI,CAACuB,EAAS,GAAI,CAChB,MAAMU,EAAY,MAAMV,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACxD3B,OAAAA,EAAO,MAAM,uBAAuB2B,EAAS,MAAM,GAAIU,CAAS,EACzD,IACT,CAEA,OAAOV,EAAS,KAAA,CAClB,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,qBAAsBG,CAAK,EACjC,IACT,CACF,CCzNA,MAAMH,EAASC,EAAAA,aAAa,IAAI,EA8BhC,eAAsBwC,GACpBC,EACAC,EACAC,EACuC,CACvC,GAAI,CACF,MAAMjB,EAAW,MAAM,MACrB,GAAGjB,EAAA,CAAgB,SAASgC,CAAM,kBAClC,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,EAElB,YAAa,UACb,KAAM,KAAK,UAAU,CACnB,kBAAmBC,EACnB,GAAIC,GAAmB,OAAO,KAAKA,CAAe,EAAE,OAAS,EACzD,CAAE,gBAAAA,GACF,CAAA,CAAC,CACN,CAAA,CACH,EAGF,GAAI,CAACjB,EAAS,GAAI,CAChB,MAAMU,EAAY,MAAMV,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACxD3B,MAAAA,EAAO,MAAM,kCAAmCqC,CAAS,EACnD,IAAI,MAAMA,EAAU,OAAS,iCAAiC,CACtE,CAEA,MAAMQ,EAAO,MAAMlB,EAAS,KAAA,EAC5B3B,OAAAA,EAAO,MAAM,0BAA2B6C,CAAI,EACrCA,CACT,OAAS1C,EAAO,CACdH,OAAAA,EAAO,MAAM,6BAA8BG,CAAK,EACzC,IACT,CACF,CAWA,eAAsB2C,GACpBC,EACsC,CACtC,GAAI,CACF,MAAMpB,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,oBAAoBuC,CAAS,GAClD,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,CAClB,CACF,EAGF,OAAKpB,EAAS,GASP,CACL,QAAS,GACT,SAHa,MAAMA,EAAS,KAAA,GAGZ,OAAA,EATT,CACL,QAAS,GACT,OAHgB,MAAMA,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,GAGrC,OAAS,gCAAA,CAShC,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,gCAAiCG,CAAK,EAC5C,CAAE,QAAS,GAAO,MAAO,sCAAA,CAClC,CACF,CAUA,eAAsB6C,GACpBD,EACoC,CACpC,GAAI,CACF,MAAMpB,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,kBAAkBuC,CAAS,GAChD,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,CAClB,CACF,EAGF,OAAKpB,EAAS,GASP,CACL,QAAS,GACT,SAHa,MAAMA,EAAS,KAAA,GAGZ,OAAA,EATT,CACL,QAAS,GACT,OAHgB,MAAMA,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,GAGrC,OAAS,8BAAA,CAShC,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,gCAAiCG,CAAK,EAC5C,CAAE,QAAS,GAAO,MAAO,sCAAA,CAClC,CACF,CAYA,eAAsB8C,GACpBC,EACAC,EACqC,CACrC,GAAI,CACF,MAAMxB,EAAW,MAAM,MAAM,GAAGnB,EAAA,CAAkB,iBAAkB,CAClE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,EAElB,KAAM,KAAK,UAAU,CACnB,QAAS0C,EACT,UAAAC,CAAA,CACD,CAAA,CACF,EAED,GAAI,CAACxB,EAAS,GAAI,CAChB,MAAMU,EAAY,MAAMV,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACxD3B,OAAAA,EAAO,MAAM,uBAAwBqC,CAAS,EACvC,IACT,CAEA,OAAOV,EAAS,KAAA,CAClB,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,qBAAsBG,CAAK,EACjC,IACT,CACF,CAUA,eAAsBiD,GAASC,EAAwC,CACrE,OAAOb,GAAmB,GAAGhC,EAAA,CAAkB,WAAW6C,CAAO,EAAE,CACrE,CAYA,eAAsBC,GACpBZ,EACAa,EACyC,CACzC,GAAI,CACF,MAAM5B,EAAW,MAAM,MACrB,GAAGjB,EAAA,CAAgB,0BAA0BgC,CAAM,GACnD,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,EAElB,KAAM,KAAK,UAAUa,CAAO,CAAA,CAC9B,EAGF,GAAI,CAAC5B,EAAS,GAAI,CAChB,MAAMU,EAAY,MAAMV,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACxD3B,OAAAA,EAAO,MAAM,6BAA8BqC,CAAS,EAC7C,CACL,QAAS,GACT,OAAQ,SACR,MAAOA,EAAU,OAAS,2BAAA,CAE9B,CAEA,MAAMmB,EAAS,MAAM7B,EAAS,KAAA,EAC9B,MAAO,CACL,QAAS,GACT,OAAQ6B,EAAO,QAAU,oBACzB,UAAWA,EAAO,WAAaA,EAAO,IAAA,CAE1C,OAASrD,EAAO,CACdH,OAAAA,EAAO,MAAM,+BAAgCG,CAAK,EAC3C,IACT,CACF,CAUA,eAAsBsD,GACpBV,EACgC,CAChC,GAAI,CACF,MAAMpB,EAAW,MAAM,MAAM,GAAGnB,EAAA,CAAkB,yBAA0B,CAC1E,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,EAElB,KAAM,KAAK,UAAU,CAAE,UAAAuC,EAAW,CAAA,CACnC,EAED,GAAI,CAACpB,EAAS,GAEZ,MAAO,CACL,QAAS,GACT,OAHgB,MAAMA,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,GAGrC,OAAS,0BAAA,EAI9B,MAAM6B,EAAS,MAAM7B,EAAS,KAAA,EAC9B,MAAO,CACL,QAAS,GACT,cAAe6B,EAAO,cACtB,oBAAqBA,EAAO,mBAAA,CAEhC,OAASrD,EAAO,CACdH,OAAAA,EAAO,MAAM,oCAAqCG,CAAK,EAChD,CAAE,QAAS,GAAO,MAAO,iCAAA,CAClC,CACF,CAUA,eAAsBuD,GAAiBX,EAA2C,CAChF,GAAI,CACF,MAAMpB,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,mBAAmBuC,CAAS,EAAA,EAGnD,GAAI,CAACpB,EAAS,GAEZ,MAAO,CAAE,OADS,MAAMA,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,GAC9B,OAAS,yBAAA,EAGrC,MAAM6B,EAAS,MAAM7B,EAAS,KAAA,EAC9B,MAAO,CACL,UAAW6B,EAAO,UAClB,eAAgBA,EAAO,eACvB,oBAAqBA,EAAO,oBAC5B,UAAWA,EAAO,UAClB,iBAAkBA,EAAO,gBAAA,CAE7B,OAASrD,EAAO,CACdH,OAAAA,EAAO,MAAM,gCAAiCG,CAAK,EAC5C,CAAE,MAAO,sCAAA,CAClB,CACF,CAWA,eAAsBwD,GACpBC,EAA2G,GACnF,CACxB,GAAI,CACF,MAAMjC,EAAW,MAAM,MAAM,GAAGnB,EAAA,CAAkB,iBAAkB,CAClE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,EAElB,KAAM,KAAK,UAAUoD,CAAQ,CAAA,CAC9B,EAED,GAAI,CAACjC,EAAS,GAAI,CAChB,MAAMU,EAAY,MAAMV,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACxD3B,OAAAA,EAAO,MAAM,2BAA4BqC,CAAS,EAC3C,IACT,CAGA,OADa,MAAMV,EAAS,KAAA,GAChB,IACd,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,uBAAwBG,CAAK,EACnC,IACT,CACF,CAUA,eAAsB0D,GAAeC,EAAyC,CAC5E,GAAI,OAAO,OAAW,IAAa,OAGnC,MAAMC,EADY,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAChC,IAAI,YAAY,GAAK,SAEjD,GAAI,CACF,MAAM,MACJ,GAAGvD,GAAkB,QAAQsD,CAAO,IAAI,mBAAmBC,CAAS,CAAC,EAAA,CAEzE,OAAS5D,EAAO,CACdH,EAAO,MAAM,uBAAwBG,CAAK,CAC5C,CACF,CC3XA,MAAMH,EAASC,EAAAA,aAAa,IAAI,EAehC,eAAsB+D,GACpBd,EACAe,EACkC,CAClC,GAAI,CACF,GAAI,CAACA,GAAQ,CAACA,EAAK,OACjB,MAAO,CAAE,MAAO,GAAO,MAAO,wBAAA,EAIhC,MAAMC,EAAc,mBAAmBD,EAAK,KAAA,CAAM,EAC5CtC,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,yBAAyB0C,CAAO,IAAIgB,CAAW,EAAA,EAGtE,GAAI,CAACvC,EAAS,GAEZ,OAAIA,EAAS,SAAW,IACf,CAAE,MAAO,GAAO,MAAO,oBAAA,EAGzB,CAAE,MAAO,GAAO,OADL,MAAMA,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,GAChB,OAAS,yBAAA,EAGnD,MAAM6B,EAAS,MAAM7B,EAAS,KAAA,EAC9B,MAAO,CACL,MAAO6B,EAAO,OAAS,GACvB,oBAAqBA,EAAO,oBAC5B,gBAAiBA,EAAO,gBACxB,gBAAiBA,EAAO,gBACxB,aAAcA,EAAO,aACrB,OAAQA,EAAO,OACf,KAAMA,EAAO,MAAQS,CAAA,CAEzB,OAAS9D,EAAO,CACdH,OAAAA,EAAO,MAAM,+BAAgCG,CAAK,EAC3C,CAAE,MAAO,GAAO,MAAO,+BAAA,CAChC,CACF,CAUA,eAAsBgE,GAAcjB,EAA4C,CAC9E,GAAI,CACF,MAAMvB,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,sBAAsB0C,CAAO,EAAA,EAGpD,OAAKvB,EAAS,IAKwB,MAAMA,EAAS,KAAA,GACvC,gBAAkB,GAJvB,EAKX,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,2CAA4CG,CAAK,EAEvD,EACT,CACF,CAWA,eAAsBiE,GACpB1B,EACAuB,EAC+C,CAC/C,GAAI,CACF,MAAMtC,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,WAAWkC,CAAM,eACtC,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,EAElB,KAAM,KAAK,UAAU,CAAE,KAAAuB,EAAM,CAAA,CAC/B,EAGF,OAAKtC,EAAS,GAQP,CAAE,QAAS,EAAA,EANT,CACL,QAAS,GACT,OAHgB,MAAMA,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,GAGrC,OAAS,4BAAA,CAKhC,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,6BAA8BG,CAAK,EACzC,CAAE,QAAS,GAAO,MAAO,6BAAA,CAClC,CACF,CAQA,eAAsBkE,GACpB3B,EAC+C,CAC/C,GAAI,CACF,MAAMf,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,WAAWkC,CAAM,gBACtC,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAAA,CAClB,CACF,EAGF,OAAKf,EAAS,GAQP,CAAE,QAAS,EAAA,EANT,CACL,QAAS,GACT,OAHgB,MAAMA,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,GAGrC,OAAS,6BAAA,CAKhC,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,6BAA8BG,CAAK,EACzC,CAAE,QAAS,GAAO,MAAO,6BAAA,CAClC,CACF,CC5JA,MAAMH,EAASC,EAAAA,aAAa,IAAI,EAqB1BqE,MAA4B,IAWlC,eAAsBC,GACpBrB,EACAsB,EAA4B,MACL,CACvB,MAAMC,EAAM,OAAOvB,CAAO,EAG1B,GAAIsB,IAAgB,MAAO,CACzB,MAAME,EAAWJ,EAAsB,IAAIG,CAAG,EAC9C,GAAIC,EAAU,OAAOA,CACvB,CAEA,MAAMC,GAAO,SAAY,CACvB,GAAI,CACF,MAAMhD,EAAW,MAAM6C,EAAY,GAAGhE,GAAkB,WAAW0C,CAAO,EAAE,EAC5E,GAAI,CAACvB,EAAS,GACZ,MAAM,IAAI,MAAM,kCAAkCA,EAAS,MAAM,EAAE,EAErE,OAAO,MAAMA,EAAS,KAAA,CACxB,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,gCAAiCG,CAAK,EAC5C,IACT,CACF,GAAA,EAEA,OAAIqE,IAAgB,QAClBF,EAAsB,IAAIG,EAAKE,CAAG,EAClCA,EAAI,QAAQ,IAAM,CAIZL,EAAsB,IAAIG,CAAG,IAAME,GACrCL,EAAsB,OAAOG,CAAG,CAEpC,CAAC,GAEIE,CACT,CAUA,eAAsBC,GACpB1B,EAC4B,CAC5B,GAAI,CACF,MAAMvB,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,kBAAkB0C,CAAO,EAAA,EAGhD,GAAI,CAACvB,EAAS,GACZ,MAAM,IAAI,MAAM,4BAA4BA,EAAS,MAAM,EAAE,EAG/D,MAAMkD,EAAU,MAAMlD,EAAS,KAAA,EAC/B,OAAO,MAAM,QAAQkD,CAAO,EAAIA,EAAU,CAAA,CAC5C,OAAS1E,EAAO,CACdH,OAAAA,EAAO,MAAM,0BAA2BG,CAAK,EACtC,CAAA,CACT,CACF,CAUA,eAAsB2E,GACpB5B,EACkC,CAClC,GAAI,CACF,GAAI,CAACA,EACHlD,OAAAA,EAAO,KAAK,6CAA6C,EAClD,CAAE,WAAY,GAAI,eAAgB,EAAA,EAG3C,MAAM2B,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,WAAW0C,CAAO,aAAA,EAGzC,GAAI,CAACvB,EAAS,GACZ3B,OAAAA,EAAO,MACL,+BAA+B2B,EAAS,MAAM,IAAIA,EAAS,UAAU,EAAA,EAEhE,CAAE,WAAY,GAAI,eAAgB,EAAA,EAG3C,MAAMkB,EAAO,MAAMlB,EAAS,KAAA,EAC5B,MAAO,CACL,WAAY,MAAM,QAAQkB,EAAK,UAAU,EAAIA,EAAK,WAAa,CAAA,EAC/D,eAAgBA,EAAK,iBAAmB,EAAA,CAE5C,OAAS1C,EAAO,CACdH,OAAAA,EAAO,MAAM,mCAAoCG,CAAK,EAC/C,CAAE,WAAY,GAAI,eAAgB,EAAA,CAC3C,CACF,CAQA,eAAsB4E,GAAeC,EAAwC,CAC3E,GAAI,CACF,GAAI,CAACA,EACHhF,OAAAA,EAAO,KAAK,qCAAqC,EAC1C,CAAA,EAGT,MAAM2B,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,wBAAwBwE,CAAK,EAAA,EAGpD,GAAI,CAACrD,EAAS,GACZ3B,OAAAA,EAAO,MACL,2BAA2B2B,EAAS,MAAM,IAAIA,EAAS,UAAU,EAAA,EAE5D,CAAA,EAGT,MAAMsD,EAAS,MAAMtD,EAAS,KAAA,EAC9B,OAAO,MAAM,QAAQsD,CAAM,EAAIA,EAAS,CAAA,CAC1C,OAAS9E,EAAO,CACdH,OAAAA,EAAO,MAAM,yBAA0BG,CAAK,EACrC,CAAA,CACT,CACF,CAQA,eAAsB+E,GAAiBpB,EAA4C,CACjF,GAAI,CACF,GAAI,CAACA,EACH9D,OAAAA,EAAO,KAAK,yCAAyC,EAC9C,CAAA,EAGT,MAAM2B,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,iBAAiBsD,CAAO,EAAA,EAG/C,GAAI,CAACnC,EAAS,GACZ3B,OAAAA,EAAO,MACL,iCAAiC2B,EAAS,MAAM,IAAIA,EAAS,UAAU,EAAA,EAElE,CAAA,EAGT,MAAMwD,EAAS,MAAMxD,EAAS,KAAA,EAC9B,OAAO,MAAM,QAAQwD,CAAM,EAAIA,EAAS,CAAA,CAC1C,OAAShF,EAAO,CACdH,OAAAA,EAAO,MAAM,+BAAgCG,CAAK,EAC3C,CAAA,CACT,CACF,CAYA,eAAsBiF,GACpBtB,EACAuB,EACAC,EACkB,CAClB,GAAI,CACF,MAAM3D,EAAW,MAAM,MACrB,GAAGnB,GAAkB,iBAAiBsD,CAAO,UAAUuB,CAAI,IAAIC,CAAK,EAAA,EAGtE,GAAI,CAAC3D,EAAS,GACZ3B,OAAAA,EAAO,MAAM,iCAAiC2B,EAAS,MAAM,EAAE,EACxD,CAAA,EAGT,MAAMkB,EAAO,MAAMlB,EAAS,KAAA,EAC5B,OAAO,MAAM,QAAQkB,EAAK,MAAM,EAAIA,EAAK,OAAS,MAAM,QAAQA,CAAI,EAAIA,EAAO,CAAA,CACjF,OAAS1C,EAAO,CACdH,OAAAA,EAAO,MAAM,+BAAgCG,CAAK,EAC3C,CAAA,CACT,CACF,CAUA,eAAsBoF,GACpBP,EACAK,EACAC,EACkB,CAClB,GAAI,CACF,MAAM3D,EAAW,MAAM,MACrB,GAAGnB,GAAkB,wBAAwBwE,CAAK,UAAUK,CAAI,IAAIC,CAAK,EAAA,EAG3E,GAAI,CAAC3D,EAAS,GACZ3B,OAAAA,EAAO,MAAM,qCAAqC2B,EAAS,MAAM,EAAE,EAC5D,CAAA,EAGT,MAAMkB,EAAO,MAAMlB,EAAS,KAAA,EAC5B,OAAO,MAAM,QAAQkB,EAAK,MAAM,EAAIA,EAAK,OAAS,MAAM,QAAQA,CAAI,EAAIA,EAAO,CAAA,CACjF,OAAS1C,EAAO,CACdH,OAAAA,EAAO,MAAM,mCAAoCG,CAAK,EAC/C,CAAA,CACT,CACF,CAUA,eAAsBqF,GACpBC,EAC2C,CAC3C,GAAI,CACF,MAAM9D,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,WAAWiF,CAAa,cAAA,EAG/C,OAAK9D,EAAS,GAKPA,EAAS,KAAA,GAJd3B,EAAO,MAAM,uCAAuC2B,EAAS,MAAM,EAAE,EAC9D,KAIX,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,qCAAsCG,CAAK,EACjD,IACT,CACF,CAWA,eAAsBuF,GACpBD,EACA3B,EAC2C,CAC3C,GAAI,CACF,MAAMnC,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,WAAWiF,CAAa,wBAAwB3B,CAAO,EAAA,EAG9E,OAAKnC,EAAS,GAKPA,EAAS,KAAA,GAJd3B,EAAO,MAAM,oCAAoC2B,EAAS,MAAM,EAAE,EAC3D,KAIX,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,qCAAsCG,CAAK,EACjD,IACT,CACF,CAUA,eAAsBwF,GACpBC,EACgC,CAChC,GAAI,CACF,MAAMjE,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,WAAWoF,CAAQ,OAAA,EAG1C,GAAI,CAACjE,EAAS,GACZ,MAAM,IAAI,MAAM,gCAAgCA,EAAS,MAAM,EAAE,EAGnE,OAAOA,EAAS,KAAA,CAClB,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,8BAA+BG,CAAK,EAC1C,IACT,CACF,CAYA,eAAsB0F,GACpBC,EACAC,EACsC,CACtC,GAAI,CACF,MAAM/E,EAAM+E,EACR,GAAGvF,EAAA,CAAkB,gBAAgBsF,CAAY,oBAAoB,mBAAmBC,CAAQ,CAAC,GACjG,GAAGvF,EAAA,CAAkB,gBAAgBsF,CAAY,UAE/CnE,EAAW,MAAM,MAAMX,CAAG,EAEhC,GAAI,CAACW,EAAS,GACZ,MAAM,IAAI,MAAM,+BAA+BA,EAAS,MAAM,EAAE,EAGlE,OAAOA,EAAS,KAAA,CAClB,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,6BAA8BG,CAAK,EACzC,IACT,CACF,CAWA,eAAsB6F,GACpBF,EACAC,EACkB,CAClB,GAAI,CACF,MAAME,EAAkB,mBAAmBF,CAAQ,EAC7CpE,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,gBAAgBsF,CAAY,mBAAmBG,CAAe,EAAA,EAGrF,OAAKtE,EAAS,IAIC,MAAMA,EAAS,KAAA,GAChB,QAAU,GAJf,EAKX,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,sCAAuCG,CAAK,EAClD,EACT,CACF,CAWA,eAAsB+F,GACpBhD,EACA6C,EAC6B,CAC7B,GAAI,CAGF,MAAMpE,EAAW,MAAM,MACrB,GAAGnB,EAAA,CAAkB,WAAW0C,CAAO,kBACvC,CACE,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CAAE,SAAA6C,EAAU,CAAA,CACnC,EAGF,GAAI,CAACpE,EAAS,GAAI,MAAO,CAAE,MAAO,EAAA,EAElC,MAAM6B,EAAS,MAAM7B,EAAS,KAAA,EAC9B,OAAI,OAAO6B,GAAW,UAAkB,CAAE,MAAOA,CAAA,EAC1C,CAAE,MAAOA,EAAO,QAAU,IAAQA,IAAW,EAAA,CACtD,OAASrD,EAAO,CACdH,OAAAA,EAAO,MAAM,iCAAkCG,CAAK,EAC7C,CAAE,MAAO,EAAA,CAClB,CACF,CAWA,eAAsBgG,GACpBnB,EACAlB,EACkB,CAClB,GAAI,CAEF,MAAM9C,EAAM8C,EACR,GAAGtD,EAAA,CAAkB,iBAAiBsD,CAAO,GAC7CkB,EACA,GAAGxE,GAAkB,wBAAwBwE,CAAK,GAClD,GAAGxE,GAAkB,UAMzB,OAJiB,MAAM,MAAMQ,EAAK,CAChC,OAAQ,MAAA,CACT,GAEe,EAClB,OAASb,EAAO,CACdH,OAAAA,EAAO,MAAM,kCAAmCG,CAAK,EAC9C,EACT,CACF,CCheA,MAAMH,EAASC,EAAAA,aAAa,IAAI,EAahC,eAAsBmG,EAAStC,EAAiD,CAC9E,GAAI,CACF,GAAI,CAACA,EACH9D,OAAAA,EAAO,KAAK,iCAAiC,EACtC,KAGT,MAAM2B,EAAW,MAAM,MAAM,GAAGnB,GAAkB,WAAWsD,CAAO,EAAE,EAEtE,OAAKnC,EAAS,GAKPA,EAAS,KAAA,GAJd3B,EAAO,MAAM,0BAA0B2B,EAAS,MAAM,EAAE,EACjD,KAIX,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,wBAAyBG,CAAK,EACpC,IACT,CACF,CAUA,eAAsBkG,GACpBvC,EAKQ,CACR,MAAMwC,EAAQ,MAAMF,EAAStC,CAAO,EAEpC,OAAKwC,EAIE,CACL,qBAAsBA,EAAM,sBAAwB,EACpD,gBAAiBA,EAAM,iBAAmB,EAC1C,cAAeA,EAAM,eAAiB,CAAA,EAN/B,IAQX,CAUA,eAAsBC,GAAeC,EAAqC,CACxE,GAAI,CACF,GAAI,CAACA,EACHxG,OAAAA,EAAO,KAAK,oCAAoC,EACzC,KAGT,MAAMyG,EAAc,mBAAmBD,CAAI,EACrC7E,EAAW,MAAM,MAAM,GAAGnB,GAAkB,gBAAgBiG,CAAW,EAAE,EAE/E,OAAK9E,EAAS,GAKPA,EAAS,KAAA,GAJd3B,EAAO,MAAM,kCAAkC2B,EAAS,MAAM,EAAE,EACzD,KAIX,OAASxB,EAAO,CACdH,OAAAA,EAAO,MAAM,gCAAiCG,CAAK,EAC5C,IACT,CACF,CC1FA,MAAMH,EAASC,EAAAA,aAAa,IAAI,EAE1ByG,GAAe,0BACfC,GAAgB,GAAGD,EAAY,iBAC/BE,EAAmB,IAAMlG,EAAA,EAyC/B,eAAsBmG,GACpBC,EAC0C,CAC1C,GAAI,CACF,MAAMnF,EAAW,MAAM,MACrB,GAAGgF,EAAa,cAChB,CACE,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAUG,CAAG,CAAA,CAC1B,EAGF,GAAI,CAACnF,EAAS,GAAI,CAChB,MAAMU,EAAY,MAAMV,EAAS,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACxD3B,MAAAA,EAAO,MAAM,sCAAuCqC,CAAS,EACvD,IAAI,MAAMA,EAAU,OAAS,qCAAqC,CAC1E,CAEA,MAAMQ,EAAO,MAAMlB,EAAS,KAAA,EAC5B3B,OAAAA,EAAO,MAAM,8BAA+B6C,CAAI,EACzCA,CACT,OAAS1C,EAAO,CACdH,OAAAA,EAAO,MAAM,qCAAsCG,CAAK,EACjD,IACT,CACF,CAiBA,eAAsB4G,GACpBrE,EACAuB,EAC8B,CAC9B,GAAI,CACF,MAAM+C,EAAM,MAAM,MAAM,GAAGJ,GAAkB,SAASlE,CAAM,mBAAoB,CAC9E,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CAAE,aAAcuB,EAAM,CAAA,CAC5C,EAED,GAAI,CAAC+C,EAAI,GAAI,CACX,GAAIA,EAAI,SAAW,IACjB,MAAO,CACL,MAAO,GACP,MAAO,wDAAA,EAGX,MAAM3E,EAAY,MAAM2E,EAAI,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACnDhH,OAAAA,EAAO,MAAM,0BAA2BqC,CAAS,EAC1C,CAAE,MAAO,GAAO,MAAOA,EAAU,OAAS,wBAAA,CACnD,CAEA,MAAMQ,EAAO,MAAMmE,EAAI,KAAA,EACvB,MAAO,CACL,MAAO,GACP,aAAcnE,EAAK,aACnB,eAAgBA,EAAK,eACrB,gBAAiBA,EAAK,gBACtB,YAAaA,EAAK,YAClB,aAAcA,EAAK,aACnB,WAAYA,EAAK,WACjB,eAAgBA,EAAK,cAAA,CAEzB,OAASjB,EAAK,CACZ5B,OAAAA,EAAO,MAAM,uBAAwB4B,CAAG,EACjC,CACL,MAAO,GACP,MAAO,4DAAA,CAEX,CACF,CAUA,eAAsBqF,GAAevE,EAA+C,CAClF,GAAI,CACF,MAAMsE,EAAM,MAAM,MAAM,GAAGJ,GAAkB,SAASlE,CAAM,aAAc,CACxE,OAAQ,SACR,QAAS,CAAE,eAAgB,kBAAA,CAAmB,CAC/C,EAED,GAAI,CAACsE,EAAI,GAAI,CACX,MAAM3E,EAAY,MAAM2E,EAAI,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACnDhH,OAAAA,EAAO,MAAM,2BAA4BqC,CAAS,EAC3C,CAAE,QAAS,GAAO,MAAOA,EAAU,OAAS,4BAAA,CACrD,CAEA,MAAO,CAAE,QAAS,EAAA,CACpB,OAAST,EAAK,CACZ5B,OAAAA,EAAO,MAAM,wBAAyB4B,CAAG,EAClC,CACL,QAAS,GACT,MAAO,4DAAA,CAEX,CACF,CAoBA,eAAsBsF,GACpBxE,EACAyE,EACwC,CACxC,GAAI,CACF,MAAMH,EAAM,MAAM,MAChB,GAAGJ,EAAA,CAAkB,SAASlE,CAAM,8BACpC,CACE,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CACnB,UAAWyE,EAAgB,UAC3B,SAAUA,EAAgB,SAC1B,MAAOA,EAAgB,MACvB,YAAaA,EAAgB,aAAe,KAC5C,YAAaA,EAAgB,aAAe,EAAA,CAC7C,CAAA,CACH,EAGF,GAAI,CAACH,EAAI,GAAI,CACX,MAAM3E,EAAY,MAAM2E,EAAI,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACnDhH,OAAAA,EAAO,MAAM,qCAAsCqC,CAAS,EACrD,CAAE,QAAS,GAAO,MAAOA,EAAU,OAAS,4BAAA,CACrD,CAEA,MAAMQ,EAAO,MAAMmE,EAAI,KAAA,EACvB,MAAO,CACL,QAAS,GACT,QAASnE,EAAK,QACd,mBAAoBA,EAAK,kBAAA,CAE7B,OAASjB,EAAK,CACZ5B,OAAAA,EAAO,MAAM,iCAAkC4B,CAAG,EAC3C,CACL,QAAS,GACT,MAAO,4DAAA,CAEX,CACF,CC1NA,MAAM5B,EAASC,EAAAA,aAAa,IAAI,EAS1BmH,GAAkD,CACtD,qBAAsB,2CACtB,gBAAiB,kBACjB,cAAe,oCACf,kBAAmB,oDACnB,yBAA0B,8CAC5B,EAKA,eAAsBC,GACpBnE,EACAoE,EACAC,EAAuB,KACvBC,EAAW,GACkB,CAC7B,GAAI,CACF,MAAMtF,EAAgC,CAAE,MAAAoF,CAAA,EACpCC,GAASC,IACXtF,EAAK,MAAQqF,EACbrF,EAAK,SAAW,IAGlB,MAAM8E,EAAM,MAAM,MAAM,GAAGxG,GAAkB,WAAW0C,CAAO,YAAa,CAC1E,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAUhB,CAAI,CAAA,CAC1B,EAED,GAAI,CAAC8E,EAAI,GAAI,CACX,MAAM3E,EAAY,MAAM2E,EAAI,KAAA,EAAO,MAAM,KAAO,CAAA,EAAG,EACnD,OAAAhH,EAAO,MAAM,wBAAyBqC,CAAS,EACxC,CACL,QAAS,GACT,MACE+E,GAAwB/E,EAAU,KAAK,GACvC,4CAAA,CAEN,CAEA,MAAMQ,EAAO,MAAMmE,EAAI,KAAA,EACvB,MAAO,CACL,QAAS,GACT,SAAUnE,EAAK,SACf,QAASA,EAAK,OAAA,CAElB,OAASjB,EAAK,CACZ,OAAA5B,EAAO,MAAM,sBAAuB4B,CAAG,EAChC,CACL,QAAS,GACT,MAAO,4DAAA,CAEX,CACF,CAUA,eAAsB6F,GACpBvE,EACAoE,EACiC,CACjC,GAAI,CACF,MAAMN,EAAM,MAAM,MAChB,GAAGxG,GAAkB,WAAW0C,CAAO,4BAA4B,mBAAmBoE,CAAK,CAAC,EAAA,EAG9F,OAAKN,EAAI,GAMF,CAAE,UADI,MAAMA,EAAI,KAAA,GACC,QAAA,EALlBA,EAAI,SAAW,IAAY,CAAE,SAAU,IAAA,EACpC,CAAE,SAAU,KAAM,MAAO,0BAAA,CAKpC,OAASpF,EAAK,CACZ,OAAA5B,EAAO,MAAM,6BAA8B4B,CAAG,EACvC,CAAE,SAAU,KAAM,MAAO,eAAA,CAClC,CACF,CChDO,SAAS8F,GACdC,EACA9C,EACA9C,EAA2B,CAAA,EACjB,CACV,KAAM,CACJ,UAAA6F,EAAY,GACZ,eAAAC,EAAiB,GACjB,gBAAAC,EAAkB,EAAA,EAChB/F,EACEgG,MAAU,KAEhB,GAAIH,EACF,MAAO,CAAE,KAAM,YAAa,SAAU,GAAM,OAAQ,WAAA,EAEtD,MAAMI,EAAWL,EAAM,aAAeA,EAAM,cAC5C,GAAIK,GAAY,IAAI,KAAKA,CAAQ,EAAID,EACnC,MAAO,CAAE,KAAM,cAAe,SAAU,GAAM,OAAQ,YAAA,EAGxD,MAAME,GAAiBpD,GAAW,IAAI,OAAOqD,GAAKA,EAAE,eAAiB,CAAC,EACtE,GAAID,EAAc,SAAW,EAC3B,MAAO,CACL,KAAM,uBACN,SAAU,GACV,OAAQ,YAAA,EAIZ,IAAIE,EAAiB,GACjBC,EAAa,GACbC,EAAgB,GAChBC,EAAkC,KAEtC,UAAWC,KAAUN,EAAe,CAClC,MAAMO,EACJD,EAAO,YACPA,EAAO,YACPA,EAAO,WACPA,EAAO,YACHE,EAAWF,EAAO,UAAYA,EAAO,SAAWA,EAAO,UACvDG,EACJH,EAAO,mBAAqBA,EAAO,mBAAqBA,EAAO,SAC3DI,EACJJ,EAAO,SACNG,GAAc,MAAmCA,GAAa,EAE3DE,EAAcJ,EAAa,IAAI,KAAKA,CAAU,EAAIT,EAAM,GACxDc,EAAgBJ,EAAW,IAAI,KAAKA,CAAQ,EAAIV,EAAM,GAO5D,GANsB,CAACY,GAAa,CAACC,GAAe,CAACC,IAElCV,EAAiB,IAC/BQ,IAAWP,EAAa,IACxBQ,IAAaP,EAAgB,IAE9BO,GAAeJ,GAAc,CAACG,GAAa,CAACE,EAAe,CAC7D,MAAMC,EAAY,IAAI,KAAKN,CAAU,GACjC,CAACF,GAAsBQ,EAAYR,KACrCA,EAAqBQ,EAEzB,CACF,CAEA,GAAIX,EACF,MAAO,CACL,KAAMN,EAAiB,iBAAmB,cAC1C,SAAU,GACV,OAAQ,WAAA,EAIZ,GAAIQ,GAAiBC,EAAoB,CACvC,MAAMS,EAAST,EAAmB,QAAA,EAAYP,EAAI,QAAA,EAC5CiB,EAAYD,GAAU,IAAO,GAAK,IAClCE,EAAWF,GAAU,IAAO,GAAK,GAAK,IAC5C,IAAIG,EACJ,GAAIF,EAAY,GACdE,EAAWZ,EAAmB,mBAAmB,QAAS,CACxD,KAAM,UACN,OAAQ,UACR,OAAQ,EAAA,CACT,UACQW,GAAY,EACrBC,EAAWC,EAAAA,cACTb,EACA,CAAE,QAAS,QAAS,KAAM,UAAW,OAAQ,UAAW,OAAQ,EAAA,EAChE,OAAA,MAEG,CACL,MAAMc,EAAID,EAAAA,cACRb,EACA,CAAE,MAAO,QAAS,IAAK,SAAA,EACvB,OAAA,EAEIJ,EAAII,EAAmB,mBAAmB,QAAS,CACvD,KAAM,UACN,OAAQ,UACR,OAAQ,EAAA,CACT,EACDY,EAAW,GAAGE,CAAC,IAAIlB,CAAC,EACtB,CACA,MAAO,CACL,KAAM,WAAWgB,CAAQ,GACzB,SAAU,GACV,OAAQ,aAAA,CAEZ,CAEA,OAAId,EACEN,EACK,CACL,KAAM,gBACN,SAAU,GACV,OAAQ,mBAAA,EAGL,CAAE,KAAM,WAAY,SAAU,GAAM,OAAQ,UAAA,EAG9C,CAAE,KAAM,cAAe,SAAU,GAAM,OAAQ,aAAA,CACxD,CCnFO,SAASuB,EAAgBC,EAAuC,CACrE,MAAO,CACL,KAAMA,EAAU,MAAQ,OAAOA,EAAU,IAAMA,EAAU,IAAM,EAAE,EACjE,GAAIA,EAAU,IAAMA,EAAU,GAC9B,aAAcA,EAAU,cAAgBA,EAAU,cAClD,QAASA,EAAU,SAAWA,EAAU,SACxC,kBACEA,EAAU,mBACVA,EAAU,qBACVA,EAAU,UACZ,iBACEA,EAAU,kBACVA,EAAU,oBACVA,EAAU,SACZ,cACEA,EAAU,eAAiBA,EAAU,gBAAkBA,EAAU,MACnE,WACEA,EAAU,YAAcA,EAAU,aAAeA,EAAU,MAAQ,GACrE,aAAcA,EAAU,cAAgBA,EAAU,eAClD,cACEA,EAAU,eACVA,EAAU,gBACVA,EAAU,OACV,EACF,OAAQA,EAAU,OAClB,UAAWA,EAAU,WAAaA,EAAU,WAC5C,YAAaA,EAAU,aAAeA,EAAU,aAAA,CAEpD,CAUO,SAASC,EAAeC,EAA2B,CAExD,MAAMC,EACJD,EAAS,kBACTA,EAAS,SACTA,EAAS,mBACT,CAAA,EAEF,MAAO,CACL,KAAMA,EAAS,MAAQ,OAAOA,EAAS,IAAMA,EAAS,IAAM,EAAE,EAC9D,GAAIA,EAAS,IAAMA,EAAS,GAC5B,cACEA,EAAS,eACTA,EAAS,OACTA,EAAS,gBACT,GACF,kBACEA,EAAS,mBACTA,EAAS,WACTA,EAAS,WACX,iBACEA,EAAS,kBACTA,EAAS,UACTA,EAAS,UACX,OAAQA,EAAS,QAAU,UAC3B,YACEA,EAAS,aACTA,EAAS,OACTA,EAAS,cACT,EACF,SAAUA,EAAS,SACnB,kBACEA,EAAS,mBACTA,EAAS,YACTA,EAAS,aACTA,EAAS,qBACT,EACF,UACEA,EAAS,WAAaA,EAAS,KAAOA,EAAS,YAAc,EAC/D,SAAUA,EAAS,UAAY,EAC/B,gBACEA,EAAS,iBAAmBA,EAAS,kBACvC,cAAeA,EAAS,eAAiBA,EAAS,eAClD,iBAAkBC,EAAW,IAAIJ,CAAe,EAChD,UAAWG,EAAS,WAAaA,EAAS,WAC1C,UAAWA,EAAS,WAAaA,EAAS,UAAA,CAE9C,CAOO,SAASE,GAAyBF,EASvC,CACA,MAAMG,EAAQJ,EAAeC,CAAQ,EAC/BI,EAAYD,EAAM,KAAK,MAAM,GAAG,EAAE,CAAC,GAAKA,EAAM,KAEpD,MAAO,CACL,QAASA,EAAM,KACf,eAAgBC,EAChB,MAAOD,EAAM,cACb,aAAc,CAACA,EAAM,kBAAmBA,EAAM,gBAAgB,EAC3D,OAAO,OAAO,EACd,KAAK,GAAG,EACX,MAAOA,EAAM,YACb,eAAgB,GAAGE,EAAAA,eAAgBF,EAAM,YAAc,GAAA,CAA2J,GAClN,YAAaA,EAAM,iBAAiB,OACpC,OAAQA,EAAM,MAAA,CAElB,CCtMA,MAAMG,GAAe,qDAkEd,SAASC,EAAeC,EAAkC,CAC/D,OAAKA,EACDA,EAAK,WAAW,MAAM,EAAUA,EAC7B,GAAGF,EAAY,IAAIE,EAAK,QAAQ,MAAO,EAAE,CAAC,GAF/B,EAGpB,CAKO,SAASC,EAAiBC,EAA4B,CAC3D,MAAMC,EACJD,EAAS,UACTA,EAAS,UACTA,EAAS,WACTA,EAAS,OACT,GAEF,OAAOH,EAAeI,CAAM,CAC9B,CAKO,SAASC,EACdF,EACoD,CAEpD,MAAMG,EAAgBH,EAAS,UAAYA,EAAS,UACpD,GAAIG,EACF,OAAOA,EAIT,GAAIH,EAAS,aAAeA,EAAS,aACnC,MAAO,QAIT,MAAMI,EAAYJ,EAAS,eAAiBA,EAAS,iBAAmBA,EAAS,KACjF,GAAII,EAAW,CACb,MAAMC,EAAY,IAAI,KAAKD,CAAS,EAAE,QAAA,EAChCvC,EAAM,KAAK,IAAA,EAEjB,GAAIwC,EAAYxC,EACd,MAAO,OAEX,CAGA,MAAMyC,EACJN,EAAS,kBAAoBA,EAAS,kBAExC,GAAIM,IAAmB,OACrB,OAAIA,GAAkB,EACb,WAEF,YAIT,MAAM3F,EACJqF,EAAS,kBACTA,EAAS,mBACTA,EAAS,SACT,CAAA,EAEF,OAAIrF,EAAQ,SAAW,EACd,cAGcA,EAAQ,OAAO,CAAC4F,EAAavC,IAAW,CAC7D,MAAMwC,EACJxC,EAAE,mBAAqBA,EAAE,oBAAsBA,EAAE,UAAY,EACzDyC,EAAOzC,EAAE,cAAgBA,EAAE,eAAiB,EAClD,OAAOuC,EAAM,KAAK,IAAI,EAAGC,EAAMC,CAAI,CACrC,EAAG,CAAC,GAEkB,EACb,WAGF,WACT,CAKO,SAAStB,EAAgBC,EAAiC,CAC/D,MAAO,CACL,GAAIA,EAAU,IAAMA,EAAU,GAC9B,KAAMA,EAAU,MAAQA,EAAU,YAAc,GAChD,YAAaA,EAAU,YACvB,MAAOA,EAAU,OAAS,EAC1B,SAAUA,EAAU,UAAYA,EAAU,eAAiB,EAC3D,aAAcA,EAAU,cAAgBA,EAAU,eAAiB,EACnE,kBACEA,EAAU,mBACVA,EAAU,qBACTA,EAAU,UAAY,IAAMA,EAAU,cAAgB,GACzD,YAAaA,EAAU,aAAeA,EAAU,eAAiB,EACjE,YAAaA,EAAU,aAAeA,EAAU,eAAiB,GACjE,cAAeA,EAAU,eAAiBA,EAAU,gBACpD,YAAaA,EAAU,aAAeA,EAAU,cAChD,SAAUA,EAAU,UAAYA,EAAU,WAAa,GACvD,oBACEA,EAAU,qBAAuBA,EAAU,uBAC7C,WAAYA,EAAU,YAAcA,EAAU,aAAe,EAC7D,UAAWA,EAAU,WAAaA,EAAU,WAC5C,UAAWA,EAAU,WAAaA,EAAU,YAAc,CAAA,CAE9D,CAKO,SAASsB,EAAeV,EAA2B,CAQxD,MAAMrF,GALJqF,EAAS,kBACTA,EAAS,mBACTA,EAAS,SACT,CAAA,GAEyB,IAAIb,CAAe,EAGxCwB,EAAShG,EAAQ,IAAKqD,GAAMA,EAAE,KAAK,EAAE,OAAQ4C,GAAMA,EAAI,CAAC,EACxDC,EAAWF,EAAO,OAAS,EAAI,KAAK,IAAI,GAAGA,CAAM,EAAI,OACrDG,EAAWH,EAAO,OAAS,EAAI,KAAK,IAAI,GAAGA,CAAM,EAAI,OAE3D,MAAO,CACL,QAASX,EAAS,SAAWA,EAAS,IAAMA,EAAS,IAAM,EAC3D,GAAIA,EAAS,IAAMA,EAAS,GAC5B,KAAMA,EAAS,MAAQA,EAAS,OAAS,GACzC,MAAOA,EAAS,OAASA,EAAS,KAClC,KAAMA,EAAS,KACf,YAAaA,EAAS,YACtB,KAAMA,EAAS,MAAQA,EAAS,eAAiBA,EAAS,iBAAmB,GAC7E,cAAeA,EAAS,eAAiBA,EAAS,gBAClD,YAAaA,EAAS,aAAeA,EAAS,cAC9C,cAAeA,EAAS,eAAiBA,EAAS,gBAClD,SAAUA,EAAS,UAAYA,EAAS,UACxC,QAASA,EAAS,SAAWA,EAAS,SACtC,UAAWA,EAAS,WAAaA,EAAS,WAC1C,aAAcA,EAAS,cAAgBA,EAAS,cAChD,SAAUA,EAAS,UAAYA,EAAS,cAAgBA,EAAS,cACjE,SAAUD,EAAiBC,CAAQ,EACnC,SAAUD,EAAiBC,CAAQ,EACnC,OAAQA,EAAS,OACjB,YAAaA,EAAS,aAAeA,EAAS,aAC9C,YAAaA,EAAS,aAAeA,EAAS,aAC9C,iBAAkBrF,EAClB,iBACEqF,EAAS,kBACTA,EAAS,mBACTrF,EAAQ,OAAO,CAAC4F,EAAKvC,IAAMuC,GAAOvC,EAAE,mBAAqB,GAAI,CAAC,EAChE,YAAagC,EAAS,aAAeA,EAAS,aAC9C,SAAUA,EAAS,UAAYA,EAAS,WAAaa,EACrD,SAAUb,EAAS,UAAYA,EAAS,WAAac,EACrD,QAASd,EAAS,SAAWA,EAAS,SACtC,SAAUE,EAAkBF,CAAQ,EACpC,eAAgBA,EAAS,gBAAkBA,EAAS,gBACpD,cAAeA,EAAS,eAAiBA,EAAS,gBAClD,qBACEA,EAAS,sBAAwBA,EAAS,sBAAA,CAEhD,CAKO,MAAMe,GAAqBL,EC9O5Bd,GAAe,qDAoCrB,SAASoB,GAAWlB,EAAkC,CACpD,OAAKA,EACDA,EAAK,WAAW,MAAM,EAAUA,EAC7B,GAAGF,EAAY,IAAIE,EAAK,QAAQ,MAAO,EAAE,CAAC,GAF/B,EAGpB,CAKO,SAASmB,GAAeC,EAA2B,CACxD,MAAMC,EACJD,EAAS,SAAWA,EAAS,UAAYA,EAAS,KAEpD,MAAO,CACL,GAAIA,EAAS,IAAMA,EAAS,IAAM,EAClC,KAAMA,EAAS,MAAQ,GACvB,KAAMA,EAAS,KACf,QAASA,EAAS,QAClB,wBACEA,EAAS,yBACTA,EAAS,2BACX,KAAMA,EAAS,KACf,MAAOA,EAAS,MAChB,QAASA,EAAS,SAAWA,EAAS,SACtC,QAASA,EAAS,QAClB,SAAUA,EAAS,UAAYA,EAAS,UACxC,QAASF,GAAWG,CAAQ,EAC5B,qBACED,EAAS,sBACTA,EAAS,wBACT,EACF,gBACEA,EAAS,iBAAmBA,EAAS,mBAAqB,EAC5D,cACEA,EAAS,eAAiBA,EAAS,gBAAkB,EACvD,eACEA,EAAS,gBAAkBA,EAAS,eAAA,CAE1C,CAKO,SAASE,GAAiBF,EAI/B,CACA,MAAO,CACL,qBACEA,EAAS,sBACTA,EAAS,wBACT,EACF,gBACEA,EAAS,iBAAmBA,EAAS,mBAAqB,EAC5D,cACEA,EAAS,eAAiBA,EAAS,gBAAkB,CAAA,CAE3D,CAKO,SAASG,GAAmBjF,EAAsB,CAQvD,MAPc,CACZA,EAAM,QACNA,EAAM,KACNA,EAAM,MACNA,EAAM,OAAA,EACN,OAAO,OAAO,EAEH,KAAK,IAAI,CACxB"}