UNPKG

ws-dottie

Version:

Your friendly TypeScript companion for Washington State transportation APIs - WSDOT and WSF data with smart caching and React Query integration

1 lines 433 kB
{"version":3,"sources":["../src/shared/config/configManager.ts","../src/api/wsdot-border-crossings/index.ts","../src/shared/logger.ts","../src/shared/fetching/errors/errors.ts","../src/shared/fetching/parsing/dateParsers.ts","../src/shared/fetching/parsing/parseJson.ts","../src/shared/fetching/strategies/utils.ts","../src/shared/fetching/strategies/fetchJsonp.ts","../src/shared/fetching/strategies/fetchNative.ts","../src/shared/fetching/utils/selectFetchStrategy.ts","../src/shared/fetching/api/createApiClient.ts","../src/shared/fetching/api/createFetchFactory.ts","../src/shared/validation/index.ts","../src/api/wsdot-border-crossings/schemas.ts","../src/api/wsdot-border-crossings/api.ts","../src/shared/caching/config.ts","../src/api/wsdot-border-crossings/queries.ts","../src/api/wsdot-bridge-clearances/index.ts","../src/api/wsdot-bridge-clearances/schemas.ts","../src/api/wsdot-bridge-clearances/api.ts","../src/api/wsdot-bridge-clearances/queries.ts","../src/api/wsdot-commercial-vehicle-restrictions/index.ts","../src/api/wsdot-commercial-vehicle-restrictions/schemas.ts","../src/api/wsdot-commercial-vehicle-restrictions/api.ts","../src/api/wsdot-commercial-vehicle-restrictions/queries.ts","../src/api/wsdot-highway-alerts/index.ts","../src/api/wsdot-highway-alerts/schemas.ts","../src/api/wsdot-highway-alerts/api.ts","../src/api/wsdot-highway-alerts/queries.ts","../src/api/wsdot-highway-cameras/index.ts","../src/api/wsdot-highway-cameras/schemas.ts","../src/api/wsdot-highway-cameras/api.ts","../src/api/wsdot-highway-cameras/queries.ts","../src/api/wsdot-mountain-pass-conditions/index.ts","../src/api/wsdot-mountain-pass-conditions/schemas.ts","../src/api/wsdot-mountain-pass-conditions/api.ts","../src/api/wsdot-mountain-pass-conditions/queries.ts","../src/api/wsdot-toll-rates/index.ts","../src/api/wsdot-toll-rates/schemas.ts","../src/api/wsdot-toll-rates/api.ts","../src/api/wsdot-toll-rates/queries.ts","../src/api/wsdot-traffic-flow/index.ts","../src/api/wsdot-traffic-flow/schemas.ts","../src/api/wsdot-traffic-flow/api.ts","../src/api/wsdot-traffic-flow/queries.ts","../src/api/wsdot-travel-times/index.ts","../src/api/wsdot-travel-times/schemas.ts","../src/api/wsdot-travel-times/api.ts","../src/api/wsdot-travel-times/queries.ts","../src/api/wsdot-weather-information/index.ts","../src/api/wsdot-weather-information/schemas.ts","../src/api/wsdot-weather-information/api.ts","../src/api/wsdot-weather-information/queries.ts","../src/api/wsdot-weather-information-extended/index.ts","../src/api/wsdot-weather-information-extended/schemas.ts","../src/api/wsdot-weather-information-extended/api.ts","../src/api/wsdot-weather-information-extended/queries.ts","../src/api/wsdot-weather-stations/index.ts","../src/api/wsdot-weather-stations/schemas.ts","../src/api/wsdot-weather-stations/api.ts","../src/api/wsdot-weather-stations/queries.ts","../src/api/wsf-fares/index.ts","../src/api/wsf-fares/schemas.ts","../src/api/wsf-fares/api.ts","../src/api/wsf-schedule/index.ts","../src/api/wsf-schedule/schemas.ts","../src/api/wsf-schedule/api.ts","../src/shared/caching/CacheProvider.tsx","../src/api/wsf-schedule/queries.ts","../src/api/wsf-schedule/cache.ts","../src/api/wsf-terminals/index.ts","../src/api/wsf-terminals/schemas.ts","../src/api/wsf-terminals/api.ts","../src/api/wsf-terminals/queries.ts","../src/api/wsf-terminals/cache.ts","../src/api/wsf-vessels/index.ts","../src/api/wsf-vessels/schemas.ts","../src/api/wsf-vessels/api.ts","../src/api/wsf-vessels/queries.ts","../src/api/wsf-vessels/cache.ts","../src/api/wsf-fares/queries.ts"],"names":["DEFAULT_BASE_URL","getEnvVar","key","env","initializeFromEnv","apiKey","baseUrl","globalConfig","getApiKey","getBaseUrl","setApiKey","setBaseUrl","clearConfig","configManager","wsdot_border_crossings_exports","__export","getBorderCrossings","useBorderCrossings","isDevelopment","log","logger_default","WsdotApiError","message","code","context","createApiError","error","endpoint","url","status","jsDateToYyyyMmDd","date","MM_DD_YYYY_REGEX","MM_DD_YYYY_DATETIME_REGEX","parseMmDdYyyyDate","dateString","match","month","day","year","parseMmDdYyyyDateTime","dateTimeString","hours","minutes","seconds","ampm","adjustedHours","convert12To24Hour","hour","isWsdotDateString","value","wsdotDateTimestampToJsDate","timestamp","WSF_DATE_PARSERS","parseWsdotJson","text","wsdotDateReviver","wsfDateParser","hasApiError","data","errorData","processApiResponse","JSONP_TIMEOUT_MS","ARRAY_ENDPOINTS","shouldReturnArray","generateCallbackName","fetchJsonp","resolve","reject","callbackName","script","jsonpWindow","isArrayEndpoint","cleanup","cleanupWithTimeout","timeoutId","result","fetchNative","_expectedType","response","selectFetchStrategy","environment","getEnvironmentType","isWebEnvironment","isTestEnvironment","userAgent","createApiClient","fetchStrategy","logMode","expectedType","logDebug","responseString","transformedResponse","prefix","createFetchFactory","apiPath","fetchFn","createFetch","endpointTemplate","params","interpolateParams","buildUrl","getApiKeyParam","entry","substituteParam","apiKeyParam","separator","placeholder","stringValue","zWsdotDate","z","v","val","zNullableString","zNullableNumber","borderCrossingLocationSchema","borderCrossingDataSchema","borderCrossingDataArraySchema","tanstackQueryOptions","attemptIndex","options","useQuery","wsdot_bridge_clearances_exports","getBridgeClearances","useBridgeClearances","bridgeDataGisSchema","bridgeDataGisArraySchema","wsdot_commercial_vehicle_restrictions_exports","getCommercialVehicleRestrictions","getCommercialVehicleRestrictionsWithId","useCommercialVehicleRestrictions","useCommercialVehicleRestrictionsWithId","roadwayLocationSchema","commercialVehicleRestrictionSchema","commercialVehicleRestrictionWithIdSchema","commercialVehicleRestrictionArraySchema","commercialVehicleRestrictionWithIdArraySchema","wsdot_highway_alerts_exports","getHighwayAlertById","getHighwayAlerts","getHighwayAlertsByMapArea","useHighwayAlertById","useHighwayAlerts","useHighwayAlertsByMapArea","highwayAlertSchema","highwayAlertArraySchema","wsdot_highway_cameras_exports","getHighwayCamera","getHighwayCameras","searchHighwayCameras","useHighwayCamera","useHighwayCameras","useSearchHighwayCameras","cameraLocationSchema","cameraSchema","cameraArraySchema","searchCamerasParamsSchema","queryParams","wsdot_mountain_pass_conditions_exports","getMountainPassConditionById","getMountainPassConditions","useMountainPassConditionById","useMountainPassConditions","travelRestrictionSchema","mountainPassConditionSchema","mountainPassConditionArraySchema","wsdot_toll_rates_exports","getTollRates","getTollTripInfo","getTollTripRates","useTollRates","useTollTripInfo","useTollTripRates","tollRateSchema","tollRateArraySchema","tollTripInfoSchema","tollTripInfoArraySchema","tollTripRateSchema","tollTripRatesSchema","wsdot_traffic_flow_exports","getTrafficFlowById","getTrafficFlows","useTrafficFlowById","useTrafficFlows","flowStationLocationSchema","trafficFlowSchema","trafficFlowArraySchema","wsdot_travel_times_exports","getTravelTimeById","getTravelTimes","useTravelTimeById","useTravelTimes","travelTimeEndpointSchema","travelTimeRouteSchema","travelTimesArraySchema","wsdot_weather_information_exports","getWeatherInformation","getWeatherInformationByStationId","getWeatherInformationForStations","useWeatherInformation","useWeatherInformationByStationId","useWeatherInformationForStations","weatherInfoSchema","weatherInfoArraySchema","wsdot_weather_information_extended_exports","getWeatherInformationExtended","useWeatherInformationExtended","zIsoDateNullable","d","surfaceMeasurementSchema","subSurfaceMeasurementSchema","weatherReadingSchema","weatherReadingArraySchema","wsdot_weather_stations_exports","getWeatherStations","useWeatherStations","weatherStationDataSchema","weatherStationDataArraySchema","wsf_fares_exports","getFareLineItems","getFareLineItemsBasic","getFareLineItemsVerbose","getFareTotals","getFaresCacheFlushDate","getFaresTerminalMates","getFaresTerminals","getFaresValidDateRange","getTerminalCombo","getTerminalComboVerbose","zIsoOrEpochDate","faresCacheFlushDateSchema","faresValidDateRangeSchema","faresTerminalSchema","terminalMateSchema","terminalComboSchema","terminalComboVerboseSchema","fareLineItemSchema","fareLineItemBasicSchema","lineItemLookupSchema","fareLineItemsVerboseResponseSchema","faresTerminalsArraySchema","terminalMatesArraySchema","terminalComboVerboseArraySchema","fareLineItemsArraySchema","fareLineItemsBasicArraySchema","fareTotalsArraySchema","wsf_schedule_exports","ScheduleCacheProvider","activeSeasonSchema","activeSeasonsArraySchema","alertSchema","alertsArraySchema","alternativeFormatSchema","alternativeFormatsArraySchema","annotationSchema","contingencyAdjustmentSchema","getActiveSeasons","getAlerts","getAllSailings","getAlternativeFormats","getCacheFlushDateSchedule","getRouteDetails","getRouteDetailsByRoute","getRouteDetailsByTerminals","getRoutes","getRoutesByTerminals","getRoutesWithDisruptions","getSailings","getScheduleByRoute","getScheduleByTerminals","getScheduleTodayByRoute","getScheduleTodayByTerminals","getScheduledRoutes","getScheduledRoutesBySeason","getTerminalMates","getTerminals","getTerminalsAndMates","getTerminalsAndMatesByRoute","getTimeAdjustments","getTimeAdjustmentsByRoute","getTimeAdjustmentsBySchedRoute","getValidDateRange","journeySchema","routeDetailsLooseSchema","routeDetailsSchema","routeSchema","routesArrayLooseSchema","routesArraySchema","sailingSchema","sailingsArraySchema","scheduleCacheFlushDateSchema","scheduleDepartureSchema","scheduleResponseSchema","scheduleResponseTerminalComboSchema","scheduleSchema","scheduleTerminalComboSchema","scheduleTerminalCombosArraySchema","scheduleTerminalSchema","scheduleTerminalsArraySchema","scheduleTimeSchema","scheduledRouteSchema","scheduledRoutesArraySchema","serviceDisruptionSchema","terminalTimeSchema","timeAdjustmentSchema","timeAdjustmentsArraySchema","useActiveSeasons","useAlerts","useAllSailings","useAlternativeFormats","useCacheFlushDateSchedule","useRouteDetails","useRouteDetailsByRoute","useRouteDetailsByTerminals","useRoutes","useRoutesByTerminals","useRoutesWithDisruptions","useSailings","useScheduleByRoute","useScheduleByTerminals","useScheduleTodayByRoute","useScheduleTodayByTerminals","useScheduledRoutes","useScheduledRoutesBySeason","useTerminalMates","useTerminals","useTerminalsAndMates","useTerminalsAndMatesByRoute","useTimeAdjustments","useTimeAdjustmentsByRoute","useTimeAdjustmentsBySchedRoute","useValidDateRange","validDateRangeSchema","zDate","zNullableDate","CacheProvider","queryKey","useCacheFlushDateHook","queryClient","useQueryClient","previousFlushDate","useRef","currentFlushDate","useEffect","wsf_terminals_exports","TerminalCacheProvider","getCacheFlushDateTerminals","getTerminalBasics","getTerminalBasicsByTerminalId","getTerminalBulletins","getTerminalBulletinsByTerminalId","getTerminalLocations","getTerminalLocationsByTerminalId","getTerminalSailingSpace","getTerminalSailingSpaceByTerminalId","getTerminalTransports","getTerminalTransportsByTerminalId","getTerminalVerbose","getTerminalVerboseByTerminalId","getTerminalWaitTimes","getTerminalWaitTimesByTerminalId","terminalArrivalSpaceSchema","terminalBasicsArraySchema","terminalBasicsSchema","terminalBulletinArraySchema","terminalBulletinItemSchema","terminalBulletinSchema","terminalCacheFlushDateSchema","terminalDepartingSpaceSchema","terminalLocationArraySchema","terminalLocationSchema","terminalSailingSpaceArraySchema","terminalSailingSpaceSchema","terminalTransitLinkSchema","terminalTransportArraySchema","terminalTransportSchema","terminalVerboseArraySchema","terminalVerboseSchema","terminalWaitTimeSchema","terminalWaitTimesArraySchema","terminalWaitTimesSchema","useCacheFlushDateTerminals","useTerminalBasics","useTerminalBasicsByTerminalId","useTerminalBulletins","useTerminalBulletinsByTerminalId","useTerminalLocations","useTerminalLocationsByTerminalId","useTerminalSailingSpace","useTerminalSailingSpaceByTerminalId","useTerminalTransports","useTerminalTransportsByTerminalId","useTerminalVerbose","useTerminalVerboseByTerminalId","useTerminalWaitTimes","useTerminalWaitTimesByTerminalId","zNullableBoolean","wsf_vessels_exports","VesselCacheProvider","getAllVesselHistories","getCacheFlushDateVessels","getMultipleVesselHistories","getVesselAccommodations","getVesselAccommodationsById","getVesselBasics","getVesselBasicsById","getVesselHistoryByVesselAndDateRange","getVesselLocations","getVesselLocationsByVesselId","getVesselStats","getVesselStatsById","getVesselVerbose","getVesselVerboseById","useAllVesselHistories","useCacheFlushDateVessels","useMultipleVesselHistories","useVesselAccommodations","useVesselAccommodationsById","useVesselBasics","useVesselBasicsById","useVesselHistoryByVesselAndDateRange","useVesselLocations","useVesselLocationsByVesselId","useVesselStats","useVesselStatsById","useVesselVerbose","useVesselVerboseById","vesselAccommodationArraySchema","vesselAccommodationSchema","vesselBasicArraySchema","vesselBasicSchema","vesselClassSchema","vesselHistoryArraySchema","vesselHistorySchema","vesselLocationArraySchema","vesselLocationSchema","vesselStatsArraySchema","vesselStatsSchema","vesselVerboseArraySchema","vesselVerboseSchema","vesselsCacheFlushDateSchema","vesselNames","dateStart","dateEnd","batchSize","results","i","batchPromises","vesselName","batchResults","useFaresCacheFlushDate","useFaresValidDateRange","useFaresTerminals","useFaresTerminalMates","useTerminalCombo","useTerminalComboVerbose","useFareLineItemsBasic","useFareLineItems","useFareLineItemsVerbose","useFareTotals"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * WSDOT API Configuration Manager\n *\n * This module provides centralized configuration management for WSDOT and WSF APIs.\n * It handles API key management, base URL configuration, and environment-based\n * configuration loading across different platforms (Node.js, browser, test environments).\n *\n * Key Features:\n * - Environment-based API key loading (WSDOT_ACCESS_TOKEN)\n * - Configurable base URL (WSDOT_BASE_URL)\n * - Cross-platform compatibility (Node.js, browser, test)\n * - Global configuration state management\n * - Type-safe configuration interface\n *\n * Usage:\n * ```typescript\n * // Set API key only\n * configManager.setApiKey(\"your-api-key\");\n *\n * // Set base URL only\n * configManager.setBaseUrl(\"https://custom.wsdot.wa.gov\");\n *\n * // Get API key (auto-initializes from environment if not set)\n * const apiKey = configManager.getApiKey();\n *\n * // Get base URL\n * const baseUrl = configManager.getBaseUrl();\n * ```\n */\n\n// Default base URL for WSDOT/WSF requests\nconst DEFAULT_BASE_URL = \"https://www.wsdot.wa.gov\";\n\n// Configuration interface\nexport interface WsdotConfig {\n  WSDOT_ACCESS_TOKEN: string;\n  WSDOT_BASE_URL?: string;\n}\n\n// Helper function to safely access environment variables\nconst getEnvVar = (key: string): string | undefined => {\n  // Node.js environment\n  if (typeof process !== \"undefined\" && process.env) {\n    return process.env[key];\n  }\n\n  // Browser environment - try to access via window object if available\n  if (typeof window !== \"undefined\") {\n    type EnvWindow = Window & { __ENV__?: Record<string, string> };\n    const env = (window as EnvWindow).__ENV__;\n    if (env) return env[key];\n  }\n\n  // For bundlers that inject environment variables, we'll rely on the consuming application\n  // to provide these via configuration rather than trying to access them directly\n  return undefined;\n};\n\n// Initialize configuration from environment variables at module load\nconst initializeFromEnv = (): WsdotConfig => {\n  const apiKey = getEnvVar(\"WSDOT_ACCESS_TOKEN\") || \"\";\n  const baseUrl = getEnvVar(\"WSDOT_BASE_URL\") || DEFAULT_BASE_URL;\n\n  return {\n    WSDOT_ACCESS_TOKEN: apiKey,\n    WSDOT_BASE_URL: baseUrl,\n  };\n};\n\n// Global configuration state - initialized from environment at module load\nlet globalConfig: WsdotConfig = initializeFromEnv();\n\n// Configuration management functions\nconst getApiKey = (): string => {\n  if (!globalConfig.WSDOT_ACCESS_TOKEN) {\n    throw new Error(\n      \"WSDOT_ACCESS_TOKEN is required. Set it via WSDOT_ACCESS_TOKEN environment variable or use configManager.setApiKey().\"\n    );\n  }\n  return globalConfig.WSDOT_ACCESS_TOKEN;\n};\n\nconst getBaseUrl = (): string => {\n  return globalConfig.WSDOT_BASE_URL || DEFAULT_BASE_URL;\n};\n\nconst setApiKey = (apiKey: string): void => {\n  if (!apiKey || apiKey.trim() === \"\") {\n    throw new Error(\"API key cannot be empty\");\n  }\n\n  globalConfig.WSDOT_ACCESS_TOKEN = apiKey.trim();\n};\n\nconst setBaseUrl = (baseUrl: string): void => {\n  if (!baseUrl || baseUrl.trim() === \"\") {\n    throw new Error(\"Base URL cannot be empty\");\n  }\n\n  globalConfig.WSDOT_BASE_URL = baseUrl.trim();\n};\n\nconst clearConfig = (): void => {\n  globalConfig = initializeFromEnv();\n};\n\n// Configuration manager object for clean interface\nexport const configManager = {\n  getApiKey,\n  getBaseUrl,\n  setApiKey,\n  setBaseUrl,\n  clearConfig,\n};\n","// WSDOT Border Crossings API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___border_crossings.html\n\n// API functions\nexport { getBorderCrossings } from \"./api\";\n// React Query hooks\nexport { useBorderCrossings } from \"./queries\";\n// Types inferred from Zod schemas\nexport type {\n  BorderCrossingData,\n  BorderCrossingLocation,\n} from \"./schemas\";\n","// Simple logger for the WSDOT API client library\n\n// Logging modes for individual API calls\nexport type LoggingMode = \"none\" | \"info\" | \"debug\";\n\nconst isDevelopment =\n  typeof process !== \"undefined\" && process.env.NODE_ENV === \"development\";\n\nconst log = {\n  debug: isDevelopment\n    ? console.debug.bind(console, \"[WS-Dottie Debug]\")\n    : () => {},\n  info: console.info.bind(console, \"[WS-Dottie Info]\"),\n  warn: console.warn.bind(console, \"[WS-Dottie Warn]\"),\n  error: console.error.bind(console, \"[WS-Dottie Error]\"),\n};\n\nexport default log;\n","/**\n * Error Handling Utilities for WSDOT and WSF APIs\n *\n * This module provides comprehensive error handling for API requests, including\n * custom error types, error context management, and user-friendly error messages.\n * It ensures consistent error handling across all API operations and provides\n * detailed error information for debugging and monitoring.\n *\n * Key Features:\n * - Custom WsdotApiError class with error codes and context\n * - Automatic error classification based on error messages and status codes\n * - User-friendly error messages for different error types\n * - Comprehensive error context including URL, status, and timestamp\n * - Type-safe error handling with TypeScript\n *\n * Error Types:\n * - NETWORK_ERROR: Connection failures, fetch errors\n * - API_ERROR: HTTP 4xx/5xx responses from the API\n * - TRANSFORM_ERROR: JSON parsing or data transformation errors\n * - TIMEOUT_ERROR: Request timeout errors\n * - CORS_ERROR: Cross-origin request failures\n * - INVALID_RESPONSE: Malformed or unexpected API responses\n * - RATE_LIMIT_ERROR: API rate limiting errors\n *\n * Usage:\n * ```typescript\n * try {\n *   const data = await apiClient(\"https://api.example.com/data\");\n * } catch (error) {\n *   const apiError = createApiError(error, \"getData\", \"https://api.example.com/data\", 404);\n *   console.log(apiError.getUserMessage()); // \"The API is currently unavailable...\"\n *   console.log(apiError.code); // \"API_ERROR\"\n * }\n * ```\n */\n// Custom error types for WSDOT API client\n\nexport type ErrorCode =\n  | \"NETWORK_ERROR\"\n  | \"API_ERROR\"\n  | \"TRANSFORM_ERROR\"\n  | \"TIMEOUT_ERROR\"\n  | \"CORS_ERROR\"\n  | \"INVALID_RESPONSE\"\n  | \"RATE_LIMIT_ERROR\";\n\nexport interface ErrorContext {\n  url?: string;\n  status?: number;\n  retryCount?: number;\n  endpoint?: string;\n  timestamp: Date;\n}\n\n/**\n * Base error class for WSDOT API client errors\n */\nexport class WsdotApiError extends Error {\n  public readonly code: ErrorCode;\n  public readonly context: ErrorContext;\n\n  constructor(\n    message: string,\n    code: ErrorCode,\n    context: Partial<ErrorContext> = {}\n  ) {\n    super(message);\n    this.name = \"WsdotApiError\";\n    this.code = code;\n    this.context = {\n      timestamp: new Date(),\n      ...context,\n    };\n  }\n\n  /**\n   * Get a user-friendly error message\n   */\n  getUserMessage(): string {\n    switch (this.code) {\n      case \"NETWORK_ERROR\":\n        return \"Network connection failed. Please check your internet connection.\";\n      case \"API_ERROR\":\n        return \"The API is currently unavailable. Please try again later.\";\n      case \"TRANSFORM_ERROR\":\n        return \"Received invalid data from the server.\";\n      case \"TIMEOUT_ERROR\":\n        return \"Request timed out. Please try again.\";\n      case \"CORS_ERROR\":\n        return \"Cross-origin request failed. This may be a browser security issue.\";\n      case \"INVALID_RESPONSE\":\n        return \"Received an invalid response from the server.\";\n      case \"RATE_LIMIT_ERROR\":\n        return \"Too many requests. Please wait before trying again.\";\n      default:\n        return this.message;\n    }\n  }\n}\n\n/**\n * Create appropriate error type based on the error context\n */\nexport function createApiError(\n  error: unknown,\n  endpoint: string,\n  url?: string,\n  status?: number\n): WsdotApiError {\n  const context: Partial<ErrorContext> = { endpoint, url, status };\n\n  if (error instanceof WsdotApiError) {\n    return error;\n  }\n\n  if (error instanceof Error) {\n    const message = error.message.toLowerCase();\n\n    if (message.includes(\"timeout\") || message.includes(\"timed out\")) {\n      return new WsdotApiError(error.message, \"TIMEOUT_ERROR\", context);\n    }\n\n    if (message.includes(\"cors\") || message.includes(\"cross-origin\")) {\n      return new WsdotApiError(error.message, \"CORS_ERROR\", context);\n    }\n\n    if (message.includes(\"network\") || message.includes(\"fetch\")) {\n      return new WsdotApiError(error.message, \"NETWORK_ERROR\", context);\n    }\n\n    if (status && status >= 400) {\n      return new WsdotApiError(error.message, \"API_ERROR\", context);\n    }\n\n    return new WsdotApiError(error.message, \"NETWORK_ERROR\", context);\n  }\n\n  return new WsdotApiError(\n    typeof error === \"string\" ? error : \"Unknown error occurred\",\n    \"NETWORK_ERROR\",\n    context\n  );\n}\n","/**\n * Date Parsing Utilities for WSDOT and WSF APIs\n *\n * This module provides comprehensive date parsing and formatting utilities for\n * handling the various date formats used by WSDOT and WSF APIs. It includes\n * both parsing functions for converting API date strings to JavaScript Date\n * objects and formatting functions for converting JavaScript Date objects to\n * API-compatible string formats.\n *\n * Key Features:\n * - WSDOT date format parsing (\"/Date(timestamp)/\")\n * - WSF Schedule date format parsing (\"MM/DD/YYYY\", \"MM/DD/YYYY HH:MM:SS AM/PM\")\n * - Date formatting for API requests (YYYY-MM-DD, MM/DD/YYYY)\n * - Field-specific date parsers for WSF Schedule API\n * - Comprehensive validation and error handling\n *\n * Supported Formats:\n * - WSDOT: \"/Date(1703123456789)/\" or \"/Date(1703123456789-0700)/\"\n * - WSF Schedule: \"12/25/2024\" or \"12/25/2024 02:30:45 PM\"\n * - ISO: \"2024-12-25\" or \"2024-12-25T14:30:00\"\n *\n * Usage:\n * ```typescript\n * // Parse WSDOT date format\n * const date = wsdotDateTimestampToJsDate(\"/Date(1703123456789)/\");\n *\n * // Parse WSF Schedule date format\n * const date = parseMmDdYyyyDate(\"12/25/2024\");\n *\n * // Format date for API requests\n * const formatted = jsDateToYyyyMmDd(new Date(\"2024-12-25\"));\n * ```\n */\n\n/**\n * Converts a JavaScript Date to ISO date stamp (YYYY-MM-DD)\n *\n * @example\n * Input: new Date('2024-12-25')\n * Output: \"2024-12-25\"\n */\nexport const jsDateToYyyyMmDd = (date: Date): string => {\n  return date.toISOString().split(\"T\")[0];\n};\n\n// Regex patterns for date parsing\nconst MM_DD_YYYY_REGEX = /^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/;\nconst MM_DD_YYYY_DATETIME_REGEX =\n  /^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})\\s+(\\d{1,2}):(\\d{2}):(\\d{2})\\s+(AM|PM)$/i;\n\n/**\n * Parse MM/DD/YYYY date format to JavaScript Date or null\n *\n * Handles WSF Schedule date fields like FromDate and ThruDate\n *\n * @param dateString - Date string in MM/DD/YYYY format\n * @returns JavaScript Date object or null if invalid\n *\n * @example\n * ```typescript\n * parseMmDdYyyyDate(\"12/25/2024\") // Returns Date object for Dec 25, 2024\n * parseMmDdYyyyDate(\"02/30/2024\") // Returns null (invalid date)\n * parseMmDdYyyyDate(\"\") // Returns null\n * ```\n */\nexport const parseMmDdYyyyDate = (dateString: string): Date | null => {\n  if (!dateString) return null;\n\n  const match = dateString.match(MM_DD_YYYY_REGEX);\n  if (!match) return null;\n\n  const [, month, day, year] = match.map(Number);\n\n  // Validate date components\n  if (month < 1 || month > 12 || day < 1 || day > 31 || year < 1900) {\n    return null;\n  }\n\n  const date = new Date(year, month - 1, day);\n\n  // Validate the created date matches the input (handles edge cases like Feb 30)\n  return date.getFullYear() === year &&\n    date.getMonth() === month - 1 &&\n    date.getDate() === day\n    ? date\n    : null;\n};\n\n/**\n * Parse MM/DD/YYYY HH:MM:SS AM/PM datetime format to JavaScript Date or null\n *\n * Handles WSF Schedule datetime fields like ModifiedDate\n *\n * @param dateTimeString - DateTime string in MM/DD/YYYY HH:MM:SS AM/PM format\n * @returns JavaScript Date object or null if invalid\n *\n * @example\n * ```typescript\n * parseMmDdYyyyDateTime(\"12/25/2024 02:30:45 PM\") // Returns Date object\n * parseMmDdYyyyDateTime(\"12/25/2024 12:00:00 AM\") // Returns Date object\n * parseMmDdYyyyDateTime(\"invalid\") // Returns null\n * ```\n */\nexport const parseMmDdYyyyDateTime = (dateTimeString: string): Date | null => {\n  if (!dateTimeString) return null;\n\n  const match = dateTimeString.match(MM_DD_YYYY_DATETIME_REGEX);\n  if (!match) return null;\n\n  const [, month, day, year, hours, minutes, seconds] = match.map(Number);\n  const ampm = match[7].toUpperCase();\n\n  const adjustedHours = convert12To24Hour(hours, ampm);\n  const date = new Date(\n    year,\n    month - 1,\n    day,\n    adjustedHours,\n    minutes,\n    seconds,\n    0\n  );\n\n  return Number.isNaN(date.getTime()) ? null : date;\n};\n\n/**\n * Convert 12-hour format to 24-hour format\n *\n * @param h - Hour in 12-hour format (1-12)\n * @param ampm - \"AM\" or \"PM\"\n * @returns Hour in 24-hour format (0-23)\n */\nexport const convert12To24Hour = (hour: number, ampm: string): number => {\n  if (ampm === \"PM\") return hour === 12 ? 12 : hour + 12;\n  if (ampm === \"AM\") return hour === 12 ? 0 : hour;\n  return hour;\n};\n\n/**\n * Check if a string is a valid WSDOT date string\n */\nexport const isWsdotDateString = (value: string): boolean =>\n  value.length >= 19 && value.startsWith(\"/Date(\") && value.endsWith(\")/\");\n\n/**\n * Convert WSDOT date string format to JavaScript Date\n *\n * WSDOT APIs return dates in \"/Date(timestamp)/\" format where timestamp\n * is milliseconds since Unix epoch, optionally with timezone offset.\n *\n * @param dateString - Date string in \"/Date(timestamp)/\" format\n * @returns JavaScript Date object or null if invalid\n *\n * @example\n * ```typescript\n * wsdotDateTimestampToJsDate(\"/Date(1753121700000-0700)/\") // Returns Date object\n * wsdotDateTimestampToJsDate(\"/Date(1753121700000)/\") // Returns Date object\n * wsdotDateTimestampToJsDate(\"not a date\") // Returns null\n * ```\n */\nexport const wsdotDateTimestampToJsDate = (dateString: string): Date | null => {\n  const timestamp = parseInt(dateString.slice(6, 19), 10);\n\n  // Validate timestamp is a valid positive number\n  if (Number.isNaN(timestamp) || timestamp < 0) {\n    return null;\n  }\n\n  const date = new Date(timestamp);\n  return Number.isNaN(date.getTime()) ? null : date;\n};\n\n// Field-specific date parsers for WSF APIs\nexport const WSF_DATE_PARSERS = new Map<string, (value: string) => Date | null>(\n  [\n    // WSF Schedule API fields\n    [\"FromDate\", parseMmDdYyyyDate],\n    [\"ThruDate\", parseMmDdYyyyDate],\n    [\"ModifiedDate\", parseMmDdYyyyDateTime],\n    // WSF Vessels API fields (WSDOT date format)\n    [\"ScheduledDeparture\", wsdotDateTimestampToJsDate],\n    [\"TimeStamp\", wsdotDateTimestampToJsDate],\n    [\"LeftDock\", wsdotDateTimestampToJsDate],\n    [\"Eta\", wsdotDateTimestampToJsDate],\n  ]\n);\n","/**\n * JSON parsing utilities for WSDOT and WSF APIs\n *\n * Lean JSON parsing with a reviver that converts known WSDOT/WSF date string\n * formats into JavaScript Date objects. It:\n * - Uses helpers from `dateParsers.ts` (WSF field-specific dates and WSDOT \"/Date(...)\" strings)\n * - Preserves upstream PascalCase property names\n * - Performs no field filtering and no structural normalization\n *\n * Note: Structural validation and additional transformations are handled by Zod\n * schemas downstream. This file intentionally keeps parsing minimal.\n */\n\nimport {\n  isWsdotDateString,\n  WSF_DATE_PARSERS,\n  wsdotDateTimestampToJsDate,\n} from \"./dateParsers\";\n// Note: We intentionally do not filter VesselWatch fields here to keep responses pass-through\n\n/**\n * Type representing JSON-like data that can be transformed\n */\nexport type JsonValue =\n  | string\n  | number\n  | boolean\n  | null\n  | JsonValue[]\n  | { [key: string]: JsonValue };\n\n/**\n * Type representing transformed data with Date objects and preserved PascalCase keys\n * Note: Properties can be removed by returning undefined in the reviver function\n */\nexport type JsonWithDates =\n  | string\n  | number\n  | boolean\n  | null\n  | Date\n  | JsonWithDates[]\n  | { [key: string]: JsonWithDates };\n\n/**\n * Parse JSON string with automatic WSDOT and WSF date conversion.\n *\n * @param text - The JSON string to parse\n * @returns The parsed object with Date objects for recognized date strings\n *\n * @example\n * ```typescript\n * // WSDOT API response\n * const wsdotJson = '{\"Time\": \"/Date(1753121700000-0700)/\", \"Name\": \"Test\"}';\n * const data = parseWsdotJson(wsdotJson);\n * // data.Time is now a Date object, data.Name remains a string\n *\n * // With TypeScript typing\n * interface ApiResponse { Time: Date; Name: string; }\n * const typed = parseWsdotJson<ApiResponse>(wsdotJson);\n * ```\n */\nexport const parseWsdotJson = <T = JsonWithDates>(text: string): T =>\n  JSON.parse(text, wsdotDateReviver);\n\n/**\n * JSON reviver function that transforms WSDOT and WSF API data\n *\n * Handles:\n * - WSF Schedule date formats (FromDate, ThruDate, ModifiedDate)\n * - WSDOT date strings in \"/Date(timestamp)/\" format\n * - Preserves all other data types unchanged\n *\n * @param key - The property key (used to identify specific date fields)\n * @param value - The property value to potentially transform\n * @returns The original value, a Date object if the value was a date string, or undefined to remove the property\n *\n * @example\n * ```typescript\n * // WSDOT API response\n * const wsdotJson = '{\"Time\": \"/Date(1753121700000-0700)/\", \"Name\": \"Test\"}';\n * const data = JSON.parse(wsdotJson, wsdotDateReviver);\n * // data.Time is now a Date object, data.Name remains a string\n *\n * // WSF Schedule API response\n * const wsfJson = '{\"FromDate\": \"12/25/2024\", \"ModifiedDate\": \"12/25/2024 02:30:45 PM\"}';\n * const data = JSON.parse(wsfJson, wsdotDateReviver);\n * // Both FromDate and ModifiedDate are now Date objects\n *\n */\nconst wsdotDateReviver = (\n  key: string,\n  value: JsonValue\n): JsonWithDates | undefined => {\n  // Early return for non-string values\n  if (typeof value !== \"string\") {\n    return value;\n  }\n\n  // Handle WSF Schedule field-specific date parsing\n  const wsfDateParser = WSF_DATE_PARSERS.get(key);\n  if (wsfDateParser) {\n    return wsfDateParser(value);\n  }\n\n  // Handle WSDOT date strings\n  if (isWsdotDateString(value)) {\n    return wsdotDateTimestampToJsDate(value);\n  }\n\n  return value;\n};\n","import type { ApiErrorResponse } from \"./types\";\n\n/**\n * Checks if the API response contains an error message\n *\n * WSDOT and WSF APIs return error messages in a \"Message\" field rather than\n * using HTTP error status codes for some validation errors.\n */\nexport const hasApiError = (data: unknown): data is ApiErrorResponse => {\n  if (!data || typeof data !== \"object\") return false;\n\n  const errorData = data as ApiErrorResponse;\n  if (!(\"Message\" in errorData) || typeof errorData.Message !== \"string\")\n    return false;\n\n  const message = errorData.Message.toLowerCase();\n  return (\n    message.includes(\"failed\") ||\n    message.includes(\"invalid\") ||\n    message.includes(\"not valid\") ||\n    message.includes(\"cannot be used\") ||\n    message.includes(\"error\")\n  );\n};\n\n/**\n * Processes API response data and handles error checking\n *\n * @param data - The raw response data from the API\n * @returns The JSON string representation of the data\n * @throws Error if the response contains an API error message\n */\nexport const processApiResponse = (data: unknown): string => {\n  if (hasApiError(data)) {\n    throw new Error(data.Message);\n  }\n\n  return JSON.stringify(data);\n};\n","/**\n * JSONP Fetch Strategy for Browser Environments\n *\n * This module provides a JSONP (JSON with Padding) implementation for browser\n * environments where CORS restrictions prevent direct fetch requests to external\n * APIs. It dynamically injects script tags to bypass CORS limitations and\n * provides a consistent interface with other fetch strategies.\n *\n * =============================================================================\n * JSONP EXPLANATION - Why This Technique is Necessary\n * =============================================================================\n *\n * JSONP (JSON with Padding) is a legacy technique that allows cross-origin requests\n * in browsers when the target server doesn't support CORS (Cross-Origin Resource Sharing).\n * WSDOT and WSF APIs run on legacy servers that don't implement CORS headers,\n * making direct fetch() requests impossible from web browsers.\n *\n * HOW JSONP WORKS:\n *\n * 1. CORS PROBLEM:\n *    - Modern browsers block cross-origin fetch() requests unless the server\n *      sends specific CORS headers (Access-Control-Allow-Origin, etc.)\n *    - WSDOT servers don't send these headers, so fetch() fails with CORS errors\n *\n * 2. SCRIPT TAG LOOPHOLE:\n *    - Browsers allow <script> tags to load resources from any domain\n *    - Script tags are not subject to CORS restrictions\n *    - WSDOT encourages JSONP as a workaround for their legacy APIs\n *\n * 3. JSONP PROCESS:\n *    a) Generate a unique callback function name (e.g., \"jsonp_1234567890_abc123\")\n *    b) Create a <script> element with src=\"https://api.wsdot.wa.gov/endpoint?callback=jsonp_1234567890_abc123\"\n *    c) Inject the script tag into the document head\n *    d) The server responds with: jsonp_1234567890_abc123({\"data\": \"value\"})\n *    e) Browser executes this as JavaScript, calling our callback function\n *    f) Our callback receives the data and resolves the Promise\n *    g) Clean up by removing the script tag and callback function\n *\n * 4. LIMITATIONS OF JSONP:\n *    - Only works with GET requests (no POST, PUT, DELETE)\n *    - No access to HTTP status codes or headers\n *    - Requires server-side JSONP support (WSDOT has this)\n *    - More complex error handling than fetch()\n *\n * JSONP is the most practical solution for WSDOT APIs until they modernize\n * their infrastructure to support CORS.\n *\n * =============================================================================\n *\n * Key Features:\n * - JSONP implementation for CORS-bypass in browsers\n * - Dynamic script tag injection and cleanup\n * - Automatic callback management and cleanup\n * - Timeout handling and error recovery\n * - Consistent interface with other fetch strategies\n * - Support for both array and object response types\n *\n * Usage:\n * ```typescript\n * const fetchStrategy = fetchJsonp;\n * const data = await fetchStrategy(\"https://api.example.com/data\");\n *\n * // With expected type for better error handling\n * const data = await fetchStrategy(\"https://api.example.com/data\", \"array\");\n * ```\n *\n * Note: This strategy is automatically selected for browser environments\n * where CORS restrictions would prevent direct API access.\n */\n\nimport type { FetchStrategy, JSONPWindow } from \"./types\";\nimport { processApiResponse } from \"./utils\";\n\n// Constants for JSONP request configuration\nconst JSONP_TIMEOUT_MS = 30_000; // 30 seconds\n\n/**\n * Set of endpoints that should return arrays\n * Used to determine how to handle empty responses in JSONP\n *\n * Some APIs return empty objects {} when they should return empty arrays [].\n * This causes Zod validation to fail with \"Expected array, received object\".\n * The issue only appears with JSONP because native fetch handles empty responses differently.\n */\nconst ARRAY_ENDPOINTS = [\n  // WSF Schedule API endpoints\n  \"/timeadjbyroute/\",\n  \"/timeadjbyschedroute/\",\n  \"/alternativeformats/\",\n  \"/schedroutes\",\n  \"/routes\",\n  \"/sailings\",\n  \"/allsailings\",\n  \"/terminals\",\n  \"/terminalsandmates\",\n  \"/alerts\",\n  \"/timeadjustments\",\n  \"/activeseasons\",\n\n  // WSDOT API endpoints\n  \"/BorderCrossings\",\n  \"/BridgeClearances\",\n  \"/CommercialVehicleRestrictions\",\n  \"/HighwayAlerts\",\n  \"/HighwayCameras\",\n  \"/MountainPasses\",\n  \"/TollRates\",\n  \"/TrafficFlow\",\n  \"/TravelTimes\",\n  \"/WeatherInformation\",\n  \"/WeatherInformationExtended\",\n  \"/WeatherStations\",\n];\n\n/**\n * Determines if an endpoint should return an array based on the URL\n *\n * This is a simple O(n) string matching operation on a small, fixed set of endpoints.\n * The performance impact is negligible given the small number of endpoints.\n */\nconst shouldReturnArray = (url: string): boolean => {\n  return ARRAY_ENDPOINTS.some((endpoint) => url.includes(endpoint));\n};\n\n/**\n * Generates a unique JSONP callback name to avoid conflicts\n *\n * Uses timestamp and random string to ensure uniqueness across\n * concurrent requests and page reloads.\n */\nconst generateCallbackName = (): string =>\n  `jsonp_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n\n/**\n * Web JSONP fetch strategy (bypasses CORS restrictions)\n *\n * Uses script tag injection to make cross-origin requests that would otherwise\n * be blocked by CORS policy. The WSDOT and WSF APIs support JSONP callbacks.\n *\n * STEP-BY-STEP JSONP PROCESS:\n * 1. Generate unique callback name to avoid conflicts\n * 2. Create <script> element with API URL + callback parameter\n * 3. Define callback function on window object\n * 4. Inject script tag into document head\n * 5. Server responds with: callbackName(data)\n * 6. Browser executes response, calling our callback\n * 7. Callback processes data and resolves Promise\n * 8. Clean up script tag and callback function\n *\n * @param url - The API endpoint URL\n * @returns Promise resolving to raw JSON string\n * @throws Error for timeouts, script load failures, or API errors\n */\nexport const fetchJsonp: FetchStrategy = (url: string): Promise<string> => {\n  return new Promise((resolve, reject) => {\n    // Step 1: Generate unique callback name to avoid conflicts\n    const callbackName = generateCallbackName();\n    const script = document.createElement(\"script\");\n    const jsonpWindow = window as unknown as JSONPWindow;\n\n    // Determine if this endpoint should return an array\n    const isArrayEndpoint = shouldReturnArray(url);\n\n    // Cleanup function to remove script tag and callback\n    const cleanup = () => {\n      if (script.parentNode) document.head.removeChild(script);\n      if (jsonpWindow[callbackName]) delete jsonpWindow[callbackName];\n    };\n\n    // Cleanup with timeout clearing\n    const cleanupWithTimeout = () => {\n      clearTimeout(timeoutId);\n      cleanup();\n    };\n\n    // Step 2: Set up timeout to prevent hanging requests\n    const timeoutId = setTimeout(() => {\n      cleanup();\n      reject(new Error(\"JSONP request timeout\"));\n    }, JSONP_TIMEOUT_MS);\n\n    // Step 3: Define callback function that server will call\n    jsonpWindow[callbackName] = (data: unknown) => {\n      cleanupWithTimeout();\n\n      // Handle empty responses more gracefully\n      // Empty responses are valid for some APIs (e.g., no time adjustments, no alternative formats)\n      if (data == null) {\n        // Null/undefined - determine if this should be an array or object based on endpoint\n        resolve(isArrayEndpoint ? \"[]\" : \"{}\");\n        return;\n      }\n\n      if (typeof data === \"string\" && !data.trim()) {\n        // Empty string - determine if this should be an array or object based on endpoint\n        resolve(isArrayEndpoint ? \"[]\" : \"{}\");\n        return;\n      }\n\n      if (\n        typeof data === \"object\" &&\n        data !== null &&\n        Object.keys(data).length === 0\n      ) {\n        // Empty object - determine if this should be an array or object based on endpoint\n        resolve(isArrayEndpoint ? \"[]\" : \"{}\");\n        return;\n      }\n\n      try {\n        const result = processApiResponse(data);\n        resolve(result);\n      } catch (error) {\n        reject(error);\n      }\n    };\n\n    // Step 4: Handle script loading errors\n    script.onerror = () => {\n      cleanupWithTimeout();\n      reject(new Error(\"JSONP script load failed\"));\n    };\n\n    // Step 5: Build callback URL and inject script tag\n    // Server will respond with: callbackName({\"data\": \"value\"})\n    script.src = `${url}${url.includes(\"?\") ? \"&\" : \"?\"}callback=${callbackName}`;\n    document.head.appendChild(script);\n  });\n};\n","/**\n * Native Fetch Strategy for Server Environments\n *\n * This module provides a native fetch implementation for server-side environments\n * such as Node.js, Bun, and React Native. It uses the built-in fetch API or\n * polyfills where necessary, providing a consistent interface for making HTTP\n * requests without CORS restrictions.\n *\n * Key Features:\n * - Native fetch implementation for server environments\n * - Automatic response type detection and handling\n * - Proper error handling and timeout management\n * - Consistent interface with other fetch strategies\n * - No CORS restrictions (server-side execution)\n *\n * Usage:\n * ```typescript\n * const fetchStrategy = fetchNative;\n * const data = await fetchStrategy(\"https://api.example.com/data\");\n *\n * // With expected type for better error handling\n * const data = await fetchStrategy(\"https://api.example.com/data\", \"array\");\n * ```\n *\n * Note: This strategy is automatically selected for Node.js, Bun, React Native,\n * and test environments where CORS is not a concern.\n */\n\nimport type { FetchStrategy } from \"./types\";\nimport { processApiResponse } from \"./utils\";\n\n/**\n * Native fetch strategy for server-side and test environments\n *\n * Uses the standard fetch API for environments where CORS is not a concern,\n * such as Node.js, Bun, React Native, and test environments.\n *\n * @param url - The API endpoint URL\n * @param expectedType - Optional expected return type (ignored for native fetch)\n * @returns Promise resolving to raw JSON string\n * @throws Error for HTTP errors or API error messages\n */\nexport const fetchNative: FetchStrategy = async (\n  url: string,\n  _expectedType?: \"array\" | \"object\"\n): Promise<string> => {\n  const response = await fetch(url);\n\n  if (!response.ok) {\n    const error = new Error(`HTTP ${response.status}: ${response.statusText}`);\n    (error as Error & { status?: number }).status = response.status;\n    throw error;\n  }\n\n  // Read the response as text to check for empty body\n  const text = await response.text();\n  if (!text.trim()) {\n    throw new Error(\"API returned HTTP 200 with empty body (invalid response)\");\n  }\n\n  // Parse as JSON\n  const data = JSON.parse(text);\n  return processApiResponse(data);\n};\n","/**\n * Fetch Strategy Selection for Cross-Platform Compatibility\n *\n * This module provides intelligent fetch strategy selection based on the current\n * environment. It automatically chooses the appropriate fetching method for\n * different platforms while maintaining a consistent API interface.\n *\n * Key Features:\n * - Automatic environment detection (browser, Node.js, test)\n * - Platform-specific strategy selection (JSONP for browsers, fetch for Node.js)\n * - Environment variable overrides for testing\n * - Consistent API across all platforms\n * - Debugging utilities for environment identification\n *\n * Strategy Selection:\n * - Browser environments: JSONP (to bypass CORS restrictions)\n * - Node.js environments: Native fetch (for server-side requests)\n * - Test environments: Native fetch (to avoid JSONP complexity)\n * - Override: FORCE_JSONP=true for JSONP testing\n *\n * Environment Detection:\n * - Browser: window and document objects available\n * - Test: NODE_ENV=test, VITEST_WORKER_ID, or jsdom/happy-dom user agent\n * - Server: Node.js, Bun, React Native, etc.\n *\n * Usage:\n * ```typescript\n * // Get the appropriate fetch strategy for current environment\n * const fetchStrategy = selectFetchStrategy();\n * const data = await fetchStrategy(\"https://api.example.com/data\");\n *\n * // Check current environment type\n * const envType = getEnvironmentType(); // \"web\", \"server\", or \"test\"\n *\n * // Force JSONP for testing (set FORCE_JSONP=true)\n * const jsonpStrategy = selectFetchStrategy(); // Returns JSONP even in tests\n * ```\n */\n\nimport type { FetchStrategy } from \"../strategies\";\nimport { fetchJsonp, fetchNative } from \"../strategies\";\n\n/**\n * Cross-platform fetch strategy selector\n *\n * Selects the appropriate fetch strategy based on the current environment:\n * - Test environments: Native fetch (to avoid JSONP complexity in tests)\n * - Web browsers: JSONP (to bypass CORS restrictions)\n * - Server environments: Native fetch (Node.js, Bun, React Native, etc.)\n *\n * Environment variable override:\n * - FORCE_JSONP=true: Forces JSONP strategy even in tests (for JSONP testing)\n *\n * @returns A fetch strategy function that can be used to make requests\n */\nexport const selectFetchStrategy = (): FetchStrategy => {\n  const environment = getEnvironmentType();\n\n  // Allow forcing JSONP for testing purposes\n  if (typeof process !== \"undefined\" && process.env.FORCE_JSONP === \"true\") {\n    return fetchJsonp;\n  }\n\n  switch (environment) {\n    case \"test\":\n    case \"server\":\n      return fetchNative;\n    case \"web\":\n      return fetchJsonp;\n    default:\n      return fetchNative; // Fallback\n  }\n};\n\n/**\n * Get the current environment type for debugging/logging purposes\n */\nexport { getEnvironmentType };\n\n/**\n * Environment detection utilities\n */\nconst isWebEnvironment = () => {\n  return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n};\n\nconst isTestEnvironment = () => {\n  // Check for test environment indicators\n  if (typeof process !== \"undefined\") {\n    if (\n      process.env.NODE_ENV === \"test\" ||\n      process.env.VITEST_WORKER_ID !== undefined\n    ) {\n      return true;\n    }\n  }\n\n  // Check for test DOM environments\n  if (typeof window !== \"undefined\" && window.navigator?.userAgent) {\n    const userAgent = window.navigator.userAgent;\n    return userAgent.includes(\"jsdom\") || userAgent.includes(\"happy-dom\");\n  }\n\n  return false;\n};\n\n/**\n * Determines the current environment type\n */\nconst getEnvironmentType = (): \"test\" | \"web\" | \"server\" => {\n  if (isTestEnvironment()) return \"test\";\n  if (isWebEnvironment()) return \"web\";\n  return \"server\";\n};\n","/**\n * API Client Creation for WSDOT and WSF APIs\n *\n * This module provides the core API client creation functionality with automatic\n * platform detection and appropriate fetching strategies. It handles the complete\n * request lifecycle including fetching, response transformation, and error handling.\n *\n * Key Features:\n * - Automatic platform detection (browser, Node.js, test environments)\n * - Platform-specific fetching strategies (JSONP for browsers, fetch for Node.js)\n * - Automatic response transformation (date parsing, field filtering)\n * - Comprehensive error handling and logging\n * - Type-safe API responses\n *\n * The JSONP approach is necessary because WSDOT and WSF APIs don't support CORS,\n * making direct fetch requests impossible in browser environments.\n *\n * Usage:\n * ```typescript\n * const apiClient = createApiClient();\n *\n * // Make a request with automatic transformation\n * const data = await apiClient<MyResponseType>(\"https://api.example.com/data\");\n *\n * // With logging enabled\n * const data = await apiClient<MyResponseType>(\n *   \"https://api.example.com/data\",\n *   \"debug\"\n * );\n * ```\n */\n\nimport log, { type LoggingMode } from \"@/shared/logger\";\n\nimport { createApiError } from \"../errors\";\nimport { parseWsdotJson } from \"../parsing\";\nimport { getEnvironmentType, selectFetchStrategy } from \"../utils\";\n\n/**\n * Creates a simple API client that handles fetching and response transformation\n *\n * This function focuses solely on the fetch request lifecycle:\n * - Platform-specific fetching (JSONP for browsers, fetch for Node.js, mocks for tests)\n * - Response transformation (handling WSDOT/WSF date formats and normalization)\n * - Error handling and logging\n *\n * URL construction is handled externally by the calling code.\n *\n * @returns An API client function that handles the complete request lifecycle\n */\nexport const createApiClient = () => {\n  // Select the appropriate fetch strategy for the current environment\n  // This automatically selects JSONP for browsers, fetch for Node.js, or mocks for tests\n  const fetchStrategy = selectFetchStrategy();\n\n  return async <T>(\n    url: string,\n    logMode?: LoggingMode,\n    expectedType?: \"array\" | \"object\"\n  ): Promise<T> => {\n    // Extract endpoint from URL for logging purposes\n    // Handle both full URLs and relative paths\n    const endpoint = url.startsWith(\"http\") ? new URL(url).pathname : url;\n\n    // Log the fetch strategy being used (useful for debugging CORS/JSONP issues)\n    logDebug(logMode, endpoint, `Using ${getEnvironmentType()} fetch strategy`);\n\n    try {\n      // Execute the platform-appropriate fetch strategy\n      // - Browser: JSONP with script tag injection\n      // - Node.js: Native fetch with proper headers\n      // - Tests: Mocked responses\n      const responseString = await fetchStrategy(url, expectedType);\n\n      // Transform the raw response string into structured data\n      // Handles WSDOT date formats (\"/Date(timestamp)/\"), WSF date formats (\"MM/DD/YYYY\"),\n      // and empty response normalization based on expected type\n      const transformedResponse = parseWsdotJson<T>(responseString);\n\n      // Log the transformed response for debugging\n      logDebug(logMode, endpoint, \"Response transformed\", transformedResponse);\n\n      return transformedResponse;\n    } catch (error: unknown) {\n      // Log errors for debugging and monitoring\n      if (logMode === \"debug\" || logMode === \"info\") {\n        log.error(`[${endpoint}] Request failed:`, error);\n      }\n\n      // Extract HTTP status code if available\n      const status =\n        error instanceof Error\n          ? (error as Error & { status?: number }).status\n          : undefined;\n\n      // Wrap all errors in a consistent WsdotApiError format\n      // This provides uniform error handling regardless of the underlying cause\n      throw createApiError(error, endpoint, url, status);\n    }\n  };\n};\n\n/**\n * Debug logging helper to reduce noise in the main function\n */\nconst logDebug = (\n  logMode: LoggingMode | undefined,\n  endpoint: string,\n  message: string,\n  data?: unknown\n) => {\n  if (logMode !== \"debug\") return;\n\n  const prefix = `[${endpoint}]`;\n  if (data !== undefined) {\n    log.debug(`${prefix} ${message}:`, data);\n  } else {\n    log.debug(`${prefix} ${message}`);\n  }\n};\n","/**\n * API Fetch Factory for WSDOT and WSF APIs\n *\n * This module provides factory functions for creating pre-configured fetch functions\n * that handle URL construction, parameter interpolation, and API key injection.\n * It reduces boilerplate code in API modules by providing a consistent interface\n * for creating endpoint-specific fetch functions.\n *\n * Key Features:\n * - Automatic API key injection (WSDOT vs WSF parameter names)\n * - Parameter interpolation with type safety\n * - Automatic date formatting for Date objects\n * - URL construction with proper query parameter handling\n * - Function overloads for cleaner API\n * - Configurable base URL support via WSDOT_BASE_URL environment variable\n *\n * Usage:\n * ```typescript\n * // Create a factory for a specific API path (base URL is configurable)\n * const createFetch = createFetchFactory(\"/api/endpoint\");\n *\n * // Create a simple fetch function\n * const getData = createFetch(\"/endpoint\");\n * const data = await getData(); // unknown -> validate with Zod schema\n *\n * // Create a fetch function with parameters\n * const getItem = createFetch<{id: string}>(\"/item/{id}\");\n * const item = await getItem({ id: \"123\" }); // unknown -> validate with Zod schema\n *\n * // With logging\n * const item = await getItem({ id: \"123\" }, \"debug\");\n * ```\n */\n\nimport { configManager } from \"@/shared/config\";\nimport type { LoggingMode } from \"@/shared/logger\";\n\nimport type { JsonWithDates } from \"../parsing\";\nimport { jsDateToYyyyMmDd } from \"../parsing\";\nimport { createApiClient } from \"./createApiClient\";\n\n/**\n * Creates a factory function that returns fetch functions pre-configured with a specific API path\n * The base URL is automatically determined from configManager.getBaseUrl()\n *\n * @param apiPath - The API path to append to the base URL (e.g., \"/ferries/api/vessels/rest\")\n * @returns A function that creates fetch functions for the specified API path\n */\nexport const createFetchFactory = (apiPath: string) => {\n  const fetchFn = createApiClient();\n\n  // Function overloads for cleaner API\n  function createFetch(\n    endpointTemplate: string\n  ): (logMode?: LoggingMode) => Promise<unknown>;\n  function createFetch<P extends Record<string, JsonWithDates>>(\n    endpointTemplate: string\n  ): (params: P, logMode?: LoggingMode) => Promise<unknown>;\n\n  // Implementation\n  function createFetch<P extends Record<string, JsonWithDates> = never>(\n    endpointTemplate: string\n  ) {\n    return (params?: P, logMode?: LoggingMode): Promise<unknown> => {\n      // Interpolate parameters into the endpoint template\n      const endpoint = interpolateParams(endpointTemplate, params);\n\n      // Build the complete URL with API key parameter\n      const url = buildUrl(apiPath, endpoint);\n\n      // Use the API client to make the request\n      return fetchFn<unknown>(url, logMode);\n    };\n  }\n\n  return createFetch;\n};\n\n/**\n * Determines the API key parameter name based on the API path\n * WSF APIs use \"apiaccesscode\", WSDOT APIs use \"AccessCode\"\n */\nconst getApiKeyParam = (apiPath: string): string => {\n  const isWsf = apiPath.includes(\"/ferries/\");\n  return isWsf ? \"apiaccesscode\" : \"AccessCode\";\n};\n\n/**\n * Interpolates parameters into an endpoint template\n * Automatically formats Date objects as YYYY-MM-DD strings\n */\nconst interpolateParams = (\n  endpointTemplate: string,\n  params?: Record<string, JsonWithDates>\n): string => {\n  if (!params || Object.keys(params).length === 0) {\n    return endpointTemplate;\n  }\n\n  return Object.entries(params).reduce(\n    (endpoint, entry) => substituteParam(endpoint, entry),\n    endpointTemplate\n  );\n};\n\n/**\n * Constructs a complete URL with configurable base URL and API key parameter\n */\nconst buildUrl = (apiPath: string, endpoint: string): string => {\n  const baseUrl = configManager.getBaseUrl();\n  const apiKeyParam = getApiKeyParam(apiPath);\n  const separator = endpoint.includes(\"?\") ? \"&\" : \"?\";\n  return `${baseUrl}${apiPath}${endpoint}${separator}${apiKeyParam}=${configManager.getApiKey()}`;\n};\n\nconst substituteParam = (\n  endpoint: string,\n  [key, value]: [string, JsonWithDates]\n): string => {\n  const placeholder = `{${key}}`;\n  if (!endpoint.includes(placeholder)) {\n    // Parameter was passed but placeholder doesn't exist in endpoint\n    throw new Error(\n      `Parameter \"${key}\" was provided but placeholder \"{${key}}\" not found in endpoint template. ` +\n        `Available placeholders: ${endpoint.match(/\\{[^}]+\\}/g)?.join(\", \") || \"none\"}`\n    );\n  }\n  // Automatically format dates as YYYY-MM-DD, convert others to string\n  const stringValue =\n    value instanceof Date ? jsDateToYyyyMmDd(value) : String(value);\n  return endpoint.replace(placeholder, stringValue);\n};\n","import { z } from \"zod\";\n\n// WSDOT date format: \"/Date(1753121700000)/\" or with offset\nexport const zWsdotDate = () =>\n  z\n    .string()\n    .refine(\n      (v) => v.length >= 19 && v.startsWith(\"/Date(\") && v.endsWith(\")/\"),\n      { message: \"Invalid WSDOT date format\" }\n    )\n    .transform((val) => new Date(parseInt(val.slice(6, 19), 10)))\n    .or(z.date());\n\nexport const zWsdotNullableDate = () => zWsdotDate().nullable();\n\n// WSF Schedule dates\nconst mmddyyyy = /^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/;\nconst mmddyyyyTime =\n  /^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})\\s+(\\d{1,2}):(\\d{2}):(\\d{2})\\s+(AM|PM)$/i;\n\nexport const zWsfDate = () =>\n  z\n    .string()\n    .regex(mmddyyyy, { message: \"Invalid WSF MM/DD/YYYY date\" })\n    .transform((val) => {\n      const match = val.match(mmddyyyy);\n      if (!match) return new Date(NaN);\n      const [, m, d, y] = match;\n      return new Date(Number(y), Number(m) - 1, Number(d));\n    })\n    .or(z.date());\n\nexport const zWsfDateTime = () =>\n  z\n    .string()\n    .regex(mmddyyyyTime, { message: \"Invalid WSF datetime\" })\n    .transform((val) => {\n      const match = val.match(mmddyyyyTime);\n      if (!match) return new Date(NaN);\n      const [, m, d, y, hh, mm, ss, ap] = match;\n      const hNum = Number(hh);\n      const adjusted =\n        ap.toUpperCase() === \"PM\"\n          ? hNum === 12\n            ? 12\n            : hNum + 12\n          : hNum === 12\n            ? 0\n            : hNum;\n      return new Date(\n        Number(y),\n        Number(m) - 1,\n        Number(d),\n        adjusted,\n        Number(mm),\n        Number(ss)\n      );\n    })\n    .or(z.date());\n\nexport const zNullableString = () => z.string().nullable();\nexport const zNullableNumber = () => z.number().nullable();\nexport const zNullableBoolean = () => z.boolean().nullable();\n","import { z } from \"zod\";\n\nimport { zNullableString, zWsdotDate } from \"@/shared/validation\";\n\nexport const borderCrossingLocationSchema = z\n  .object({\n    Description: z.string(),\n    Direction: zNullableString(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    MilePost: z.number(),\n    RoadName: z.string(),\n  })\n  .catchall(z.unknown())\n  .nullable();\n\nexport const borderCrossingDataSchema = z\n  .object({\n    BorderCrossingLocation: borderCrossingLocationSchema,\n    CrossingName: z.string(),\n    Time: zWsdotDate(),\n    WaitTime: z.number(),\n  })\n  .catchall(z.unknown());\n\nexport const borderCrossingDataArraySchema = z.array(borderCrossingDataSchema);\n\nexport type BorderCrossingData = z.infer<typeof borderCrossingDataSchema>;\nexport type BorderCrossingLocation = z.infer<\n  typeof borderCrossingLocationSchema\n>;\n","// WSDOT Border Crossings API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___border_crossings.html\n// API Help: https://wsdot.wa.gov/traffic/api/BorderCrossings/BorderCrossingsREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { BorderCrossingData } from \"./schemas\";\nimport { borderCrossingDataArraySchema } from \"./schemas\";\n\n// Create a factory function for WSDOT Border Crossings API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/BorderCrossings/BorderCrossingsREST.svc\"\n);\n\n/**\n * Get border crossing wait times from WSDOT Border Crossings API\n *\n * Returns estimated wait times for all border crossings between Washington State and Canada.\n * Data includes location information, crossing names, timestamps, and current wait times.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to array of border crossing data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const crossings = await getBorderCrossings();\n * console.log(crossings[0].CrossingName); // \"Peace Arch\"\n * ```\n */\nexport const getBorderCrossings = async () => {\n  const fetcher = createFetch(\"/GetBorderCrossingsAsJson\");\n  const data = await fetcher();\n  // Validate strictly but with passthrough on objects\n  return borderCrossingDataArraySchema.parse(data) as BorderCrossingData[];\n};\n","// WSF API Caching Configuration\n// Defines caching strategies for different types of data based on update frequency\n// Optimized for ferry operations in Puget Sound with potentially spotty internet connections\n\nconst SECOND = 1000;\nconst MINUTE = 60 * SECOND;\nconst HOUR = 60 * MINUTE;\nconst DAY = 24 * HOUR;\nconst WEEK = 7 * DAY;\n\nexport const tanstackQueryOptions = {\n  /**\n   * Real-time data updates (every few seconds to minutes)\n   * Examples: Vessel locations, terminal sailing space, wait times, highway alerts\n   *\n   * Optimized for ferry operations:\n   * - 5-second refetch interval for real-time data like vessel locations\n   * - 1 retry with 2-second delay (fits within 5s interval)\n   * - Conservative retry strategy for WSF API's 1000ms+ latency\n   */\n  REALTIME_UPDATES: {\n    // Data is considered stale after 5 seconds (same as refetch interval)\n    staleTime: 5 * SECOND,\n    // Keep in cache for 2 minutes\n    gcTime: 1 * HOUR,\n    // Refetch every 5 seconds when component is active\n    refetchInterval: 5 * SECOND,\n    // Refetch when window regains focus\n    refetchOnWindowFocus: true,\n    // Retry once with 2-second delay (fits within 5s interval)\n    retry: 1,\n    retryDelay: 2 * SECOND,\n  },\n\n  /**\n   * Minute-level updates (every minute to few minutes)\n   * Examples: Cache flush coordination, moderate real-time data\n   *\n   * Optimized for ferry operations:\n   * - 1-minute refetch interval for infrequently updated coordination data\n   * - No retries since this data changes rarely and failures are not critical\n   * - Simple and efficient for cache coordination\n   */\n  MINUTE_UPDATES: {\n    // Data is considered stale after 5 minutes\n    staleTime: 1 * MINUTE,\n    // Keep in cache for 10 minutes\n    gcTime: 1 * HOUR,\n    // Refetch every 1 minute to check for updates\n    refetchInterval: 1 * MINUTE,\n    // Refetch when window regains focus\n    refetchOnWindowFocus: true,\n    // No retries - cache flush data is infrequently updated\n    retry: false,\n  },\n\n  /**\n   * Hourly updates (every hour to few hours)\n   * Examples: Weather forecasts, traffic patterns, moderate frequency data\n   *\n   * Optimized for ferry operations:\n   * - 1-hour refetch interval for moderately changing data\n   * - 3 retries with 30s-2min delays for reliability\n   * - Balanced approach for data that changes occasionally\n   */\n  HOURLY_UPDATES: {\n    // Data is considered stale after 2 hours\n    staleTime: 1 * HOUR,\n    // Keep in cache for 4 hours\n    gcTime: 4 * HOUR,\n    // Refetch every 1 hour to check for updates\n    refetchInterval: 1 * HOUR,\n    // Refetch when window regains focus\n    refetchOnWindowFocus: true,\n    // Retry up to 5 times with exponential backoff\n    retry: 5,\n    retryDelay: (attemptIndex: number) =>\n      Math.min(30 * SECOND * 2 ** attemptIndex, 2 * MINUTE),\n  },\n\n  /**\n   * Daily updates (every day to few days)\n   * Examples: Schedule changes, fare updates, daily reports\n   *\n   * Optimized for ferry operations:\n   * - 1-day refetch interval for daily changing data\n   * - 4 retries with 1-8 minute delays for reliability\n   * - Conservative approach for data that changes daily\n   */\n  DAILY_UPDATES: {\n    // Data is considered stale after 1 day\n    staleTime: 1 * DAY,\n    // Keep in cache for 2 days\n    gcTime: 2 * DAY,\n    // Refetch every 1 day to check for updates\n    refetchInterval: 1 * DAY,\n    // Refetch when window regains focus\n    refetchOnWindowFocus: true,\n    // Retry up to 5 times with exponential backoff\n    retry: 5,\n    retryDelay: (attemptIndex: number) =>\n      Math.min(1 * MINUTE * 2 ** attemptIndex, 10 * MINUTE),\n  },\n\n  /**\n   * Weekly updates (daily to weekly)\n   * Examples: Terminal info, vessel specs, routes, schedules, fares\n   *\n   * Optimized for ferry operations:\n   * - No automatic refetch interval - rely on cache flush invalidation\n   * - 5 retries with 10s-10min delays for static data\n   * - Conservative retry strategy for static data\n   * - Longer retry delays to avoid unnecessary network usage\n   */\n  WEEKLY_UPDATES: {\n    // Data is considered stale after 1 week (since cache flush will invalidate if it changes)\n    staleTime: 1 * WEEK,\n    // Keep in cache for 2 weeks (reduced from 1 month to avoid timeout overflow)\n    gcTime: 2 * WEEK,\n    // No automatic refetch interval - rely on cache flush invalidation\n    refetchInterval: false,\n    // Refetch when window regains focus (but only if stale)\n    refetchOnWindowFocus: true,\n    // Retry up to 5 times with exponential backoff (reduced for static data)\n    retry: 5,\n    retryDelay: (attemptIndex: number) =>\n      Math.min(1 * MINUTE * 2 ** attemptIndex, 10 * MINUTE),\n  },\n} as const;\n","// WSDOT Border Crossings API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___border_crossings.html\n// API Help: https://wsdot.wa.gov/traffic/api/BorderCrossings/BorderCrossingsREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport { getBorderCrossings } from \"./api\";\nimport type { BorderCrossingData } from \"./schemas\";\n\n/**\n * Hook for getting border crossing wait times from WSDOT Border Crossings API\n *\n * Returns estimated wait times for all border crossings between Washington State and Canada.\n * Uses frequent update options since border crossing data changes frequently.\n *\n * @param options - Optional React Query options to override defaults\n * @returns React Query result with border crossing data\n *\n * @example\n * ```typescript\n * const { data: crossings } = useBorderCrossings();\n * console.log(crossings?.[0]?.CrossingName); // \"Peace Arch\"\n * ```\n */\nexport const useBorderCrossings = (\n  options?: TanStackOptions<BorderCrossingData[]>\n): UseQueryResult<BorderCrossingData[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"border-crossings\", \"getBorderCrossings\"],\n    queryFn: () => getBorderCrossings(),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Bridge Clearances API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_clearance.html\n\n// API functions\nexport { getBridgeClearances } from \"./api\";\n// React Query hooks\nexport { useBridgeClearances } from \"./queries\";\n// Types inferred from Zod schemas\nexport type { BridgeDataGIS } from \"./schemas\";\n","import { z } from \"zod\";\n\nimport { zNullableString, zWsdotDate } from \"@/shared/validation\";\n\nexport const bridgeDataGisSchema = z\n  .object({\n    APILastUpdate: zWsdotDate(),\n    BridgeNumber: z.string(),\n    ControlEntityGuid: z.string(),\n    CrossingDescription: z.string(),\n    CrossingLocationId: z.number(),\n    CrossingRecordGuid: z.string(),\n    InventoryDirection: zNullableString(),\n    Latitude: z.number(),\n    LocationGuid: z.string(),\n    Longitude: z.number(),\n    RouteDate: zWsdotDate(),\n    SRMP: z.number(),\n    SRMPAheadBackIndicator: zNullableString(),\n    StateRouteID: z.string(),\n    StateStructureId: z.string(),\n    VerticalClearanceMaximumFeetInch: z.string(),\n    VerticalClearanceMaximumInches: z.number(),\n    VerticalClearanceMinimumFeetInch: z.string(),\n    VerticalClearanceMinimumInches: z.number(),\n  })\n  .catchall(z.unknown());\n\nexport const bridgeDataGisArraySchema = z.array(bridgeDataGisSchema);\n\nexport type BridgeDataGIS = z.infer<typeof bridgeDataGisSchema>;\n","// WSDOT Bridge Clearances API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_clearance.html\n// API Help: https://wsdot.wa.gov/traffic/api/Bridges/ClearanceREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { BridgeDataGIS } from \"./schemas\";\nimport { bridgeDataGisArraySchema } from \"./schemas\";\n\n// Create a factory function for WSDOT Bridge Clearances API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/Bridges/ClearanceREST.svc\"\n);\n\n/**\n * Get bridge clearances from WSDOT Bridge Clearances API\n *\n * Returns bridge clearance data for a specific route. The Route parameter is required\n * and should be a valid WSDOT route identifier (e.g., \"005\" for I-5).\n *\n * @param params - Object containing route and optional logMode\n * @param params.route - The WSDOT route identifier (e.g., \"005\" for I-5)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing bridge clearance data for the specified route\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const clearances = await getBridgeClearances({ route: \"005\" });\n * console.log(clearances[0].BridgeName); // \"Aurora Bridge\"\n * ```\n */\nexport const getBridgeClearances = async (params: { route: string }) => {\n  const fetcher = createFetch<{ route: string }>(\n    \"/GetClearancesAsJson?Route={route}\"\n  );\n  const data = await fetcher(params);\n  return bridgeDataGisArraySchema.parse(data) as BridgeDataGIS[];\n};\n","// WSDOT Bridge Clearances API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_clearance.html\n// API Help: https://wsdot.wa.gov/traffic/api/Bridges/ClearanceREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport { getBridgeClearances } from \"./api\";\nimport type { BridgeDataGIS } from \"./schemas\";\n\n/**\n * Hook for getting bridge clearances from WSDOT Bridge Clearances API\n *\n * Returns bridge clearance data for a specific route. The Route parameter is required\n * and should be a valid WSDOT route identifier (e.g., \"005\" for I-5).\n *\n * @param params - Object containing route\n * @param params.route - The WSDOT route identifier (e.g., \"005\" for I-5)\n * @param options - Optional React Query options to override defaults\n * @returns React Query result with bridge clearance data\n *\n * @example\n * ```typescript\n * const { data: clearances } = useBridgeClearances({ route: \"005\" });\n * console.log(clearances?.[0]?.BridgeName); // \"Aurora Bridge\"\n * ```\n */\nexport const useBridgeClearances = (\n  params: { route: string },\n  options?: TanStackOptions<BridgeDataGIS[]>\n): UseQueryResult<BridgeDataGIS[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"bridge-clearances\",\n      \"getBridgeClearances\",\n      params.route,\n    ],\n    queryFn: () => getBridgeClearances({ route: params.route }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Commercial Vehicle Restrictions API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_c_v_restrictions.html\n\n// API functions\nexport {\n  getCommercialVehicleRestrictions,\n  getCommercialVehicleRestrictionsWithId,\n} from \"./api\";\n// React Query hooks\nexport {\n  useCommercialVehicleRestrictions,\n  useCommercialVehicleRestrictionsWithId,\n} from \"./queries\";\n// Types inferred from Zod schemas\nexport type {\n  CommercialVehicleRestriction,\n  CommercialVehicleRestrictionWithId,\n  RoadwayLocation,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\nimport {\n  zNullableNumber,\n  zNullableString,\n  zWsdotDate,\n} from \"@/shared/validation\";\n\nexport const roadwayLocationSchema = z\n  .object({\n    Description: zNullableString(),\n    Direction: zNullableString(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    MilePost: z.number(),\n    RoadName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const commercialVehicleRestrictionSchema = z\n  .object({\n    BLMaxAxle: zNullableNumber(),\n    BridgeName: z.string(),\n    BridgeNumber: z.string(),\n    CL8MaxAxle: zNullableNumber(),\n    DateEffective: zWsdotDate(),\n    DateExpires: zWsdotDate(),\n    DatePosted: zWsdotDate(),\n    EndRoadwayLocation: roadwayLocationSchema,\n    IsDetourAvailable: z.boolean(),\n    IsExceptionsAllowed: z.boolean(),\n    IsPermanentRestriction: z.boolean(),\n    IsWarning: z.boolean(),\n    Latitude: z.number(),\n    LocationDescription: z.string(),\n    LocationName: z.string(),\n    Longitude: z.number(),\n    MaximumGrossVehicleWeightInPounds: zNullableNumber(),\n    RestrictionComment: z.string(),\n    RestrictionHeightInInches: zNullableNumber(),\n    RestrictionLengthInInches: zNullableNumber(),\n    RestrictionType: z.number(),\n    RestrictionWeightInPounds: zNullableNumber(),\n    RestrictionWidthInInches: zNullableNumber(),\n    SAMaxAxle: zNullableNumber(),\n    StartRoadwayLocation: roadwayLocationSchema,\n    State: z.string(),\n    StateRouteID: z.string(),\n    TDMaxAxle: zNullableNumber(),\n    VehicleType: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const commercialVehicleRestrictionWithIdSchema =\n  commercialVehicleRestrictionSchema\n    .extend({ UniqueID: z.string() })\n    .catchall(z.unknown());\n\nexport const commercialVehicleRestrictionArraySchema = z.array(\n  commercialVehicleRestrictionSchema\n);\nexport const commercialVehicleRestrictionWithIdArraySchema = z.array(\n  commercialVehicleRestrictionWithIdSchema\n);\n\nexport type RoadwayLocation = z.infer<typeof roadwayLocationSchema>;\nexport type CommercialVehicleRestriction = z.infer<\n  typeof commercialVehicleRestrictionSchema\n>;\nexport type CommercialVehicleRestrictionWithId = z.infer<\n  typeof commercialVehicleRestrictionWithIdSchema\n>;\n","// WSDOT Commercial Vehicle Restrictions API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_c_v_restrictions.html\n// API Help: https://wsdot.wa.gov/traffic/api/CVRestrictions/CVRestrictionsREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type {\n  CommercialVehicleRestriction,\n  CommercialVehicleRestrictionWithId,\n} from \"./schemas\";\nimport {\n  commercialVehicleRestrictionArraySchema,\n  commercialVehicleRestrictionWithIdArraySchema,\n} from \"./schemas\";\n\n// Create a factory function for WSDOT Commercial Vehicle Restrictions API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/CVRestrictions/CVRestrictionsREST.svc\"\n);\n\n/**\n * Get commercial vehicle restrictions from WSDOT Commercial Vehicle Restrictions API\n *\n * Returns commercial vehicle restriction data including weight limits, bridge restrictions,\n * and other commercial vehicle limitations across Washington State highways.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to array of commercial vehicle restriction data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const restrictions = await getCommercialVehicleRestrictions();\n * console.log(restrictions[0].RouteName); // \"I-5\"\n * ```\n */\nexport const getCommercialVehicleRestrictions = async () => {\n  const fetcher = createFetch(\"/GetCommercialVehicleRestrictionsAsJson\");\n  const data = await fetcher();\n  return commercialVehicleRestrictionArraySchema.parse(\n    data\n  ) as CommercialVehicleRestriction[];\n};\n\n/**\n * Get commercial vehicle restrictions with unique IDs from WSDOT Commercial Vehicle Restrictions API\n *\n * Returns commercial vehicle restriction data including weight limits, bridge restrictions,\n * and other commercial vehicle limitations across Washington State highways. This endpoint\n * includes unique identifiers for each restriction.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to array of commercial vehicle restriction data with unique IDs\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const restrictions = await getCommercialVehicleRestrictionsWithId();\n * console.log(restrictions[0].RestrictionID); // 12345\n * ```\n */\nexport const getCommercialVehicleRestrictionsWithId = async () => {\n  const fetcher = createFetch(\"/GetCommercialVehicleRestrictionsWithIdAsJson\");\n  const data = await fetcher();\n  return commercialVehicleRestrictionWithIdArraySchema.parse(\n    data\n  ) as CommercialVehicleRestrictionWithId[];\n};\n","// WSDOT Commercial Vehicle Restrictions API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_c_v_restrictions.html\n// API Help: https://wsdot.wa.gov/traffic/api/CVRestrictions/CVRestrictionsREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport {\n  getCommercialVehicleRestrictions,\n  getCommercialVehicleRestrictionsWithId,\n} from \"./api\";\nimport type {\n  CommercialVehicleRestriction,\n  CommercialVehicleRestrictionWithId,\n} from \"./schemas\";\n\n/**\n * Hook for getting commercial vehicle restrictions from WSDOT Commercial Vehicle Restrictions API\n *\n * Returns commercial vehicle restriction data including weight limits, bridge restrictions,\n * and other commercial vehicle limitations across Washington State highways.\n *\n * @param options - Optional React Query options to override defaults\n * @returns React Query result with commercial vehicle restriction data\n *\n * @example\n * ```typescript\n * const { data: restrictions } = useCommercialVehicleRestrictions();\n * console.log(restrictions?.[0]?.RouteName); // \"I-5\"\n * ```\n */\nexport const useCommercialVehicleRestrictions = (\n  options?: TanStackOptions<CommercialVehicleRestriction[]>\n): UseQueryResult<CommercialVehicleRestriction[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"commercial-vehicle-restrictions\",\n      \"getCommercialVehicleRestrictions\",\n    ],\n    queryFn: () => getCommercialVehicleRestrictions(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting commercial vehicle restrictions with unique IDs from WSDOT Commercial Vehicle Restrictions API\n *\n * Returns commercial vehicle restriction data including weight limits, bridge restrictions,\n * and other commercial vehicle limitations across Washington State highways. This endpoint\n * includes unique identifiers for each restriction.\n *\n * @param options - Optional React Query options to override defaults\n * @returns React Query result with commercial vehicle restriction data with unique IDs\n *\n * @example\n * ```typescript\n * const { data: restrictions } = useCommercialVehicleRestrictionsWithId();\n * console.log(restrictions?.[0]?.RestrictionID); // 12345\n * ```\n */\nexport const useCommercialVehicleRestrictionsWithId = (\n  options?: TanStackOptions<CommercialVehicleRestrictionWithId[]>\n): UseQueryResult<CommercialVehicleRestriction[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"commercial-vehicle-restrictions\",\n      \"getCommercialVehicleRestrictionsWithId\",\n    ],\n    queryFn: () => getCommercialVehicleRestrictionsWithId(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Highway Alerts API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___highway_alerts.html\n// API Help: https://wsdot.wa.gov/traffic/api/HighwayAlerts/HighwayAlertsREST.svc/Help\n\n// Export API functions\nexport {\n  getHighwayAlertById,\n  getHighwayAlerts,\n  getHighwayAlertsByMapArea,\n} from \"./api\";\n// Export React Query hooks\nexport {\n  useHighwayAlertById,\n  useHighwayAlerts,\n  useHighwayAlertsByMapArea,\n} from \"./queries\";\n// Export types\nexport type {\n  HighwayAlert,\n  RoadwayLocation,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\nimport { zNullableString, zWsdotDate } from \"@/shared/validation\";\n\nexport const roadwayLocationSchema = z\n  .object({\n    Description: zNullableString(),\n    Direction: zNullableString(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    MilePost: z.number(),\n    RoadName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const highwayAlertSchema = z\n  .object({\n    AlertID: z.number(),\n    County: zNullableString(),\n    EndRoadwayLocation: roadwayLocationSchema,\n    EndTime: zWsdotDate().nullable(),\n    EventCategory: z.string(),\n    EventStatus: z.string(),\n    ExtendedDescription: z.string(),\n    HeadlineDescription: z.string(),\n    LastUpdatedTime: zWsdotDate(),\n    Priority: z.string(),\n    Region: z.string(),\n    StartRoadwayLocation: roadwayLocationSchema,\n    StartTime: zWsdotDate(),\n  })\n  .catchall(z.unknown());\n\nexport const highwayAlertArraySchema = z.array(highwayAlertSchema);\n\nexport type RoadwayLocation = z.infer<typeof roadwayLocationSchema>;\nexport type HighwayAlert = z.infer<typeof highwayAlertSchema>;\n","// WSDOT Highway Alerts API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___highway_alerts.html\n// API Help: https://wsdot.wa.gov/traffic/api/HighwayAlerts/HighwayAlertsREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { HighwayAlert } from \"./schemas\";\nimport { highwayAlertArraySchema, highwayAlertSchema } from \"./schemas\";\n\n// Create a factory function for WSDOT Highway Alerts API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/HighwayAlerts/HighwayAlertsREST.svc\"\n);\n\n/**\n * Get all highway alerts from WSDOT Highway Alerts API\n *\n * Returns current traffic alerts in JSON format. This endpoint provides\n * all active highway alerts across Washington State.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing all highway alert data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const alerts = await getHighwayAlerts();\n * console.log(alerts[0].HeadlineDescription); // \"Collision on I-5\"\n * ```\n */\nexport const getHighwayAlerts = async () => {\n  const fetcher = createFetch(\"/GetAlertsAsJson\");\n  const data = await fetcher();\n  return highwayAlertArraySchema.parse(data) as HighwayAlert[];\n};\n\n/**\n * Get a specific highway alert by ID from WSDOT Highway Alerts API\n *\n * Returns detailed information about a specific highway alert identified by its ID.\n *\n * @param params - Object containing alertId and optional logMode\n * @param params.alertId - The unique identifier of the highway alert\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing the specific highway alert data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const alert = await getHighwayAlertById({ alertId: 12345 });\n * console.log(alert.HeadlineDescription); // \"Collision on I-5\"\n * ```\n */\nexport const getHighwayAlertById = async (params: { alertId: number }) => {\n  const fetcher = createFetch<{ alertId: number }>(\n    \"/GetAlertAsJson?AlertID={alertId}\"\n  );\n  const data = await fetcher(params);\n  return highwayAlertSchema.parse(data) as HighwayAlert;\n};\n\n/**\n * Get highway alerts by map area from WSDOT Highway Alerts API\n *\n * Returns highway alerts filtered by a specific map area or region.\n *\n * @param params - Object containing mapArea and optional logMode\n * @param params.mapArea - The map area or region to filter alerts by\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing filtered highway alert data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const alerts = await getHighwayAlertsByMapArea({ mapArea: \"Seattle\" });\n * console.log(alerts[0].HeadlineDescription); // \"Collision on I-5\"\n * ```\n */\nexport const getHighwayAlertsByMapArea = async (params: {\n  mapArea: string;\n}) => {\n  const fetcher = createFetch<{ mapArea: string }>(\n    \"/GetAlertsByMapAreaAsJson?MapArea={mapArea}\"\n  );\n  const data = await fetcher(params);\n  return highwayAlertArraySchema.parse(data) as HighwayAlert[];\n};\n","// WSDOT Highway Alerts API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___highway_alerts.html\n// API Help: https://wsdot.wa.gov/traffic/api/HighwayAlerts/HighwayAlertsREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport {\n  getHighwayAlertById,\n  getHighwayAlerts,\n  getHighwayAlertsByMapArea,\n} from \"./api\";\nimport type { HighwayAlert } from \"./schemas\";\n\n/**\n * Hook for getting all highway alerts from WSDOT Highway Alerts API\n *\n * Returns current traffic alerts in JSON format. This endpoint provides\n * all active highway alerts across Washington State.\n *\n * @param options - Optional React Query options to override defaults\n * @returns React Query result with highway alert data\n */\nexport const useHighwayAlerts = (\n  options?: TanStackOptions<HighwayAlert[]>\n): UseQueryResult<HighwayAlert[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"highway-alerts\", \"getHighwayAlerts\"],\n    queryFn: () => getHighwayAlerts(),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting a specific highway alert by ID from WSDOT Highway Alerts API\n *\n * Returns detailed information about a specific highway alert identified by its ID.\n *\n * @param params - Object containing alertId\n * @param params.alertId - The unique identifier of the highway alert\n * @param options - Optional React Query options to override defaults\n * @returns React Query result with a single highway alert\n */\nexport const useHighwayAlertById = (\n  params: { alertId: number },\n  options?: TanStackOptions<HighwayAlert>\n): UseQueryResult<HighwayAlert, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"highway-alerts\",\n      \"getHighwayAlertById\",\n      params.alertId,\n    ],\n    queryFn: () => getHighwayAlertById({ alertId: params.alertId }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting highway alerts by map area from WSDOT Highway Alerts API\n *\n * Returns highway alerts filtered by a specific map area or region.\n *\n * @param params - Object containing mapArea\n * @param params.mapArea - The map area or region to filter alerts by\n * @param options - Optional React Query options to override defaults\n * @returns React Query result with highway alert data for the specified area\n */\nexport const useHighwayAlertsByMapArea = (\n  params: { mapArea: string },\n  options?: TanStackOptions<HighwayAlert[]>\n): UseQueryResult<HighwayAlert[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"highway-alerts\",\n      \"getHighwayAlertsByMapArea\",\n      params.mapArea,\n    ],\n    queryFn: () => getHighwayAlertsByMapArea({ mapArea: params.mapArea }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n","/**\n * WSDOT Highway Cameras API\n *\n * Exports all types, functions, and React hooks for the WSDOT Highway Cameras API.\n *\n * Based on cURL validation of:\n * - https://wsdot.wa.gov/traffic/api/HighwayCameras/HighwayCamerasREST.svc/Help\n * - https://wsdot.wa.gov/traffic/api/Documentation/group___highway_cameras.html\n */\n\n// Export API functions\nexport {\n  getHighwayCamera,\n  getHighwayCameras,\n  searchHighwayCameras,\n} from \"./api\";\n// Export React hooks\nexport {\n  useHighwayCamera,\n  useHighwayCameras,\n  useSearchHighwayCameras,\n} from \"./queries\";\n// Export types\nexport type {\n  Camera,\n  CameraLocation,\n  GetCameraResponse,\n  SearchCamerasParams,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\nimport { zNullableString } from \"@/shared/validation\";\n\nexport const cameraLocationSchema = z\n  .object({\n    Description: zNullableString(),\n    Direction: zNullableString(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    MilePost: z.number(),\n    RoadName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const cameraSchema = z\n  .object({\n    CameraID: z.number(),\n    CameraLocation: cameraLocationSchema,\n    CameraOwner: zNullableString(),\n    Description: zNullableString(),\n    DisplayLatitude: z.number(),\n    DisplayLongitude: z.number(),\n    ImageHeight: z.number(),\n    ImageURL: z.string(),\n    ImageWidth: z.number(),\n    IsActive: z.boolean(),\n    OwnerURL: zNullableString(),\n    Region: z.string(),\n    SortOrder: z.number(),\n    Title: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const cameraArraySchema = z.array(cameraSchema);\n\nexport const searchCamerasParamsSchema = z\n  .object({\n    StateRoute: z.string().optional(),\n    Region: z.string().optional(),\n    StartingMilepost: z.number().optional(),\n    EndingMilepost: z.number().optional(),\n  })\n  .strict();\n\nexport type CameraLocation = z.infer<typeof cameraLocationSchema>;\nexport type Camera = z.infer<typeof cameraSchema>;\nexport type GetCameraResponse = Camera;\nexport type SearchCamerasParams = z.infer<typeof searchCamerasParamsSchema>;\n","/**\n * WSDOT Highway Cameras API Functions\n *\n * Based on cURL validation of:\n * - https://wsdot.wa.gov/traffic/api/HighwayCameras/HighwayCamerasREST.svc/Help\n * - https://wsdot.wa.gov/traffic/api/Documentation/group___highway_cameras.html\n */\n\nimport { configManager } from \"@/shared/config\";\nimport { createApiClient, createFetchFactory } from \"@/shared/fetching/api\";\nimport type { LoggingMode } from \"@/shared/logger\";\n\nimport type { Camera, GetCameraResponse, SearchCamerasParams } from \"./schemas\";\nimport {\n  cameraArraySchema,\n  cameraSchema,\n  searchCamerasParamsSchema,\n} from \"./schemas\";\n\n// Create a factory function for WSDOT Highway Cameras API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/HighwayCameras/HighwayCamerasREST.svc\"\n);\n\n/**\n * Get all highway cameras\n *\n * Returns all available highway cameras from the WSDOT Highway Cameras API.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing all camera data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const cameras = await getHighwayCameras();\n * console.log(cameras[0].Title); // \"I-5 @ NE 85th St\"\n * ```\n */\nexport const getHighwayCameras = async () => {\n  const fetcher = createFetch(\"/GetCamerasAsJson\");\n  const data = await fetcher();\n  return cameraArraySchema.parse(data) as Camera[];\n};\n\n/**\n * Get a specific highway camera by ID\n *\n * Returns detailed information about a specific highway camera identified by its ID.\n *\n * @param params - Object containing cameraID and optional logMode\n * @param params.cameraID - The unique identifier of the highway camera\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing the specific camera data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const camera = await getHighwayCamera({ cameraID: 1001 });\n * console.log(camera.Title); // \"I-5 @ NE 85th St\"\n * ```\n */\nexport const getHighwayCamera = async (params: { cameraID: number }) => {\n  const fetcher = createFetch<{ cameraID: number }>(\n    \"/GetCameraAsJson?CameraID={cameraID}\"\n  );\n  const data = await fetcher(params);\n  return cameraSchema.parse(data) as GetCameraResponse;\n};\n\n/**\n * Search for highway cameras with optional filters\n *\n * Returns filtered highway camera data based on search criteria such as region,\n * state route, or milepost range.\n *\n * @param params - Object containing search parameters and optional logMode\n * @param params.StateRoute - Optional state route number (e.g., \"9\", \"405\")\n * @param params.Region - Optional region code (NW, NC, SC, SW, ER, OL, OS, WA)\n * @param params.StartingMilepost - Optional starting milepost for search range\n * @param params.EndingMilepost - Optional ending milepost for search range\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing filtered camera data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const cameras = await searchHighwayCameras({ StateRoute: \"5\" });\n * console.log(cameras[0].Title); // \"I-5 @ NE 85th St\"\n * ```\n */\nexport const searchHighwayCameras = async (\n  params: SearchCamerasParams,\n  logMode?: LoggingMode\n): Promise<Camera[]> => {\n  // Validate params shape\n  searchCamerasParamsSchema.parse(params);\n\n  // Build query string by including only defined values\n  const queryParams = new URLSearchParams();\n  if (params.StateRoute !== undefined)\n    queryParams.append(\"StateRoute\", String(params.StateRoute));\n  if (params.Region !== undefined)\n    queryParams.append(\"Region\", String(params.Region));\n  if (params.StartingMilepost !== undefined)\n    queryParams.append(\"StartingMilepost\", String(params.StartingMilepost));\n  if (params.EndingMilepost !== undefined)\n    queryParams.append(\"EndingMilepost\", String(params.EndingMilepost));\n\n  const endpoint = `/SearchCamerasAsJson?${queryParams.toString()}`;\n  const url = `${configManager.getBaseUrl()}/Traffic/api/HighwayCameras/HighwayCamerasREST.svc${endpoint}`;\n\n  const fetchFn = createApiClient();\n  const data = await fetchFn<unknown>(url, logMode);\n  return cameraArraySchema.parse(data) as Camera[];\n};\n","/**\n * WSDOT Highway Cameras API React Query Hooks\n *\n * Based on cURL validation of:\n * - https://wsdot.wa.gov/traffic/api/HighwayCameras/HighwayCamerasREST.svc/Help\n * - https://wsdot.wa.gov/traffic/api/Documentation/group___highway_cameras.html\n */\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport {\n  getHighwayCamera,\n  getHighwayCameras,\n  searchHighwayCameras,\n} from \"./api\";\nimport type { Camera, GetCameraResponse, SearchCamerasParams } from \"./schemas\";\n\n/**\n * React Query hook for getting all highway cameras\n *\n * Returns all available highway cameras from the WSDOT Highway Cameras API.\n *\n * @param options - Optional query options\n * @returns React Query result containing all camera data\n *\n * @example\n * ```typescript\n * const { data: cameras } = useHighwayCameras();\n * console.log(cameras?.[0]?.Title); // \"I-5 @ NE 85th St\"\n * ```\n */\nexport const useHighwayCameras = (\n  options?: TanStackOptions<Camera[]>\n): UseQueryResult<Camera[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"highway-cameras\", \"getHighwayCameras\"],\n    queryFn: () => getHighwayCameras(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for getting a specific highway camera by ID\n *\n * Returns detailed information about a specific highway camera identified by its ID.\n *\n * @param params - Object containing cameraID\n * @param params.cameraID - The unique identifier of the highway camera\n * @param options - Optional query options\n * @returns React Query result containing the camera data\n *\n * @example\n * ```typescript\n * const { data: camera } = useHighwayCamera({ cameraID: 1001 });\n * console.log(camera?.Title); // \"I-5 @ NE 85th St\"\n * ```\n */\nexport const useHighwayCamera = (\n  params: { cameraID: number },\n  options?: TanStackOptions<GetCameraResponse>\n): UseQueryResult<GetCameraResponse, Error> => {\n  return useQuery<GetCameraResponse>({\n    queryKey: [\"wsdot\", \"highway-cameras\", \"getHighwayCamera\", params.cameraID],\n    queryFn: () => getHighwayCamera({ cameraID: params.cameraID }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for searching highway cameras with filters\n *\n * Returns filtered highway camera data based on search criteria such as region,\n * state route, or milepost range.\n *\n * @param params - Search parameters (StateRoute, Region, StartingMilepost, EndingMilepost)\n * @param params.StateRoute - Optional state route number (e.g., \"9\", \"405\")\n * @param params.Region - Optional region code (NW, NC, SC, SW, ER, OL, OS, WA)\n * @param params.StartingMilepost - Optional starting milepost for search range\n * @param params.EndingMilepost - Optional ending milepost for search range\n * @param options - Optional query options\n * @returns React Query result containing filtered camera data\n *\n * @example\n * ```typescript\n * const { data: cameras } = useSearchHighwayCameras({ StateRoute: \"5\" });\n * console.log(cameras?.[0]?.Title); // \"I-5 @ NE 85th St\"\n * ```\n */\nexport const useSearchHighwayCameras = (\n  params: SearchCamerasParams,\n  options?: TanStackOptions<Camera[]>\n): UseQueryResult<Camera[], Error> => {\n  return useQuery<Camera[]>({\n    queryKey: [\"wsdot\", \"highway-cameras\", \"searchHighwayCameras\", params],\n    queryFn: () => searchHighwayCameras(params),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Mountain Pass Conditions API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___mountain_pass.html\n// API Help: https://wsdot.wa.gov/traffic/api/MountainPassConditions/MountainPassConditionsREST.svc/Help\n\n// API functions\nexport {\n  getMountainPassConditionById,\n  getMountainPassConditions,\n} from \"./api\";\n// React Query hooks\nexport {\n  useMountainPassConditionById,\n  useMountainPassConditions,\n} from \"./queries\";\n// TypeScript types\nexport type {\n  MountainPassCondition,\n  TravelRestriction,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\nimport { zNullableNumber, zWsdotDate } from \"@/shared/validation\";\n\nexport const travelRestrictionSchema = z\n  .object({\n    TravelDirection: z.string(),\n    RestrictionText: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const mountainPassConditionSchema = z\n  .object({\n    DateUpdated: zWsdotDate(),\n    ElevationInFeet: z.number(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    MountainPassId: z.number(),\n    MountainPassName: z.string(),\n    RestrictionOne: travelRestrictionSchema,\n    RestrictionTwo: travelRestrictionSchema,\n    RoadCondition: z.string(),\n    TemperatureInFahrenheit: zNullableNumber(),\n    TravelAdvisoryActive: z.boolean(),\n    WeatherCondition: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const mountainPassConditionArraySchema = z.array(\n  mountainPassConditionSchema\n);\n\nexport type TravelRestriction = z.infer<typeof travelRestrictionSchema>;\nexport type MountainPassCondition = z.infer<typeof mountainPassConditionSchema>;\n","// WSDOT Mountain Pass Conditions API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___mountain_pass.html\n// API Help: https://wsdot.wa.gov/traffic/api/MountainPassConditions/MountainPassConditionsREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { MountainPassCondition } from \"./schemas\";\nimport {\n  mountainPassConditionArraySchema,\n  mountainPassConditionSchema,\n} from \"./schemas\";\n\n// Create a factory function for WSDOT Mountain Pass Conditions API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/MountainPassConditions/MountainPassConditionsREST.svc\"\n);\n\n/**\n * Retrieves all mountain pass conditions from WSDOT API\n *\n * Returns current mountain pass conditions across Washington State, including\n * road conditions, restrictions, and travel advisories.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing all mountain pass condition data\n * @throws {WsdotApiError} When the API request fails\n */\nexport const getMountainPassConditions = async () => {\n  const fetcher = createFetch(\"/GetMountainPassConditionsAsJson\");\n  const data = await fetcher();\n  return mountainPassConditionArraySchema.parse(\n    data\n  ) as MountainPassCondition[];\n};\n\n/**\n * Retrieves a specific mountain pass condition by ID\n * Note: This endpoint may not work as expected based on testing\n *\n * Returns detailed information about a specific mountain pass condition\n * identified by its ID.\n *\n * @param params - Object containing passConditionId and optional logMode\n * @param params.passConditionId - The ID of the specific mountain pass condition\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing the specific mountain pass condition data\n * @throws {WsdotApiError} When the API request fails\n */\nexport const getMountainPassConditionById = async (params: {\n  passConditionId: number;\n}) => {\n  const fetcher = createFetch<{ passConditionId: number }>(\n    \"/GetMountainPassConditionAsJson?PassConditionID={passConditionId}\"\n  );\n  const data = await fetcher(params);\n  return mountainPassConditionSchema.parse(data) as MountainPassCondition;\n};\n","// WSDOT Mountain Pass Conditions API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___mountain_pass.html\n// API Help: https://wsdot.wa.gov/traffic/api/MountainPassConditions/MountainPassConditionsREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport { getMountainPassConditionById, getMountainPassConditions } from \"./api\";\nimport type { MountainPassCondition } from \"./schemas\";\n\n/**\n * React Query hook for retrieving all mountain pass conditions\n *\n * Returns current mountain pass conditions across Washington State, including\n * road conditions, restrictions, and travel advisories.\n *\n * @param options - Optional query options\n * @returns React Query result containing mountain pass conditions data\n *\n * @example\n * ```typescript\n * const { data: conditions } = useMountainPassConditions();\n * console.log(conditions[0].MountainPassName); // \"Blewett Pass US 97\"\n * ```\n */\nexport const useMountainPassConditions = (\n  options?: TanStackOptions<MountainPassCondition[]>\n): UseQueryResult<MountainPassCondition[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"mountain-pass-conditions\",\n      \"getMountainPassConditions\",\n    ],\n    queryFn: () => getMountainPassConditions(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for retrieving a specific mountain pass condition by ID\n * Note: This endpoint may not work as expected based on testing\n *\n * Returns detailed information about a specific mountain pass condition\n * identified by its ID.\n *\n * @param params - Object containing passConditionId\n * @param params.passConditionId - The ID of the specific mountain pass condition\n * @param options - Optional query options\n * @returns React Query result containing mountain pass condition data\n *\n * @example\n * ```typescript\n * const { data: condition } = useMountainPassConditionById({ passConditionId: 1 });\n * console.log(condition.MountainPassName); // \"Blewett Pass US 97\"\n * ```\n */\nexport const useMountainPassConditionById = (\n  params: { passConditionId: number },\n  options?: TanStackOptions<MountainPassCondition>\n): UseQueryResult<MountainPassCondition, Error> => {\n  return useQuery<MountainPassCondition>({\n    queryKey: [\n      \"wsdot\",\n      \"mountain-pass-conditions\",\n      \"getMountainPassConditionById\",\n      params.passConditionId,\n    ],\n    queryFn: () =>\n      getMountainPassConditionById({ passConditionId: params.passConditionId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Toll Rates API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___tolling.html\n// API Help: https://wsdot.wa.gov/traffic/api/TollRates/TollRatesREST.svc/Help\n\n// API functions\nexport {\n  getTollRates,\n  getTollTripInfo,\n  getTollTripRates,\n} from \"./api\";\n// React Query hooks\nexport {\n  useTollRates,\n  useTollTripInfo,\n  useTollTripRates,\n} from \"./queries\";\n// TypeScript types\nexport type {\n  TollRate,\n  TollTripInfo,\n  TollTripRate,\n  TollTripRates,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\nimport { zNullableString, zWsdotDate } from \"@/shared/validation\";\n\nexport const tollRateSchema = z\n  .object({\n    CurrentMessage: zNullableString(),\n    CurrentToll: z.number(),\n    EndLatitude: z.number(),\n    EndLocationName: z.string(),\n    EndLongitude: z.number(),\n    EndMilepost: z.number(),\n    StartLatitude: z.number(),\n    StartLocationName: z.string(),\n    StartLongitude: z.number(),\n    StartMilepost: z.number(),\n    StateRoute: z.string(),\n    TimeUpdated: zWsdotDate(),\n    TravelDirection: z.string(),\n    TripName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const tollRateArraySchema = z.array(tollRateSchema);\n\nexport const tollTripInfoSchema = z\n  .object({\n    EndLatitude: z.number(),\n    EndLocationName: z.string(),\n    EndLongitude: z.number(),\n    EndMilepost: z.number(),\n    Geometry: z.string(),\n    ModifiedDate: zWsdotDate().nullable(),\n    StartLatitude: z.number(),\n    StartLocationName: z.string(),\n    StartLongitude: z.number(),\n    StartMilepost: z.number(),\n    TravelDirection: z.string(),\n    TripName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const tollTripInfoArraySchema = z.array(tollTripInfoSchema);\n\nexport const tollTripRateSchema = z\n  .object({\n    Message: z.string(),\n    MessageUpdateTime: zWsdotDate(),\n    Toll: z.number(),\n    TripName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const tollTripRatesSchema = z\n  .object({\n    LastUpdated: zWsdotDate(),\n    Trips: z.array(tollTripRateSchema),\n  })\n  .catchall(z.unknown());\n\nexport type TollRate = z.infer<typeof tollRateSchema>;\nexport type TollTripInfo = z.infer<typeof tollTripInfoSchema>;\nexport type TollTripRate = z.infer<typeof tollTripRateSchema>;\nexport type TollTripRates = z.infer<typeof tollTripRatesSchema>;\n","// WSDOT Toll Rates API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___tolling.html\n// API Help: https://wsdot.wa.gov/traffic/api/TollRates/TollRatesREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { TollRate, TollTripInfo, TollTripRates } from \"./schemas\";\nimport {\n  tollRateArraySchema,\n  tollTripInfoArraySchema,\n  tollTripRatesSchema,\n} from \"./schemas\";\n\n// Create a factory function for WSDOT Toll Rates API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/TollRates/TollRatesREST.svc\"\n);\n\n/**\n * Retrieves all current toll rates from WSDOT API\n *\n * Returns current toll rates for all WSDOT toll facilities, including\n * pricing information and facility details.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing all toll rate data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const tollRates = await getTollRates();\n * console.log(tollRates[0].CurrentToll); // 125\n * ```\n */\nexport const getTollRates = async () => {\n  const fetcher = createFetch(\"/GetTollRatesAsJson\");\n  const data = await fetcher();\n  return tollRateArraySchema.parse(data) as TollRate[];\n};\n\n/**\n * Retrieves toll trip information with geometry data from WSDOT API\n *\n * Returns detailed trip information including geometry data for toll\n * facilities and routes.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing all toll trip information data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const tripInfo = await getTollTripInfo();\n * console.log(tripInfo[0].TripName); // \"405tp01351\"\n * ```\n */\nexport const getTollTripInfo = async () => {\n  const fetcher = createFetch(\"/GetTollTripInfoAsJson\");\n  const data = await fetcher();\n  return tollTripInfoArraySchema.parse(data) as TollTripInfo[];\n};\n\n/**\n * Retrieves toll trip rates with messages and update times from WSDOT API\n *\n * Returns current toll trip rates along with system messages and\n * last updated timestamps.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing toll trip rates with last updated time\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const tripRates = await getTollTripRates();\n * console.log(tripRates.LastUpdated); // Date object\n * console.log(tripRates.Trips[0].Toll); // 0\n * ```\n */\nexport const getTollTripRates = async () => {\n  const fetcher = createFetch(\"/GetTollTripRatesAsJson\");\n  const data = await fetcher();\n  return tollTripRatesSchema.parse(data) as TollTripRates;\n};\n","// WSDOT Toll Rates API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___tolling.html\n// API Help: https://wsdot.wa.gov/traffic/api/TollRates/TollRatesREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport { getTollRates, getTollTripInfo, getTollTripRates } from \"./api\";\nimport type { TollRate, TollTripInfo, TollTripRates } from \"./schemas\";\n\n/**\n * React Query hook for retrieving all toll rates\n *\n * Returns current toll rates for all WSDOT toll facilities, including\n * pricing information and facility details.\n *\n * @param options - Optional query options\n * @returns React Query result containing toll rates data\n *\n * @example\n * ```typescript\n * const { data: tollRates } = useTollRates();\n * console.log(tollRates[0].CurrentToll); // 125\n * ```\n */\nexport const useTollRates = (\n  options?: TanStackOptions<TollRate[]>\n): UseQueryResult<TollRate[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"toll-rates\", \"getTollRates\"],\n    queryFn: () => getTollRates(),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for retrieving toll trip information with geometry\n *\n * Returns detailed trip information including geometry data for toll\n * facilities and routes.\n *\n * @param options - Optional query options\n * @returns React Query result containing toll trip information data\n *\n * @example\n * ```typescript\n * const { data: tripInfo } = useTollTripInfo();\n * console.log(tripInfo[0].TripName); // \"405tp01351\"\n * ```\n */\nexport const useTollTripInfo = (\n  options?: TanStackOptions<TollTripInfo[]>\n): UseQueryResult<TollTripInfo[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"toll-rates\", \"getTollTripInfo\"],\n    queryFn: () => getTollTripInfo(),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for retrieving toll trip rates with messages\n *\n * Returns current toll trip rates along with system messages and\n * last updated timestamps.\n *\n * @param options - Optional query options\n * @returns React Query result containing toll trip rates data\n *\n * @example\n * ```typescript\n * const { data: tripRates } = useTollTripRates();\n * console.log(tripRates.LastUpdated); // Date object\n * console.log(tripRates.Trips[0].Toll); // 0\n * ```\n */\nexport const useTollTripRates = (\n  options?: TanStackOptions<TollTripRates>\n): UseQueryResult<TollTripRates, Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"toll-rates\", \"getTollTripRates\"],\n    queryFn: () => getTollTripRates(),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Traffic Flow API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___traffic_flow.html\n// API Help: https://wsdot.wa.gov/traffic/api/TrafficFlow/TrafficFlowREST.svc/Help\n\n// API functions\nexport {\n  getTrafficFlowById,\n  getTrafficFlows,\n} from \"./api\";\n// React Query hooks\nexport {\n  useTrafficFlowById,\n  useTrafficFlows,\n} from \"./queries\";\n// TypeScript types\nexport type {\n  FlowStationLocation,\n  TrafficFlow,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\nimport { zWsdotDate } from \"@/shared/validation\";\n\nexport const flowStationLocationSchema = z\n  .object({\n    Description: z.string(),\n    Direction: z.string(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    MilePost: z.number(),\n    RoadName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const trafficFlowSchema = z\n  .object({\n    FlowDataID: z.number(),\n    FlowReadingValue: z.number(),\n    FlowStationLocation: flowStationLocationSchema,\n    Region: z.string(),\n    StationName: z.string(),\n    Time: zWsdotDate(),\n  })\n  .catchall(z.unknown());\n\nexport const trafficFlowArraySchema = z.array(trafficFlowSchema);\n\nexport type FlowStationLocation = z.infer<typeof flowStationLocationSchema>;\nexport type TrafficFlow = z.infer<typeof trafficFlowSchema>;\n","// WSDOT Traffic Flow API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___traffic_flow.html\n// API Help: https://wsdot.wa.gov/traffic/api/TrafficFlow/TrafficFlowREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { TrafficFlow } from \"./schemas\";\nimport { trafficFlowArraySchema, trafficFlowSchema } from \"./schemas\";\n\n// Create a factory function for WSDOT Traffic Flow API\nconst createFetch = createFetchFactory(\n  \"/traffic/api/TrafficFlow/TrafficFlowREST.svc\"\n);\n\n/**\n * Get all traffic flow data from WSDOT Traffic Flow API\n *\n * Retrieves current traffic flow readings from all flow stations.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing all traffic flow data\n * @throws {WsdotApiError} When the API request fails\n */\nexport const getTrafficFlows = async () => {\n  const fetcher = createFetch(\"/GetTrafficFlowsAsJson\");\n  const data = await fetcher();\n  return trafficFlowArraySchema.parse(data) as TrafficFlow[];\n};\n\n/**\n * Get specific traffic flow by ID from WSDOT Traffic Flow API\n *\n * Returns detailed information about a specific traffic flow station\n * identified by its ID.\n *\n * @param params - Object containing flowDataID and optional logMode\n * @param params.flowDataID - The ID of the specific traffic flow station\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing the specific traffic flow data\n * @throws {WsdotApiError} When the API request fails\n */\nexport const getTrafficFlowById = async (params: { flowDataID: number }) => {\n  const fetcher = createFetch<{ flowDataID: number }>(\n    \"/GetTrafficFlowAsJson?FlowDataID={flowDataID}\"\n  );\n  const data = await fetcher(params);\n  return trafficFlowSchema.parse(data) as TrafficFlow;\n};\n","// WSDOT Traffic Flow API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___traffic_flow.html\n// API Help: https://wsdot.wa.gov/traffic/api/TrafficFlow/TrafficFlowREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport { getTrafficFlowById, getTrafficFlows } from \"./api\";\nimport type { TrafficFlow } from \"./schemas\";\n\n/**\n * React Query hook for retrieving all traffic flow data\n *\n * Retrieves current traffic flow readings from all flow stations.\n *\n * @param options - Optional query options\n * @returns React Query result containing traffic flow data\n *\n * @example\n * ```typescript\n * const { data: trafficFlows } = useTrafficFlows();\n * console.log(trafficFlows[0].FlowReadingValue); // 45\n * ```\n */\nexport const useTrafficFlows = (\n  options?: TanStackOptions<TrafficFlow[]>\n): UseQueryResult<TrafficFlow[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"traffic-flow\", \"getTrafficFlows\"],\n    queryFn: () => getTrafficFlows(),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for retrieving a specific traffic flow by ID\n *\n * Returns detailed information about a specific traffic flow station\n * identified by its ID.\n *\n * @param params - Object containing flowDataID\n * @param params.flowDataID - The ID of the specific traffic flow station\n * @param options - Optional query options\n * @returns React Query result containing traffic flow data\n *\n * @example\n * ```typescript\n * const { data: trafficFlow } = useTrafficFlowById({ flowDataID: 2482 });\n * console.log(trafficFlow.FlowReadingValue); // 45\n * ```\n */\nexport const useTrafficFlowById = (\n  params: { flowDataID: number },\n  options?: TanStackOptions<TrafficFlow>\n): UseQueryResult<TrafficFlow, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"traffic-flow\",\n      \"getTrafficFlowById\",\n      params.flowDataID,\n    ],\n    queryFn: () => getTrafficFlowById({ flowDataID: params.flowDataID }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Travel Times API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___travel_times.html\n// API Help: https://wsdot.wa.gov/traffic/api/TravelTimes/TravelTimesREST.svc/Help\n\n// API functions\nexport {\n  getTravelTimeById,\n  getTravelTimes,\n} from \"./api\";\n// React Query hooks\nexport {\n  useTravelTimeById,\n  useTravelTimes,\n} from \"./queries\";\n// TypeScript types\nexport type {\n  TravelTimeEndpoint,\n  TravelTimeRoute,\n  TravelTimesResponse,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\nimport { zWsdotDate } from \"@/shared/validation\";\n\nexport const travelTimeEndpointSchema = z\n  .object({\n    Description: z.string(),\n    Direction: z.string(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    MilePost: z.number(),\n    RoadName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const travelTimeRouteSchema = z\n  .object({\n    AverageTime: z.number(),\n    CurrentTime: z.number(),\n    Description: z.string(),\n    Distance: z.number(),\n    EndPoint: travelTimeEndpointSchema,\n    Name: z.string(),\n    StartPoint: travelTimeEndpointSchema,\n    TimeUpdated: zWsdotDate(),\n    TravelTimeID: z.number(),\n  })\n  .catchall(z.unknown());\n\nexport const travelTimesArraySchema = z.array(travelTimeRouteSchema);\n\nexport type TravelTimeEndpoint = z.infer<typeof travelTimeEndpointSchema>;\nexport type TravelTimeRoute = z.infer<typeof travelTimeRouteSchema>;\nexport type TravelTimesResponse = z.infer<typeof travelTimesArraySchema>;\n","// WSDOT Travel Times API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___travel_times.html\n// API Help: https://wsdot.wa.gov/traffic/api/TravelTimes/TravelTimesREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { TravelTimeRoute } from \"./schemas\";\nimport { travelTimeRouteSchema, travelTimesArraySchema } from \"./schemas\";\n\n// Create a factory function for WSDOT Travel Times API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/TravelTimes/TravelTimesREST.svc\"\n);\n\n/**\n * Get all travel times from WSDOT Travel Times API\n *\n * Retrieves current travel time data for all monitored routes.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing all travel time data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const travelTimes = await getTravelTimes();\n * console.log(travelTimes[0].CurrentTime); // 30\n * ```\n */\nexport const getTravelTimes = async () => {\n  const fetcher = createFetch(\"/GetTravelTimesAsJson\");\n  const data = await fetcher();\n  return travelTimesArraySchema.parse(data) as TravelTimeRoute[];\n};\n\n/**\n * Get specific travel time by ID from WSDOT Travel Times API\n *\n * Returns detailed information about a specific travel time route\n * identified by its ID.\n *\n * @param params - Object containing travelTimeId and optional logMode\n * @param params.travelTimeId - The ID of the specific travel time route\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing the specific travel time data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const travelTime = await getTravelTimeById(2);\n * console.log(travelTime.CurrentTime); // 30\n * ```\n */\nexport const getTravelTimeById = async (params: { travelTimeId: number }) => {\n  const fetcher = createFetch<{ travelTimeId: number }>(\n    \"/GetTravelTimeAsJson?TravelTimeID={travelTimeId}\"\n  );\n  const data = await fetcher(params);\n  return travelTimeRouteSchema.parse(data) as TravelTimeRoute;\n};\n","// WSDOT Travel Times API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/group___travel_times.html\n// API Help: https://wsdot.wa.gov/traffic/api/TravelTimes/TravelTimesREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport { getTravelTimeById, getTravelTimes } from \"./api\";\nimport type { TravelTimeRoute } from \"./schemas\";\n\n/**\n * React Query hook for retrieving all travel times\n *\n * Retrieves current travel time data for all monitored routes.\n *\n * @param options - Optional query options\n * @returns React Query result containing travel times data\n */\nexport const useTravelTimes = (\n  options?: TanStackOptions<TravelTimeRoute[]>\n): UseQueryResult<TravelTimeRoute[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"travel-times\", \"getTravelTimes\"],\n    queryFn: () => getTravelTimes(),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for retrieving a specific travel time by ID\n *\n * Returns detailed information about a specific travel time route\n * identified by its ID.\n *\n * @param params - Object containing travelTimeId\n * @param params.travelTimeId - The ID of the specific travel time route\n * @param options - Optional query options\n * @returns React Query result containing travel time data\n */\nexport const useTravelTimeById = (\n  params: { travelTimeId: number },\n  options?: TanStackOptions<TravelTimeRoute>\n): UseQueryResult<TravelTimeRoute, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"travel-times\",\n      \"getTravelTimeById\",\n      params.travelTimeId,\n    ],\n    queryFn: () => getTravelTimeById({ travelTimeId: params.travelTimeId }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Weather Information API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_weather_information.html\n// API Help: https://wsdot.wa.gov/traffic/api/WeatherInformation/WeatherInformationREST.svc/Help\n\n// API functions\nexport {\n  getWeatherInformation,\n  getWeatherInformationByStationId,\n  getWeatherInformationForStations,\n} from \"./api\";\n// React Query hooks\nexport {\n  useWeatherInformation,\n  useWeatherInformationByStationId,\n  useWeatherInformationForStations,\n} from \"./queries\";\n// TypeScript types\nexport type { WeatherInfo } from \"./schemas\";\n","import { z } from \"zod\";\n\nimport {\n  zNullableNumber,\n  zNullableString,\n  zWsdotDate,\n} from \"@/shared/validation\";\n\nexport const weatherInfoSchema = z\n  .object({\n    BarometricPressure: zNullableNumber(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    PrecipitationInInches: zNullableNumber(),\n    ReadingTime: zWsdotDate(),\n    RelativeHumidity: zNullableNumber(),\n    SkyCoverage: zNullableString(),\n    StationID: z.number(),\n    StationName: z.string(),\n    TemperatureInFahrenheit: zNullableNumber(),\n    Visibility: zNullableNumber(),\n    WindDirection: zNullableNumber(),\n    WindDirectionCardinal: zNullableString(),\n    WindGustSpeedInMPH: zNullableNumber(),\n    WindSpeedInMPH: zNullableNumber(),\n  })\n  .catchall(z.unknown());\n\nexport const weatherInfoArraySchema = z.array(weatherInfoSchema);\n\nexport type WeatherInfo = z.infer<typeof weatherInfoSchema>;\nexport type WeatherInformationResponse = z.infer<typeof weatherInfoArraySchema>;\n","// WSDOT Weather Information API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_weather_information.html\n// API Help: https://wsdot.wa.gov/traffic/api/WeatherInformation/WeatherInformationREST.svc/Help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { WeatherInfo } from \"./schemas\";\nimport { weatherInfoArraySchema, weatherInfoSchema } from \"./schemas\";\n\n// Create a factory function for WSDOT Weather Information API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/WeatherInformation/WeatherInformationREST.svc\"\n);\n\n/**\n * Get all weather information from WSDOT Weather Information API\n *\n * Retrieves current weather data for all monitored weather stations.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing all weather information data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const weatherInfo = await getWeatherInformation();\n * console.log(weatherInfo[0].TemperatureInFahrenheit); // 66.38\n * ```\n */\nexport const getWeatherInformation = async () => {\n  const fetcher = createFetch(\"/GetCurrentWeatherInformationAsJson\");\n  const data = await fetcher();\n  return weatherInfoArraySchema.parse(data) as WeatherInfo[];\n};\n\n/**\n * Get weather information for a specific station by ID from WSDOT Weather Information API\n *\n * Returns detailed weather information for a specific weather station\n * identified by its ID.\n *\n * @param params - Object containing stationId and optional logMode\n * @param params.stationId - The ID of the specific weather station\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing the specific weather station data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const weatherInfo = await getWeatherInformationByStationId(1909);\n * console.log(weatherInfo.TemperatureInFahrenheit); // 66.38\n * ```\n */\nexport const getWeatherInformationByStationId = async (params: {\n  stationId: number;\n}) => {\n  const fetcher = createFetch<{ stationId: number }>(\n    \"/GetCurrentWeatherInformationByStationIDAsJson?StationID={stationId}\"\n  );\n  const data = await fetcher(params);\n  return weatherInfoSchema.parse(data) as WeatherInfo;\n};\n\n/**\n * Get weather information for multiple stations from WSDOT Weather Information API\n *\n * Returns weather information for multiple weather stations specified\n * by their IDs.\n *\n * @param params - Object containing stationIds and optional logMode\n * @param params.stationIds - Comma-separated list of station IDs\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise containing weather data for the specified stations\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const weatherInfo = await getWeatherInformationForStations(\"1909,1910,1928\");\n * console.log(weatherInfo.length); // 3\n * ```\n */\nexport const getWeatherInformationForStations = async (params: {\n  stationIds: string;\n}) => {\n  const fetcher = createFetch<{ stationIds: string }>(\n    \"/GetCurrentWeatherForStationsAsJson?StationList={stationIds}\"\n  );\n  const data = await fetcher(params);\n  return weatherInfoArraySchema.parse(data) as WeatherInfo[];\n};\n","// WSDOT Weather Information API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_weather_information.html\n// API Help: https://wsdot.wa.gov/traffic/api/WeatherInformation/WeatherInformationREST.svc/Help\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport {\n  getWeatherInformation,\n  getWeatherInformationByStationId,\n  getWeatherInformationForStations,\n} from \"./api\";\nimport type { WeatherInfo } from \"./schemas\";\n\n/**\n * React Query hook for retrieving all weather information\n *\n * Retrieves current weather data for all monitored weather stations.\n *\n * @param options - Optional query options\n * @returns React Query result containing weather information data\n */\nexport const useWeatherInformation = (\n  options?: TanStackOptions<WeatherInfo[]>\n): UseQueryResult<WeatherInfo[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"weather-information\", \"getWeatherInformation\"],\n    queryFn: () => getWeatherInformation(),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for retrieving weather information for a specific station\n *\n * Returns detailed weather information for a specific weather station\n * identified by its ID.\n *\n * @param params - Object containing stationId\n * @param params.stationId - The ID of the specific weather station\n * @param options - Optional query options\n * @returns React Query result containing weather information data\n */\nexport const useWeatherInformationByStationId = (\n  params: { stationId: number },\n  options?: TanStackOptions<WeatherInfo>\n): UseQueryResult<WeatherInfo, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"weather-information\",\n      \"getWeatherInformationByStationId\",\n      params.stationId,\n    ],\n    queryFn: () =>\n      getWeatherInformationByStationId({ stationId: params.stationId }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for retrieving weather information for multiple stations\n *\n * Returns weather information for multiple weather stations specified\n * by their IDs.\n *\n * @param params - Object containing stationIds\n * @param params.stationIds - Array of station IDs\n * @param options - Optional query options\n * @returns React Query result containing weather information data\n */\nexport const useWeatherInformationForStations = (\n  params: { stationIds: number[] },\n  options?: TanStackOptions<WeatherInfo[]>\n): UseQueryResult<WeatherInfo[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"weather-information\",\n      \"getWeatherInformationForStations\",\n      params.stationIds,\n    ],\n    queryFn: () =>\n      getWeatherInformationForStations({\n        stationIds: params.stationIds.join(\",\"),\n      }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Weather Information Extended API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_traveler_a_p_i_1_1_controller_1_1_scanweb_controller.html\n// API Endpoint: https://wsdot.wa.gov/traffic/api/api/Scanweb\n\n// API functions\nexport { getWeatherInformationExtended } from \"./api\";\n// React Query hooks\nexport { useWeatherInformationExtended } from \"./queries\";\n// TypeScript types\nexport type {\n  SubSurfaceMeasurement,\n  SurfaceMeasurement,\n  WeatherReading,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\nimport { zNullableNumber } from \"@/shared/validation\";\n\n// ReadingTime from this API is ISO string or null; normalize to Date | null\nconst zIsoDateNullable = () =>\n  z\n    .string()\n    .transform((val) => new Date(val))\n    .refine((d) => !Number.isNaN(d.getTime()), {\n      message: \"Invalid ISO date\",\n    })\n    .nullable()\n    .or(z.date().nullable());\n\nexport const surfaceMeasurementSchema = z\n  .object({\n    SensorId: z.number(),\n    SurfaceTemperature: zNullableNumber(),\n    RoadFreezingTemperature: zNullableNumber(),\n    RoadSurfaceCondition: zNullableNumber(),\n  })\n  .catchall(z.unknown());\n\nexport const subSurfaceMeasurementSchema = z\n  .object({\n    SensorId: z.number(),\n    SubSurfaceTemperature: zNullableNumber(),\n  })\n  .catchall(z.unknown());\n\nexport const weatherReadingSchema = z\n  .object({\n    StationId: z.string(),\n    StationName: z.string(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    Elevation: z.number(),\n    ReadingTime: zIsoDateNullable(),\n    AirTemperature: zNullableNumber(),\n    RelativeHumidty: zNullableNumber(),\n    AverageWindSpeed: zNullableNumber(),\n    AverageWindDirection: zNullableNumber(),\n    WindGust: zNullableNumber(),\n    Visibility: zNullableNumber(),\n    PrecipitationIntensity: zNullableNumber(),\n    PrecipitationType: zNullableNumber(),\n    PrecipitationPast1Hour: zNullableNumber(),\n    PrecipitationPast3Hours: zNullableNumber(),\n    PrecipitationPast6Hours: zNullableNumber(),\n    PrecipitationPast12Hours: zNullableNumber(),\n    PrecipitationPast24Hours: zNullableNumber(),\n    PrecipitationAccumulation: zNullableNumber(),\n    BarometricPressure: zNullableNumber(),\n    SnowDepth: zNullableNumber(),\n    SurfaceMeasurements: z.array(surfaceMeasurementSchema).nullable(),\n    SubSurfaceMeasurements: z.array(subSurfaceMeasurementSchema).nullable(),\n  })\n  .catchall(z.unknown());\n\nexport const weatherReadingArraySchema = z.array(weatherReadingSchema);\n\nexport type SurfaceMeasurement = z.infer<typeof surfaceMeasurementSchema>;\nexport type SubSurfaceMeasurement = z.infer<typeof subSurfaceMeasurementSchema>;\nexport type WeatherReading = z.infer<typeof weatherReadingSchema>;\n","// WSDOT Weather Information Extended API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_traveler_a_p_i_1_1_controller_1_1_scanweb_controller.html\n// API Endpoint: https://wsdot.wa.gov/traffic/api/api/Scanweb\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { WeatherReading } from \"./schemas\";\nimport { weatherReadingArraySchema } from \"./schemas\";\n\n// Create a factory function for WSDOT Weather Information Extended API\nconst createFetch = createFetchFactory(\"/traffic/api/api/Scanweb\");\n\n/**\n * Get extended weather information from WSDOT Weather Information Extended API\n *\n * Retrieves additional weather readings including surface and subsurface\n * measurements from WSDOT weather stations.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing extended weather readings data\n * @throws {WsdotApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const weatherReadings = await getWeatherInformationExtended();\n * console.log(weatherReadings[0].AirTemperature); // 14.7\n * ```\n */\nexport const getWeatherInformationExtended = async () => {\n  const fetcher = createFetch(\"\");\n  const data = await fetcher();\n  return weatherReadingArraySchema.parse(data) as WeatherReading[];\n};\n","// WSDOT Weather Information Extended API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_traveler_a_p_i_1_1_controller_1_1_scanweb_controller.html\n// API Endpoint: https://wsdot.wa.gov/traffic/api/api/Scanweb\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport { getWeatherInformationExtended } from \"./api\";\nimport type { WeatherReading } from \"./schemas\";\n\n/**\n * React Query hook for retrieving extended weather information\n *\n * Retrieves additional weather readings including surface and subsurface\n * measurements from WSDOT weather stations.\n *\n * @param options - Optional query options\n * @returns React Query result containing extended weather information data\n *\n * @example\n * ```typescript\n * const { data: weatherReadings } = useWeatherInformationExtended();\n * console.log(weatherReadings[0].AirTemperature); // 14.7\n * ```\n */\nexport const useWeatherInformationExtended = (\n  options?: TanStackOptions<WeatherReading[]>\n): UseQueryResult<WeatherReading[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsdot\",\n      \"weather-information-extended\",\n      \"getWeatherInformationExtended\",\n    ],\n    queryFn: () => getWeatherInformationExtended(),\n    ...tanstackQueryOptions.HOURLY_UPDATES,\n    ...options,\n  });\n};\n","// WSDOT Weather Stations API exports\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_weather_stations.html\n// API Endpoint: https://wsdot.wa.gov/traffic/api/WeatherStations/WeatherStationsREST.svc\n\n// API functions\nexport { getWeatherStations } from \"./api\";\n// React Query hooks\nexport { useWeatherStations } from \"./queries\";\n// TypeScript types\nexport type { WeatherStationData } from \"./schemas\";\n","import { z } from \"zod\";\n\nexport const weatherStationDataSchema = z\n  .object({\n    Latitude: z.number(),\n    Longitude: z.number(),\n    StationCode: z.number(),\n    StationName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const weatherStationDataArraySchema = z.array(weatherStationDataSchema);\n\nexport type WeatherStationData = z.infer<typeof weatherStationDataSchema>;\n","// WSDOT Weather Stations API functions\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_weather_stations.html\n// API Endpoint: https://wsdot.wa.gov/traffic/api/WeatherStations/WeatherStationsREST.svc\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type { WeatherStationData } from \"./schemas\";\nimport { weatherStationDataArraySchema } from \"./schemas\";\n\n// Create a factory function for WSDOT Weather Stations API\nconst createFetch = createFetchFactory(\n  \"/Traffic/api/WeatherStations/WeatherStationsREST.svc\"\n);\n\n/**\n * Get weather stations from WSDOT Weather Stations API\n *\n * Retrieves information about all weather stations maintained by WSDOT.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise containing weather stations data\n * @throws {WsdotApiError} When the API request fails\n */\nexport const getWeatherStations = async () => {\n  const fetcher = createFetch(\"/GetCurrentStationsAsJson\");\n  const data = await fetcher();\n  return weatherStationDataArraySchema.parse(data) as WeatherStationData[];\n};\n","// WSDOT Weather Stations API React Query hooks\n// Documentation: https://wsdot.wa.gov/traffic/api/Documentation/class_weather_stations.html\n// API Endpoint: https://wsdot.wa.gov/traffic/api/WeatherStations/WeatherStationsREST.svc\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport { getWeatherStations } from \"./api\";\nimport type { WeatherStationData } from \"./schemas\";\n\n/**\n * React Query hook for retrieving WSDOT weather stations\n *\n * Retrieves information about all weather stations maintained by WSDOT.\n *\n * @param options - Optional query options\n * @returns React Query result containing weather stations data\n *\n * @example\n * ```typescript\n * const { data: weatherStations } = useWeatherStations();\n * console.log(weatherStations[0].StationName); // \"Alpental\"\n * ```\n */\nexport const useWeatherStations = (\n  options?: TanStackOptions<WeatherStationData[]>\n): UseQueryResult<WeatherStationData[], Error> => {\n  return useQuery({\n    queryKey: [\"wsdot\", \"weather-stations\", \"getWeatherStations\"],\n    queryFn: () => getWeatherStations(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n","// WSF Fares API exports\n// Documentation: https://www.wsdot.wa.gov/ferries/api/fares/documentation/rest.html\n\n// API functions\nexport {\n  getFareLineItems,\n  getFareLineItemsBasic,\n  getFareLineItemsVerbose,\n  getFaresCacheFlushDate,\n  getFaresTerminalMates,\n  getFaresTerminals,\n  getFaresValidDateRange,\n  getFareTotals,\n  getTerminalCombo,\n  getTerminalComboVerbose,\n} from \"./api\";\n// Types (inferred from Zod schemas)\nexport type {\n  FareLineItem,\n  FareLineItemBasic,\n  FareLineItemVerbose,\n  FaresCacheFlushDate,\n  FaresTerminal,\n  FaresValidDateRange,\n  FareTotal,\n  TerminalCombo,\n  TerminalComboVerbose,\n  TerminalMate,\n} from \"./schemas\";\n","import { z } from \"zod\";\n\n// Generic ISO/epoch date schema used by fares endpoints\nconst zIsoOrEpochDate = () =>\n  z\n    .union([\n      z.date(),\n      z.string().transform((val) => new Date(val)),\n      z.number().transform((val) => new Date(val)),\n    ])\n    .transform((d) => (d instanceof Date ? d : new Date(d)));\n\nexport const faresCacheFlushDateSchema = zIsoOrEpochDate();\n\nexport const faresValidDateRangeSchema = z\n  .object({\n    DateFrom: zIsoOrEpochDate(),\n    DateThru: zIsoOrEpochDate(),\n  })\n  .catchall(z.unknown());\n\nexport const faresTerminalSchema = z\n  .object({\n    TerminalID: z.number(),\n    Description: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const terminalMateSchema = faresTerminalSchema;\n\nexport const terminalComboSchema = z\n  .object({\n    DepartingDescription: z.string(),\n    ArrivingDescription: z.string(),\n    CollectionDescription: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const terminalComboVerboseSchema = z\n  .object({\n    DepartingTerminalID: z.number(),\n    DepartingDescription: z.string(),\n    ArrivingTerminalID: z.number(),\n    ArrivingDescription: z.string(),\n    CollectionDescription: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const fareLineItemSchema = z\n  .object({\n    FareLineItemID: z.number(),\n    FareLineItem: z.string(),\n    Category: z.string(),\n    DirectionIndependent: z.boolean(),\n    Amount: z.number(),\n  })\n  .catchall(z.unknown());\n\nexport const fareLineItemBasicSchema = fareLineItemSchema;\n\nexport const fareLineItemVerboseSchema = z\n  .object({\n    DepartingTerminalID: z.number(),\n    DepartingDescription: z.string(),\n    ArrivingTerminalID: z.number(),\n    ArrivingDescription: z.string(),\n    FareLineItemID: z.number(),\n    FareLineItem: z.string(),\n    Category: z.string(),\n    DirectionIndependent: z.boolean(),\n    Amount: z.number(),\n    RoundTrip: z.boolean(),\n  })\n  .catchall(z.unknown());\n\nexport const lineItemLookupSchema = z\n  .object({\n    TerminalComboIndex: z.number(),\n    LineItemIndex: z.number(),\n    RoundTripLineItemIndex: z.number(),\n  })\n  .catchall(z.unknown());\n\nexport const fareLineItemsVerboseResponseSchema = z\n  .object({\n    TerminalComboVerbose: z.array(terminalComboVerboseSchema),\n    LineItemLookup: z.array(lineItemLookupSchema),\n    LineItems: z.array(z.array(fareLineItemSchema)),\n    RoundTripLineItems: z.array(z.array(fareLineItemSchema)),\n  })\n  .catchall(z.unknown());\n\n// Array schemas\nexport const faresTerminalsArraySchema = z.array(faresTerminalSchema);\nexport const terminalMatesArraySchema = z.array(terminalMateSchema);\nexport const terminalComboVerboseArraySchema = z.array(\n  terminalComboVerboseSchema\n);\nexport const fareLineItemsArraySchema = z.array(fareLineItemSchema);\nexport const fareLineItemsBasicArraySchema = z.array(fareLineItemBasicSchema);\nexport const fareTotalsArraySchema = z.array(\n  z\n    .object({\n      TotalType: z.number(),\n      Description: z.string(),\n      BriefDescription: z.string(),\n      Amount: z.number(),\n    })\n    .catchall(z.unknown())\n);\n\n// Inferred types\nexport type FaresCacheFlushDate = z.infer<typeof faresCacheFlushDateSchema>;\nexport type FaresValidDateRange = z.infer<typeof faresValidDateRangeSchema>;\nexport type FaresTerminal = z.infer<typeof faresTerminalSchema>;\nexport type TerminalMate = z.infer<typeof terminalMateSchema>;\nexport type TerminalCombo = z.infer<typeof terminalComboSchema>;\nexport type TerminalComboVerbose = z.infer<typeof terminalComboVerboseSchema>;\nexport type FareLineItem = z.infer<typeof fareLineItemSchema>;\nexport type FareLineItemBasic = z.infer<typeof fareLineItemBasicSchema>;\nexport type FareLineItemVerbose = z.infer<typeof fareLineItemVerboseSchema>;\nexport type FareLineItemsVerboseResponse = z.infer<\n  typeof fareLineItemsVerboseResponseSchema\n>;\nexport type FareTotal = z.infer<(typeof fareTotalsArraySchema)[\"element\"]>;\n","// WSF Fares API functions\n// Documentation: https://www.wsdot.wa.gov/ferries/api/fares/documentation/rest.html\n// API Help: https://www.wsdot.wa.gov/ferries/api/fares/rest/help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type {\n  FareLineItem,\n  FareLineItemBasic,\n  FareLineItemsVerboseResponse,\n  FaresCacheFlushDate,\n  FaresTerminal,\n  FaresValidDateRange,\n  FareTotal,\n  TerminalCombo,\n  TerminalComboVerbose,\n  TerminalMate,\n} from \"./schemas\";\nimport {\n  fareLineItemsArraySchema,\n  fareLineItemsBasicArraySchema,\n  fareLineItemsVerboseResponseSchema,\n  faresCacheFlushDateSchema,\n  faresTerminalsArraySchema,\n  faresValidDateRangeSchema,\n  fareTotalsArraySchema,\n  terminalComboSchema,\n  terminalComboVerboseArraySchema,\n  terminalMatesArraySchema,\n} from \"./schemas\";\n\n// Create a factory function for WSF Fares API\nconst createFetch = createFetchFactory(\"/ferries/api/fares/rest\");\n\n/**\n * Get cache flush date from WSF Fares API\n *\n * Some of the retrieval operations return data that changes infrequently.\n * Use this operation to poll for changes. When the date returned is modified,\n * drop your application cache and retrieve fresh data.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to cache flush date\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const flushDate = await getFaresCacheFlushDate();\n * console.log(flushDate); // \"2024-01-15T10:30:00Z\"\n * ```\n */\nexport const getFaresCacheFlushDate = async () => {\n  const fetcher = createFetch(\"/cacheflushdate\");\n  const data = await fetcher();\n  return faresCacheFlushDateSchema.parse(data) as FaresCacheFlushDate;\n};\n\n/**\n * Get valid date range for fares data from WSF Fares API\n *\n * Retrieves a date range for which fares data is currently published & available.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to valid date range information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const dateRange = await getFaresValidDateRange();\n * console.log(dateRange.StartDate); // \"2024-01-01T00:00:00Z\"\n * ```\n */\nexport const getFaresValidDateRange = async () => {\n  const fetcher = createFetch(\"/validdaterange\");\n  const data = await fetcher();\n  return faresValidDateRangeSchema.parse(data) as FaresValidDateRange;\n};\n\n/**\n * Get valid departing terminals for a trip date from WSF Fares API\n *\n * Retrieves valid departing terminals for a given trip date. A valid trip date\n * may be determined using validDateRange.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to array of valid departing terminals\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const terminals = await getFaresTerminals({ tripDate: new Date('2024-01-15') });\n * console.log(terminals[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getFaresTerminals = async (params: { tripDate: Date }) => {\n  const fetcher = createFetch<{ tripDate: Date }>(\"/terminals/{tripDate}\");\n  const data = await fetcher(params);\n  return faresTerminalsArraySchema.parse(data) as FaresTerminal[];\n};\n\n/**\n * Get arriving terminals for a departing terminal and trip date from WSF Fares API\n *\n * Provides arriving terminals for a given departing terminal and trip date. A valid departing\n * terminal may be found by using terminals. Similarly, a valid trip date may be determined\n * using validDateRange.\n *\n * @param params - Object containing tripDate and terminalID\n * @param params.tripDate - The trip date as a Date object\n * @param params.terminalID - The unique identifier for the departing terminal\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to array of arriving terminals\n * @throws {WsfApiError} When the API request fails\n */\nexport const getFaresTerminalMates = async (params: {\n  tripDate: Date;\n  terminalID: number;\n}) => {\n  const fetcher = createFetch<{ tripDate: Date; terminalID: number }>(\n    \"/terminalmates/{tripDate}/{terminalID}\"\n  );\n  const data = await fetcher(params);\n  return terminalMatesArraySchema.parse(data) as TerminalMate[];\n};\n\n/**\n * Get fare collection description for a terminal combination from WSF Fares API\n *\n * Retrieves fare collection description for a specific terminal combination on a given trip date.\n * This endpoint provides information about how fares are collected for the specified route.\n *\n * @param params - Object containing tripDate, departingTerminalID, and arrivingTerminalID\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalID - The unique identifier for the departing terminal\n * @param params.arrivingTerminalID - The unique identifier for the arriving terminal\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to terminal combination information\n * @throws {WsfApiError} When the API request fails\n */\nexport const getTerminalCombo = async (params: {\n  tripDate: Date;\n  departingTerminalID: number;\n  arrivingTerminalID: number;\n}) => {\n  const fetcher = createFetch<{\n    tripDate: Date;\n    departingTerminalID: number;\n    arrivingTerminalID: number;\n  }>(\"/terminalcombo/{tripDate}/{departingTerminalID}/{arrivingTerminalID}\");\n  const data = await fetcher(params);\n  return terminalComboSchema.parse(data) as TerminalCombo;\n};\n\n/**\n * Get all terminal combinations for a trip date from WSF Fares API\n *\n * Retrieves all valid terminal combinations for a given trip date. This endpoint provides\n * comprehensive information about all available routes and their fare collection methods.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to array of all terminal combinations\n * @throws {WsfApiError} When the API request fails\n */\nexport const getTerminalComboVerbose = async (params: { tripDate: Date }) => {\n  const fetcher = createFetch<{ tripDate: Date }>(\n    \"/terminalcomboverbose/{tripDate}\"\n  );\n  const data = await fetcher(params);\n  return terminalComboVerboseArraySchema.parse(data) as TerminalComboVerbose[];\n};\n\n/**\n * Get most popular fares for a route from WSF Fares API\n *\n * Retrieves the most popular fare line items for a specific route. This endpoint provides\n * the commonly used fare options for the specified terminal combination and trip type.\n *\n * @param params - Object containing tripDate, departingTerminalID, arrivingTerminalID, and roundTrip\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalID - The unique identifier for the departing terminal\n * @param params.arrivingTerminalID - The unique identifier for the arriving terminal\n * @param params.roundTrip - Whether this is a round trip\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to array of most popular fare line items\n * @throws {WsfApiError} When the API request fails\n */\nexport const getFareLineItemsBasic = async (params: {\n  tripDate: Date;\n  departingTerminalID: number;\n  arrivingTerminalID: number;\n  roundTrip: boolean;\n}) => {\n  const fetcher = createFetch<{\n    tripDate: Date;\n    departingTerminalID: number;\n    arrivingTerminalID: number;\n    roundTrip: boolean;\n  }>(\n    \"/farelineitemsbasic/{tripDate}/{departingTerminalID}/{arrivingTerminalID}/{roundTrip}\"\n  );\n  const data = await fetcher(params);\n  return fareLineItemsBasicArraySchema.parse(data) as FareLineItemBasic[];\n};\n\n/**\n * Get all fares for a route from WSF Fares API\n *\n * Retrieves all available fare line items for a specific route. This endpoint provides\n * comprehensive fare information including all fare types and options for the specified\n * terminal combination and trip type.\n *\n * @param params - Object containing tripDate, departingTerminalID, arrivingTerminalID, and roundTrip\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalID - The unique identifier for the departing terminal\n * @param params.arrivingTerminalID - The unique identifier for the arriving terminal\n * @param params.roundTrip - Whether this is a round trip\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to array of all fare line items\n * @throws {WsfApiError} When the API request fails\n */\nexport const getFareLineItems = async (params: {\n  tripDate: Date;\n  departingTerminalID: number;\n  arrivingTerminalID: number;\n  roundTrip: boolean;\n}) => {\n  const fetcher = createFetch<{\n    tripDate: Date;\n    departingTerminalID: number;\n    arrivingTerminalID: number;\n    roundTrip: boolean;\n  }>(\n    \"/farelineitems/{tripDate}/{departingTerminalID}/{arrivingTerminalID}/{roundTrip}\"\n  );\n  const data = await fetcher(params);\n  return fareLineItemsArraySchema.parse(data) as FareLineItem[];\n};\n\n/**\n * Get all fares for all terminal combinations on a trip date from WSF Fares API\n *\n * Retrieves all fare line items for all terminal combinations on a given trip date.\n * This endpoint provides comprehensive fare information for all available routes\n * in a single call.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to complex object with all fare line items for all routes\n * @throws {WsfApiError} When the API request fails\n */\nexport const getFareLineItemsVerbose = async (params: { tripDate: Date }) => {\n  const fetcher = createFetch<{ tripDate: Date }>(\n    \"/farelineitemsverbose/{tripDate}\"\n  );\n  const data = await fetcher(params);\n  return fareLineItemsVerboseResponseSchema.parse(\n    data\n  ) as FareLineItemsVerboseResponse;\n};\n\n/**\n * Calculate fare totals for a set of fare line items from WSF Fares API\n *\n * Calculates the total fare cost for a specific combination of fare line items and quantities.\n * This endpoint provides fare calculation functionality for booking and reservation systems.\n *\n * @param params - Object containing tripDate, departingTerminalID, arrivingTerminalID, roundTrip, fareLineItemIDs, and quantities\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalID - The unique identifier for the departing terminal\n * @param params.arrivingTerminalID - The unique identifier for the arriving terminal\n * @param params.roundTrip - Whether this is a round trip\n * @param params.fareLineItemIDs - Array of fare line item IDs to include in the calculation\n * @param params.quantities - Array of quantities corresponding to fare line item IDs\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to fare total calculation\n * @throws {WsfApiError} When the API request fails\n */\nexport const getFareTotals = async (params: {\n  tripDate: Date;\n  departingTerminalID: number;\n  arrivingTerminalID: number;\n  roundTrip: boolean;\n  fareLineItemIDs: number[];\n  quantities: number[];\n}) => {\n  const fetcher = createFetch<{\n    tripDate: Date;\n    departingTerminalID: number;\n    arrivingTerminalID: number;\n    roundTrip: boolean;\n    fareLineItemIDs: number[];\n    quantities: number[];\n  }>(\n    \"/faretotals/{tripDate}/{departingTerminalID}/{arrivingTerminalID}/{roundTrip}/{fareLineItemIDs}/{quantities}\"\n  );\n  const data = await fetcher(params);\n  return fareTotalsArraySchema.parse(data) as FareTotal[];\n};\n","// WSF Schedule API exports\n\nexport * from \"./api\";\nexport * from \"./cache\";\nexport * from \"./queries\";\nexport * from \"./schemas\";\n","import { z } from \"zod\";\n\n// Base helpers\nconst zDate = () => z.date();\nconst zNullableDate = () => z.date().nullable();\nconst zNullableString = () => z.string().nullable();\nconst zNullableNumber = () => z.number().nullable();\n\nexport const serviceDisruptionSchema = z.record(z.string(), z.unknown());\n\nexport const annotationSchema = z\n  .object({\n    AnnotationID: z.number(),\n    AnnotationText: z.string(),\n    AnnotationIVRText: z.string(),\n    AdjustedCrossingTime: zNullableNumber(),\n    AnnotationImg: z.string(),\n    TypeDescription: z.string(),\n    SortSeq: z.number(),\n  })\n  .catchall(z.unknown());\n\nexport const contingencyAdjustmentSchema = z\n  .object({\n    DateFrom: zDate(),\n    DateThru: zDate(),\n    EventID: zNullableNumber(),\n    EventDescription: zNullableString(),\n    AdjType: z.number(),\n    ReplacedBySchedRouteID: zNullableNumber(),\n  })\n  .catchall(z.unknown());\n\nexport const scheduledRouteSchema = z\n  .object({\n    ScheduleID: z.number(),\n    SchedRouteID: z.number(),\n    ContingencyOnly: z.boolean(),\n    RouteID: z.number(),\n    RouteAbbrev: z.string(),\n    Description: z.string(),\n    SeasonalRouteNotes: z.string(),\n    RegionID: z.number(),\n    ServiceDisruptions: z.array(serviceDisruptionSchema),\n    ContingencyAdj: z.array(contingencyAdjustmentSchema),\n  })\n  .catchall(z.unknown());\n\nexport const routeSchema = z\n  .object({\n    RouteID: z.number(),\n    RouteAbbrev: z.string(),\n    Description: z.string(),\n    RegionID: z.number(),\n    Alerts: z.array(serviceDisruptionSchema).optional(),\n  })\n  .catchall(z.unknown());\n\nexport const routeDetailsSchema = z\n  .object({\n    RouteID: z.number(),\n    RouteAbbrev: z.string(),\n    Description: z.string(),\n    RegionID: z.number(),\n    CrossingTime: zNullableNumber(),\n    ReservationFlag: z.boolean(),\n    PassengerOnlyFlag: z.boolean(),\n    InternationalFlag: z.boolean(),\n    VesselWatchID: z.number(),\n    GeneralRouteNotes: z.string(),\n    SeasonalRouteNotes: z.string(),\n    AdaNotes: zNullableString(),\n    Alerts: z.array(serviceDisruptionSchema),\n  })\n  .catchall(z.unknown());\n\nexport const terminalTimeSchema = z\n  .object({\n    JourneyTerminalID: z.number(),\n    TerminalID: z.number(),\n    TerminalDescription: z.string(),\n    TerminalBriefDescription: z.string(),\n    Time: zNullableDate(),\n    DepArrIndicator: zNullableNumber(),\n    IsNA: z.boolean(),\n    Annotations: z.array(annotationSchema),\n  })\n  .catchall(z.unknown());\n\nexport const journeySchema = z\n  .object({\n    JourneyID: z.number(),\n    ReservationInd: z.boolean(),\n    InternationalInd: z.boolean(),\n    InterislandInd: z.boolean(),\n    VesselID: z.number(),\n    VesselName: z.string(),\n    VesselHandicapAccessible: z.boolean(),\n    VesselPositionNum: z.number(),\n    TerminalTimes: z.array(terminalTimeSchema),\n  })\n  .catchall(z.unknown());\n\nexport const sailingSchema = z\n  .object({\n    ScheduleID: z.number(),\n    SchedRouteID: z.number(),\n    RouteID: z.number(),\n    SailingID: z.number(),\n    SailingDescription: z.string(),\n    SailingNotes: z.string(),\n    DisplayColNum: z.number(),\n    SailingDir: z.number(),\n    DayOpDescription: z.string(),\n    DayOpUseForHoliday: z.boolean(),\n    ActiveDateRanges: z.array(\n      z\n        .object({\n          DateFrom: zDate(),\n          DateThru: zDate(),\n          EventID: zNullableNumber(),\n          EventDescription: zNullableString(),\n        })\n        .catchall(z.unknown())\n    ),\n    Journs: z.array(journeySchema),\n  })\n  .catchall(z.unknown());\n\nexport const alertSchema = z\n  .object({\n    BulletinID: z.number(),\n    BulletinFlag: z.boolean(),\n    BulletinText: z.string(),\n    CommunicationFlag: z.boolean(),\n    CommunicationText: zNullableString(),\n    RouteAlertFlag: z.boolean(),\n    RouteAlertText: z.string(),\n    HomepageAlertText: z.string(),\n    PublishDate: zDate(),\n    DisruptionDescription: zNullableString(),\n    AllRoutesFlag: z.boolean(),\n    SortSeq: z.number(),\n    AlertTypeID: z.number(),\n    AlertType: z.string(),\n    AlertFullTitle: z.string(),\n    AffectedRouteIDs: z.array(z.number()),\n    IVRText: zNullableString(),\n  })\n  .catchall(z.unknown());\n\nexport const timeAdjustmentSchema = z\n  .object({\n    ScheduleID: z.number(),\n    SchedRouteID: z.number(),\n    RouteID: z.number(),\n    RouteDescription: z.string(),\n    RouteSortSeq: z.number(),\n    SailingID: z.number(),\n    SailingDescription: z.string(),\n    ActiveSailingDateRange: z\n      .object({\n        DateFrom: zDate(),\n        DateThru: zDate(),\n        EventID: zNullableNumber(),\n        EventDescription: zNullableString(),\n      })\n      .catchall(z.unknown()),\n    SailingDir: z.number(),\n    JourneyID: z.number(),\n    VesselID: z.number(),\n    VesselName: z.string(),\n    VesselHandicapAccessible: z.boolean(),\n    VesselPositionNum: z.number(),\n    TerminalID: z.number(),\n    TerminalDescription: z.string(),\n    TerminalBriefDescription: z.string(),\n    JourneyTerminalID: z.number(),\n    DepArrIndicator: z.number(),\n    AdjDateFrom: zDate(),\n    AdjDateThru: zDate(),\n    AdjType: z.number(),\n    TidalAdj: z.boolean(),\n    TimeToAdj: zNullableDate(),\n    Annotations: z.array(annotationSchema),\n    EventID: zNullableNumber(),\n    EventDescription: zNullableString(),\n  })\n  .catchall(z.unknown());\n\nexport const scheduleTerminalSchema = z\n  .object({\n    TerminalID: z.number(),\n    Description: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const scheduleTerminalComboSchema = z\n  .object({\n    DepartingTerminalID: z.number(),\n    DepartingDescription: z.string(),\n    ArrivingTerminalID: z.number(),\n    ArrivingDescription: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const scheduleTimeSchema = z\n  .object({\n    DepartingTime: zDate(),\n    ArrivingTime: zDate(),\n    LoadingRule: z.number(),\n    VesselID: z.number(),\n    VesselName: z.string(),\n    VesselHandicapAccessible: z.boolean(),\n    VesselPositionNum: z.number(),\n    Routes: z.array(z.number()),\n    AnnotationIndexes: z.array(z.number()),\n  })\n  .catchall(z.unknown());\n\nexport const scheduleResponseTerminalComboSchema = z\n  .object({\n    DepartingTerminalID: z.number(),\n    DepartingTerminalName: z.string(),\n    ArrivingTerminalID: z.number(),\n    ArrivingTerminalName: z.string(),\n    SailingNotes: z.string(),\n    Annotations: z.array(z.string()),\n    AnnotationsIVR: z.array(z.string()),\n    Times: z.array(scheduleTimeSchema),\n  })\n  .catchall(z.unknown());\n\nexport const scheduleResponseSchema = z\n  .object({\n    ScheduleID: z.number(),\n    ScheduleName: z.string(),\n    ScheduleSeason: z.number(),\n    SchedulePDFUrl: z.string(),\n    ScheduleStart: zDate(),\n    ScheduleEnd: zDate(),\n    AllRoutes: z.array(z.number()),\n    TerminalCombos: z.array(scheduleResponseTerminalComboSchema),\n  })\n  .catchall(z.unknown());\n\nexport const scheduleDepartureSchema = z\n  .object({\n    SailingID: z.number(),\n    SchedRouteID: z.number(),\n    DepartureTime: zDate(),\n    ArrivalTime: zDate(),\n    VesselID: z.number(),\n    VesselName: z.string(),\n    DepartingTerminalID: z.number(),\n    DepartingTerminalName: z.string(),\n    ArrivingTerminalID: z.number(),\n    ArrivingTerminalName: z.string(),\n    IsCancelled: z.boolean(),\n    Notes: z.string().optional(),\n    LastUpdated: zDate(),\n  })\n  .catchall(z.unknown());\n\nexport const scheduleSchema = z\n  .object({\n    RouteID: z.number(),\n    RouteName: z.string(),\n    SailingDate: zDate(),\n    Departures: z.array(scheduleDepartureSchema),\n    LastUpdated: zDate(),\n  })\n  .catchall(z.unknown());\n\nexport const validDateRangeSchema = z\n  .object({\n    DateFrom: zDate(),\n    DateThru: zDate(),\n  })\n  .catchall(z.unknown());\n\nexport const scheduleCacheFlushDateSchema = zDate();\n\nexport const activeSeasonSchema = z\n  .object({\n    ScheduleID: z.number(),\n    ScheduleName: z.string(),\n    ScheduleSeason: z.number(),\n    SchedulePDFUrl: z.string(),\n    ScheduleStart: zDate(),\n    ScheduleEnd: zDate(),\n  })\n  .catchall(z.unknown());\n\nexport const alternativeFormatSchema = z\n  .object({\n    AltID: z.number(),\n    SubjectID: z.number(),\n    SubjectName: z.string(),\n    AltTitle: z.string(),\n    AltUrl: z.string(),\n    AltDesc: z.string(),\n    FileType: z.string(),\n    Status: z.string(),\n    SortSeq: z.number(),\n    FromDate: zNullableDate(),\n    ThruDate: zNullableDate(),\n    ModifiedDate: zNullableDate(),\n    ModifiedBy: z.string(),\n  })\n  .catchall(z.unknown());\n\n// Array schemas\nexport const scheduledRoutesArraySchema = z.array(scheduledRouteSchema);\nexport const routesArraySchema = z.array(routeSchema);\nexport const sailingsArraySchema = z.array(sailingSchema);\nexport const alertsArraySchema = z.array(alertSchema);\nexport const timeAdjustmentsArraySchema = z.array(timeAdjustmentSchema);\nexport const scheduleTerminalsArraySchema = z.array(scheduleTerminalSchema);\nexport const scheduleTerminalCombosArraySchema = z.array(\n  scheduleTerminalComboSchema\n);\nexport const activeSeasonsArraySchema = z.array(activeSeasonSchema);\nexport const alternativeFormatsArraySchema = z.array(alternativeFormatSchema);\n\n// Loose fallbacks for endpoints with occasionally inconsistent shapes\nexport const routesArrayLooseSchema = z.array(\n  z.record(z.string(), z.unknown())\n);\nexport const routeDetailsLooseSchema = z.record(z.string(), z.unknown());\n\n// Types\nexport type ValidDateRange = z.infer<typeof validDateRangeSchema>;\nexport type ScheduleCacheFlushDate = z.infer<\n  typeof scheduleCacheFlushDateSchema\n>;\nexport type ActiveSeason = z.infer<typeof activeSeasonSchema>;\nexport type ServiceDisruption = z.infer<typeof serviceDisruptionSchema>;\nexport type ContingencyAdjustment = z.infer<typeof contingencyAdjustmentSchema>;\nexport type ScheduledRoute = z.infer<typeof scheduledRouteSchema>;\nexport type Route = z.infer<typeof routeSchema>;\nexport type RouteDetails = z.infer<typeof routeDetailsSchema>;\nexport type Annotation = z.infer<typeof annotationSchema>;\nexport type TerminalTime = z.infer<typeof terminalTimeSchema>;\nexport type Journey = z.infer<typeof journeySchema>;\nexport type Sailing = z.infer<typeof sailingSchema>;\nexport type Alert = z.infer<typeof alertSchema>;\nexport type TimeAdjustment = z.infer<typeof timeAdjustmentSchema>;\nexport type ScheduleTerminal = z.infer<typeof scheduleTerminalSchema>;\nexport type ScheduleTerminalCombo = z.infer<typeof scheduleTerminalComboSchema>;\nexport type ScheduleTime = z.infer<typeof scheduleTimeSchema>;\nexport type ScheduleResponseTerminalCombo = z.infer<\n  typeof scheduleResponseTerminalComboSchema\n>;\nexport type ScheduleResponse = z.infer<typeof scheduleResponseSchema>;\nexport type ScheduleDeparture = z.infer<typeof scheduleDepartureSchema>;\nexport type Schedule = z.infer<typeof scheduleSchema>;\nexport type AlternativeFormat = z.infer<typeof alternativeFormatSchema>;\n","// WSF Schedule API functions\n// Documentation: https://www.wsdot.wa.gov/ferries/api/schedule/documentation/rest.html\n// API Help: https://www.wsdot.wa.gov/ferries/api/schedule/rest/help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport {\n  activeSeasonsArraySchema,\n  alertsArraySchema,\n  alternativeFormatsArraySchema,\n  routesArraySchema,\n  routesArrayLooseSchema,\n  routeDetailsSchema,\n  routeDetailsLooseSchema,\n  sailingsArraySchema,\n  scheduledRoutesArraySchema,\n  scheduleCacheFlushDateSchema,\n  scheduleResponseSchema,\n  scheduleTerminalCombosArraySchema,\n  scheduleTerminalsArraySchema,\n  timeAdjustmentsArraySchema,\n  validDateRangeSchema,\n} from \"./schemas\";\nimport type {\n  ActiveSeason,\n  Alert,\n  AlternativeFormat,\n  Route,\n  RouteDetails,\n  Sailing,\n  ScheduledRoute,\n  ScheduleResponse,\n  ScheduleTerminal,\n  ScheduleTerminalCombo,\n  TimeAdjustment,\n  ValidDateRange,\n} from \"./schemas\";\n\n// Create a factory function for WSF Schedule API\nconst createFetch = createFetchFactory(\"/ferries/api/schedule/rest\");\n\n// ============================================================================\n// CACHE FLUSH DATE API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching cache flush date from WSF Schedule API\n *\n * Retrieves the cache flush date for the schedule API. This endpoint helps\n * determine when cached data should be refreshed. When the date returned\n * from this operation is modified, drop your application cache and retrieve\n * fresh data from the service.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to Date object containing cache flush information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const flushDate = await getCacheFlushDateSchedule();\n * console.log(flushDate); // \"2024-01-15T10:30:00Z\"\n * ```\n */\nexport const getCacheFlushDateSchedule = async () => {\n  const fetcher = createFetch(\"/cacheflushdate\");\n  const data = await fetcher();\n  return scheduleCacheFlushDateSchema.parse(data) as Date;\n};\n\n// ============================================================================\n// VALID DATE RANGE API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching valid date range from WSF Schedule API\n *\n * Retrieves a date range for which schedule data is currently published & available.\n * A valid API Access Code from the WSDOT Traveler API must be passed as part of the URL string.\n * Please consider using cacheflushdate to coordinate the caching of this data in your application.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to ValidDateRange object containing valid date range information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const dateRange = await getValidDateRange();\n * console.log(dateRange.StartDate); // \"2024-01-01T00:00:00Z\"\n * ```\n */\nexport const getValidDateRange = async () => {\n  const fetcher = createFetch(\"/validdaterange\");\n  const data = await fetcher();\n  return validDateRangeSchema.parse(data) as ValidDateRange;\n};\n\n// ============================================================================\n// TERMINALS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching terminals from WSF Schedule API\n *\n * Retrieves valid departing terminals for a given trip date. A valid trip date\n * may be determined using validDateRange.\n *\n * @param params - Object containing tripDate and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of ScheduleTerminal objects containing terminal information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const terminals = await getTerminals({ tripDate: new Date('2024-01-15') });\n * console.log(terminals[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminals = async (params: { tripDate: Date }) => {\n  const fetcher = createFetch<{ tripDate: Date }>(`/terminals/{tripDate}`);\n  const data = await fetcher(params);\n  return scheduleTerminalsArraySchema.parse(data) as ScheduleTerminal[];\n};\n\n/**\n * API function for fetching terminals and mates from WSF Schedule API\n *\n * Retrieves all valid departing and arriving terminal combinations for a given trip date.\n * A valid trip date may be determined using validDateRange.\n *\n * @param params - Object containing tripDate and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of ScheduleTerminalCombo objects containing terminal combinations\n * @throws {WsfApiError} When the API request fails\n */\nexport const getTerminalsAndMates = async (params: { tripDate: Date }) => {\n  const fetcher = createFetch<{ tripDate: Date }>(`/terminalsandmates/{tripDate}`);\n  const data = await fetcher(params);\n  return scheduleTerminalCombosArraySchema.parse(data) as ScheduleTerminalCombo[];\n};\n\n/**\n * API function for fetching terminals and mates by route from WSF Schedule API\n *\n * Provides valid departing and arriving terminal combinations for a given trip date and route.\n * Valid routes may be found by using routes. Similarly, a valid trip date may be determined\n * using validDateRange.\n *\n * @param params - Object containing tripDate, routeId and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.routeId - The unique identifier for the route\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of ScheduleTerminalCombo objects containing terminal combinations for the route\n * @throws {WsfApiError} When the API request fails\n */\nexport const getTerminalsAndMatesByRoute = async (params: {\n  tripDate: Date;\n  routeId: number;\n}) => {\n  const fetcher = createFetch<{ tripDate: Date; routeId: number }>(\n    `/terminalsandmatesbyroute/{tripDate}/{routeId}`\n  );\n  const data = await fetcher(params);\n  return scheduleTerminalCombosArraySchema.parse(data) as ScheduleTerminalCombo[];\n};\n\n/**\n * API function for fetching terminal mates from WSF Schedule API\n *\n * Provides arriving terminals for a given departing terminal and trip date. A valid departing\n * terminal may be found by using terminals. Similarly, a valid trip date may be determined\n * using validDateRange.\n *\n * @param params - Object containing tripDate, terminalId and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.terminalId - The unique identifier for the departing terminal\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of ScheduleTerminal objects containing arriving terminals\n * @throws {WsfApiError} When the API request fails\n */\nexport const getTerminalMates = async (params: {\n  tripDate: Date;\n  terminalId: number;\n}) => {\n  const fetcher = createFetch<{ tripDate: Date; terminalId: number }>(\n    `/terminalmates/{tripDate}/{terminalId}`\n  );\n  const data = await fetcher(params);\n  return scheduleTerminalsArraySchema.parse(data) as ScheduleTerminal[];\n};\n\n// ============================================================================\n// ROUTES API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching all routes from WSF Schedule API\n *\n * Retrieves the most basic/brief information pertaining to routes for a given trip date.\n * If only a trip date is included, all routes available for that date of travel are returned.\n * Valid trip dates may be determined using the validDateRange endpoint.\n *\n * @param params - Object containing tripDate and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of Route objects containing basic route information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const routes = await getRoutes({ tripDate: new Date('2024-01-15') });\n * console.log(routes[0].RouteAbbrev); // \"ANA-SID\"\n * ```\n */\nexport const getRoutes = async (params: { tripDate: Date }) => {\n  const fetcher = createFetch<{ tripDate: Date }>(`/routes/{tripDate}`);\n  const data = await fetcher(params);\n  try {\n    return routesArraySchema.parse(data) as Route[];\n  } catch {\n    return routesArrayLooseSchema.parse(data) as unknown as Route[];\n  }\n};\n\n/**\n * API function for fetching routes between specific terminals from WSF Schedule API\n *\n * Retrieves the most basic/brief information pertaining to routes filtered by departing\n * and arriving terminals for a given trip date. Routes in the resultset are filtered\n * to match the specified terminal combination. Valid departing and arriving terminals\n * may be found using the terminalsAndMates endpoint.\n *\n * @param params - Object containing tripDate, departingTerminalId, arrivingTerminalId and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalId - The unique identifier for the departing terminal\n * @param params.arrivingTerminalId - The unique identifier for the arriving terminal\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of Route objects filtered by terminal combination\n * @throws {WsfApiError} When the API request fails\n */\nexport const getRoutesByTerminals = async (params: {\n  tripDate: Date;\n  departingTerminalId: number;\n  arrivingTerminalId: number;\n}) => {\n  const fetcher = createFetch<{\n    tripDate: Date;\n    departingTerminalId: number;\n    arrivingTerminalId: number;\n  }>(`/routes/{tripDate}/{departingTerminalId}/{arrivingTerminalId}`);\n  const data = await fetcher(params);\n  return routesArraySchema.parse(data) as Route[];\n};\n\n/**\n * API function for fetching routes with service disruptions from WSF Schedule API\n *\n * Retrieves the most basic/brief information for routes currently associated with\n * service disruptions for a given trip date. This endpoint helps identify routes\n * that may have delays, cancellations, or other service issues.\n *\n * @param params - Object containing tripDate and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of Route objects that have service disruptions\n * @throws {WsfApiError} When the API request fails\n */\nexport const getRoutesWithDisruptions = async (params: { tripDate: Date }) => {\n  const fetcher = createFetch<{ tripDate: Date }>(\n    `/routeshavingservicedisruptions/{tripDate}`\n  );\n  const data = await fetcher(params);\n  return routesArraySchema.parse(data) as Route[];\n};\n\n/**\n * API function for fetching detailed route information from WSF Schedule API\n *\n * Retrieves highly detailed information pertaining to routes for a given trip date.\n * If only a trip date is included, all routes available for that date of travel are returned.\n * This endpoint provides comprehensive route details including sailing times, vessel assignments,\n * and operational information.\n *\n * @param params - Object containing tripDate and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of Route objects containing detailed route information\n * @throws {WsfApiError} When the API request fails\n */\nexport const getRouteDetails = async (params: { tripDate: Date }) => {\n  const fetcher = createFetch<{ tripDate: Date }>(`/routedetails/{tripDate}`);\n  const data = await fetcher(params);\n  return routesArraySchema.parse(data) as Route[];\n};\n\n/**\n * API function for fetching detailed route information between specific terminals from WSF Schedule API\n *\n * Retrieves highly detailed information pertaining to routes filtered by departing and\n * arriving terminals for a given trip date. Routes in the resultset are filtered to match\n * the specified terminal combination. Valid departing and arriving terminals may be found\n * using the terminalsAndMates endpoint.\n *\n * @param params - Object containing tripDate, departingTerminalId, arrivingTerminalId and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalId - The unique identifier for the departing terminal\n * @param params.arrivingTerminalId - The unique identifier for the arriving terminal\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of Route objects with detailed information filtered by terminal combination\n * @throws {WsfApiError} When the API request fails\n */\nexport const getRouteDetailsByTerminals = async (params: {\n  tripDate: Date;\n  departingTerminalId: number;\n  arrivingTerminalId: number;\n}) => {\n  const fetcher = createFetch<{\n    tripDate: Date;\n    departingTerminalId: number;\n    arrivingTerminalId: number;\n  }>(`/routedetails/{tripDate}/{departingTerminalId}/{arrivingTerminalId}`);\n  const data = await fetcher(params);\n  return routesArraySchema.parse(data) as Route[];\n};\n\n/**\n * API function for fetching detailed route information by route ID from WSF Schedule API\n *\n * Retrieves highly detailed information for a specific route identified by route ID\n * for a given trip date. This endpoint filters the resultset to a single route,\n * providing comprehensive details for that specific route.\n *\n * @param params - Object containing tripDate, routeId and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.routeId - The unique identifier for the route\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a RouteDetails object containing detailed information for the specified route\n * @throws {WsfApiError} When the API request fails\n */\nexport const getRouteDetailsByRoute = async (params: {\n  tripDate: Date;\n  routeId: number;\n}) => {\n  const fetcher = createFetch<{ tripDate: Date; routeId: number }>(\n    `/routedetails/{tripDate}/{routeId}`\n  );\n  const data = await fetcher(params);\n  try {\n    return routeDetailsSchema.parse(data) as RouteDetails;\n  } catch {\n    return routeDetailsLooseSchema.parse(data) as unknown as RouteDetails;\n  }\n};\n\n// ============================================================================\n// ACTIVE SEASONS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching active seasons from WSF Schedule API\n *\n * Retrieves a summary of active seasons. This endpoint provides information about\n * current and upcoming ferry service seasons, which can be used to determine\n * valid schedule IDs for other endpoints.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of ActiveSeason objects containing active season information\n * @throws {WsfApiError} When the API request fails\n */\nexport const getActiveSeasons = async () => {\n  const fetcher = createFetch(`/activeseasons`);\n  const data = await fetcher();\n  return activeSeasonsArraySchema.parse(data) as ActiveSeason[];\n};\n\n// ============================================================================\n// SCHEDULED ROUTES API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching scheduled routes from WSF Schedule API\n *\n * Provides a listing of routes that are active for a season. Results include all known\n * scheduled routes spanning current and upcoming seasons. For example, \"Anacortes / Sidney B.C.\"\n * may be a valid route, but if it's not scheduled to run during a specific season,\n * it won't be returned as part of that season's scheduled routes resultset.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of ScheduledRoute objects representing all scheduled routes\n * @throws {WsfApiError} When the API request fails\n */\nexport const getScheduledRoutes = async () => {\n  const fetcher = createFetch(`/schedroutes`);\n  const data = await fetcher();\n  return scheduledRoutesArraySchema.parse(data) as ScheduledRoute[];\n};\n\n/**\n * API function for fetching scheduled routes by season from WSF Schedule API\n *\n * Provides a listing of routes that are active for a specific season identified by schedule ID.\n * Results are filtered to only include scheduled routes for the specified season.\n * Seasons may be determined using the activeSeasons endpoint.\n *\n * @param params - Object containing scheduleId and optional logMode\n * @param params.scheduleId - The unique identifier for the season (schedule ID)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of ScheduledRoute objects representing scheduled routes for the specified season\n * @throws {WsfApiError} When the API request fails\n */\nexport const getScheduledRoutesBySeason = async (params: {\n  scheduleId: number;\n}) => {\n  const fetcher = createFetch<{ scheduleId: number }>(`/schedroutes/{scheduleId}`);\n  const data = await fetcher(params);\n  return scheduledRoutesArraySchema.parse(data) as ScheduledRoute[];\n};\n\n// ============================================================================\n// SAILINGS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching sailings from WSF Schedule API\n *\n * Provides sailings for a particular scheduled route. Sailings are departure times\n * organized by direction of travel (eastbound / westbound), days of operation groups\n * (daily, weekday, weekend, etc) and, in some cases, date ranges (eg. Early Fall / Late Fall).\n * Sailings largely mimic the groupings of departures found on the printed PDF version of the schedule.\n * Scheduled routes may be determined using schedRoutes.\n *\n * @param params - Object containing schedRouteId and optional logMode\n * @param params.schedRouteId - The unique identifier for the scheduled route\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of Sailing objects containing sailing information\n * @throws {WsfApiError} When the API request fails\n */\nexport const getSailings = async (params: { schedRouteId: number }) => {\n  const fetcher = createFetch<{ schedRouteId: number }>(`/sailings/{schedRouteId}`);\n  const data = await fetcher(params);\n  return sailingsArraySchema.parse(data) as Sailing[];\n};\n\n/**\n * API function for fetching all sailings from WSF Schedule API\n *\n * Provides all sailings for a particular scheduled route. Sailings are departure times\n * organized by direction of travel (eastbound / westbound), days of operation groups\n * (daily, weekday, weekend, etc) and, in some cases, date ranges (eg. Early Fall / Late Fall).\n * Sailings largely mimic the groupings of departures found on the printed PDF version of the schedule.\n * Scheduled routes may be determined using schedRoutes.\n *\n * @param params - Object containing schedRouteId and optional logMode\n * @param params.schedRouteId - The unique identifier for the scheduled route\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of Sailing objects containing all sailing information\n * @throws {WsfApiError} When the API request fails\n */\nexport const getAllSailings = async (params: { schedRouteId: number }) => {\n  const fetcher = createFetch<{ schedRouteId: number }>(`/allsailings/{schedRouteId}`);\n  const data = await fetcher(params);\n  return sailingsArraySchema.parse(data) as Sailing[];\n};\n\n// ============================================================================\n// TIME ADJUSTMENTS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching time adjustments from WSF Schedule API\n *\n * Provides a listing of all additions and cancellations that deviate on specific dates\n * from the scheduled times found in the sailings resultset (eg. tidal cancellations\n * affecting Port Townsend departures on 9/9/2014).\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TimeAdjustment objects containing time adjustment information\n * @throws {WsfApiError} When the API request fails\n */\nexport const getTimeAdjustments = async () => {\n  const fetcher = createFetch(`/timeadj`);\n  const data = await fetcher();\n  return timeAdjustmentsArraySchema.parse(data) as TimeAdjustment[];\n};\n\n/**\n * API function for fetching time adjustments by route from WSF Schedule API\n *\n * Provides a listing of all additions and cancellations for a route that deviate on\n * specific dates from the scheduled times found in the sailings resultset (eg. tidal\n * cancellations affecting Port Townsend departures on 9/9/2014). A valid route may\n * be determined using routes.\n *\n * @param params - Object containing routeId and optional logMode\n * @param params.routeId - The unique identifier for the route\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TimeAdjustment objects containing time adjustment information for the route\n * @throws {WsfApiError} When the API request fails\n */\nexport const getTimeAdjustmentsByRoute = async (params: { routeId: number }) => {\n  const fetcher = createFetch<{ routeId: number }>(`/timeadjbyroute/{routeId}`);\n  const data = await fetcher(params);\n  return timeAdjustmentsArraySchema.parse(data) as TimeAdjustment[];\n};\n\n/**\n * API function for fetching time adjustments by scheduled route from WSF Schedule API\n *\n * Provides a listing of all additions and cancellations for a scheduled route that\n * deviate on specific dates from the scheduled times found in the sailings resultset\n * (eg. tidal cancellations affecting Port Townsend departures on 9/9/2014). A valid\n * scheduled route may be determined using schedRoutes.\n *\n * @param params - Object containing schedRouteId and optional logMode\n * @param params.schedRouteId - The unique identifier for the scheduled route\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TimeAdjustment objects containing time adjustment information for the scheduled route\n * @throws {WsfApiError} When the API request fails\n */\nexport const getTimeAdjustmentsBySchedRoute = async (params: {\n  schedRouteId: number;\n}) => {\n  const fetcher = createFetch<{ schedRouteId: number }>(\n    `/timeadjbyschedroute/{schedRouteId}`\n  );\n  const data = await fetcher(params);\n  return timeAdjustmentsArraySchema.parse(data) as TimeAdjustment[];\n};\n\n// ============================================================================\n// SCHEDULE API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching schedule by route from WSF Schedule API\n *\n * Provides departure times for a trip date and route. The resultset accounts for all\n * contingencies, sailing date ranges and time adjustments. Valid routes may be found\n * using routes. Similarly, a valid trip date may be determined using validDateRange.\n *\n * @param params - Object containing tripDate, routeId and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.routeId - The unique identifier for the route\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a ScheduleResponse object containing schedule information, or null if no schedule found\n * @throws {WsfApiError} When the API request fails\n */\nexport const getScheduleByRoute = async (params: {\n  tripDate: Date;\n  routeId: number;\n}) => {\n  const fetcher = createFetch<{ tripDate: Date; routeId: number }>(\n    `/schedule/{tripDate}/{routeId}`\n  );\n  const data = await fetcher(params);\n  return scheduleResponseSchema.parse(data) as ScheduleResponse;\n};\n\n/**\n * API function for fetching schedule by terminals from WSF Schedule API\n *\n * Provides departure times for a trip date and terminal combination. The resultset\n * accounts for all contingencies, sailing date ranges and time adjustments. Valid\n * departing and arriving terminals may be found using terminalsAndMates. Similarly,\n * a valid trip date may be determined using validDateRange.\n *\n * @param params - Object containing tripDate, departingTerminalId, arrivingTerminalId and optional logMode\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalId - The unique identifier for the departing terminal\n * @param params.arrivingTerminalId - The unique identifier for the arriving terminal\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a ScheduleResponse object containing schedule information, or null if no schedule found\n * @throws {WsfApiError} When the API request fails\n */\nexport const getScheduleByTerminals = async (params: {\n  tripDate: Date;\n  departingTerminalId: number;\n  arrivingTerminalId: number;\n}) => {\n  const fetcher = createFetch<{\n    tripDate: Date;\n    departingTerminalId: number;\n    arrivingTerminalId: number;\n  }>(`/schedule/{tripDate}/{departingTerminalId}/{arrivingTerminalId}`);\n  const data = await fetcher(params);\n  return scheduleResponseSchema.parse(data) as ScheduleResponse;\n};\n\n/**\n * API function for fetching today's schedule by route from WSF Schedule API\n *\n * Provides today's departure times for a route. Valid routes may be found using routes.\n * For the onlyRemainingTimes value, please indicate 'true' if departure times prior\n * to now should not be included in the resultset and 'false' if they should be included\n * in the resultset.\n *\n * @param params - Object containing routeId, onlyRemainingTimes and optional logMode\n * @param params.routeId - The unique identifier for the route\n * @param params.onlyRemainingTimes - Whether to include only remaining departure times (defaults to false)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a ScheduleResponse object containing today's schedule information, or null if no schedule found\n * @throws {WsfApiError} When the API request fails\n */\nexport const getScheduleTodayByRoute = async (params: {\n  routeId: number;\n  onlyRemainingTimes?: boolean;\n}) => {\n  const fetcher = createFetch<{\n    routeId: number;\n    onlyRemainingTimes?: boolean;\n  }>(`/scheduletoday/{routeId}/{onlyRemainingTimes}`);\n  const data = await fetcher(params);\n  return scheduleResponseSchema.parse(data) as ScheduleResponse;\n};\n\n/**\n * API function for fetching today's schedule by terminals from WSF Schedule API\n *\n * Provides today's departure times for a terminal combination. Valid departing and\n * arriving terminals may be found using terminalsAndMates. For the onlyRemainingTimes\n * value, please indicate 'true' if departure times prior to now should not be included\n * in the resultset and 'false' if they should be included in the resultset.\n *\n * @param params - Object containing departingTerminalId, arrivingTerminalId, onlyRemainingTimes and optional logMode\n * @param params.departingTerminalId - The unique identifier for the departing terminal\n * @param params.arrivingTerminalId - The unique identifier for the arriving terminal\n * @param params.onlyRemainingTimes - Whether to include only remaining departure times (defaults to false)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a ScheduleResponse object containing today's schedule information, or null if no schedule found\n * @throws {WsfApiError} When the API request fails\n */\nexport const getScheduleTodayByTerminals = async (params: {\n  departingTerminalId: number;\n  arrivingTerminalId: number;\n  onlyRemainingTimes?: boolean;\n}) => {\n  const fetcher = createFetch<{\n    departingTerminalId: number;\n    arrivingTerminalId: number;\n    onlyRemainingTimes?: boolean;\n  }>(\n    `/scheduletoday/{departingTerminalId}/{arrivingTerminalId}/{onlyRemainingTimes}`\n  );\n  const data = await fetcher(params);\n  return scheduleResponseSchema.parse(data) as ScheduleResponse;\n};\n\n// ============================================================================\n// ALERTS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching alerts from WSF Schedule API\n *\n * Provides alert information tailored for routes, bulletins, service disruptions, etc.\n * This endpoint returns important notifications and updates that may affect ferry service,\n * including weather-related delays, maintenance notices, and other operational alerts.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of Alert objects containing alert information\n * @throws {WsfApiError} When the API request fails\n */\nexport const getAlerts = async () => {\n  const fetcher = createFetch(`/alerts`);\n  const data = await fetcher();\n  return alertsArraySchema.parse(data) as Alert[];\n};\n\n// ============================================================================\n// ALTERNATIVE FORMATS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching alternative format data from WSF Schedule API\n *\n * Retrieves alternative format data for a given subject name. This endpoint\n * provides access to different data formats and representations that may be\n * useful for various applications and use cases.\n *\n * @param params - Object containing subjectName and optional logMode\n * @param params.subjectName - The subject name for which to retrieve alternative formats\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of AlternativeFormat objects containing format information\n * @throws {WsfApiError} When the API request fails\n */\nexport const getAlternativeFormats = async (params: { subjectName: string }) => {\n  const fetcher = createFetch<{ subjectName: string }>(\n    `/alternativeformats/{subjectName}`\n  );\n  const data = await fetcher(params);\n  return alternativeFormatsArraySchema.parse(data) as AlternativeFormat[];\n};\n","// Generic Cache Provider Component\n// Monitors cache flush dates and automatically invalidates queries when data changes\n\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useRef } from \"react\";\n\n/**\n * Generic Cache Provider Component\n *\n * This component monitors cache flush dates and automatically\n * invalidates queries when the cache flush date changes, indicating\n * that the underlying data has been updated on the server.\n *\n * @param queryKey - The React Query key to invalidate when cache flush date changes\n * @param useCacheFlushDateHook - Hook that returns cache flush date data\n * @returns null (this component doesn't render anything)\n */\nexport const CacheProvider = <T extends Date | null | undefined>(\n  queryKey: string[],\n  useCacheFlushDateHook: () => { data: T }\n) => {\n  const queryClient = useQueryClient();\n  const previousFlushDate = useRef<Date | null>(null);\n  const { data: currentFlushDate } = useCacheFlushDateHook();\n\n  useEffect(() => {\n    if (\n      previousFlushDate.current &&\n      currentFlushDate &&\n      previousFlushDate.current.getTime() !== currentFlushDate.getTime()\n    ) {\n      queryClient.invalidateQueries({ queryKey });\n    }\n\n    previousFlushDate.current = currentFlushDate || null;\n  }, [currentFlushDate, queryClient, queryKey]);\n\n  // This component doesn't render anything\n  return null;\n};\n","// WSF Schedule API React Query hooks\n\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport { jsDateToYyyyMmDd } from \"@/shared/fetching/parsing\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport {\n  getActiveSeasons,\n  getAlerts,\n  getAllSailings,\n  getAlternativeFormats,\n  getCacheFlushDateSchedule,\n  getRouteDetails,\n  getRouteDetailsByRoute,\n  getRouteDetailsByTerminals,\n  getRoutes,\n  getRoutesByTerminals,\n  getRoutesWithDisruptions,\n  getSailings,\n  getScheduleByRoute,\n  getScheduleByTerminals,\n  getScheduledRoutes,\n  getScheduledRoutesBySeason,\n  getScheduleTodayByRoute,\n  getScheduleTodayByTerminals,\n  getTerminalMates,\n  getTerminals,\n  getTerminalsAndMates,\n  getTerminalsAndMatesByRoute,\n  getTimeAdjustments,\n  getTimeAdjustmentsByRoute,\n  getTimeAdjustmentsBySchedRoute,\n  getValidDateRange,\n} from \"./api\";\nimport type {\n  ActiveSeason,\n  Alert,\n  AlternativeFormat,\n  Route,\n  RouteDetails,\n  Sailing,\n  ScheduledRoute,\n  ScheduleResponse,\n  ScheduleTerminal,\n  ScheduleTerminalCombo,\n  TimeAdjustment,\n  ValidDateRange,\n} from \"./schemas\";\n\n// ============================================================================\n// CACHE FLUSH DATE HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching cache flush date from WSF Schedule API\n *\n * Retrieves the cache flush date for the schedule API. This endpoint helps\n * determine when cached data should be refreshed. When the date returned\n * from this operation is modified, drop your application cache and retrieve\n * fresh data from the service.\n *\n * @param options - Optional React Query options\n * @returns React Query result object containing cache flush date information\n *\n * @example\n * ```typescript\n * const { data: flushDate } = useCacheFlushDateSchedule();\n * console.log(flushDate); // \"2024-01-15T10:30:00Z\"\n * ```\n */\nexport const useCacheFlushDateSchedule = (options?: TanStackOptions<Date>) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"cacheFlushDate\"],\n    queryFn: () => getCacheFlushDateSchedule(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// VALID DATE RANGE HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching valid date range from WSF Schedule API\n *\n * Retrieves a date range for which schedule data is currently published & available.\n * A valid API Access Code from the WSDOT Traveler API must be passed as part of the URL string.\n * Please consider using cacheflushdate to coordinate the caching of this data in your application.\n *\n * @param options - Optional React Query options\n * @returns React Query result object containing valid date range\n *\n * @example\n * ```typescript\n * const { data: dateRange } = useValidDateRange();\n * console.log(dateRange?.StartDate); // \"2024-01-01T00:00:00Z\"\n * ```\n */\nexport const useValidDateRange = (options?: TanStackOptions<ValidDateRange>) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"validDateRange\"],\n    queryFn: () => getValidDateRange(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// TERMINALS HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching terminals from WSF Schedule API\n *\n * Retrieves valid departing terminals for a given trip date. A valid trip date\n * may be determined using validDateRange.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param options - Optional React Query options\n * @returns React Query result object containing departing terminals\n *\n * @example\n * ```typescript\n * const { data: terminals } = useTerminals({ tripDate: new Date('2024-01-15') });\n * console.log(terminals?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminals = (\n  params: { tripDate: Date },\n  options?: TanStackOptions<ScheduleTerminal[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"terminals\",\n      jsDateToYyyyMmDd(params.tripDate),\n    ],\n    queryFn: () => getTerminals({ tripDate: params.tripDate }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching terminals and mates from WSF Schedule API\n *\n * Retrieves all valid departing and arriving terminal combinations for a given trip date.\n * A valid trip date may be determined using validDateRange.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param options - Optional React Query options\n * @returns React Query result object containing terminal combinations\n */\nexport const useTerminalsAndMates = (\n  params: { tripDate: Date },\n  options?: TanStackOptions<ScheduleTerminalCombo[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"terminalsAndMates\",\n      jsDateToYyyyMmDd(params.tripDate),\n    ],\n    queryFn: () => getTerminalsAndMates({ tripDate: params.tripDate }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching terminals and mates by route from WSF Schedule API\n *\n * Provides valid departing and arriving terminal combinations for a given trip date and route.\n * Valid routes may be found by using routes. Similarly, a valid trip date may be determined\n * using validDateRange.\n *\n * @param params - Object containing tripDate and routeId\n * @param params.tripDate - The trip date as a Date object\n * @param params.routeId - The unique identifier for the route\n * @param options - Optional React Query options\n * @returns React Query result object containing terminal combinations for the route\n */\nexport const useTerminalsAndMatesByRoute = (\n  params: { tripDate: Date; routeId: number },\n  options?: TanStackOptions<ScheduleTerminalCombo[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"terminalsAndMatesByRoute\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.routeId,\n    ],\n    queryFn: () =>\n      getTerminalsAndMatesByRoute({\n        tripDate: params.tripDate,\n        routeId: params.routeId,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching terminal mates from WSF Schedule API\n *\n * Provides arriving terminals for a given departing terminal and trip date. A valid departing\n * terminal may be found by using terminals. Similarly, a valid trip date may be determined\n * using validDateRange.\n *\n * @param params - Object containing tripDate and terminalId\n * @param params.tripDate - The trip date as a Date object\n * @param params.terminalId - The unique identifier for the departing terminal\n * @param options - Optional React Query options\n * @returns React Query result object containing arriving terminals\n */\nexport const useTerminalMates = (\n  params: { tripDate: Date; terminalId: number },\n  options?: TanStackOptions<ScheduleTerminal[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"terminalMates\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.terminalId,\n    ],\n    queryFn: () =>\n      getTerminalMates({\n        tripDate: params.tripDate,\n        terminalId: params.terminalId,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// ROUTES HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching routes from WSF Schedule API\n *\n * Retrieves the most basic/brief information pertaining to routes for a given trip date.\n * If only a trip date is included, all routes available for that date of travel are returned.\n * Valid trip dates may be determined using the validDateRange endpoint.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param options - Optional React Query options\n * @returns React Query result object containing routes\n *\n * @example\n * ```typescript\n * const { data: routes } = useRoutes({ tripDate: new Date('2024-01-15') });\n * console.log(routes?.[0]?.RouteAbbrev); // \"ANA-SID\"\n * ```\n */\nexport const useRoutes = (\n  params: { tripDate: Date },\n  options?: TanStackOptions<Route[]>\n) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"routes\", jsDateToYyyyMmDd(params.tripDate)],\n    queryFn: () => getRoutes({ tripDate: params.tripDate }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching routes by terminals from WSF Schedule API\n *\n * Retrieves the most basic/brief information pertaining to routes filtered by departing\n * and arriving terminals for a given trip date. Routes in the resultset are filtered\n * to match the specified terminal combination. Valid departing and arriving terminals\n * may be found using the terminalsAndMates endpoint.\n *\n * @param params - Object containing tripDate, departingTerminalId, and arrivingTerminalId\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalId - The unique identifier for the departing terminal\n * @param params.arrivingTerminalId - The unique identifier for the arriving terminal\n * @param options - Optional React Query options\n * @returns React Query result object containing routes for the terminal combination\n */\nexport const useRoutesByTerminals = (\n  params: {\n    tripDate: Date;\n    departingTerminalId: number;\n    arrivingTerminalId: number;\n  },\n  options?: TanStackOptions<Route[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"routesByTerminals\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.departingTerminalId,\n      params.arrivingTerminalId,\n    ],\n    queryFn: () =>\n      getRoutesByTerminals({\n        tripDate: params.tripDate,\n        departingTerminalId: params.departingTerminalId,\n        arrivingTerminalId: params.arrivingTerminalId,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching routes with disruptions from WSF Schedule API\n *\n * Retrieves the most basic/brief information for routes currently associated with\n * service disruptions for a given trip date. This endpoint helps identify routes\n * that may have delays, cancellations, or other service issues.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param options - Optional React Query options\n * @returns React Query result object containing routes with disruption information\n */\nexport const useRoutesWithDisruptions = (\n  params: { tripDate: Date },\n  options?: TanStackOptions<Route[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"routesWithDisruptions\",\n      jsDateToYyyyMmDd(params.tripDate),\n    ],\n    queryFn: () => getRoutesWithDisruptions({ tripDate: params.tripDate }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// ROUTE DETAILS HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching route details from WSF Schedule API\n *\n * Retrieves highly detailed information pertaining to routes for a given trip date.\n * If only a trip date is included, all routes available for that date of travel are returned.\n * This endpoint provides comprehensive route details including sailing times, vessel assignments,\n * and operational information.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param options - Optional React Query options\n * @returns React Query result object containing route details\n */\nexport const useRouteDetails = (\n  params: { tripDate: Date },\n  options?: TanStackOptions<Route[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"routeDetails\",\n      jsDateToYyyyMmDd(params.tripDate),\n    ],\n    queryFn: () => getRouteDetails({ tripDate: params.tripDate }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching route details by terminals from WSF Schedule API\n *\n * Retrieves highly detailed information pertaining to routes filtered by departing and\n * arriving terminals for a given trip date. Routes in the resultset are filtered to match\n * the specified terminal combination. Valid departing and arriving terminals may be found\n * using the terminalsAndMates endpoint.\n *\n * @param params - Object containing tripDate, departingTerminalId, arrivingTerminalId\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalId - The unique identifier for the departing terminal\n * @param params.arrivingTerminalId - The unique identifier for the arriving terminal\n * @param options - Optional React Query options\n * @returns React Query result object containing route details for the terminal combination\n */\nexport const useRouteDetailsByTerminals = (\n  params: {\n    tripDate: Date;\n    departingTerminalId: number;\n    arrivingTerminalId: number;\n  },\n  options?: TanStackOptions<Route[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"routeDetailsByTerminals\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.departingTerminalId,\n      params.arrivingTerminalId,\n    ],\n    queryFn: () =>\n      getRouteDetailsByTerminals({\n        tripDate: params.tripDate,\n        departingTerminalId: params.departingTerminalId,\n        arrivingTerminalId: params.arrivingTerminalId,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching route details by route from WSF Schedule API\n *\n * Retrieves highly detailed information for a specific route identified by route ID\n * for a given trip date. This endpoint filters the resultset to a single route,\n * providing comprehensive details for that specific route.\n *\n * @param params - Object containing tripDate and routeId\n * @param params.tripDate - The trip date as a Date object\n * @param params.routeId - The unique identifier for the route\n * @param options - Optional React Query options\n * @returns React Query result object containing route details for the specified route\n */\nexport const useRouteDetailsByRoute = (\n  params: { tripDate: Date; routeId: number },\n  options?: TanStackOptions<RouteDetails | null>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"routeDetailsByRoute\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.routeId,\n    ],\n    queryFn: () =>\n      getRouteDetailsByRoute({\n        tripDate: params.tripDate,\n        routeId: params.routeId,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// SEASONS HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching active seasons from WSF Schedule API\n *\n * Retrieves a summary of active seasons. This endpoint provides information about\n * current and upcoming ferry service seasons, which can be used to determine\n * valid schedule IDs for other endpoints.\n *\n * @param options - Optional React Query options\n * @returns React Query result object containing active seasons\n */\nexport const useActiveSeasons = (options?: TanStackOptions<ActiveSeason[]>) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"activeSeasons\"],\n    queryFn: () => getActiveSeasons(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// SCHEDULED ROUTES HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching scheduled routes from WSF Schedule API\n *\n * Provides a listing of routes that are active for a season. Results include all known\n * scheduled routes spanning current and upcoming seasons. For example, \"Anacortes / Sidney B.C.\"\n * may be a valid route, but if it's not scheduled to run during a specific season,\n * it won't be returned as part of that season's scheduled routes resultset.\n *\n * @param options - Optional React Query options\n * @returns React Query result object containing scheduled routes\n */\nexport const useScheduledRoutes = (\n  options?: TanStackOptions<ScheduledRoute[]>\n) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"scheduledRoutes\"],\n    queryFn: () => getScheduledRoutes(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching scheduled routes by season from WSF Schedule API\n *\n * Provides a listing of routes that are active for a specific season identified by schedule ID.\n * Results are filtered to only include scheduled routes for the specified season.\n * Seasons may be determined using the activeSeasons endpoint.\n *\n * @param params - Object containing scheduleId\n * @param params.scheduleId - The unique identifier for the season (schedule ID)\n * @param options - Optional React Query options\n * @returns React Query result object containing scheduled routes for the season\n */\nexport const useScheduledRoutesBySeason = (\n  params: { scheduleId: number },\n  options?: TanStackOptions<ScheduledRoute[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"scheduledRoutes\",\n      \"bySeason\",\n      params.scheduleId,\n    ],\n    queryFn: () =>\n      getScheduledRoutesBySeason({ scheduleId: params.scheduleId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// SAILINGS HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching sailings from WSF Schedule API\n *\n * Provides sailings for a particular scheduled route. Sailings are departure times\n * organized by direction of travel (eastbound / westbound), days of operation groups\n * (daily, weekday, weekend, etc) and, in some cases, date ranges (eg. Early Fall / Late Fall).\n * Sailings largely mimic the groupings of departures found on the printed PDF version of the schedule.\n * Scheduled routes may be determined using schedRoutes.\n *\n * @param params - Object containing schedRouteId\n * @param params.schedRouteId - The unique identifier for the scheduled route\n * @param options - Optional React Query options\n * @returns React Query result object containing sailings for the scheduled route\n */\nexport const useSailings = (\n  params: { schedRouteId: number },\n  options?: TanStackOptions<Sailing[]>\n) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"sailings\", params.schedRouteId],\n    queryFn: () => getSailings({ schedRouteId: params.schedRouteId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching all sailings from WSF Schedule API\n *\n * Provides all sailings for a particular scheduled route. Sailings are departure times\n * organized by direction of travel (eastbound / westbound), days of operation groups\n * (daily, weekday, weekend, etc) and, in some cases, date ranges (eg. Early Fall / Late Fall).\n * Sailings largely mimic the groupings of departures found on the printed PDF version of the schedule.\n * Scheduled routes may be determined using schedRoutes.\n *\n * @param params - Object containing schedRouteId\n * @param params.schedRouteId - The unique identifier for the scheduled route\n * @param options - Optional React Query options\n * @returns React Query result object containing all sailings for the scheduled route\n */\nexport const useAllSailings = (\n  params: { schedRouteId: number },\n  options?: TanStackOptions<Sailing[]>\n) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"allSailings\", params.schedRouteId],\n    queryFn: () => getAllSailings({ schedRouteId: params.schedRouteId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// TIME ADJUSTMENTS HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching time adjustments from WSF Schedule API\n *\n * Provides a listing of all additions and cancellations that deviate on specific dates\n * from the scheduled times found in the sailings resultset (eg. tidal cancellations\n * affecting Port Townsend departures on 9/9/2014).\n *\n * @param options - Optional React Query options\n * @returns React Query result object containing time adjustments\n */\nexport const useTimeAdjustments = (\n  options?: TanStackOptions<TimeAdjustment[]>\n) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"timeAdjustments\"],\n    queryFn: () => getTimeAdjustments(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching time adjustments by route from WSF Schedule API\n *\n * Provides a listing of all additions and cancellations for a route that deviate on\n * specific dates from the scheduled times found in the sailings resultset (eg. tidal\n * cancellations affecting Port Townsend departures on 9/9/2014). A valid route may\n * be determined using routes.\n *\n * @param params - Object containing routeId\n * @param params.routeId - The unique identifier for the route\n * @param options - Optional React Query options\n * @returns React Query result object containing time adjustments for the route\n */\nexport const useTimeAdjustmentsByRoute = (\n  params: { routeId: number },\n  options?: TanStackOptions<TimeAdjustment[]>\n) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"timeAdjustments\", \"byRoute\", params.routeId],\n    queryFn: () => getTimeAdjustmentsByRoute({ routeId: params.routeId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching time adjustments by scheduled route from WSF Schedule API\n *\n * Provides a listing of all additions and cancellations for a scheduled route that\n * deviate on specific dates from the scheduled times found in the sailings resultset\n * (eg. tidal cancellations affecting Port Townsend departures on 9/9/2014). A valid\n * scheduled route may be determined using schedRoutes.\n *\n * @param params - Object containing schedRouteId\n * @param params.schedRouteId - The unique identifier for the scheduled route\n * @param options - Optional React Query options\n * @returns React Query result object containing time adjustments for the scheduled route\n */\nexport const useTimeAdjustmentsBySchedRoute = (\n  params: { schedRouteId: number },\n  options?: TanStackOptions<TimeAdjustment[]>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"timeAdjustments\",\n      \"bySchedRoute\",\n      params.schedRouteId,\n    ],\n    queryFn: () =>\n      getTimeAdjustmentsBySchedRoute({ schedRouteId: params.schedRouteId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// SCHEDULE HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching schedule by route from WSF Schedule API\n *\n * Provides departure times for a trip date and route. The resultset accounts for all\n * contingencies, sailing date ranges and time adjustments. Valid routes may be found\n * using routes. Similarly, a valid trip date may be determined using validDateRange.\n *\n * @param params - Object containing tripDate and routeId\n * @param params.tripDate - The trip date as a Date object\n * @param params.routeId - The unique identifier for the route\n * @param options - Optional React Query options\n * @returns React Query result object containing schedule for the route\n */\nexport const useScheduleByRoute = (\n  params: { tripDate: Date; routeId: number },\n  options?: TanStackOptions<ScheduleResponse | null>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"scheduleByRoute\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.routeId,\n    ],\n    queryFn: () =>\n      getScheduleByRoute({\n        tripDate: params.tripDate,\n        routeId: params.routeId,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching schedule by terminals from WSF Schedule API\n *\n * Provides departure times for a trip date and terminal combination. The resultset\n * accounts for all contingencies, sailing date ranges and time adjustments. Valid\n * terminal combinations may be found using terminalsAndMates. Similarly, a valid trip date\n * may be determined using validDateRange.\n *\n * @param params - Object containing tripDate, departingTerminalId, and arrivingTerminalId\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalId - The unique identifier for the departing terminal\n * @param params.arrivingTerminalId - The unique identifier for the arriving terminal\n * @param options - Optional React Query options\n * @returns React Query result object containing schedule for the terminal combination\n */\nexport const useScheduleByTerminals = (\n  params: {\n    tripDate: Date;\n    departingTerminalId: number;\n    arrivingTerminalId: number;\n  },\n  options?: TanStackOptions<ScheduleResponse | null>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"scheduleByTerminals\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.departingTerminalId,\n      params.arrivingTerminalId,\n    ],\n    queryFn: () =>\n      getScheduleByTerminals({\n        tripDate: params.tripDate,\n        departingTerminalId: params.departingTerminalId,\n        arrivingTerminalId: params.arrivingTerminalId,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching today's schedule by route from WSF Schedule API\n *\n * Provides today's departure times for a route. Valid routes may be found using routes.\n * For the onlyRemainingTimes value, please indicate 'true' if departure times prior\n * to now should not be included in the resultset and 'false' if they should be included\n * in the resultset.\n *\n * @param params - Object containing routeId and onlyRemainingTimes\n * @param params.routeId - The unique identifier for the route\n * @param params.onlyRemainingTimes - Optional flag to return only remaining sailings for today\n * @param options - Optional React Query options\n * @returns React Query result object containing today's schedule for the route\n */\nexport const useScheduleTodayByRoute = (\n  params: { routeId: number; onlyRemainingTimes?: boolean },\n  options?: TanStackOptions<ScheduleResponse | null>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"scheduleTodayByRoute\",\n      params.routeId,\n      params.onlyRemainingTimes,\n    ],\n    queryFn: () =>\n      getScheduleTodayByRoute({\n        routeId: params.routeId,\n        onlyRemainingTimes: params.onlyRemainingTimes,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n/**\n * React Query hook for fetching today's schedule by terminals from WSF Schedule API\n *\n * Provides today's departure times for a terminal combination. Valid terminal combinations\n * may be found using terminalsAndMates. For the onlyRemainingTimes value, please indicate\n * 'true' if departure times prior to now should not be included in the resultset and\n * 'false' if they should be included in the resultset.\n *\n * @param params - Object containing departingTerminalId, arrivingTerminalId, and onlyRemainingTimes\n * @param params.departingTerminalId - The unique identifier for the departing terminal\n * @param params.arrivingTerminalId - The unique identifier for the arriving terminal\n * @param params.onlyRemainingTimes - Optional flag to return only remaining sailings for today\n * @param options - Optional React Query options\n * @returns React Query result object containing today's schedule for the terminal combination\n */\nexport const useScheduleTodayByTerminals = (\n  params: {\n    departingTerminalId: number;\n    arrivingTerminalId: number;\n    onlyRemainingTimes?: boolean;\n  },\n  options?: TanStackOptions<ScheduleResponse | null>\n) =>\n  useQuery({\n    queryKey: [\n      \"wsf\",\n      \"schedule\",\n      \"scheduleTodayByTerminals\",\n      params.departingTerminalId,\n      params.arrivingTerminalId,\n      params.onlyRemainingTimes,\n    ],\n    queryFn: () =>\n      getScheduleTodayByTerminals({\n        departingTerminalId: params.departingTerminalId,\n        arrivingTerminalId: params.arrivingTerminalId,\n        onlyRemainingTimes: params.onlyRemainingTimes,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// ALERTS HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching alerts from WSF Schedule API\n *\n * Provides alert information tailored for routes, bulletins, service disruptions, etc.\n * This endpoint returns important notifications and updates that may affect ferry service,\n * including weather-related delays, maintenance notices, and other operational alerts.\n *\n * @param options - Optional React Query options\n * @returns React Query result object containing alerts\n */\nexport const useAlerts = (options?: TanStackOptions<Alert[]>) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"alerts\"],\n    queryFn: () => getAlerts(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n\n// ============================================================================\n// ALTERNATIVE FORMATS HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching alternative formats from WSF Schedule API\n *\n * Retrieves alternative format data for a given subject name. This endpoint\n * provides access to different data formats and representations that may be\n * useful for various applications and use cases.\n *\n * @param params - Object containing subjectName\n * @param params.subjectName - The subject name for which to retrieve alternative formats\n * @param options - Optional React Query options\n * @returns React Query result object containing alternative formats\n */\nexport const useAlternativeFormats = (\n  params: { subjectName: string },\n  options?: TanStackOptions<AlternativeFormat[]>\n) =>\n  useQuery({\n    queryKey: [\"wsf\", \"schedule\", \"alternativeFormats\", params.subjectName],\n    queryFn: () => getAlternativeFormats({ subjectName: params.subjectName }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n","// Schedule Cache Provider Component\n// Monitors schedule cache flush dates and automatically invalidates schedule queries when data changes\n\nimport { CacheProvider } from \"@/shared/caching/CacheProvider\";\n\nimport { useCacheFlushDateSchedule } from \"./queries\";\n\n/**\n * Schedule Cache Provider Component\n *\n * This component monitors schedule cache flush dates and automatically\n * invalidates schedule queries when the cache flush date changes, indicating\n * that the underlying schedule data has been updated on the server.\n *\n * This component should be placed in your component tree where schedule data\n * is used, or at the root if schedule data is used throughout the app.\n */\nexport const ScheduleCacheProvider = () => {\n  return CacheProvider([\"schedule\"], useCacheFlushDateSchedule);\n};\n","// WSF Terminals API exports\n\nexport * from \"./api\";\nexport * from \"./cache\";\nexport * from \"./queries\";\nexport * from \"./schemas\";\n","import { z } from \"zod\";\n\nconst zNullableString = () => z.string().nullable();\nconst zNullableNumber = () => z.number().nullable();\nconst zNullableBoolean = () => z.boolean().nullable();\nconst zDate = () => z.date();\n\nexport const terminalBasicsSchema = z\n  .object({\n    TerminalID: z.number(),\n    TerminalSubjectID: z.number(),\n    RegionID: z.number(),\n    TerminalName: z.string(),\n    TerminalAbbrev: z.string(),\n    SortSeq: z.number(),\n    OverheadPassengerLoading: z.boolean(),\n    Elevator: z.boolean(),\n    WaitingRoom: z.boolean(),\n    FoodService: z.boolean(),\n    Restroom: z.boolean(),\n  })\n  .catchall(z.unknown());\n\nexport const terminalBulletinItemSchema = z\n  .object({\n    BulletinTitle: z.string(),\n    BulletinText: z.string(),\n    BulletinSortSeq: z.number(),\n    BulletinLastUpdated: zDate().optional(),\n    BulletinLastUpdatedSortable: z.string().optional(),\n  })\n  .catchall(z.unknown());\n\nexport const terminalBulletinSchema = z\n  .object({\n    TerminalID: z.number(),\n    TerminalSubjectID: z.number(),\n    RegionID: z.number(),\n    TerminalName: z.string(),\n    TerminalAbbrev: z.string(),\n    SortSeq: z.number(),\n    Bulletins: z.array(terminalBulletinItemSchema),\n  })\n  .catchall(z.unknown());\n\nexport const terminalLocationSchema = z\n  .object({\n    TerminalID: z.number(),\n    TerminalSubjectID: z.number(),\n    RegionID: z.number(),\n    TerminalName: z.string(),\n    TerminalAbbrev: z.string(),\n    SortSeq: z.number(),\n    AddressLineOne: z.string(),\n    AddressLineTwo: zNullableString(),\n    City: z.string(),\n    State: z.string(),\n    ZipCode: z.string(),\n    Country: z.string(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    Directions: zNullableString(),\n    DispGISZoomLoc: z.array(\n      z\n        .object({\n          Latitude: z.number(),\n          Longitude: z.number(),\n          ZoomLevel: z.number(),\n        })\n        .catchall(z.unknown())\n    ),\n    MapLink: zNullableString(),\n  })\n  .catchall(z.unknown());\n\nexport const terminalArrivalSpaceSchema = z\n  .object({\n    TerminalID: z.number(),\n    TerminalName: z.string(),\n    VesselID: z.number(),\n    VesselName: z.string(),\n    DisplayReservableSpace: z.boolean(),\n    ReservableSpaceCount: zNullableNumber(),\n    ReservableSpaceHexColor: zNullableString(),\n    DisplayDriveUpSpace: z.boolean(),\n    DriveUpSpaceCount: z.number(),\n    DriveUpSpaceHexColor: z.string(),\n    MaxSpaceCount: z.number(),\n    ArrivalTerminalIDs: z.array(z.number()),\n  })\n  .catchall(z.unknown());\n\nexport const terminalDepartingSpaceSchema = z\n  .object({\n    Departure: zDate(),\n    IsCancelled: z.boolean(),\n    VesselID: z.number(),\n    VesselName: z.string(),\n    MaxSpaceCount: z.number(),\n    SpaceForArrivalTerminals: z.array(terminalArrivalSpaceSchema),\n  })\n  .catchall(z.unknown());\n\nexport const terminalSailingSpaceSchema = z\n  .object({\n    TerminalID: z.number(),\n    TerminalSubjectID: z.number(),\n    RegionID: z.number(),\n    TerminalName: z.string(),\n    TerminalAbbrev: z.string(),\n    SortSeq: z.number(),\n    DepartingSpaces: z.array(terminalDepartingSpaceSchema),\n    IsNoFareCollected: zNullableBoolean(),\n    NoFareCollectedMsg: zNullableString(),\n  })\n  .catchall(z.unknown());\n\nexport const terminalTransitLinkSchema = z\n  .object({\n    LinkName: z.string(),\n    LinkURL: z.string(),\n    SortSeq: zNullableNumber(),\n  })\n  .catchall(z.unknown());\n\nexport const terminalTransportSchema = z\n  .object({\n    TerminalID: z.number(),\n    TerminalSubjectID: z.number(),\n    RegionID: z.number(),\n    TerminalName: z.string(),\n    TerminalAbbrev: z.string(),\n    SortSeq: z.number(),\n    ParkingInfo: z.string(),\n    ParkingShuttleInfo: zNullableString(),\n    AirportInfo: zNullableString(),\n    AirportShuttleInfo: zNullableString(),\n    MotorcycleInfo: z.string(),\n    TruckInfo: z.string(),\n    BikeInfo: zNullableString(),\n    TrainInfo: zNullableString(),\n    TaxiInfo: zNullableString(),\n    HovInfo: zNullableString(),\n    TransitLinks: z.array(terminalTransitLinkSchema),\n  })\n  .catchall(z.unknown());\n\nexport const terminalWaitTimeSchema = z\n  .object({\n    RouteID: zNullableNumber(),\n    RouteName: zNullableString(),\n    WaitTimeIVRNotes: zNullableString(),\n    WaitTimeLastUpdated: zDate(),\n    WaitTimeNotes: zNullableString(),\n  })\n  .catchall(z.unknown());\n\nexport const terminalWaitTimesSchema = z\n  .object({\n    TerminalID: z.number(),\n    TerminalSubjectID: z.number(),\n    RegionID: z.number(),\n    TerminalName: z.string(),\n    TerminalAbbrev: z.string(),\n    SortSeq: z.number(),\n    WaitTimes: z.array(terminalWaitTimeSchema),\n  })\n  .catchall(z.unknown());\n\nexport const terminalVerboseSchema = z\n  .object({\n    TerminalID: z.number(),\n    TerminalSubjectID: z.number(),\n    RegionID: z.number(),\n    TerminalName: z.string(),\n    TerminalAbbrev: z.string(),\n    SortSeq: z.number(),\n    AddressLineOne: z.string(),\n    AddressLineTwo: zNullableString(),\n    City: z.string(),\n    State: z.string(),\n    ZipCode: z.string(),\n    Country: z.string(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    Directions: zNullableString(),\n    DispGISZoomLoc: z.array(\n      z\n        .object({\n          Latitude: z.number(),\n          Longitude: z.number(),\n          ZoomLevel: z.number(),\n        })\n        .catchall(z.unknown())\n    ),\n    MapLink: zNullableString(),\n    Elevator: z.boolean(),\n    WaitingRoom: z.boolean(),\n    FoodService: z.boolean(),\n    Restroom: z.boolean(),\n    OverheadPassengerLoading: z.boolean(),\n    IsNoFareCollected: zNullableBoolean(),\n    NoFareCollectedMsg: zNullableString(),\n    AdaInfo: zNullableString(),\n    AdditionalInfo: zNullableString(),\n    AirportInfo: zNullableString(),\n    AirportShuttleInfo: zNullableString(),\n    BikeInfo: zNullableString(),\n    ChamberOfCommerce: terminalTransitLinkSchema.nullable(),\n    ConstructionInfo: zNullableString(),\n    FacInfo: zNullableString(),\n    FareDiscountInfo: zNullableString(),\n    FoodServiceInfo: zNullableString(),\n    HovInfo: zNullableString(),\n    LostAndFoundInfo: zNullableString(),\n    MotorcycleInfo: zNullableString(),\n    ParkingInfo: zNullableString(),\n    ParkingShuttleInfo: zNullableString(),\n    REALTIME_SHUTOFF_FLAG: z.boolean(),\n    REALTIME_SHUTOFF_MESSAGE: zNullableString(),\n    RealtimeIntroMsg: zNullableString(),\n    ResourceStatus: zNullableString(),\n    SecurityInfo: zNullableString(),\n    TallySystemInfo: zNullableString(),\n    TaxiInfo: zNullableString(),\n    TrainInfo: zNullableString(),\n    TruckInfo: zNullableString(),\n    TypeDesc: zNullableString(),\n    VisitorLinks: z.array(z.any()).nullable(),\n    Bulletins: z.array(terminalBulletinItemSchema),\n    TransitLinks: z.array(terminalTransitLinkSchema),\n    WaitTimes: z.array(terminalWaitTimeSchema),\n  })\n  .catchall(z.unknown());\n\nexport const terminalCacheFlushDateSchema = zDate().nullable();\n\n// Arrays\nexport const terminalBasicsArraySchema = z.array(terminalBasicsSchema);\nexport const terminalBulletinArraySchema = z.array(terminalBulletinSchema);\nexport const terminalLocationArraySchema = z.array(terminalLocationSchema);\nexport const terminalSailingSpaceArraySchema = z.array(\n  terminalSailingSpaceSchema\n);\nexport const terminalTransportArraySchema = z.array(terminalTransportSchema);\nexport const terminalWaitTimesArraySchema = z.array(terminalWaitTimesSchema);\nexport const terminalVerboseArraySchema = z.array(terminalVerboseSchema);\n\n// Types\nexport type TerminalBasics = z.infer<typeof terminalBasicsSchema>;\nexport type TerminalBulletinItem = z.infer<typeof terminalBulletinItemSchema>;\nexport type TerminalBulletin = z.infer<typeof terminalBulletinSchema>;\nexport type TerminalLocation = z.infer<typeof terminalLocationSchema>;\nexport type TerminalArrivalSpace = z.infer<typeof terminalArrivalSpaceSchema>;\nexport type TerminalDepartingSpace = z.infer<\n  typeof terminalDepartingSpaceSchema\n>;\nexport type TerminalSailingSpace = z.infer<typeof terminalSailingSpaceSchema>;\nexport type TerminalTransitLink = z.infer<typeof terminalTransitLinkSchema>;\nexport type TerminalTransport = z.infer<typeof terminalTransportSchema>;\nexport type TerminalWaitTime = z.infer<typeof terminalWaitTimeSchema>;\nexport type TerminalWaitTimes = z.infer<typeof terminalWaitTimesSchema>;\nexport type TerminalVerbose = z.infer<typeof terminalVerboseSchema>;\n","// WSF Terminals API functions\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type {\n  TerminalBasics,\n  TerminalBulletin,\n  TerminalLocation,\n  TerminalSailingSpace,\n  TerminalTransport,\n  TerminalVerbose,\n  TerminalWaitTimes,\n} from \"./schemas\";\nimport {\n  terminalBasicsArraySchema,\n  terminalBasicsSchema,\n  terminalBulletinArraySchema,\n  terminalBulletinSchema,\n  terminalCacheFlushDateSchema,\n  terminalLocationArraySchema,\n  terminalLocationSchema,\n  terminalSailingSpaceArraySchema,\n  terminalSailingSpaceSchema,\n  terminalTransportArraySchema,\n  terminalTransportSchema,\n  terminalVerboseArraySchema,\n  terminalVerboseSchema,\n  terminalWaitTimesArraySchema,\n} from \"./schemas\";\n\n// Create a factory function for WSF Terminals API\nconst createFetch = createFetchFactory(\"/ferries/api/terminals/rest\");\n\n// ============================================================================\n// TERMINAL BASICS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching all terminal basics from WSF Terminals API\n *\n * Retrieves the most basic/brief information pertaining to terminals.\n * This includes location, contact details, and basic status information.\n * Please consider using /cacheflushdate to coordinate the caching of this data.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TerminalBasics objects containing basic terminal information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const terminals = await getTerminalBasics();\n * console.log(terminals[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalBasics = async () => {\n  const fetcher = createFetch(\"/terminalbasics\");\n  const data = await fetcher();\n  return terminalBasicsArraySchema.parse(data) as TerminalBasics[];\n};\n\n/**\n * API function for fetching specific terminal basics from WSF Terminals API\n *\n * Retrieves the most basic/brief information for a specific terminal identified by terminal ID.\n * This includes location, contact details, and basic status information for the specified terminal.\n * Please consider using /cacheflushdate to coordinate the caching of this data.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a TerminalBasics object containing basic information for the specified terminal\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const terminal = await getTerminalBasicsByTerminalId({ terminalId: 7 });\n * console.log(terminal.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalBasicsByTerminalId = async (params: {\n  terminalId: number;\n}) => {\n  const fetcher = createFetch<{ terminalId: number }>(\n    \"/terminalbasics/{terminalId}\"\n  );\n  const data = await fetcher(params);\n  return terminalBasicsSchema.parse(data) as TerminalBasics;\n};\n\n// ============================================================================\n// TERMINAL LOCATIONS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching terminal locations from WSF Terminals API\n *\n * Retrieves location information for all terminals including coordinates,\n * addresses, and geographic data. This endpoint provides the physical\n * location details for all WSF terminals.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TerminalLocation objects containing terminal location information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const locations = await getTerminalLocations();\n * console.log(locations[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalLocations = async () => {\n  const fetcher = createFetch(\"/terminallocations\");\n  const data = await fetcher();\n  return terminalLocationArraySchema.parse(data) as TerminalLocation[];\n};\n\n/**\n * API function for fetching terminal location for a specific terminal from WSF Terminals API\n *\n * Retrieves location information for a specific terminal identified by terminal ID,\n * including coordinates, address, and geographic data. This endpoint filters the\n * resultset to a single terminal, providing the physical location details for\n * that specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TerminalLocation objects containing location information for the specified terminal\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const location = await getTerminalLocationsByTerminalId({ terminalId: 7 });\n * console.log(location.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalLocationsByTerminalId = async (params: {\n  terminalId: number;\n}) => {\n  const fetcher = createFetch<{ terminalId: number }>(\n    \"/terminallocations/{terminalId}\"\n  );\n  const data = await fetcher(params);\n  return terminalLocationSchema.parse(data) as TerminalLocation;\n};\n\n// ============================================================================\n// TERMINAL SAILING SPACE API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching terminal sailing space data from WSF Terminals API\n *\n * Retrieves sailing space information for all terminals including capacity,\n * availability, and space allocation data. This endpoint provides detailed\n * information about the sailing space configuration for all WSF terminals.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TerminalSailingSpace objects containing sailing space information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const sailingSpaces = await getTerminalSailingSpace();\n * console.log(sailingSpaces[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalSailingSpace = async () => {\n  const fetcher = createFetch(\"/terminalsailingspace\");\n  const data = await fetcher();\n  return terminalSailingSpaceArraySchema.parse(data) as TerminalSailingSpace[];\n};\n\n/**\n * API function for fetching terminal sailing space for a specific terminal from WSF Terminals API\n *\n * Retrieves sailing space information for a specific terminal identified by terminal ID,\n * including capacity, availability, and space allocation data. This endpoint filters the\n * resultset to a single terminal, providing detailed information about the sailing space\n * configuration for that specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a TerminalSailingSpace object containing sailing space information for the specified terminal\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const sailingSpace = await getTerminalSailingSpaceByTerminalId({ terminalId: 7 });\n * console.log(sailingSpace.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalSailingSpaceByTerminalId = async (params: {\n  terminalId: number;\n}) => {\n  const fetcher = createFetch<{ terminalId: number }>(\n    \"/terminalsailingspace/{terminalId}\"\n  );\n  const data = await fetcher(params);\n  return terminalSailingSpaceSchema.parse(data) as TerminalSailingSpace;\n};\n\n// ============================================================================\n// TERMINAL BULLETINS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching terminal bulletins from WSF Terminals API\n *\n * Retrieves bulletin information for all terminals including announcements,\n * notices, and important updates. This endpoint provides current bulletin\n * information for all WSF terminals.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TerminalBulletin objects containing bulletin information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const bulletins = await getTerminalBulletins();\n * console.log(bulletins[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalBulletins = async () => {\n  const fetcher = createFetch(\"/terminalbulletins\");\n  const data = await fetcher();\n  return terminalBulletinArraySchema.parse(data) as TerminalBulletin[];\n};\n\n/**\n * API function for fetching terminal bulletins for a specific terminal from WSF Terminals API\n *\n * Retrieves bulletin information for a specific terminal identified by terminal ID,\n * including announcements, notices, and important updates. This endpoint filters the\n * resultset to a single terminal, providing current bulletin information for that\n * specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a TerminalBulletin object containing bulletin information for the specified terminal\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const bulletin = await getTerminalBulletinsByTerminalId({ terminalId: 7 });\n * console.log(bulletin.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalBulletinsByTerminalId = async (params: {\n  terminalId: number;\n}) => {\n  const fetcher = createFetch<{ terminalId: number }>(\n    \"/terminalbulletins/{terminalId}\"\n  );\n  const data = await fetcher(params);\n  return terminalBulletinSchema.parse(data) as TerminalBulletin;\n};\n\n// ============================================================================\n// TERMINAL TRANSPORTS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching terminal transports from WSF Terminals API\n *\n * Retrieves transport information for all terminals including connections,\n * routes, and transportation options. This endpoint provides detailed\n * information about transportation connections for all WSF terminals.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TerminalTransport objects containing transport information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const transports = await getTerminalTransports();\n * console.log(transports[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalTransports = async () => {\n  const fetcher = createFetch(\"/terminaltransports\");\n  const data = await fetcher();\n  return terminalTransportArraySchema.parse(data) as TerminalTransport[];\n};\n\n/**\n * API function for fetching terminal transports for a specific terminal from WSF Terminals API\n *\n * Retrieves transport information for a specific terminal identified by terminal ID,\n * including connections, routes, and transportation options. This endpoint filters the\n * resultset to a single terminal, providing detailed information about transportation\n * connections for that specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a TerminalTransport object containing transport information for the specified terminal\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const transport = await getTerminalTransportsByTerminalId({ terminalId: 7 });\n * console.log(transport.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalTransportsByTerminalId = async (params: {\n  terminalId: number;\n}) => {\n  const fetcher = createFetch<{ terminalId: number }>(\n    \"/terminaltransports/{terminalId}\"\n  );\n  const data = await fetcher(params);\n  return terminalTransportSchema.parse(data) as TerminalTransport;\n};\n\n// ============================================================================\n// TERMINAL WAIT TIMES API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching terminal wait times from WSF Terminals API\n *\n * Retrieves wait time information for all terminals including current wait times,\n * estimated wait times, and wait time trends. This endpoint provides real-time\n * wait time data for all WSF terminals.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TerminalWaitTimes objects containing wait time information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const waitTimes = await getTerminalWaitTimes();\n * console.log(waitTimes[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalWaitTimes = async () => {\n  const fetcher = createFetch(\"/terminalwaittimes\");\n  const data = await fetcher();\n  return terminalWaitTimesArraySchema.parse(data) as TerminalWaitTimes[];\n};\n\n/**\n * API function for fetching terminal wait times for a specific terminal from WSF Terminals API\n *\n * Retrieves wait time information for a specific terminal identified by terminal ID,\n * including current wait times, estimated wait times, and wait time trends. This endpoint\n * filters the resultset to a single terminal, providing real-time wait time data for that\n * specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a TerminalWaitTimes object containing wait time information for the specified terminal\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const waitTime = await getTerminalWaitTimesByTerminalId({ terminalId: 7 });\n * console.log(waitTime.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalWaitTimesByTerminalId = async (params: {\n  terminalId: number;\n}) => {\n  const fetcher = createFetch<{ terminalId: number }>(\n    \"/terminalwaittimes/{terminalId}\"\n  );\n  const data = await fetcher(params);\n  return terminalCacheFlushDateSchema && terminalWaitTimesArraySchema.element\n    ? terminalWaitTimesArraySchema.element.parse(data)\n    : (data as TerminalWaitTimes);\n};\n\n// ============================================================================\n// TERMINAL VERBOSE API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching terminal verbose data from WSF Terminals API\n *\n * Retrieves comprehensive terminal information including all available data\n * for all terminals. This endpoint provides the most detailed information\n * available for all WSF terminals in a single call.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of TerminalVerbose objects containing comprehensive terminal information\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const terminals = await getTerminalVerbose();\n * console.log(terminals[0].TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalVerbose = async () => {\n  const fetcher = createFetch(\"/terminalverbose\");\n  const data = await fetcher();\n  return terminalVerboseArraySchema.parse(data) as TerminalVerbose[];\n};\n\n/**\n * API function for fetching terminal verbose data for a specific terminal from WSF Terminals API\n *\n * Retrieves comprehensive terminal information for a specific terminal identified by terminal ID,\n * including all available data. This endpoint filters the resultset to a single terminal,\n * providing the most detailed information available for that specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a TerminalVerbose object containing comprehensive terminal information for the specified terminal\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const terminal = await getTerminalVerboseByTerminalId({ terminalId: 7 });\n * console.log(terminal.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const getTerminalVerboseByTerminalId = async (params: {\n  terminalId: number;\n}) => {\n  const fetcher = createFetch<{ terminalId: number }>(\n    \"/terminalverbose/{terminalId}\"\n  );\n  const data = await fetcher(params);\n  return terminalVerboseSchema.parse(data) as TerminalVerbose;\n};\n\n// ============================================================================\n// CACHE FLUSH DATE API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching cache flush date from WSF Terminals API\n *\n * Retrieves the cache flush date for terminals data. This endpoint provides\n * information about when the terminals data was last updated, which can be\n * used to coordinate caching strategies.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to cache flush date\n * @throws {WsfApiError} When the API request fails\n *\n * @example\n * ```typescript\n * const flushDate = await getCacheFlushDateTerminals();\n * console.log(flushDate); // \"2024-01-15T10:30:00Z\"\n * ```\n */\nexport const getCacheFlushDateTerminals = async () => {\n  const fetcher = createFetch(\"/cacheflushdate\");\n  const data = await fetcher();\n  return terminalCacheFlushDateSchema.parse(data) as Date | null;\n};\n","// WSF Terminals hooks\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport {\n  // Cache Flush Date API functions\n  getCacheFlushDateTerminals,\n  // Terminal Basics API functions\n  getTerminalBasics,\n  getTerminalBasicsByTerminalId,\n  // Terminal Bulletins API functions\n  getTerminalBulletins,\n  getTerminalBulletinsByTerminalId,\n  // Terminal Locations API functions\n  getTerminalLocations,\n  getTerminalLocationsByTerminalId,\n  // Terminal Sailing Space API functions\n  getTerminalSailingSpace,\n  getTerminalSailingSpaceByTerminalId,\n  // Terminal Transports API functions\n  getTerminalTransports,\n  getTerminalTransportsByTerminalId,\n  // Terminal Verbose API functions\n  getTerminalVerbose,\n  getTerminalVerboseByTerminalId,\n  // Terminal Wait Times API functions\n  getTerminalWaitTimes,\n  getTerminalWaitTimesByTerminalId,\n} from \"./api\";\nimport type {\n  TerminalBasics,\n  TerminalBulletin,\n  TerminalLocation,\n  TerminalSailingSpace,\n  TerminalTransport,\n  TerminalVerbose,\n  TerminalWaitTimes,\n} from \"./schemas\";\n\n// ============================================================================\n// TERMINAL BASICS HOOKS\n// ============================================================================\n\n/**\n * React Query hook for fetching all terminal basics\n *\n * Retrieves the most basic/brief information pertaining to terminals.\n * This includes location, contact details, and basic status information.\n * Please consider using /cacheflushdate to coordinate the caching of this data.\n *\n * @param options - Optional React Query options\n * @returns Query result containing array of TerminalBasics objects\n *\n * @example\n * ```typescript\n * const { data: terminals } = useTerminalBasics();\n * console.log(terminals?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalBasics = (\n  options?: TanStackOptions<TerminalBasics[]>\n): UseQueryResult<TerminalBasics[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"basics\"],\n    queryFn: () => getTerminalBasics(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * React Query hook for fetching specific terminal basics by terminal ID\n *\n * Retrieves the most basic/brief information for a specific terminal identified by terminal ID.\n * This includes location, contact details, and basic status information for the specified terminal.\n * Please consider using /cacheflushdate to coordinate the caching of this data.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param options - Optional React Query options\n * @returns Query result containing TerminalBasics object for the specified terminal\n *\n * @example\n * ```typescript\n * const { data: terminal } = useTerminalBasicsByTerminalId({ terminalId: 7 });\n * console.log(terminal?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalBasicsByTerminalId = (\n  params: { terminalId: number },\n  options?: TanStackOptions<TerminalBasics>\n): UseQueryResult<TerminalBasics, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"basics\", \"byTerminalId\", params.terminalId],\n    queryFn: () =>\n      getTerminalBasicsByTerminalId({ terminalId: params.terminalId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// TERMINAL BULLETINS HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching terminal bulletins from WSF Terminals API\n *\n * Retrieves bulletin information for all terminals including announcements,\n * notices, and important updates. This endpoint provides current bulletin\n * information for all WSF terminals.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of TerminalBulletin objects with bulletin information\n *\n * @example\n * ```typescript\n * const { data: bulletins } = useTerminalBulletins();\n * console.log(bulletins?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalBulletins = (\n  options?: TanStackOptions<TerminalBulletin[]>\n): UseQueryResult<TerminalBulletin[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"bulletins\"],\n    queryFn: () => getTerminalBulletins(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching terminal bulletins for a specific terminal from WSF Terminals API\n *\n * Retrieves bulletin information for a specific terminal identified by terminal ID,\n * including announcements, notices, and important updates. This endpoint filters the\n * resultset to a single terminal, providing current bulletin information for that\n * specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param options - Optional React Query options\n * @returns React Query result containing a TerminalBulletin object with bulletin information for the specified terminal\n *\n * @example\n * ```typescript\n * const { data: bulletin } = useTerminalBulletinsByTerminalId({ terminalId: 7 });\n * console.log(bulletin?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalBulletinsByTerminalId = (\n  params: { terminalId: number },\n  options?: TanStackOptions<TerminalBulletin>\n): UseQueryResult<TerminalBulletin, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"terminals\",\n      \"bulletins\",\n      \"byTerminalId\",\n      params.terminalId,\n    ],\n    queryFn: () =>\n      getTerminalBulletinsByTerminalId({ terminalId: params.terminalId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// TERMINAL LOCATIONS HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching terminal locations from WSF Terminals API\n *\n * Retrieves location information for all terminals including coordinates,\n * addresses, and geographic data. This endpoint provides the physical\n * location details for all WSF terminals.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of TerminalLocation objects with terminal location information\n *\n * @example\n * ```typescript\n * const { data: locations } = useTerminalLocations();\n * console.log(locations?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalLocations = (\n  options?: TanStackOptions<TerminalLocation[]>\n): UseQueryResult<TerminalLocation[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"locations\"],\n    queryFn: () => getTerminalLocations(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching terminal location for a specific terminal from WSF Terminals API\n *\n * Retrieves location information for a specific terminal identified by terminal ID,\n * including coordinates, address, and geographic data. This endpoint filters the\n * resultset to a single terminal, providing the physical location details for\n * that specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param options - Optional React Query options\n * @returns React Query result containing an array of TerminalLocation objects with location information for the specified terminal\n *\n * @example\n * ```typescript\n * const { data: location } = useTerminalLocationsByTerminalId({ terminalId: 7 });\n * console.log(location?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalLocationsByTerminalId = (\n  params: { terminalId: number },\n  options?: TanStackOptions<TerminalLocation>\n): UseQueryResult<TerminalLocation, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"terminals\",\n      \"locations\",\n      \"byTerminalId\",\n      params.terminalId,\n    ],\n    queryFn: () =>\n      getTerminalLocationsByTerminalId({ terminalId: params.terminalId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// TERMINAL SAILING SPACE HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching terminal sailing space data from WSF Terminals API\n *\n * Retrieves current space availability information for all terminals including\n * vehicle capacity, wait times, and space status. This endpoint provides real-time\n * information about space availability at all WSF terminals, including current\n * vehicle capacity, estimated wait times, and space status for upcoming sailings.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of TerminalSailingSpace objects with real-time space availability information\n *\n * @example\n * ```typescript\n * const { data: sailingSpaces } = useTerminalSailingSpace();\n * console.log(sailingSpaces?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalSailingSpace = (\n  options?: TanStackOptions<TerminalSailingSpace[]>\n): UseQueryResult<TerminalSailingSpace[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"sailing-space\"],\n    queryFn: () => getTerminalSailingSpace(),\n    ...tanstackQueryOptions.REALTIME_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching terminal sailing space data for a specific terminal from WSF Terminals API\n *\n * Retrieves current space availability information for a specific terminal identified by terminal ID,\n * including vehicle capacity, wait times, and space status. This endpoint filters the resultset\n * to a single terminal, providing real-time information about space availability at that specific\n * terminal, including current vehicle capacity, estimated wait times, and space status for upcoming sailings.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param options - Optional React Query options\n * @returns React Query result containing a TerminalSailingSpace object with real-time space availability information for the specified terminal\n *\n * @example\n * ```typescript\n * const { data: sailingSpace } = useTerminalSailingSpaceByTerminalId({ terminalId: 7 });\n * console.log(sailingSpace?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalSailingSpaceByTerminalId = (\n  params: { terminalId: number },\n  options?: TanStackOptions<TerminalSailingSpace>\n): UseQueryResult<TerminalSailingSpace, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"terminals\",\n      \"sailingSpace\",\n      \"byTerminalId\",\n      params.terminalId,\n    ],\n    queryFn: () =>\n      getTerminalSailingSpaceByTerminalId({ terminalId: params.terminalId }),\n    ...tanstackQueryOptions.REALTIME_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// TERMINAL TRANSPORTS HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching terminal transports from WSF Terminals API\n *\n * Retrieves transport information for all terminals including connections,\n * routes, and transportation options. This endpoint provides detailed\n * information about transportation connections for all WSF terminals.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of TerminalTransport objects with transport information\n *\n * @example\n * ```typescript\n * const { data: transports } = useTerminalTransports();\n * console.log(transports?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalTransports = (\n  options?: TanStackOptions<TerminalTransport[]>\n): UseQueryResult<TerminalTransport[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"transports\"],\n    queryFn: () => getTerminalTransports(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching terminal transports for a specific terminal from WSF Terminals API\n *\n * Retrieves transport information for a specific terminal identified by terminal ID,\n * including connections, routes, and transportation options. This endpoint filters the\n * resultset to a single terminal, providing detailed information about transportation\n * connections for that specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param options - Optional React Query options\n * @returns React Query result containing a TerminalTransport object with transport information for the specified terminal\n *\n * @example\n * ```typescript\n * const { data: transport } = useTerminalTransportsByTerminalId({ terminalId: 7 });\n * console.log(transport?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalTransportsByTerminalId = (\n  params: { terminalId: number },\n  options?: TanStackOptions<TerminalTransport>\n): UseQueryResult<TerminalTransport, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"terminals\",\n      \"transports\",\n      \"byTerminalId\",\n      params.terminalId,\n    ],\n    queryFn: () =>\n      getTerminalTransportsByTerminalId({ terminalId: params.terminalId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// TERMINAL WAIT TIMES HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching terminal wait times from WSF Terminals API\n *\n * Retrieves wait time information for all terminals including current wait times,\n * estimated wait times, and wait time trends. This endpoint provides real-time\n * wait time data for all WSF terminals.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of TerminalWaitTimes objects with wait time information\n *\n * @example\n * ```typescript\n * const { data: waitTimes } = useTerminalWaitTimes();\n * console.log(waitTimes?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalWaitTimes = (\n  options?: TanStackOptions<TerminalWaitTimes[]>\n): UseQueryResult<TerminalWaitTimes[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"wait-times\"],\n    queryFn: () => getTerminalWaitTimes(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching terminal wait times for a specific terminal from WSF Terminals API\n *\n * Retrieves wait time information for a specific terminal identified by terminal ID,\n * including current wait times, estimated wait times, and wait time trends. This endpoint\n * filters the resultset to a single terminal, providing real-time wait time data for that\n * specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param options - Optional React Query options\n * @returns React Query result containing a TerminalWaitTimes object with wait time information for the specified terminal\n *\n * @example\n * ```typescript\n * const { data: waitTime } = useTerminalWaitTimesByTerminalId({ terminalId: 7 });\n * console.log(waitTime?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalWaitTimesByTerminalId = (\n  params: { terminalId: number },\n  options?: TanStackOptions<TerminalWaitTimes>\n): UseQueryResult<TerminalWaitTimes, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"terminals\",\n      \"wait-times\",\n      \"byTerminalId\",\n      params.terminalId,\n    ],\n    queryFn: () =>\n      getTerminalWaitTimesByTerminalId({ terminalId: params.terminalId }),\n    ...tanstackQueryOptions.REALTIME_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// TERMINAL VERBOSE HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching terminal verbose data from WSF Terminals API\n *\n * Retrieves comprehensive terminal information including all available data\n * for all terminals. This endpoint provides the most detailed information\n * available for all WSF terminals in a single call.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of TerminalVerbose objects with comprehensive terminal information\n *\n * @example\n * ```typescript\n * const { data: terminals } = useTerminalVerbose();\n * console.log(terminals?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalVerbose = (\n  options?: TanStackOptions<TerminalVerbose[]>\n): UseQueryResult<TerminalVerbose[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"verbose\"],\n    queryFn: () => getTerminalVerbose(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching terminal verbose data for a specific terminal from WSF Terminals API\n *\n * Retrieves comprehensive terminal information for a specific terminal identified by terminal ID,\n * including all available data. This endpoint filters the resultset to a single terminal,\n * providing the most detailed information available for that specific terminal.\n *\n * @param params - Object containing terminalId\n * @param params.terminalId - The unique identifier for the terminal (e.g., 7 for Anacortes, 8 for Friday Harbor)\n * @param options - Optional React Query options\n * @returns React Query result containing a TerminalVerbose object with comprehensive terminal information for the specified terminal\n *\n * @example\n * ```typescript\n * const { data: terminal } = useTerminalVerboseByTerminalId({ terminalId: 7 });\n * console.log(terminal?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useTerminalVerboseByTerminalId = (\n  params: { terminalId: number },\n  options?: TanStackOptions<TerminalVerbose>\n): UseQueryResult<TerminalVerbose, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"terminals\",\n      \"verbose\",\n      \"byTerminalId\",\n      params.terminalId,\n    ],\n    queryFn: () =>\n      getTerminalVerboseByTerminalId({ terminalId: params.terminalId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// CACHE FLUSH DATE HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching cache flush date from WSF Terminals API\n *\n * Retrieves the cache flush date for terminals data. This endpoint provides\n * information about when the terminals data was last updated, which can be\n * used to coordinate caching strategies.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing cache flush date\n *\n * @example\n * ```typescript\n * const { data: flushDate } = useCacheFlushDateTerminals();\n * console.log(flushDate); // \"2024-01-15T10:00:00Z\"\n * ```\n */\nexport const useCacheFlushDateTerminals = (\n  options?: TanStackOptions<Date | null>\n) =>\n  useQuery({\n    queryKey: [\"wsf\", \"terminals\", \"cache-flush-date\"],\n    queryFn: () => getCacheFlushDateTerminals(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n","// Terminal Cache Provider Component\n// Monitors terminal cache flush dates and automatically invalidates terminal queries when data changes\n\nimport { CacheProvider } from \"@/shared/caching/CacheProvider\";\n\nimport { useCacheFlushDateTerminals } from \"./queries\";\n\n/**\n * Terminal Cache Provider Component\n *\n * This component monitors terminal cache flush dates and automatically\n * invalidates terminal queries when the cache flush date changes, indicating\n * that the underlying terminal data has been updated on the server.\n *\n * This component should be placed in your component tree where terminal data\n * is used, or at the root if terminal data is used throughout the app.\n */\nexport const TerminalCacheProvider = () => {\n  return CacheProvider([\"terminals\"], useCacheFlushDateTerminals);\n};\n","export * from \"./api\";\nexport * from \"./cache\";\nexport * from \"./queries\";\nexport * from \"./schemas\";\n","import { z } from \"zod\";\n\nconst zDate = () => z.date();\nconst zNullableDate = () => z.date().nullable();\nconst zNullableString = () => z.string().nullable();\nconst zNullableNumber = () => z.number().nullable();\n\nexport const vesselClassSchema = z\n  .object({\n    ClassID: z.number(),\n    ClassSubjectID: z.number(),\n    ClassName: z.string(),\n    SortSeq: z.number(),\n    DrawingImg: z.string(),\n    SilhouetteImg: z.string(),\n    PublicDisplayName: z.string(),\n  })\n  .catchall(z.unknown());\n\nexport const vesselBasicSchema = z\n  .object({\n    VesselID: z.number(),\n    VesselSubjectID: z.number(),\n    VesselName: z.string(),\n    VesselAbbrev: z.string(),\n    Class: vesselClassSchema,\n    Status: z.number(),\n    OwnedByWSF: z.boolean(),\n  })\n  .catchall(z.unknown());\n\nexport const vesselAccommodationSchema = z\n  .object({\n    VesselID: z.number(),\n    VesselSubjectID: z.number(),\n    VesselName: z.string(),\n    VesselAbbrev: z.string(),\n    Class: vesselClassSchema,\n    CarDeckRestroom: z.boolean(),\n    CarDeckShelter: z.boolean(),\n    Elevator: z.boolean(),\n    ADAAccessible: z.boolean(),\n    MainCabinGalley: z.boolean(),\n    MainCabinRestroom: z.boolean(),\n    PublicWifi: z.boolean(),\n    ADAInfo: z.string(),\n    AdditionalInfo: zNullableString(),\n  })\n  .catchall(z.unknown());\n\nexport const vesselStatsSchema = z\n  .object({\n    VesselID: z.number(),\n    VesselSubjectID: z.number(),\n    VesselName: z.string(),\n    VesselAbbrev: z.string(),\n    Class: vesselClassSchema,\n    VesselNameDesc: z.string(),\n    VesselHistory: zNullableString(),\n    Beam: z.string(),\n    CityBuilt: z.string(),\n    SpeedInKnots: z.number(),\n    Draft: z.string(),\n    EngineCount: z.number(),\n    Horsepower: z.number(),\n    Length: z.string(),\n    MaxPassengerCount: z.number(),\n    PassengerOnly: z.boolean(),\n    FastFerry: z.boolean(),\n    PropulsionInfo: z.string(),\n    TallDeckClearance: z.number(),\n    RegDeckSpace: z.number(),\n    TallDeckSpace: z.number(),\n    Tonnage: z.number(),\n    Displacement: z.number(),\n    YearBuilt: z.number(),\n    YearRebuilt: zNullableNumber(),\n    VesselDrawingImg: zNullableString(),\n    SolasCertified: z.boolean(),\n    MaxPassengerCountForInternational: zNullableNumber(),\n  })\n  .catchall(z.unknown());\n\nexport const vesselHistorySchema = z\n  .object({\n    VesselId: z.number(),\n    Vessel: z.string(),\n    Departing: zNullableString(),\n    Arriving: zNullableString(),\n    ScheduledDepart: zNullableDate(),\n    ActualDepart: zNullableDate(),\n    EstArrival: zNullableDate(),\n    Date: zNullableDate(),\n  })\n  .catchall(z.unknown());\n\nexport const vesselLocationSchema = z\n  .object({\n    VesselID: z.number(),\n    VesselName: z.string(),\n    Mmsi: z.number(),\n    DepartingTerminalID: z.number(),\n    DepartingTerminalName: z.string(),\n    DepartingTerminalAbbrev: z.string(),\n    ArrivingTerminalID: zNullableNumber(),\n    ArrivingTerminalName: zNullableString(),\n    ArrivingTerminalAbbrev: zNullableString(),\n    Latitude: z.number(),\n    Longitude: z.number(),\n    Speed: z.number(),\n    Heading: z.number(),\n    InService: z.boolean(),\n    AtDock: z.boolean(),\n    LeftDock: zNullableDate(),\n    Eta: zNullableDate(),\n    EtaBasis: zNullableString(),\n    ScheduledDeparture: zNullableDate(),\n    OpRouteAbbrev: z.array(z.string()),\n    VesselPositionNum: zNullableNumber(),\n    SortSeq: z.number(),\n    ManagedBy: z.number(),\n    TimeStamp: zDate(),\n  })\n  .catchall(z.unknown());\n\nexport const vesselVerboseSchema = z\n  .object({\n    VesselID: z.number(),\n    VesselName: z.string(),\n    VesselAbbrev: z.string(),\n    Class: vesselClassSchema,\n    Status: z.number(),\n    OwnedByWSF: z.boolean(),\n    YearBuilt: z.number(),\n    Displacement: z.number(),\n    Length: z.string(),\n    Beam: z.string(),\n    Draft: z.string(),\n    SpeedInKnots: z.number(),\n    EngineCount: z.number(),\n    Horsepower: z.number(),\n    MaxPassengerCount: z.number(),\n    RegDeckSpace: z.number(),\n    TallDeckSpace: z.number(),\n    Tonnage: z.number(),\n    PropulsionInfo: z.string(),\n    ADAAccessible: z.boolean(),\n    Elevator: z.boolean(),\n    CarDeckRestroom: z.boolean(),\n    MainCabinGalley: z.boolean(),\n    MainCabinRestroom: z.boolean(),\n    PublicWifi: z.boolean(),\n    ADAInfo: z.string(),\n    VesselNameDesc: z.string(),\n    VesselHistory: zNullableString(),\n    CityBuilt: z.string(),\n    YearRebuilt: zNullableNumber(),\n  })\n  .catchall(z.unknown());\n\nexport const vesselsCacheFlushDateSchema = zDate();\n\n// Arrays\nexport const vesselBasicArraySchema = z.array(vesselBasicSchema);\nexport const vesselAccommodationArraySchema = z.array(\n  vesselAccommodationSchema\n);\nexport const vesselStatsArraySchema = z.array(vesselStatsSchema);\nexport const vesselHistoryArraySchema = z.array(vesselHistorySchema);\nexport const vesselLocationArraySchema = z.array(vesselLocationSchema);\nexport const vesselVerboseArraySchema = z.array(vesselVerboseSchema);\n\n// Types\nexport type VesselClass = z.infer<typeof vesselClassSchema>;\nexport type VesselBasic = z.infer<typeof vesselBasicSchema>;\nexport type VesselAccommodation = z.infer<typeof vesselAccommodationSchema>;\nexport type VesselStats = z.infer<typeof vesselStatsSchema>;\nexport type VesselHistory = z.infer<typeof vesselHistorySchema>;\nexport type VesselLocation = z.infer<typeof vesselLocationSchema>;\nexport type VesselVerbose = z.infer<typeof vesselVerboseSchema>;\nexport type VesselsCacheFlushDate = z.infer<typeof vesselsCacheFlushDateSchema>;\n","// WSF Vessels API functions\n// Documentation: https://www.wsdot.wa.gov/ferries/api/vessels/documentation/rest.html\n// API Help: https://www.wsdot.wa.gov/ferries/api/vessels/rest/help\n\nimport { createFetchFactory } from \"@/shared/fetching/api\";\n\nimport type {\n  VesselAccommodation,\n  VesselBasic,\n  VesselHistory,\n  VesselLocation,\n  VesselStats,\n  VesselsCacheFlushDate,\n  VesselVerbose,\n} from \"./schemas\";\nimport {\n  vesselAccommodationArraySchema,\n  vesselAccommodationSchema,\n  vesselBasicArraySchema,\n  vesselBasicSchema,\n  vesselHistoryArraySchema,\n  vesselLocationArraySchema,\n  vesselLocationSchema,\n  vesselStatsArraySchema,\n  vesselStatsSchema,\n  vesselsCacheFlushDateSchema,\n  vesselVerboseArraySchema,\n  vesselVerboseSchema,\n} from \"./schemas\";\n\n// Create a factory function for WSF Vessels API\nconst createFetch = createFetchFactory(\"/ferries/api/vessels/rest\");\n\n// ============================================================================\n// VESSEL BASICS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching vessel basics from WSF Vessels API\n *\n * Retrieves basic vessel information including vessel names, abbreviations,\n * class information, and operational status. This endpoint provides fundamental\n * vessel details for all vessels in the WSF fleet.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of VesselBasic objects containing basic vessel information\n *\n * @example\n * ```typescript\n * const vessels = await getVesselBasics();\n * console.log(vessels[0].VesselName); // \"M/V Cathlamet\"\n * ```\n */\nexport const getVesselBasics = async () => {\n  const fetcher = createFetch(\"/vesselbasics\");\n  const data = await fetcher();\n  return vesselBasicArraySchema.parse(data) as VesselBasic[];\n};\n\n/**\n * API function for fetching vessel basics for a specific vessel from WSF Vessels API\n *\n * Retrieves basic vessel information for a specific vessel identified by vessel ID,\n * including vessel name, abbreviation, class information, and operational status.\n *\n * @param params - Object containing vesselId and optional logMode\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a VesselBasic object containing basic information for the specified vessel\n *\n * @example\n * ```typescript\n * const vessel = await getVesselBasicsById({ vesselId: 1 });\n * console.log(vessel.VesselName); // \"M/V Cathlamet\"\n * ```\n */\nexport const getVesselBasicsById = async (params: { vesselId: number }) => {\n  const fetcher = createFetch<{ vesselId: number }>(\"/vesselbasics/{vesselId}\");\n  const data = await fetcher(params);\n  return vesselBasicSchema.parse(data) as VesselBasic;\n};\n\n// ============================================================================\n// VESSEL LOCATIONS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching current vessel location data from WSF Vessels API\n *\n * Retrieves real-time vessel positions, speeds, headings, and status information\n * from the Washington State Ferries API. This endpoint provides current location\n * data for all active vessels in the WSF fleet, including GPS coordinates,\n * vessel speed, heading direction, and operational status.\n *\n * The data is updated frequently and provides the most current information\n * about vessel locations for tracking and monitoring purposes.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of VesselLocation objects containing real-time vessel position data\n *\n * @example\n * ```typescript\n * const locations = await getVesselLocations();\n * console.log(locations[0].VesselName); // \"M/V Cathlamet\"\n * ```\n */\nexport const getVesselLocations = async () => {\n  const fetcher = createFetch(\"/vessellocations\");\n  const data = await fetcher();\n  return vesselLocationArraySchema.parse(data) as VesselLocation[];\n};\n\n/**\n * API function for fetching current vessel location data for a specific vessel from WSF Vessels API\n *\n * Retrieves real-time vessel position, speed, heading, and status information\n * for a specific vessel identified by vessel ID. This endpoint returns a single vessel object.\n *\n * @param params - Object containing vesselId and optional logMode\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a VesselLocation object containing real-time position data for the specified vessel\n */\nexport const getVesselLocationsByVesselId = async (params: {\n  vesselId: number;\n}) => {\n  const fetcher = createFetch<{ vesselId: number }>(\n    \"/vessellocations/{vesselId}\"\n  );\n  const data = await fetcher(params);\n  return vesselLocationSchema.parse(data) as VesselLocation;\n};\n\n// ============================================================================\n// VESSEL ACCOMMODATIONS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching vessel accommodation data from WSF Vessels API\n *\n * Retrieves detailed accommodation information for all vessels in the WSF fleet,\n * including passenger capacity, vehicle capacity, and other accommodation details.\n * This endpoint provides comprehensive information about the capacity and\n * accommodation features of each vessel.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of VesselAccommodation objects containing accommodation information\n */\nexport const getVesselAccommodations = async () => {\n  const fetcher = createFetch(\"/vesselaccommodations\");\n  const data = await fetcher();\n  return vesselAccommodationArraySchema.parse(data) as VesselAccommodation[];\n};\n\n/**\n * API function for fetching vessel accommodation data for a specific vessel from WSF Vessels API\n *\n * Retrieves detailed accommodation information for a specific vessel identified by vessel ID,\n * including passenger capacity, vehicle capacity, and other accommodation details.\n *\n * @param params - Object containing vesselId and optional logMode\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a VesselAccommodation object containing accommodation information for the specified vessel\n */\nexport const getVesselAccommodationsById = async (params: {\n  vesselId: number;\n}) => {\n  const fetcher = createFetch<{ vesselId: number }>(\n    \"/vesselaccommodations/{vesselId}\"\n  );\n  const data = await fetcher(params);\n  return vesselAccommodationSchema.parse(data) as VesselAccommodation;\n};\n\n// ============================================================================\n// VESSEL STATS API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching vessel statistics from WSF Vessels API\n *\n * Retrieves statistical information for all vessels in the WSF fleet,\n * including operational statistics, performance metrics, and other relevant data.\n * This endpoint provides comprehensive statistical information about vessel operations.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of VesselStats objects containing vessel statistics\n */\nexport const getVesselStats = async () => {\n  const fetcher = createFetch(\"/vesselstats\");\n  const data = await fetcher();\n  return vesselStatsArraySchema.parse(data) as VesselStats[];\n};\n\n/**\n * API function for fetching vessel statistics for a specific vessel from WSF Vessels API\n *\n * Retrieves statistical information for a specific vessel identified by vessel ID,\n * including operational statistics, performance metrics, and other relevant data.\n *\n * @param params - Object containing vesselId and optional logMode\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a VesselStats object containing statistics for the specified vessel\n */\nexport const getVesselStatsById = async (params: { vesselId: number }) => {\n  const fetcher = createFetch<{ vesselId: number }>(\"/vesselstats/{vesselId}\");\n  const data = await fetcher(params);\n  return vesselStatsSchema.parse(data) as VesselStats;\n};\n\n// ============================================================================\n// VESSEL HISTORY API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching vessel history data for a specific vessel and date range from WSF Vessels API\n *\n * Retrieves historical vessel data for a specific vessel within a specified date range,\n * including past routes, schedules, and operational history for that vessel.\n *\n * @param params - Object containing vesselName, dateStart, dateEnd, and optional logMode\n * @param params.vesselName - The name of the vessel (e.g., \"M/V Cathlamet\")\n * @param params.dateStart - The start date for the history range\n * @param params.dateEnd - The end date for the history range\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of VesselHistory objects containing historical data for the specified vessel and date range\n */\nexport const getVesselHistoryByVesselAndDateRange = async (params: {\n  vesselName: string;\n  dateStart: Date;\n  dateEnd: Date;\n}) => {\n  const fetcher = createFetch<{\n    vesselName: string;\n    dateStart: Date;\n    dateEnd: Date;\n  }>(\"/vesselhistory/{vesselName}/{dateStart}/{dateEnd}\");\n  const data = await fetcher(params);\n  return vesselHistoryArraySchema.parse(data) as VesselHistory[];\n};\n\n/**\n * Helper function for fetching vessel history data for multiple vessels and date range\n *\n * This function fetches historical data for multiple vessels by making parallel API calls\n * to the vessel history endpoint for each vessel. This is useful when you need historical\n * data for multiple vessels over the same time period.\n *\n * @param params - Object containing vesselNames, dateStart, dateEnd, and optional batchSize\n * @param params.vesselNames - Array of vessel names to fetch history for (e.g., [\"Spokane\", \"Walla Walla\"])\n * @param params.dateStart - The start date for the history range\n * @param params.dateEnd - The end date for the history range\n * @param params.batchSize - Optional batch size for processing requests (default: 6)\n * @returns Promise resolving to an array of VesselHistory objects containing historical data for all specified vessels\n *\n * @example\n * ```typescript\n * const history = await getMultipleVesselHistories({\n *   vesselNames: [\"Spokane\", \"Walla Walla\"],\n *   dateStart: new Date(\"2024-01-01\"),\n *   dateEnd: new Date(\"2024-01-02\")\n * });\n * console.log(history.length); // Total number of history records for all vessels\n * ```\n */\nexport const getMultipleVesselHistories = async (params: {\n  vesselNames: string[];\n  dateStart: Date;\n  dateEnd: Date;\n  batchSize?: number;\n}): Promise<VesselHistory[]> => {\n  const { vesselNames, dateStart, dateEnd, batchSize = 6 } = params;\n  const results: VesselHistory[] = [];\n\n  // Process in batches to avoid overwhelming the server and browser connection limits\n  for (let i = 0; i < vesselNames.length; i += batchSize) {\n    const batch = vesselNames.slice(i, i + batchSize);\n    const batchPromises = batch.map((vesselName) =>\n      getVesselHistoryByVesselAndDateRange({\n        vesselName,\n        dateStart,\n        dateEnd,\n      })\n    );\n\n    const batchResults = await Promise.all(batchPromises);\n    results.push(...batchResults.flat());\n  }\n\n  return results;\n};\n\n/**\n * Helper function for fetching vessel history data for all vessels in the WSF fleet\n *\n * This function fetches historical data for all 21 vessels in the Washington State Ferries fleet\n * by making batched API calls to the vessel history endpoint. This provides comprehensive\n * historical data for the entire fleet over a specified time period.\n *\n * @param params - Object containing dateStart, dateEnd, and optional batchSize\n * @param params.dateStart - The start date for the history range\n * @param params.dateEnd - The end date for the history range\n * @param params.batchSize - Optional batch size for processing requests (default: 6)\n * @returns Promise resolving to an array of VesselHistory objects containing historical data for all vessels\n *\n * @example\n * ```typescript\n * const allHistory = await getAllVesselHistories({\n *   dateStart: new Date(\"2024-01-01\"),\n *   dateEnd: new Date(\"2024-01-02\")\n * });\n * console.log(allHistory.length); // Total number of history records for all 21 vessels\n * ```\n */\nexport const getAllVesselHistories = async (params: {\n  dateStart: Date;\n  dateEnd: Date;\n  batchSize?: number;\n}): Promise<VesselHistory[]> => {\n  // All vessels in the WSF fleet (as of 2024)\n  const allVesselNames = [\n    \"Cathlamet\",\n    \"Chelan\",\n    \"Chetzemoka\",\n    \"Chimacum\",\n    \"Issaquah\",\n    \"Kaleetan\",\n    \"Kennewick\",\n    \"Kitsap\",\n    \"Kittitas\",\n    \"Puyallup\",\n    \"Salish\",\n    \"Samish\",\n    \"Sealth\",\n    \"Spokane\",\n    \"Suquamish\",\n    \"Tacoma\",\n    \"Tillikum\",\n    \"Tokitae\",\n    \"Walla Walla\",\n    \"Wenatchee\",\n    \"Yakima\",\n  ];\n\n  return getMultipleVesselHistories({\n    vesselNames: allVesselNames,\n    dateStart: params.dateStart,\n    dateEnd: params.dateEnd,\n    batchSize: params.batchSize,\n  });\n};\n\n// ============================================================================\n// VESSEL VERBOSE API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching verbose vessel data from WSF Vessels API\n *\n * Retrieves comprehensive vessel information for all vessels in the WSF fleet,\n * including detailed specifications, operational data, and extended information.\n * This endpoint provides the most complete vessel information available.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to an array of VesselVerbose objects containing comprehensive vessel information\n */\nexport const getVesselVerbose = async () => {\n  const fetcher = createFetch(\"/vesselverbose\");\n  const data = await fetcher();\n  return vesselVerboseArraySchema.parse(data) as VesselVerbose[];\n};\n\n/**\n * API function for fetching verbose vessel data for a specific vessel from WSF Vessels API\n *\n * Retrieves comprehensive vessel information for a specific vessel identified by vessel ID,\n * including detailed specifications, operational data, and extended information.\n *\n * @param params - Object containing vesselId and optional logMode\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param params.logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a VesselVerbose object containing comprehensive information for the specified vessel\n */\nexport const getVesselVerboseById = async (params: { vesselId: number }) => {\n  const fetcher = createFetch<{ vesselId: number }>(\n    \"/vesselverbose/{vesselId}\"\n  );\n  const data = await fetcher(params);\n  return vesselVerboseSchema.parse(data) as VesselVerbose;\n};\n\n// ============================================================================\n// CACHE FLUSH DATE API FUNCTIONS\n// ============================================================================\n\n/**\n * API function for fetching cache flush date from WSF Vessels API\n *\n * Retrieves the cache flush date for the vessels API, which indicates when\n * the cached data was last updated. This information is useful for determining\n * the freshness of the cached vessel data.\n *\n * @param logMode - Optional logging mode for debugging API calls\n * @returns Promise resolving to a VesselsCacheFlushDate object containing the cache flush date\n */\nexport const getCacheFlushDateVessels = async () => {\n  const fetcher = createFetch(\"/cacheflushdate\");\n  const data = await fetcher();\n  return vesselsCacheFlushDateSchema.parse(data) as VesselsCacheFlushDate;\n};\n","// WSF Vessels hooks\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport type { TanStackOptions } from \"@/shared/types\";\n\nimport {\n  getAllVesselHistories,\n  // Cache Flush Date API functions\n  getCacheFlushDateVessels,\n  // Multiple Vessel History API functions\n  getMultipleVesselHistories,\n  // Vessel Accommodations API functions\n  getVesselAccommodations,\n  getVesselAccommodationsById,\n  // Vessel Basics API functions\n  getVesselBasics,\n  getVesselBasicsById,\n  // Vessel History API functions\n  getVesselHistoryByVesselAndDateRange,\n  // Vessel Locations API functions\n  getVesselLocations,\n  getVesselLocationsByVesselId,\n  // Vessel Stats API functions\n  getVesselStats,\n  getVesselStatsById,\n  // Vessel Verbose API functions\n  getVesselVerbose,\n  getVesselVerboseById,\n} from \"./api\";\nimport type {\n  VesselAccommodation,\n  VesselBasic,\n  VesselHistory,\n  VesselLocation,\n  VesselStats,\n  VesselsCacheFlushDate,\n  VesselVerbose,\n} from \"./schemas\";\n\n// ============================================================================\n// VESSEL BASICS HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching vessel basics from WSF Vessels API\n *\n * Retrieves basic vessel information including vessel names, abbreviations,\n * class information, and operational status. This endpoint provides fundamental\n * vessel details for all vessels in the WSF fleet.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of VesselBasic objects with basic information for all vessels\n *\n * @example\n * ```typescript\n * const { data: vessels } = useVesselBasics();\n * console.log(vessels?.[0]?.VesselName); // \"M/V Cathlamet\"\n * ```\n */\nexport const useVesselBasics = (\n  options?: TanStackOptions<VesselBasic[]>\n): UseQueryResult<VesselBasic[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"basics\"],\n    queryFn: () => getVesselBasics(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching vessel basics for a specific vessel from WSF Vessels API\n *\n * Retrieves basic vessel information for a specific vessel identified by vessel ID,\n * including vessel name, abbreviation, class information, and operational status.\n *\n * @param params - Object containing vesselId\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param options - Optional React Query options\n * @returns React Query result containing a VesselBasic object with basic information for the specified vessel\n *\n * @example\n * ```typescript\n * const { data: vessel } = useVesselBasicsById({ vesselId: 1 });\n * console.log(vessel?.VesselName); // \"M/V Cathlamet\"\n * ```\n */\nexport const useVesselBasicsById = (\n  params: { vesselId: number },\n  options?: TanStackOptions<VesselBasic>\n): UseQueryResult<VesselBasic, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"basics\", \"byId\", params.vesselId],\n    queryFn: () => getVesselBasicsById({ vesselId: params.vesselId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// VESSEL ACCOMMODATIONS HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching vessel accommodations from WSF Vessels API\n *\n * Retrieves detailed accommodation information for all vessels in the WSF fleet,\n * including passenger capacity, vehicle capacity, and other accommodation details.\n * This endpoint provides comprehensive information about the capacity and\n * accommodation features of each vessel.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of VesselAccommodation objects with accommodation information\n *\n * @example\n * ```typescript\n * const { data: accommodations } = useVesselAccommodations();\n * console.log(accommodations?.[0]?.VesselName); // \"M/V Cathlamet\"\n * ```\n */\nexport const useVesselAccommodations = (\n  options?: TanStackOptions<VesselAccommodation[]>\n): UseQueryResult<VesselAccommodation[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"accommodations\"],\n    queryFn: () => getVesselAccommodations(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching vessel accommodations for a specific vessel from WSF Vessels API\n *\n * Retrieves detailed accommodation information for a specific vessel identified by vessel ID,\n * including passenger capacity, vehicle capacity, and other accommodation details.\n *\n * @param params - Object containing vesselId\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param options - Optional React Query options\n * @returns React Query result containing a VesselAccommodation object with accommodation information for the specified vessel\n */\nexport const useVesselAccommodationsById = (\n  params: { vesselId: number },\n  options?: TanStackOptions<VesselAccommodation>\n): UseQueryResult<VesselAccommodation, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"accommodations\", \"byId\", params.vesselId],\n    queryFn: () => getVesselAccommodationsById({ vesselId: params.vesselId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// VESSEL LOCATIONS HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching vessel location data from WSF Vessels API\n *\n * Retrieves real-time vessel positions, speeds, headings, and status information\n * from the Washington State Ferries API. This endpoint provides current location\n * data for all active vessels in the WSF fleet, including GPS coordinates,\n * vessel speed, heading direction, and operational status.\n *\n * The data is updated frequently and provides the most current information\n * about vessel locations for tracking and monitoring purposes. This hook uses\n * real-time caching configuration with 5-second refresh intervals.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of VesselLocation objects with real-time location data for all vessels\n *\n * @example\n * ```typescript\n * const { data: locations } = useVesselLocations();\n * console.log(locations?.[0]?.VesselName); // \"M/V Cathlamet\"\n * ```\n */\nexport const useVesselLocations = (\n  options?: TanStackOptions<VesselLocation[]>\n): UseQueryResult<VesselLocation[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"locations\"],\n    queryFn: () => getVesselLocations(),\n    ...tanstackQueryOptions.REALTIME_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching vessel location data for a specific vessel from WSF Vessels API\n *\n * Retrieves real-time vessel position, speed, heading, and status information\n * for a specific vessel identified by vessel ID. This endpoint returns a single vessel object.\n * This hook uses real-time caching configuration with 5-second refresh intervals.\n *\n * @param params - Object containing vesselId\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param options - Optional React Query options\n * @returns React Query result containing a VesselLocation object with real-time position data for the specified vessel\n *\n * @example\n * ```typescript\n * const { data: location } = useVesselLocationsByVesselId({ vesselId: 1 });\n * console.log(location?.VesselName); // \"M/V Cathlamet\"\n * ```\n */\nexport const useVesselLocationsByVesselId = (\n  params: { vesselId: number },\n  options?: TanStackOptions<VesselLocation>\n): UseQueryResult<VesselLocation, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"locations\", \"byVesselId\", params.vesselId],\n    queryFn: () => getVesselLocationsByVesselId({ vesselId: params.vesselId }),\n    ...tanstackQueryOptions.REALTIME_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// VESSEL STATS HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching vessel statistics from WSF Vessels API\n *\n * Retrieves statistical information for all vessels in the WSF fleet,\n * including operational statistics, performance metrics, and other relevant data.\n * This endpoint provides comprehensive statistical information about vessel operations.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of VesselStats objects with statistical information for all vessels\n */\nexport const useVesselStats = (\n  options?: TanStackOptions<VesselStats[]>\n): UseQueryResult<VesselStats[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"stats\"],\n    queryFn: () => getVesselStats(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching vessel statistics for a specific vessel from WSF Vessels API\n *\n * Retrieves statistical information for a specific vessel identified by vessel ID,\n * including operational statistics, performance metrics, and other relevant data.\n *\n * @param params - Object containing vesselId\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param options - Optional React Query options\n * @returns React Query result containing a VesselStats object with statistics for the specified vessel\n */\nexport const useVesselStatsById = (\n  params: { vesselId: number },\n  options?: TanStackOptions<VesselStats>\n): UseQueryResult<VesselStats, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"stats\", \"byId\", params.vesselId],\n    queryFn: () => getVesselStatsById({ vesselId: params.vesselId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// VESSEL HISTORY HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching vessel history data for a specific vessel and date range from WSF Vessels API\n *\n * Retrieves historical vessel data for a specific vessel within a specified date range,\n * including past routes, schedules, and operational history for that vessel.\n *\n * @param params - Object containing vesselName, dateStart, dateEnd\n * @param params.vesselName - The name of the vessel (e.g., \"M/V Cathlamet\")\n * @param params.dateStart - The start date for the history range\n * @param params.dateEnd - The end date for the history range\n * @param options - Optional React Query options\n * @returns React Query result containing an array of VesselHistory objects with historical data for the specified vessel and date range\n */\nexport const useVesselHistoryByVesselAndDateRange = (\n  params: { vesselName: string; dateStart: Date; dateEnd: Date },\n  options?: TanStackOptions<VesselHistory[]>\n): UseQueryResult<VesselHistory[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"vessels\",\n      \"history\",\n      \"byVesselAndDateRange\",\n      params.vesselName,\n      params.dateStart.toISOString(),\n      params.dateEnd.toISOString(),\n    ],\n    queryFn: () =>\n      getVesselHistoryByVesselAndDateRange({\n        vesselName: params.vesselName,\n        dateStart: params.dateStart,\n        dateEnd: params.dateEnd,\n      }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching vessel history data for multiple vessels and date range\n *\n * This hook fetches historical data for multiple vessels by making parallel API calls\n * to the vessel history endpoint for each vessel. This is useful when you need historical\n * data for multiple vessels over the same time period.\n *\n * @param params - Object containing vesselNames, dateStart, dateEnd, and optional batchSize\n * @param params.vesselNames - Array of vessel names to fetch history for (e.g., [\"Spokane\", \"Walla Walla\"])\n * @param params.dateStart - The start date for the history range\n * @param params.dateEnd - The end date for the history range\n * @param params.batchSize - Optional batch size for processing requests (default: 6)\n * @param options - Optional React Query options\n * @returns React Query result containing an array of VesselHistory objects with historical data for all specified vessels\n *\n * @example\n * ```typescript\n * const { data: history } = useMultipleVesselHistories({\n *   vesselNames: [\"Spokane\", \"Walla Walla\"],\n *   dateStart: new Date(\"2024-01-01\"),\n *   dateEnd: new Date(\"2024-01-02\")\n * });\n * ```\n */\nexport const useMultipleVesselHistories = (\n  params: {\n    vesselNames: string[];\n    dateStart: Date;\n    dateEnd: Date;\n    batchSize?: number;\n  },\n  options?: TanStackOptions<VesselHistory[]>\n): UseQueryResult<VesselHistory[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"vessels\",\n      \"history\",\n      \"multipleVessels\",\n      params.vesselNames.sort(), // Sort for consistent cache key\n      params.dateStart.toISOString(),\n      params.dateEnd.toISOString(),\n      params.batchSize,\n    ],\n    queryFn: () =>\n      getMultipleVesselHistories({\n        vesselNames: params.vesselNames,\n        dateStart: params.dateStart,\n        dateEnd: params.dateEnd,\n        batchSize: params.batchSize,\n      }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching vessel history data for all vessels in the WSF fleet\n *\n * This hook fetches historical data for all 21 vessels in the Washington State Ferries fleet\n * by making batched API calls to the vessel history endpoint. This provides comprehensive\n * historical data for the entire fleet over a specified time period.\n *\n * @param params - Object containing dateStart, dateEnd, and optional batchSize\n * @param params.dateStart - The start date for the history range\n * @param params.dateEnd - The end date for the history range\n * @param params.batchSize - Optional batch size for processing requests (default: 6)\n * @param options - Optional React Query options\n * @returns React Query result containing an array of VesselHistory objects with historical data for all vessels\n *\n * @example\n * ```typescript\n * const { data: allHistory } = useAllVesselHistories({\n *   dateStart: new Date(\"2024-01-01\"),\n *   dateEnd: new Date(\"2024-01-02\")\n * });\n * ```\n */\nexport const useAllVesselHistories = (\n  params: { dateStart: Date; dateEnd: Date; batchSize?: number },\n  options?: TanStackOptions<VesselHistory[]>\n): UseQueryResult<VesselHistory[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"vessels\",\n      \"history\",\n      \"allVessels\",\n      params.dateStart.toISOString(),\n      params.dateEnd.toISOString(),\n      params.batchSize,\n    ],\n    queryFn: () =>\n      getAllVesselHistories({\n        dateStart: params.dateStart,\n        dateEnd: params.dateEnd,\n        batchSize: params.batchSize,\n      }),\n    ...tanstackQueryOptions.MINUTE_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// VESSEL VERBOSE HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching verbose vessel data from WSF Vessels API\n *\n * Retrieves comprehensive vessel information for all vessels in the WSF fleet,\n * including detailed specifications, operational data, and extended information.\n * This endpoint provides the most complete vessel information available.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing an array of VesselVerbose objects with comprehensive information for all vessels\n */\nexport const useVesselVerbose = (\n  options?: TanStackOptions<VesselVerbose[]>\n): UseQueryResult<VesselVerbose[], Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"verbose\"],\n    queryFn: () => getVesselVerbose(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for fetching verbose vessel data for a specific vessel from WSF Vessels API\n *\n * Retrieves comprehensive vessel information for a specific vessel identified by vessel ID,\n * including detailed specifications, operational data, and extended information.\n *\n * @param params - Object containing vesselId\n * @param params.vesselId - The unique identifier for the vessel (e.g., 1 for M/V Cathlamet)\n * @param options - Optional React Query options\n * @returns React Query result containing a VesselVerbose object with comprehensive information for the specified vessel\n */\nexport const useVesselVerboseById = (\n  params: { vesselId: number },\n  options?: TanStackOptions<VesselVerbose>\n): UseQueryResult<VesselVerbose, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"verbose\", \"byId\", params.vesselId],\n    queryFn: () => getVesselVerboseById({ vesselId: params.vesselId }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n// ============================================================================\n// CACHE FLUSH DATE HOOKS\n// ============================================================================\n\n/**\n * Hook for fetching cache flush date from WSF Vessels API\n *\n * Retrieves the cache flush date for the vessels API, which indicates when\n * the cached data was last updated. This information is useful for determining\n * the freshness of the cached vessel data.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing the cache flush date for vessels data\n */\nexport const useCacheFlushDateVessels = (\n  options?: TanStackOptions<VesselsCacheFlushDate>\n): UseQueryResult<VesselsCacheFlushDate, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"vessels\", \"cacheFlushDate\"],\n    queryFn: () => getCacheFlushDateVessels(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n","// Vessel Cache Provider Component\n// Monitors vessel cache flush dates and automatically invalidates vessel queries when data changes\n\nimport { CacheProvider } from \"@/shared/caching/CacheProvider\";\n\nimport { useCacheFlushDateVessels } from \"./queries\";\n\n/**\n * Vessel Cache Provider Component\n *\n * This component monitors vessel cache flush dates and automatically\n * invalidates vessel queries when the cache flush date changes, indicating\n * that the underlying vessel data has been updated on the server.\n *\n * This component should be placed in your component tree where vessel data\n * is used, or at the root if vessel data is used throughout the app.\n */\nexport const VesselCacheProvider = () => {\n  return CacheProvider([\"vessels\"], useCacheFlushDateVessels);\n};\n","// WSF Fares API React Query hooks\n// Documentation: https://www.wsdot.wa.gov/ferries/api/fares/documentation/rest.html\n// API Help: https://www.wsdot.wa.gov/ferries/api/fares/rest/help\n\nimport type { UseQueryOptions, UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { tanstackQueryOptions } from \"@/shared/caching/config\";\nimport { jsDateToYyyyMmDd } from \"@/shared/fetching/parsing\";\n\nimport {\n  getFareLineItems,\n  getFareLineItemsBasic,\n  getFareLineItemsVerbose,\n  getFaresCacheFlushDate,\n  getFaresTerminalMates,\n  getFaresTerminals,\n  getFaresValidDateRange,\n  getFareTotals,\n  getTerminalCombo,\n  getTerminalComboVerbose,\n} from \"./api\";\nimport type {\n  FareLineItem,\n  FareLineItemsVerboseResponse,\n  FaresValidDateRange,\n  FareTotal,\n  TerminalComboVerbose,\n} from \"./schemas\";\n\n/**\n * Hook for getting cache flush date from WSF Fares API\n *\n * Some of the retrieval operations return data that changes infrequently.\n * Use this operation to poll for changes. When the date returned is modified,\n * drop your application cache and retrieve fresh data.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing cache flush date\n *\n * @example\n * ```typescript\n * const { data: flushDate } = useFaresCacheFlushDate();\n * console.log(flushDate); // \"2024-01-15T10:30:00Z\"\n * ```\n */\nexport const useFaresCacheFlushDate = (\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getFaresCacheFlushDate>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<Date, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"fares\", \"cacheFlushDate\"],\n    queryFn: () => getFaresCacheFlushDate(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting valid date range from WSF Fares API\n *\n * Retrieves a date range for which fares data is currently published & available.\n *\n * @param options - Optional React Query options\n * @returns React Query result containing valid date range information\n *\n * @example\n * ```typescript\n * const { data: dateRange } = useFaresValidDateRange();\n * console.log(dateRange?.StartDate); // \"2024-01-01T00:00:00Z\"\n * ```\n */\nexport const useFaresValidDateRange = (\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getFaresValidDateRange>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<FaresValidDateRange, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"fares\", \"validDateRange\"],\n    queryFn: () => getFaresValidDateRange(),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting terminals for a trip date from WSF Fares API\n *\n * Retrieves valid departing terminals for a given trip date. A valid trip date\n * may be determined using validDateRange.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param options - Optional React Query options\n * @returns React Query result containing array of valid departing terminals\n *\n * @example\n * ```typescript\n * const { data: terminals } = useFaresTerminals({ tripDate: new Date('2024-01-15') });\n * console.log(terminals?.[0]?.TerminalName); // \"Anacortes\"\n * ```\n */\nexport const useFaresTerminals = (\n  params: { tripDate: Date },\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getFaresTerminals>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<any, Error> => {\n  return useQuery({\n    queryKey: [\"wsf\", \"fares\", \"terminals\", jsDateToYyyyMmDd(params.tripDate)],\n    queryFn: () => getFaresTerminals({ tripDate: params.tripDate }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting terminal mates from WSF Fares API\n *\n * Provides arriving terminals for a given departing terminal and trip date. A valid departing\n * terminal may be found by using terminals. Similarly, a valid trip date may be determined\n * using validDateRange.\n *\n * @param params - Object containing tripDate and terminalID\n * @param params.tripDate - The trip date as a Date object\n * @param params.terminalID - The unique identifier for the departing terminal\n * @param options - Optional React Query options\n * @returns React Query result containing array of arriving terminals\n */\nexport const useFaresTerminalMates = (\n  params: { tripDate: Date; terminalID: number },\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getFaresTerminalMates>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<any, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"fares\",\n      \"terminalMates\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.terminalID,\n    ],\n    queryFn: () =>\n      getFaresTerminalMates({\n        tripDate: params.tripDate,\n        terminalID: params.terminalID,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting terminal combo from WSF Fares API\n *\n * Retrieves fare collection description for a specific terminal combination on a given trip date.\n * This endpoint provides information about how fares are collected for the specified route.\n *\n * @param params - Object containing tripDate, departingTerminalID, arrivingTerminalID\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalID - The unique identifier for the departing terminal\n * @param params.arrivingTerminalID - The unique identifier for the arriving terminal\n * @param options - Optional React Query options\n * @returns React Query result containing terminal combination information\n */\nexport const useTerminalCombo = (\n  params: {\n    tripDate: Date;\n    departingTerminalID: number;\n    arrivingTerminalID: number;\n  },\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getTerminalCombo>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<any, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"fares\",\n      \"terminalCombo\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.departingTerminalID,\n      params.arrivingTerminalID,\n    ],\n    queryFn: () =>\n      getTerminalCombo({\n        tripDate: params.tripDate,\n        departingTerminalID: params.departingTerminalID,\n        arrivingTerminalID: params.arrivingTerminalID,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting terminal combo verbose from WSF Fares API\n *\n * Retrieves all valid terminal combinations for a given trip date. This endpoint provides\n * comprehensive information about all available routes and their fare collection methods.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param options - Optional React Query options\n * @returns React Query result containing array of all terminal combinations\n */\nexport const useTerminalComboVerbose = (\n  params: { tripDate: Date },\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getTerminalComboVerbose>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<TerminalComboVerbose[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"fares\",\n      \"terminalComboVerbose\",\n      jsDateToYyyyMmDd(params.tripDate),\n    ],\n    queryFn: () => getTerminalComboVerbose({ tripDate: params.tripDate }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting basic fare line items from WSF Fares API\n *\n * Retrieves the most popular fare line items for a specific route. This endpoint provides\n * the commonly used fare options for the specified terminal combination and trip type.\n *\n * @param params - Object containing tripDate, departingTerminalID, arrivingTerminalID, roundTrip\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalID - The unique identifier for the departing terminal\n * @param params.arrivingTerminalID - The unique identifier for the arriving terminal\n * @param params.roundTrip - Whether this is a round trip\n * @param options - Optional React Query options\n * @returns React Query result containing array of most popular fare line items\n */\nexport const useFareLineItemsBasic = (\n  params: {\n    tripDate: Date;\n    departingTerminalID: number;\n    arrivingTerminalID: number;\n    roundTrip: boolean;\n  },\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getFareLineItemsBasic>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<FareLineItem[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"fares\",\n      \"fareLineItemsBasic\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.departingTerminalID,\n      params.arrivingTerminalID,\n      params.roundTrip,\n    ],\n    queryFn: () =>\n      getFareLineItemsBasic({\n        tripDate: params.tripDate,\n        departingTerminalID: params.departingTerminalID,\n        arrivingTerminalID: params.arrivingTerminalID,\n        roundTrip: params.roundTrip,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting fare line items from WSF Fares API\n *\n * Retrieves all available fare line items for a specific route. This endpoint provides\n * comprehensive fare information including all fare types and options for the specified\n * terminal combination and trip type.\n *\n * @param params - Object containing tripDate, departingTerminalID, arrivingTerminalID, roundTrip\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalID - The unique identifier for the departing terminal\n * @param params.arrivingTerminalID - The unique identifier for the arriving terminal\n * @param params.roundTrip - Whether this is a round trip\n * @param options - Optional React Query options\n * @returns React Query result containing array of all fare line items\n */\nexport const useFareLineItems = (\n  params: {\n    tripDate: Date;\n    departingTerminalID: number;\n    arrivingTerminalID: number;\n    roundTrip: boolean;\n  },\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getFareLineItems>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<FareLineItem[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"fares\",\n      \"fareLineItems\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.departingTerminalID,\n      params.arrivingTerminalID,\n      params.roundTrip,\n    ],\n    queryFn: () =>\n      getFareLineItems({\n        tripDate: params.tripDate,\n        departingTerminalID: params.departingTerminalID,\n        arrivingTerminalID: params.arrivingTerminalID,\n        roundTrip: params.roundTrip,\n      }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting verbose fare line items from WSF Fares API\n *\n * Retrieves all fare line items for all terminal combinations on a given trip date.\n * This endpoint provides comprehensive fare information for all available routes\n * in a single call.\n *\n * @param params - Object containing tripDate\n * @param params.tripDate - The trip date as a Date object\n * @param options - Optional React Query options\n * @returns React Query result containing complex object with all fare line items for all routes\n */\nexport const useFareLineItemsVerbose = (\n  params: { tripDate: Date },\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getFareLineItemsVerbose>>>,\n    \"queryKey\" | \"queryFn\"\n  >\n): UseQueryResult<FareLineItemsVerboseResponse, Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"fares\",\n      \"fareLineItemsVerbose\",\n      jsDateToYyyyMmDd(params.tripDate),\n    ],\n    queryFn: () => getFareLineItemsVerbose({ tripDate: params.tripDate }),\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n\n/**\n * Hook for getting fare totals from WSF Fares API\n *\n * Calculates the total fare cost for a specific combination of fare line items and quantities.\n * This endpoint provides fare calculation functionality for booking and reservation systems.\n *\n * @param params - Object containing tripDate, departingTerminalID, arrivingTerminalID, roundTrip, fareLineItemIDs, quantities\n * @param params.tripDate - The trip date as a Date object\n * @param params.departingTerminalID - The unique identifier for the departing terminal\n * @param params.arrivingTerminalID - The unique identifier for the arriving terminal\n * @param params.roundTrip - Whether this is a round trip\n * @param params.fareLineItemIDs - Array of fare line item IDs to include in the calculation\n * @param params.quantities - Array of quantities corresponding to fare line item IDs\n * @param options - Optional React Query options\n * @returns React Query result containing fare total calculation\n */\nexport const useFareTotals = (\n  params: {\n    tripDate: Date;\n    departingTerminalID: number;\n    arrivingTerminalID: number;\n    roundTrip: boolean;\n    fareLineItemIDs: number[];\n    quantities: number[];\n  },\n  options?: Omit<\n    UseQueryOptions<Awaited<ReturnType<typeof getFareTotals>>>,\n    \"queryKey\" | \"queryFn\" | \"enabled\"\n  >\n): UseQueryResult<FareTotal[], Error> => {\n  return useQuery({\n    queryKey: [\n      \"wsf\",\n      \"fares\",\n      \"fareTotals\",\n      jsDateToYyyyMmDd(params.tripDate),\n      params.departingTerminalID,\n      params.arrivingTerminalID,\n      params.roundTrip,\n      params.fareLineItemIDs,\n      params.quantities,\n    ],\n    queryFn: () => getFareTotals(params),\n    enabled: params.fareLineItemIDs.length > 0 && params.quantities.length > 0,\n    ...tanstackQueryOptions.DAILY_UPDATES,\n    ...options,\n  });\n};\n"]}