@walkeros/server-destination-meta
Version:
Meta server destination for walkerOS
1 lines • 21.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, pixelId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!pixelId) logger.throw('Config settings pixelId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n pixelId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { WalkerOS } from '@walkeros/core';\nimport type {\n BodyParameters,\n CustomerInformationParameters,\n PushFn,\n ServerEventParameters,\n Env,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, mapping, data, collector, env, logger },\n) {\n const {\n accessToken,\n pixelId,\n action_source = 'website',\n doNotHash,\n test_event_code,\n url = 'https://graph.facebook.com/v22.0/',\n user_data,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data)\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n const userData: CustomerInformationParameters = {\n // Destination config\n ...(isObject(configData) && isObject(configData.user_data)\n ? configData.user_data\n : {}),\n // Custom user_data\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n // Event mapping\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n if (userData.fbclid) {\n userData.fbc = formatClickId(\n userData.fbclid,\n collector?.session?.start || event.timestamp,\n );\n delete userData.fbclid;\n }\n const serverEvent: ServerEventParameters = {\n event_name: event.name,\n event_id: event.id,\n event_time: Math.round((event.timestamp || Date.now()) / 1000),\n action_source,\n ...eventData,\n user_data: userData,\n };\n\n if (action_source === 'website')\n serverEvent.event_source_url = event.source.id;\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: BodyParameters = { data: [hashedServerEvent] };\n\n // Test event code\n if (test_event_code) body.test_event_code = test_event_code;\n\n const endpoint = `${url}${pixelId}/events`;\n logger.debug('Calling Meta API', {\n endpoint,\n method: 'POST',\n eventName: serverEvent.event_name,\n eventId: serverEvent.event_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(\n `${endpoint}?access_token=${accessToken}`,\n JSON.stringify(body),\n );\n\n logger.debug('Meta API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Meta API error: ${JSON.stringify(result)}`);\n }\n};\n\nfunction formatClickId(clickId: unknown, time?: number): string | undefined {\n // https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/fbp-and-fbc#2--format-clickid\n\n if (!clickId) return;\n\n // Version is always \"fb\"\n const version = 'fb';\n\n // Subdomain ('com' = 0, 'example.com' = 1, 'www.example.com' = 2)\n const subdomainIndex = '1';\n\n // Get the current timestamp in milliseconds (or when the fbclid was observed)\n const creationTime = time || Date.now();\n\n return `${version}.${subdomainIndex}.${creationTime}.${clickId}`;\n}\n\nfunction lower(str: WalkerOS.Property): string {\n return String(str).toLocaleLowerCase();\n}\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'em',\n 'ph',\n 'fn',\n 'ln',\n 'db',\n 'ge',\n 'ct',\n 'st',\n 'zp',\n 'country',\n 'external_id',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUserData = 'user_data' in value;\n const target = (isUserData ? value.user_data : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUserData && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUserData ? { ...value, user_data: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n pixelId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test_event_code?: string;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/main-body\nexport interface BodyParameters {\n data: Array<ServerEventParameters>;\n test_event_code?: string;\n}\n\n/**\n * Represents the top‑level parameters for a server event sent via Meta's Conversions API.\n * https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/server-event\n */\nexport interface ServerEventParameters extends StandardParameters {\n /** The event name or custom event identifier. Required for deduplication. */\n event_name: EventName;\n\n /** Unix timestamp (in seconds) when the event actually occurred. GMT timezone. */\n event_time: number;\n\n /** Map of customer information for matching (emails, phone, etc.). */\n user_data: CustomerInformationParameters;\n\n /** Additional business data about the event. */\n custom_data?: Record<string, unknown>;\n\n /** URL of the page where the event occurred. */\n event_source_url?: string;\n\n /** If true, exclude this event from ads optimization (only attribution). */\n opt_out?: boolean;\n\n /** Unique ID for deduplication across Pixel and CAPI. */\n event_id?: string;\n\n /** Source of the event (e.g., website, app). */\n action_source: ActionSource;\n\n /** Processing options (e.g., ['LDU'] for CCPA limited data use). */\n data_processing_options?: DataProcessingOption[];\n\n /** Country code for data processing option (1 = USA, 0 = auto‑geolocate). */\n data_processing_options_country?: number;\n\n /** State code for data processing option (1000 = California, 0 = auto). */\n data_processing_options_state?: number;\n\n /** App‑specific data (required if action_source is 'app'). */\n app_data?: AppData;\n\n /** HTTP referrer header of the event. */\n referrer_url?: string;\n\n /** Metadata to link delayed events to past acquisition events. */\n original_event_data?: OriginalEventDataParameters;\n\n /** User segment for more context about the customer's relationship. */\n customer_segmentation?: CustomerSegmentation;\n}\n\nexport type EventName =\n | 'AddPaymentInfo'\n | 'AddToCart'\n | 'AddToWishlist'\n | 'CompleteRegistration'\n | 'Contact'\n | 'CustomizeProduct'\n | 'Donate'\n | 'FindLocation'\n | 'InitiateCheckout'\n | 'Lead'\n | 'Purchase'\n | 'Schedule'\n | 'Search'\n | 'StartTrial'\n | 'SubmitApplication'\n | 'Subscribe'\n | 'ViewContent'\n | string;\n\nexport type ActionSource =\n | 'email'\n | 'website'\n | 'app'\n | 'phone_call'\n | 'chat'\n | 'physical_store'\n | 'system_generated'\n | 'business_messaging'\n | 'other';\n\nexport type DataProcessingOption = 'LDU';\n\nexport type CustomerSegmentation =\n | 'new_customer_to_business'\n | 'new_customer_to_business_line'\n | 'new_customer_to_product_area'\n | 'new_customer_to_medium'\n | 'existing_customer_to_business'\n | 'existing_customer_to_business_line'\n | 'existing_customer_to_product_area'\n | 'existing_customer_to_medium'\n | 'customer_in_loyalty_program';\n\n/** Extended device info for app events (Android version 'a2', iOS 'i2') */\nexport interface AppData {\n /**\n * Comma-separated array of strings with fixed order:\n * [sdk_version, os_version, device_model, device_brand,\n * screen_width, screen_height, ...]\n */\n extinfo: string[];\n}\n\n// Customer Information Parameters\n// https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters\nexport interface CustomerInformationParameters {\n /** Email(s), SHA-256 hashed, lowercase and trimmed */\n em?: string | string[];\n\n /** Phone number(s), SHA-256 hashed, E.164 format (no leading 0s or symbols) */\n ph?: string | string[];\n\n /** First name(s), SHA-256 hashed, lowercase */\n fn?: string | string[];\n\n /** Last name(s), SHA-256 hashed, lowercase */\n ln?: string | string[];\n\n /** Date(s) of birth in YYYYMMDD, SHA-256 hashed */\n db?: string | string[];\n\n /** Gender(s) in lowercase single letter (\"m\", \"f\", etc.), SHA-256 hashed */\n ge?: string | string[];\n\n /** City name(s), SHA-256 hashed, lowercase */\n ct?: string | string[];\n\n /** State abbreviation(s), SHA-256 hashed, lowercase (e.g., \"ca\", \"ny\") */\n st?: string | string[];\n\n /** ZIP or postal code(s), SHA-256 hashed, lowercase */\n zp?: string | string[];\n\n /** Country code(s), SHA-256 hashed, lowercase (ISO 3166-1 alpha-2) */\n country?: string | string[];\n\n /** External IDs, unique per user. SHA-256 hash recommended */\n external_id?: string | string[];\n\n /** IPv4 or IPv6 address of client. Do NOT hash. */\n client_ip_address?: string;\n\n /** User agent string from browser. Do NOT hash. */\n client_user_agent?: string;\n\n /** fbclid parameter value from the URL. Do NOT hash. */\n fbclid?: string;\n\n /** Facebook click ID (_fbc cookie). Do NOT hash. */\n fbc?: string;\n\n /** Facebook browser ID (_fbp cookie). Do NOT hash. */\n fbp?: string;\n\n /** Subscription ID for the transaction. Do NOT hash. */\n subscription_id?: string;\n\n /** Facebook login ID (App-Scoped ID). Do NOT hash. */\n fb_login_id?: number;\n\n /** Meta Lead Ad lead ID. Do NOT hash. */\n lead_id?: number;\n\n /** Anonymous install ID. App events only. Do NOT hash. */\n anon_id?: string;\n\n /** Mobile advertiser ID (GAID/IDFA). Do NOT hash. */\n madid?: string;\n\n /** Facebook Page ID. Do NOT hash. */\n page_id?: string;\n\n /** Messenger Page-scoped user ID. Do NOT hash. */\n page_scoped_user_id?: string;\n\n /** Click to WhatsApp ad click ID. Do NOT hash. */\n ctwa_clid?: string;\n\n /** Instagram business account ID. Do NOT hash. */\n ig_account_id?: string;\n\n /** Instagram-scoped user ID. Do NOT hash. */\n ig_sid?: string;\n}\n\n// https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/custom-data\nexport interface StandardParameters {\n // Web and Offline parameters\n availability?: string;\n body_style?: string;\n checkin_date?: string;\n city?: string;\n condition_of_vehicle?: string;\n content_ids?: string[];\n content_type?: 'product' | 'product_group' | string;\n contents?: Array<{\n id: string;\n quantity?: number;\n item_price?: number;\n delivery_category?: string;\n }>;\n country?: string;\n currency?: string;\n delivery_category?: 'in_store' | 'curbside' | 'home_delivery' | string;\n departing_arrival_date?: string;\n departing_departure_date?: string;\n destination_airport?: string;\n destination_ids?: string[];\n dma_code?: string;\n drivetrain?: string;\n exterior_color?: string;\n fuel_type?: string;\n hotel_score?: number;\n interior_color?: string;\n lead_event_source?: string;\n lease_end_date?: string;\n lease_start_date?: string;\n listing_type?: string;\n make?: string;\n // @TODO is mileage an object?\n 'mileage.unit'?: string;\n 'mileage.value'?: number;\n model?: string;\n neighborhood?: string;\n net_revenue?: number;\n num_adults?: number;\n num_children?: number;\n num_infants?: number;\n num_items?: number;\n order_id?: string;\n origin_airport?: string;\n postal_code?: string;\n predicted_ltv?: number;\n preferred_baths_range?: string;\n preferred_beds_range?: string;\n preferred_neighborhoods?: string[];\n preferred_num_stops?: number;\n preferred_price_range?: string;\n preferred_star_ratings?: [number, number];\n price?: string;\n product_catalog_id?: string;\n property_type?: string;\n region?: string;\n returning_arrival_date?: string;\n returning_departure_date?: string;\n search_string?: string;\n state_of_vehicle?: string;\n suggested_destinations?: string[];\n suggested_home_listings?: string[];\n suggested_hotels?: string[];\n suggested_jobs?: string[];\n suggested_local_service_businesses?: string[];\n suggested_location_based_items?: string[];\n suggested_vehicles?: string[];\n transmission?: string;\n travel_class?: string;\n travel_end?: string;\n travel_start?: string;\n trim?: string;\n\n // App-specific parameters (with fb_ prefix)\n fb_availability?: string;\n fb_body_style?: string;\n fb_checkin_date?: string;\n fb_city?: string;\n fb_condition_of_vehicle?: string;\n fb_content_ids?: string[];\n fb_content_type?: string;\n fb_contents?: Array<{ id: string; quantity?: number; item_price?: number }>;\n fb_country?: string;\n fb_currency?: string;\n fb_delivery_category?: string;\n fb_departing_arrival_date?: string;\n fb_departing_departure_date?: string;\n fb_destination_airport?: string;\n fb_destination_ids?: string[];\n fb_dma_code?: string;\n fb_drivetrain?: string;\n fb_exterior_color?: string;\n fb_fuel_type?: string;\n fb_hotel_score?: number;\n fb_interior_color?: string;\n fb_lease_end_date?: string;\n fb_lease_start_date?: string;\n fb_listing_type?: string;\n fb_make?: string;\n // @TODO is fb_mileage an object?\n 'fb_mileage.unit'?: string;\n 'fb_mileage.value'?: number;\n fb_model?: string;\n fb_neighborhood?: string;\n fb_num_adults?: number;\n fb_num_children?: number;\n fb_num_infants?: number;\n fb_num_items?: number;\n fb_order_id?: string;\n fb_origin_airport?: string;\n fb_postal_code?: string;\n fb_predicted_ltv?: number;\n fb_preferred_baths_range?: string;\n fb_preferred_beds_range?: string;\n fb_preferred_neighborhoods?: string[];\n fb_preferred_num_stops?: number;\n fb_preferred_price_range?: string;\n fb_preferred_star_ratings?: [number, number];\n fb_price?: string;\n fb_product_catalog_id?: string;\n fb_property_type?: string;\n fb_region?: string;\n fb_returning_arrival_date?: string;\n fb_returning_departure_date?: string;\n fb_search_string?: string;\n fb_state_of_vehicle?: string;\n fb_suggested_destinations?: string[];\n fb_suggested_home_listings?: string[];\n fb_suggested_hotels?: string[];\n fb_suggested_jobs?: string[];\n fb_suggested_local_service_businesses?: string[];\n fb_suggested_location_based_items?: string[];\n fb_suggested_vehicles?: string[];\n fb_transmission?: string;\n fb_travel_class?: string;\n fb_travel_end?: string;\n fb_travel_start?: string;\n\n // Offline-specific parameters\n user_bucket?: string;\n value?: number;\n vin?: string;\n year?: number;\n item_number?: string;\n}\n\nexport interface OriginalEventDataParameters {\n event_name?: EventName;\n event_time?: number;\n order_id?: number;\n event_id?: string;\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationMeta from './types';\n\nexport const destinationMeta: Destination = {\n type: 'meta',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, { config, mapping, data, collector, env, logger }) {\n return await push(event, { config, mapping, data, collector, env, logger });\n },\n};\n\nexport default destinationMeta;\n"],"mappings":";AAGO,SAAS,UACd,gBAA+B,CAAC,GAChC,QACQ;AACR,QAAM,WAAY,cAAc,YAAY,CAAC;AAC7C,QAAM,EAAE,aAAa,QAAQ,IAAI;AAEjC,MAAI,CAAC,YAAa,QAAO,MAAM,qCAAqC;AACpE,MAAI,CAAC,QAAS,QAAO,MAAM,iCAAiC;AAE5D,QAAM,iBAA2B;AAAA,IAC/B,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACF;AAEA,SAAO,EAAE,GAAG,eAAe,UAAU,eAAe;AACtD;;;ACZA,SAAS,iBAAiB,YAAAA,iBAAgB;AAC1C,SAAS,kBAAkB;;;ACR3B,SAAS,SAAS,UAAU,gBAAgB;AAC5C,SAAS,qBAAqB;AAE9B,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,eAAe,KAAa,YAAsB,CAAC,GAAY;AACtE,SAAO,WAAW,SAAS,GAAG,KAAK,CAAC,UAAU,SAAS,GAAG;AAC5D;AAIA,eAAe,aACb,OACA,YACkB;AAClB,MAAI,CAAC,WAAY,QAAO;AACxB,MAAI,QAAQ,KAAK,GAAG;AAClB,WAAO,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS,cAAc,OAAO,IAAI,CAAC,CAAC,CAAC;AAAA,EACrE;AACA,SAAO,cAAc,OAAO,KAAK,CAAC;AACpC;AAEA,eAAsB,UACpB,OACA,YAAsB,CAAC,GACX;AACZ,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,QAAM,aAAa,eAAe;AAClC,QAAM,SAAU,aAAa,MAAM,YAAY;AAE/C,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,OAAO,QAAQ,MAAM,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM;AAAA,MAC3C;AAAA,MACA,MAAM,aAAa,GAAG,cAAc,eAAe,GAAG,SAAS,CAAC;AAAA,IAClE,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,QAAQ,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;AAC7C,QAAI,SAAS,CAAC,EAAG,KAAI,CAAC,IAAI;AAC1B,WAAO;AAAA,EACT,GAAG,CAAC,CAAuB;AAE3B,SAAO,aAAa,EAAE,GAAG,OAAO,WAAW,OAAO,IAAK;AACzD;;;AD7CO,IAAM,OAAe,eAC1B,OACA,EAAE,QAAQ,SAAS,MAAM,WAAW,KAAK,OAAO,GAChD;AAfF;AAgBE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,EACF,IAAI,OAAO;AAEX,QAAM,YAAYC,UAAS,IAAI,IAAI,OAAO,CAAC;AAC3C,QAAM,aAAa,OAAO,OACtB,MAAM,gBAAgB,OAAO,OAAO,IAAI,IACxC,CAAC;AACL,QAAM,iBAAiB,YACnB,MAAM,gBAAgB,OAAO,EAAE,KAAK,UAAU,CAAC,IAC/C,CAAC;AAEL,QAAM,WAA0C;AAAA;AAAA,IAE9C,GAAIA,UAAS,UAAU,KAAKA,UAAS,WAAW,SAAS,IACrD,WAAW,YACX,CAAC;AAAA;AAAA,IAEL,GAAIA,UAAS,cAAc,IAAI,iBAAiB,CAAC;AAAA;AAAA,IAEjD,GAAIA,UAAS,UAAU,SAAS,IAAI,UAAU,YAAY,CAAC;AAAA,EAC7D;AAEA,MAAI,SAAS,QAAQ;AACnB,aAAS,MAAM;AAAA,MACb,SAAS;AAAA,QACT,4CAAW,YAAX,mBAAoB,UAAS,MAAM;AAAA,IACrC;AACA,WAAO,SAAS;AAAA,EAClB;AACA,QAAM,cAAqC;AAAA,IACzC,YAAY,MAAM;AAAA,IAClB,UAAU,MAAM;AAAA,IAChB,YAAY,KAAK,OAAO,MAAM,aAAa,KAAK,IAAI,KAAK,GAAI;AAAA,IAC7D;AAAA,IACA,GAAG;AAAA,IACH,WAAW;AAAA,EACb;AAEA,MAAI,kBAAkB;AACpB,gBAAY,mBAAmB,MAAM,OAAO;AAE9C,QAAM,oBAAoB,MAAM,UAAU,aAAa,SAAS;AAEhE,QAAM,OAAuB,EAAE,MAAM,CAAC,iBAAiB,EAAE;AAGzD,MAAI,gBAAiB,MAAK,kBAAkB;AAE5C,QAAM,WAAW,GAAG,GAAG,GAAG,OAAO;AACjC,SAAO,MAAM,oBAAoB;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR,WAAW,YAAY;AAAA,IACvB,SAAS,YAAY;AAAA,EACvB,CAAC;AAED,QAAM,gBAAe,2BAAK,eAAc;AACxC,QAAM,SAAS,MAAM;AAAA,IACnB,GAAG,QAAQ,iBAAiB,WAAW;AAAA,IACvC,KAAK,UAAU,IAAI;AAAA,EACrB;AAEA,SAAO,MAAM,qBAAqB;AAAA,IAChC,IAAIA,UAAS,MAAM,IAAI,OAAO,KAAK;AAAA,EACrC,CAAC;AAED,MAAIA,UAAS,MAAM,KAAK,OAAO,OAAO,OAAO;AAC3C,WAAO,MAAM,mBAAmB,KAAK,UAAU,MAAM,CAAC,EAAE;AAAA,EAC1D;AACF;AAEA,SAAS,cAAc,SAAkB,MAAmC;AAG1E,MAAI,CAAC,QAAS;AAGd,QAAM,UAAU;AAGhB,QAAM,iBAAiB;AAGvB,QAAM,eAAe,QAAQ,KAAK,IAAI;AAEtC,SAAO,GAAG,OAAO,IAAI,cAAc,IAAI,YAAY,IAAI,OAAO;AAChE;;;AE7GA;;;ACOO,IAAM,kBAA+B;AAAA,EAC1C,MAAM;AAAA,EAEN,QAAQ,CAAC;AAAA,EAET,MAAM,KAAK,EAAE,QAAQ,eAAe,OAAO,GAAG;AAC5C,UAAM,SAAS,UAAU,eAAe,MAAM;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,OAAO,EAAE,QAAQ,SAAS,MAAM,WAAW,KAAK,OAAO,GAAG;AACnE,WAAO,MAAM,KAAK,OAAO,EAAE,QAAQ,SAAS,MAAM,WAAW,KAAK,OAAO,CAAC;AAAA,EAC5E;AACF;AAEA,IAAO,gBAAQ;","names":["isObject","isObject"]}