bitsnap-react 1.18.0 → 1.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/AGENTS.md +85 -0
  2. package/README.md +53 -0
  3. package/dist/CartProvider-CC6YIZVS.js +2 -0
  4. package/dist/CartProvider-CC6YIZVS.js.map +1 -0
  5. package/dist/CartProvider-ZL65WZN6.mjs +2 -0
  6. package/dist/{PanelModelFiles-JZFSF7BF.mjs → PanelModelFiles-4B2HYGIE.mjs} +2 -2
  7. package/dist/{PanelModelFiles-7HPXWONN.js → PanelModelFiles-EKQRLF46.js} +2 -2
  8. package/dist/PanelModelFiles-EKQRLF46.js.map +1 -0
  9. package/dist/analytics.js +1 -1
  10. package/dist/analytics.js.map +1 -1
  11. package/dist/analytics.mjs +1 -1
  12. package/dist/catalog.js +1 -1
  13. package/dist/catalog.js.map +1 -1
  14. package/dist/catalog.mjs +1 -1
  15. package/dist/{chunk-VNV5BD4X.js → chunk-2XSLIZ27.js} +2 -2
  16. package/dist/chunk-2XSLIZ27.js.map +1 -0
  17. package/dist/{chunk-G4V2KWTV.js → chunk-5OCGXVLC.js} +2 -2
  18. package/dist/chunk-5OCGXVLC.js.map +1 -0
  19. package/dist/{chunk-5X7TP3TQ.mjs → chunk-5YN752OV.mjs} +2 -2
  20. package/dist/{chunk-GEBRXFT3.mjs → chunk-62WDFH7K.mjs} +2 -2
  21. package/dist/chunk-6Q3VGPSF.js.map +1 -1
  22. package/dist/chunk-7BG22YBF.js +5 -0
  23. package/dist/chunk-7BG22YBF.js.map +1 -0
  24. package/dist/{chunk-ZATPBYOA.js → chunk-AHISXVEE.js} +2 -2
  25. package/dist/chunk-AHISXVEE.js.map +1 -0
  26. package/dist/{chunk-JA62KNAQ.js → chunk-DR7WYI37.js} +2 -2
  27. package/dist/chunk-DR7WYI37.js.map +1 -0
  28. package/dist/{chunk-GWF3MRUP.js → chunk-EOFJAQPT.js} +2 -2
  29. package/dist/chunk-EOFJAQPT.js.map +1 -0
  30. package/dist/{chunk-DP2NOHCI.js → chunk-G4SEOVLD.js} +2 -2
  31. package/dist/chunk-G4SEOVLD.js.map +1 -0
  32. package/dist/{chunk-CF45RDMD.mjs → chunk-GKJURMDO.mjs} +2 -2
  33. package/dist/{chunk-CF45RDMD.mjs.map → chunk-GKJURMDO.mjs.map} +1 -1
  34. package/dist/{chunk-UPAOIY4R.mjs → chunk-IGQZP4YR.mjs} +2 -2
  35. package/dist/chunk-JSDGZ4NY.js.map +1 -1
  36. package/dist/chunk-KOYBZORL.js.map +1 -1
  37. package/dist/{chunk-4HGZZJEL.js → chunk-N3B25GTY.js} +2 -2
  38. package/dist/chunk-N3B25GTY.js.map +1 -0
  39. package/dist/chunk-OFPRIENJ.mjs +2 -0
  40. package/dist/chunk-OFPRIENJ.mjs.map +1 -0
  41. package/dist/chunk-Q337IQNA.js +2 -0
  42. package/dist/chunk-Q337IQNA.js.map +1 -0
  43. package/dist/{chunk-JHJ3ZZF4.mjs → chunk-UTUPPMLK.mjs} +2 -2
  44. package/dist/{chunk-EVIDNS22.mjs → chunk-VWA3ZCNI.mjs} +2 -2
  45. package/dist/chunk-W3RGQYPD.js.map +1 -1
  46. package/dist/chunk-YGE2223J.mjs +5 -0
  47. package/dist/chunk-YGE2223J.mjs.map +1 -0
  48. package/dist/{chunk-4OVOKGGS.mjs → chunk-ZKT4N553.mjs} +2 -2
  49. package/dist/{chunk-ZHTMK5TA.mjs → chunk-ZM5T4TQW.mjs} +2 -2
  50. package/dist/consent.js.map +1 -1
  51. package/dist/course.js +1 -1
  52. package/dist/course.js.map +1 -1
  53. package/dist/course.mjs +1 -1
  54. package/dist/embed/analytics.js +1 -1
  55. package/dist/errors.js.map +1 -1
  56. package/dist/index.css +1 -1
  57. package/dist/index.css.map +1 -1
  58. package/dist/index.d.mts +272 -2
  59. package/dist/index.d.ts +272 -2
  60. package/dist/index.js +1 -1
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.mjs +1 -1
  63. package/dist/index.mjs.map +1 -1
  64. package/dist/internal.js.map +1 -1
  65. package/dist/methods-7DWKFCPK.js +2 -0
  66. package/dist/methods-7DWKFCPK.js.map +1 -0
  67. package/dist/methods-DQTADIN4.mjs +2 -0
  68. package/dist/model-files-client-P4PORZJ6.js.map +1 -1
  69. package/dist/models.js.map +1 -1
  70. package/dist/returns.js +1 -1
  71. package/dist/returns.js.map +1 -1
  72. package/dist/returns.mjs +1 -1
  73. package/dist/viewer3d.js.map +1 -1
  74. package/dist/viewer3d.mjs +1 -1
  75. package/package.json +4 -3
  76. package/dist/CartProvider-OEI526IN.js +0 -2
  77. package/dist/CartProvider-OEI526IN.js.map +0 -1
  78. package/dist/CartProvider-RYAA3JDA.mjs +0 -2
  79. package/dist/PanelModelFiles-7HPXWONN.js.map +0 -1
  80. package/dist/chunk-4HGZZJEL.js.map +0 -1
  81. package/dist/chunk-7RXW6XFY.js +0 -2
  82. package/dist/chunk-7RXW6XFY.js.map +0 -1
  83. package/dist/chunk-DP2NOHCI.js.map +0 -1
  84. package/dist/chunk-G4V2KWTV.js.map +0 -1
  85. package/dist/chunk-GWF3MRUP.js.map +0 -1
  86. package/dist/chunk-JA62KNAQ.js.map +0 -1
  87. package/dist/chunk-V5ECGBFW.js +0 -5
  88. package/dist/chunk-V5ECGBFW.js.map +0 -1
  89. package/dist/chunk-VNV5BD4X.js.map +0 -1
  90. package/dist/chunk-VNYHJT6V.mjs +0 -2
  91. package/dist/chunk-VNYHJT6V.mjs.map +0 -1
  92. package/dist/chunk-WJO5GSY3.mjs +0 -5
  93. package/dist/chunk-WJO5GSY3.mjs.map +0 -1
  94. package/dist/chunk-ZATPBYOA.js.map +0 -1
  95. package/dist/methods-AULQDKVS.mjs +0 -2
  96. package/dist/methods-PMH5VQ25.js +0 -2
  97. package/dist/methods-PMH5VQ25.js.map +0 -1
  98. /package/dist/{CartProvider-RYAA3JDA.mjs.map → CartProvider-ZL65WZN6.mjs.map} +0 -0
  99. /package/dist/{PanelModelFiles-JZFSF7BF.mjs.map → PanelModelFiles-4B2HYGIE.mjs.map} +0 -0
  100. /package/dist/{chunk-5X7TP3TQ.mjs.map → chunk-5YN752OV.mjs.map} +0 -0
  101. /package/dist/{chunk-GEBRXFT3.mjs.map → chunk-62WDFH7K.mjs.map} +0 -0
  102. /package/dist/{chunk-UPAOIY4R.mjs.map → chunk-IGQZP4YR.mjs.map} +0 -0
  103. /package/dist/{chunk-JHJ3ZZF4.mjs.map → chunk-UTUPPMLK.mjs.map} +0 -0
  104. /package/dist/{chunk-EVIDNS22.mjs.map → chunk-VWA3ZCNI.mjs.map} +0 -0
  105. /package/dist/{chunk-4OVOKGGS.mjs.map → chunk-ZKT4N553.mjs.map} +0 -0
  106. /package/dist/{chunk-ZHTMK5TA.mjs.map → chunk-ZM5T4TQW.mjs.map} +0 -0
  107. /package/dist/{methods-AULQDKVS.mjs.map → methods-DQTADIN4.mjs.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/analytics/contract.ts"],"names":["LIMITS","STREAMS","ENVS","SOURCES","CHANNELS","PAGE_TYPES","SOURCES_FOR_STREAM","MONEY","STOREFRONT_EVENT_SPEC","APP_EVENT_SPEC","TX","SUB","BUSINESS_EVENT_SPEC","EVENT_SPEC","EVENT_NAMES","STREAM_FOR_EVENT","stream","name","isEventName","CONSENT_COOKIE_MAX_AGE_SECONDS","CONSENT_SHOWN_ACTION","normalizeProjectKey","key","bare","CLIENT_RE","parseClientHeader","value","m","MAX_QUERY_VALUE","cleanValue","v","max","t","sanitizePath","pathname","joined","seg"],"mappings":"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","file":"/home/emems/web/bitsnap/bitsnap/bitsnap-react/dist/chunk-W3RGQYPD.js","sourcesContent":["/**\n * Bitsnap merchant analytics: the wire contract.\n *\n * SOURCE OF TRUTH: instapay `apps/collector/src/contract.ts` (prose version:\n * `docs/merchant-analytics-contract.md`). This file is a verbatim copy of it\n * (everything below the next comment block). Do not edit it here: change\n * instapay's file and copy it over. `computeVisitorId` and\n * `computeConsentedVisitorId` are pure but need the server secret; they are\n * server-only: the browser never calls them, so bundlers drop them.\n */\n\nexport const SCHEMA_VERSION = 1;\n\n// ---------------------------------------------------------------------------\n// Limits\n// ---------------------------------------------------------------------------\n\nexport const LIMITS = {\n /** Events in one POST /e. */\n maxBatchEvents: 50,\n /** Body of one POST /e or /consent, in bytes. */\n maxBodyBytes: 64 * 1024,\n /** `JSON.stringify(props)` of one event, in UTF-16 code units. */\n maxPropsChars: 4096,\n maxPropString: 200,\n maxPropArray: 50,\n host: 253,\n path: 512,\n referrerHost: 253,\n utm: 100,\n refCode: 64,\n id: 64,\n sdk: 64,\n pageId: 32,\n region: 64,\n osBrowser: 32,\n /** Collector replaces a client `ts` farther than this from `received_at`. */\n tsSkewMs: 24 * 60 * 60 * 1000,\n} as const;\n\n// ---------------------------------------------------------------------------\n// Enumerations\n// ---------------------------------------------------------------------------\n\nexport const STREAMS = [\n \"storefront_events\",\n \"app_events\",\n \"business_events\",\n] as const;\nexport type Stream = (typeof STREAMS)[number];\n\nexport const ENVS = [\"live\", \"test\"] as const;\nexport type Env = (typeof ENVS)[number];\n\nexport const SOURCES = [\n \"storefront\",\n \"sdk_react\",\n \"script\",\n \"server\",\n \"dashboard\",\n] as const;\nexport type Source = (typeof SOURCES)[number];\n\nexport const CHANNELS = [\n \"hosted\",\n \"custom_domain\",\n \"embed\",\n \"api\",\n \"panel\",\n] as const;\nexport type Channel = (typeof CHANNELS)[number];\n\nexport const PAGE_TYPES = [\n \"shop\",\n \"catalog\",\n \"product\",\n \"cart\",\n \"checkout\",\n \"payment\",\n \"panel\",\n \"course\",\n \"custom_page\",\n \"order\",\n \"returns\",\n \"app\",\n \"other\",\n] as const;\nexport type PageType = (typeof PAGE_TYPES)[number];\n\nexport const DEVICE_TYPES = [\"desktop\", \"mobile\", \"tablet\", \"other\"] as const;\nexport type DeviceType = (typeof DEVICE_TYPES)[number];\n\n/** Sources a browser may claim, per stream. `business_events` is server-only. */\nexport const SOURCES_FOR_STREAM: Record<Stream, readonly Source[]> = {\n storefront_events: [\"storefront\", \"sdk_react\", \"script\"],\n app_events: [\"dashboard\"],\n business_events: [\"server\"],\n};\n\n// ---------------------------------------------------------------------------\n// Event catalogue\n//\n// Each prop is `<type>[?]`: type is `string`, `number`, `boolean`, `string[]`,\n// `number[]` or `enum:a|b|c`; a trailing `?` makes the prop optional.\n// Money is always integer minor units (`*_minor`, grosze/cents) + `currency`\n// (ISO 4217, upper case). `product_id`, `variant_id` and `order_ref` live in\n// the envelope, never in props. Strings never hold PII (see the prose doc).\n// ---------------------------------------------------------------------------\n\nconst MONEY = { value_minor: \"number\", currency: \"string\" } as const;\n\n/** Browser events from hosted pages (H), bitsnap-react (R) and the script (S). */\nexport const STOREFRONT_EVENT_SPEC = {\n page_view: { landing: \"boolean\" },\n product_list_viewed: { list_id: \"string?\", item_count: \"number\" },\n product_impression: {\n list_id: \"string?\",\n product_ids: \"string[]\",\n positions: \"number[]\",\n },\n product_clicked: { list_id: \"string?\", position: \"number?\" },\n product_view: {\n price_minor: \"number\",\n currency: \"string\",\n availability: \"enum:in_stock|out_of_stock|preorder\",\n },\n variant_selected: {},\n add_to_cart: { qty: \"number\", ...MONEY },\n remove_from_cart: { qty: \"number\", ...MONEY },\n cart_opened: { item_count: \"number\", ...MONEY },\n checkout_started: {\n item_count: \"number\",\n checkout_type: \"enum:single|cart|link\",\n ...MONEY,\n },\n checkout_step_completed: {\n step: \"enum:contact|delivery|invoice|consents\",\n },\n checkout_validation_error: { field: \"string\", rule: \"string\" },\n coupon_applied: { coupon_id: \"string\" },\n coupon_rejected: { coupon_id: \"string?\", reason: \"string\" },\n delivery_method_selected: { method: \"string\" },\n payment_method_selected: { gateway: \"string\", method: \"string\" },\n payment_submitted: { gateway: \"string\", method: \"string\" },\n apple_pay_clicked: {},\n apple_pay_result: { outcome: \"enum:success|fail|cancel\" },\n payment_returned: {\n gateway: \"string\",\n method: \"string?\",\n outcome: \"enum:success|fail|cancel|pending\",\n error_code: \"string?\",\n },\n availability_signup: {},\n panel_login: {},\n panel_order_viewed: {},\n panel_download: {},\n return_started: {},\n return_submitted: { reason_code: \"string\", item_count: \"number\" },\n course_opened: { course_id: \"string\" },\n lesson_started: {\n course_id: \"string\",\n lesson_id: \"string\",\n position: \"number\",\n },\n lesson_completed: {\n course_id: \"string\",\n lesson_id: \"string\",\n position: \"number\",\n },\n video_progress: {\n course_id: \"string\",\n lesson_id: \"string\",\n /** 25, 50, 75 or 100. */\n milestone: \"number\",\n },\n test_submitted: {\n course_id: \"string\",\n lesson_id: \"string\",\n score_bucket: \"enum:0-24|25-49|50-74|75-99|100\",\n },\n lesson_rated: {\n course_id: \"string\",\n lesson_id: \"string\",\n /** 1..5. */\n rating: \"number\",\n },\n /** Written by the collector's POST /consent, never sent to POST /e. */\n consent_updated: {\n consent_id: \"string\",\n action: \"enum:accept_all|reject_all|custom|withdraw\",\n analytics: \"boolean\",\n marketing: \"boolean\",\n preferences: \"boolean\",\n banner_version: \"number\",\n },\n /**\n * Written by the collector's POST /consent (action `shown`), never sent to\n * POST /e. A banner impression: no consent id, no choice, no visitor.\n */\n consent_shown: {\n banner_version: \"number\",\n },\n} as const;\n\n/** Merchant behaviour in /app, sent through the same tracker core. */\nexport const APP_EVENT_SPEC = {\n app_page_view: { route: \"string\", previous_route: \"string?\" },\n insight_shown: { insight_type: \"string\", rank: \"number\", category: \"string\" },\n insight_clicked: {\n insight_type: \"string\",\n rank: \"number\",\n category: \"string\",\n },\n insight_dismissed: {\n insight_type: \"string\",\n rank: \"number\",\n category: \"string\",\n },\n checklist_step_viewed: { step: \"string\" },\n checklist_step_completed: { step: \"string\" },\n gateway_connect_started: { gateway: \"string\", step: \"string?\" },\n gateway_connect_completed: { gateway: \"string\", step: \"string?\" },\n gateway_connect_failed: {\n gateway: \"string\",\n step: \"string?\",\n error_code: \"string?\",\n },\n domain_connect_started: {},\n domain_connect_verified: {},\n domain_connect_failed: { error_code: \"string?\" },\n product_created: { product_type: \"string?\" },\n product_published: { product_type: \"string?\" },\n product_editor_section_opened: { section: \"string\" },\n feature_enabled: { feature: \"string\" },\n stats_viewed: { tab: \"string\" },\n stats_filter_changed: { tab: \"string\", filter: \"string\" },\n report_exported: { report: \"string\", format: \"string?\" },\n search_performed: { result_count: \"number\" },\n error_shown: { code: \"string\", route: \"string\" },\n help_opened: { topic: \"string?\" },\n ai_assistant_used: { topic: \"string?\" },\n member_invited: { role: \"string\" },\n} as const;\n\nconst TX = {\n gateway: \"string?\",\n method: \"string?\",\n value_minor: \"number?\",\n currency: \"string?\",\n} as const;\nconst SUB = {\n subscription_id: \"string?\",\n value_minor: \"number?\",\n currency: \"string?\",\n} as const;\n\n/**\n * Emitted by instapay only. The lower-cased `EventType` of\n * server/event-system/event.list.ts maps 1:1 to the first group.\n */\nexport const BUSINESS_EVENT_SPEC = {\n // Mirror of the event bus (EventType.X -> x.toLowerCase()).\n transaction_created: TX,\n transaction_success: TX,\n transaction_failure: { ...TX, error_code: \"string?\" },\n transaction_expired: TX,\n transaction_charge: TX,\n subscription_created: SUB,\n subscription_paused: SUB,\n subscription_resumed: SUB,\n subscription_updated: SUB,\n subscription_deleted: SUB,\n subscription_charge_paid: SUB,\n subscription_charge_failed: { ...SUB, error_code: \"string?\" },\n subscription_past_due: SUB,\n subscription_canceled: SUB,\n access_expires_in_3_days: {},\n access_expired: {},\n cart_recovery: { value_minor: \"number?\", currency: \"string?\" },\n testimonial_email_send: {},\n testimonial_fulfilled: {},\n partner_commission_earned: {\n partner_id: \"string\",\n commission_minor: \"number\",\n currency: \"string\",\n },\n // Added by the analytics work.\n checkout_session_created: {\n item_count: \"number\",\n checkout_type: \"enum:single|cart|link\",\n gateway: \"string?\",\n ...MONEY,\n },\n order_paid: {\n gateway: \"string\",\n method: \"string?\",\n item_count: \"number?\",\n /** UTC date (`YYYY-MM-DD`) the envelope `visitor_id` was computed for. */\n visitor_day: \"string?\",\n /** Every line of the order (public hashed product ids), at most 50. */\n items: \"line_items?\",\n ...MONEY,\n },\n refund_issued: {\n gateway: \"string?\",\n reason: \"string?\",\n ...MONEY,\n },\n return_requested: { item_count: \"number\", reason_code: \"string?\" },\n automation_run_completed: {\n automation_id: \"string\",\n status: \"string\",\n trigger: \"string?\",\n },\n notification_sent: { medium: \"string\", template: \"string?\" },\n notification_failed: {\n medium: \"string\",\n template: \"string?\",\n error_code: \"string?\",\n },\n recovery_email_sent: { step: \"number?\" },\n recovery_link_clicked: {},\n api_request: {\n /** Route template without ids or query, e.g. `/api/rpc/public.v1.PublicApiService/ListProducts`. */\n endpoint: \"string\",\n /** `X-Bitsnap-Client` value, absent when the caller sent none. */\n client: \"string?\",\n status: \"number\",\n latency_bucket: \"enum:lt_50|lt_200|lt_1000|gte_1000\",\n /** 1 for errors, <1 for sampled successes; rollups divide counts by it. */\n sample_rate: \"number\",\n },\n} as const;\n\nexport const EVENT_SPEC_BY_STREAM = {\n storefront_events: STOREFRONT_EVENT_SPEC,\n app_events: APP_EVENT_SPEC,\n business_events: BUSINESS_EVENT_SPEC,\n} as const;\n\nexport const EVENT_SPEC = {\n ...STOREFRONT_EVENT_SPEC,\n ...APP_EVENT_SPEC,\n ...BUSINESS_EVENT_SPEC,\n} as const;\n\nexport type StorefrontEventName = keyof typeof STOREFRONT_EVENT_SPEC;\nexport type AppEventName = keyof typeof APP_EVENT_SPEC;\nexport type BusinessEventName = keyof typeof BUSINESS_EVENT_SPEC;\nexport type EventName = StorefrontEventName | AppEventName | BusinessEventName;\n\nexport const EVENT_NAMES = {\n storefront_events: Object.keys(STOREFRONT_EVENT_SPEC) as StorefrontEventName[],\n app_events: Object.keys(APP_EVENT_SPEC) as AppEventName[],\n business_events: Object.keys(BUSINESS_EVENT_SPEC) as BusinessEventName[],\n} as const;\n\nexport const STREAM_FOR_EVENT: Record<EventName, Stream> = Object.fromEntries(\n STREAMS.flatMap((stream) =>\n (EVENT_NAMES[stream] as string[]).map((name) => [name, stream] as const),\n ),\n) as Record<EventName, Stream>;\n\n/** True for a catalogue event name; own keys only (`constructor`, `toString` are not events). */\nexport function isEventName(name: unknown): name is EventName {\n return typeof name === \"string\" && Object.hasOwn(STREAM_FOR_EVENT, name);\n}\n\n// -- props types, derived from the spec ------------------------------------\n\ntype PropPrimitives = {\n string: string;\n number: number;\n boolean: boolean;\n \"string[]\": string[];\n \"number[]\": number[];\n line_items: Array<{ product_id: string; qty: number; value_minor: number }>;\n};\ntype SplitEnum<S extends string> = S extends `${infer H}|${infer R}`\n ? H | SplitEnum<R>\n : S;\ntype StripOpt<S extends string> = S extends `${infer B}?` ? B : S;\ntype ResolveProp<S extends string> =\n StripOpt<S> extends `enum:${infer E}`\n ? SplitEnum<E>\n : StripOpt<S> extends keyof PropPrimitives\n ? PropPrimitives[StripOpt<S>]\n : never;\ntype PropsFromSpec<S extends Record<string, string>> = {\n [K in keyof S as S[K] extends `${string}?` ? never : K]: ResolveProp<S[K]>;\n} & {\n [K in keyof S as S[K] extends `${string}?` ? K : never]?: ResolveProp<S[K]>;\n};\n\nexport type EventProps<E extends EventName> = PropsFromSpec<\n (typeof EVENT_SPEC)[E]\n>;\n\n// ---------------------------------------------------------------------------\n// Envelope\n// ---------------------------------------------------------------------------\n\n/** Fields the emitter fills in. Everything else is derived by the collector. */\nexport interface ClientEvent<E extends EventName = EventName> {\n /** UUIDv7, generated by the emitter. Dedupe key. */\n event_id: string;\n event: E;\n /** Client clock, unix ms. */\n ts: number;\n schema_version: typeof SCHEMA_VERSION;\n env: Env;\n source: Source;\n channel: Channel;\n /** `<package>@<version>`, e.g. `bitsnap-react@1.9.0`. */\n sdk?: string | null;\n /** Random per page load, in memory only. */\n page_id?: string | null;\n page_type?: PageType | null;\n host?: string | null;\n /** Path without query string and fragment, already run through `sanitizePath`. */\n path?: string | null;\n referrer_host?: string | null;\n utm_source?: string | null;\n utm_medium?: string | null;\n utm_campaign?: string | null;\n utm_content?: string | null;\n utm_term?: string | null;\n ref_code?: string | null;\n product_id?: string | null;\n variant_id?: string | null;\n order_ref?: string | null;\n /** Object on the wire; the collector stores `JSON.stringify(props)`. */\n props: EventProps<E>;\n /**\n * Only honoured for `source: \"dashboard\"`: the hashed Clerk user id computed\n * by instapay and handed to the dashboard tracker. Ignored for every other\n * source (the collector computes `visitor_id` itself).\n */\n visitor_id?: string | null;\n /**\n * The value of the first-party `bs_vid_<projectKey>` cookie (`CLIENT_ID_RE`), sent only\n * while analytics consent is granted. The collector turns it into a stable\n * `consentedVisitorId` and never stores it.\n */\n client_id?: string | null;\n}\n\n/** One row as stored in Basin (all three streams share this shape). */\nexport interface StoredEvent {\n event_id: string;\n event: EventName;\n /** Unix ms, client clock after `clampTs`. */\n ts: number;\n /** Unix ms, collector clock. */\n received_at: number;\n schema_version: number;\n /** Numeric database id. Resolved by the collector, never taken from the client. */\n project_id: number;\n env: Env;\n source: Source;\n channel: Channel;\n sdk: string | null;\n visitor_id: string | null;\n page_id: string | null;\n page_type: PageType | null;\n host: string | null;\n path: string | null;\n referrer_host: string | null;\n utm_source: string | null;\n utm_medium: string | null;\n utm_campaign: string | null;\n utm_content: string | null;\n utm_term: string | null;\n ref_code: string | null;\n country: string | null;\n region: string | null;\n device_type: DeviceType | null;\n os: string | null;\n browser: string | null;\n product_id: string | null;\n variant_id: string | null;\n order_ref: string | null;\n /** `JSON.stringify` of the props object. */\n props: string;\n}\n\n/** POST /e body. */\nexport interface IngestBody {\n /** Project key, see `normalizeProjectKey`. */\n k: string;\n events: ClientEvent[];\n}\n\n// ---------------------------------------------------------------------------\n// Consent shapes\n// ---------------------------------------------------------------------------\n\nexport const CONSENT_TEXT_KEYS = [\n \"title\",\n \"description\",\n \"acceptAll\",\n \"rejectAll\",\n \"settings\",\n \"save\",\n \"close\",\n \"necessaryTitle\",\n \"necessaryDescription\",\n \"analyticsTitle\",\n \"analyticsDescription\",\n \"marketingTitle\",\n \"marketingDescription\",\n \"preferencesTitle\",\n \"preferencesDescription\",\n \"poweredBy\",\n] as const;\nexport type ConsentTextKey = (typeof CONSENT_TEXT_KEYS)[number];\nexport type ConsentTexts = Record<ConsentTextKey, string>;\n\nexport type ConsentCategory = \"analytics\" | \"marketing\" | \"preferences\";\nexport type ConsentChoice = Record<ConsentCategory, boolean>;\n\nexport type ConsentConfig = {\n version: number;\n theme: \"auto\" | \"light\" | \"dark\";\n accentColor?: string;\n position: \"bottom\" | \"bottom-left\" | \"bottom-right\";\n privacyPolicyUrl?: string;\n categories: { analytics: boolean; marketing: boolean; preferences: boolean };\n services: Array<{\n name: string;\n category: \"analytics\" | \"marketing\" | \"preferences\";\n cookies?: string[];\n }>;\n texts?: Partial<Record<\"pl\" | \"en\", Partial<ConsentTexts>>>;\n poweredBy: true;\n};\n\n/** Value of the consent cookie, JSON then base64url. */\nexport interface ConsentCookie {\n v: 1;\n /** Random consent id (also sent to POST /consent). */\n id: string;\n /** Unix seconds. */\n ts: number;\n /** Banner version (`ConsentConfig.version`) the visitor answered. */\n bv: number;\n c: ConsentChoice;\n}\n\nexport const CONSENT_COOKIE_NAME = \"bitsnap_consent\";\nexport const CONSENT_COOKIE_MAX_AGE_SECONDS = 365 * 24 * 60 * 60;\nexport const CONSENT_ACTIONS = [\n \"accept_all\",\n \"reject_all\",\n \"custom\",\n \"withdraw\",\n] as const;\nexport type ConsentAction = (typeof CONSENT_ACTIONS)[number];\n/** POST /consent `action` of a banner impression (not a choice, not in `CONSENT_ACTIONS`). */\nexport const CONSENT_SHOWN_ACTION = \"shown\";\n\n/** POST /consent body of a choice (`CONSENT_ACTIONS`). */\nexport interface ConsentLogBody {\n k: string;\n /** Same random id as `ConsentCookie.id`. 16 to 64 chars of `[A-Za-z0-9_-]`. */\n consent_id: string;\n action: ConsentAction;\n c: ConsentChoice;\n /** Banner version. */\n bv: number;\n /** Hostname the banner ran on. Collector overwrites it with the Origin host. */\n host: string;\n /** Unix SECONDS (like the cookie), not ms. */\n ts: number;\n}\n\n/**\n * POST /consent body of a banner impression: the banner opened by itself\n * because the visitor has no valid choice. Once per page load; no consent id\n * and no choice.\n */\nexport interface ConsentShownBody {\n k: string;\n action: typeof CONSENT_SHOWN_ACTION;\n /** Banner version. */\n bv: number;\n /** Hostname the banner ran on. Collector overwrites it with the Origin host. */\n host: string;\n /** Unix SECONDS (like the cookie), not ms. */\n ts: number;\n}\n\n/** Any POST /consent body; discriminate on `action`. */\nexport type ConsentBody = ConsentLogBody | ConsentShownBody;\n\n/** `bitsnap_consent`, or `bitsnap_consent_<projectKey>` for `data-scope=\"project\"`. */\nexport function consentCookieName(scope: \"site\" | \"project\", projectKey?: string): string {\n if (scope === \"project\") {\n if (!projectKey) throw new Error(\"projectKey required for project scope\");\n return `${CONSENT_COOKIE_NAME}_${normalizeProjectKey(projectKey)}`;\n }\n return CONSENT_COOKIE_NAME;\n}\n\n/**\n * Decodes the value of a consent cookie (§11.3). Null when it is not base64url\n * JSON of the documented shape (`v` 1 and a boolean per category).\n */\nexport function parseConsentCookie(value: string | null | undefined): ConsentCookie | null {\n if (!value || !/^[A-Za-z0-9_-]+$/.test(value)) return null;\n try {\n const padded = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const bin = atob(padded + \"=\".repeat((4 - (padded.length % 4)) % 4));\n const json: unknown = JSON.parse(\n new TextDecoder().decode(Uint8Array.from(bin, (ch) => ch.charCodeAt(0))),\n );\n if (!isRecord(json) || json.v !== 1) return null;\n const c = json.c;\n if (!isRecord(c)) return null;\n if (\n typeof c.analytics !== \"boolean\" ||\n typeof c.marketing !== \"boolean\" ||\n typeof c.preferences !== \"boolean\"\n ) {\n return null;\n }\n return json as unknown as ConsentCookie;\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Project key\n// ---------------------------------------------------------------------------\n\n/**\n * The project key is the existing public hashed project id\n * (`hashId(projectId)` in apps/bitsnap/queries/hashids.ts, the `projectID`\n * of bitsnap-react). A leading `pk_` is accepted and dropped so the\n * documented `pk_…` snippets work too. Returns null when it is not a plausible\n * key (hashids default alphabet).\n */\nexport function normalizeProjectKey(key: string): string | null {\n const bare = key.startsWith(\"pk_\") ? key.slice(3) : key;\n return /^[A-Za-z0-9]{1,32}$/.test(bare) ? bare : null;\n}\n\n// ---------------------------------------------------------------------------\n// X-Bitsnap-Client\n// ---------------------------------------------------------------------------\n\nconst CLIENT_RE = /^([a-z][a-z0-9-]{0,39})@(\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.+-]{1,20})?)$/;\n\n/** `<package>@<version>`, e.g. `bitsnap-react@1.9.0`. Also the shape of `sdk`. */\nexport function parseClientHeader(\n value: string | null | undefined,\n): { package: string; version: string } | null {\n if (!value || value.length > LIMITS.sdk) return null;\n const m = CLIENT_RE.exec(value);\n return m ? { package: m[1], version: m[2] } : null;\n}\n\n// ---------------------------------------------------------------------------\n// URL stripping\n// ---------------------------------------------------------------------------\n\nconst MAX_QUERY_VALUE = LIMITS.utm;\n\n/**\n * Campaign/ref value: trimmed, capped, null when empty or when it holds an \"@\"\n * (someone put an email in a tag). The collector runs every client-supplied\n * `utm_*` and `ref_code` through it again.\n */\nexport function cleanValue(v: string | null | undefined, max: number): string | null {\n if (v == null) return null;\n const t = v.trim();\n // An \"@\" means someone put an email in a campaign tag: drop the value.\n if (t.length === 0 || t.includes(\"@\")) return null;\n return t.slice(0, max);\n}\n\n/**\n * Path sanitiser: no query, no fragment, capped. Opaque segments (24+ chars of\n * `[A-Za-z0-9_-]`, i.e. tokens in order/panel links) become `:token` and\n * segments containing `@` become `:email`.\n */\nexport function sanitizePath(pathname: string): string {\n const segments = pathname.split(\"/\").map((seg) => {\n if (seg.includes(\"@\") || seg.includes(\"%40\")) return \":email\";\n if (/^[A-Za-z0-9_-]{24,}$/.test(seg)) return \":token\";\n return seg;\n });\n const joined = segments.join(\"/\") || \"/\";\n return (joined.startsWith(\"/\") ? joined : `/${joined}`).slice(0, LIMITS.path);\n}\n\nexport interface UrlParts {\n host: string;\n /** Sanitised path, no query. */\n path: string;\n utm_source: string | null;\n utm_medium: string | null;\n utm_campaign: string | null;\n utm_content: string | null;\n utm_term: string | null;\n /** The `ref` query parameter. */\n ref_code: string | null;\n}\n\n/**\n * Parses a URL and keeps only what may leave the browser: host, sanitised path\n * and the `utm_*` and `ref` query parameters. Returns null for non-http(s) or\n * unparseable input. `base` resolves relative URLs.\n */\nexport function parseUrl(url: string, base?: string): UrlParts | null {\n let u: URL;\n try {\n u = new URL(url, base);\n } catch {\n return null;\n }\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n const q = u.searchParams;\n return {\n host: u.hostname.toLowerCase().slice(0, LIMITS.host),\n path: sanitizePath(u.pathname),\n utm_source: cleanValue(q.get(\"utm_source\"), MAX_QUERY_VALUE),\n utm_medium: cleanValue(q.get(\"utm_medium\"), MAX_QUERY_VALUE),\n utm_campaign: cleanValue(q.get(\"utm_campaign\"), MAX_QUERY_VALUE),\n utm_content: cleanValue(q.get(\"utm_content\"), MAX_QUERY_VALUE),\n utm_term: cleanValue(q.get(\"utm_term\"), MAX_QUERY_VALUE),\n ref_code: cleanValue(q.get(\"ref\"), LIMITS.refCode),\n };\n}\n\n/**\n * Returns the URL with userinfo, fragment and every query parameter removed\n * except `utm_*` and `ref`. Null when `url` is not a usable http(s) URL.\n */\nexport function stripUrl(url: string, base?: string): string | null {\n let u: URL;\n try {\n u = new URL(url, base);\n } catch {\n return null;\n }\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n const keep = new URLSearchParams();\n for (const [key, value] of u.searchParams) {\n if (key !== \"ref\" && !key.startsWith(\"utm_\")) continue;\n const cleaned = cleanValue(value, MAX_QUERY_VALUE);\n if (cleaned != null) keep.append(key, cleaned);\n }\n const qs = keep.toString();\n return `${u.protocol}//${u.host}${sanitizePath(u.pathname)}${qs ? `?${qs}` : \"\"}`;\n}\n\nconst HOSTNAME_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/;\n\n/** A plain DNS hostname (lower-cased), or null: no scheme, port, path, userinfo or \"@\". */\nexport function cleanHostname(\n v: string | null | undefined,\n max: number = LIMITS.referrerHost,\n): string | null {\n if (typeof v !== \"string\") return null;\n const h = v.trim().toLowerCase();\n return h.length > 0 && h.length <= max && HOSTNAME_RE.test(h) ? h : null;\n}\n\n/** Public hashed ids (`product_id`, `variant_id`, `order_ref`): URL-safe, at most `LIMITS.id`. */\nexport const ID_RE = /^[A-Za-z0-9_-]{1,64}$/;\n\nexport function cleanId(v: string | null | undefined): string | null {\n return typeof v === \"string\" && ID_RE.test(v) ? v : null;\n}\n\n/** Host of a referrer URL, or null (also null for non-http(s) referrers). */\nexport function referrerHost(referrer: string | null | undefined): string | null {\n if (!referrer) return null;\n try {\n const u = new URL(referrer);\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n return u.hostname.toLowerCase().slice(0, LIMITS.referrerHost);\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Bot rule\n// ---------------------------------------------------------------------------\n\nconst BOT_UA =\n /bot\\b|crawl|spider|slurp|facebookexternalhit|bingpreview|headless|phantomjs|lighthouse|pagespeed|gtmetrix|pingdom|uptime|statuscake|monitor|preview|scrapy|curl\\/|wget|python-|go-http-client|java\\/|okhttp|axios|node-fetch|undici|libwww|httpclient|aiohttp|postman|insomnia/i;\n\n/** True when the User-Agent is empty or looks automated. Such events are dropped. */\nexport function isBotUserAgent(ua: string | null | undefined): boolean {\n if (!ua || ua.trim().length === 0) return true;\n return BOT_UA.test(ua);\n}\n\n// ---------------------------------------------------------------------------\n// visitor_id\n// ---------------------------------------------------------------------------\n\nconst encoder = new TextEncoder();\n\nasync function hmacSha256(\n key: Uint8Array,\n message: string,\n): Promise<Uint8Array> {\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key,\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n return new Uint8Array(\n await crypto.subtle.sign(\"HMAC\", cryptoKey, encoder.encode(message)),\n );\n}\n\nfunction base64url(bytes: Uint8Array): string {\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n return btoa(bin).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** `YYYY-MM-DD` of a unix-ms timestamp in UTC. */\nexport function utcDate(ms: number): string {\n return new Date(ms).toISOString().slice(0, 10);\n}\n\n/**\n * IP as hashed: lower-case; IPv4 unchanged; IPv4-mapped IPv6 (`::ffff:1.2.3.4`\n * or `::ffff:102:304`) becomes plain IPv4; any other IPv6, including one with\n * an embedded dotted quad (`64:ff9b::1.2.3.4`), is cut to its /64 (first four\n * hextets, canonical form `a:b:c:d::`). Both the Worker and the instapay\n * server MUST call this on the client IP before `computeVisitorId`.\n */\nexport function normalizeIp(ip: string): string {\n let s = ip.trim().toLowerCase();\n const zone = s.indexOf(\"%\");\n if (zone >= 0) s = s.slice(0, zone);\n if (!s.includes(\":\")) return s; // plain IPv4 (or not an IP at all)\n\n // Embedded dotted quad in the last 32 bits: turn it into two hextets.\n const quad = /^(.*:)(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(s);\n if (quad) {\n const o = [quad[2], quad[3], quad[4], quad[5]].map(Number);\n if (o.some((n) => n > 255)) return s;\n const hex = (hi: number, lo: number) => (hi * 256 + lo).toString(16);\n s = `${quad[1]}${hex(o[0], o[1])}:${hex(o[2], o[3])}`;\n }\n\n const [head, tail] = s.split(\"::\");\n const headParts = head ? head.split(\":\") : [];\n const tailParts = tail !== undefined && tail !== \"\" ? tail.split(\":\") : [];\n const fill =\n tail === undefined ? 0 : Math.max(0, 8 - headParts.length - tailParts.length);\n const groups = [...headParts, ...Array<string>(fill).fill(\"0\"), ...tailParts];\n if (groups.length !== 8) return s;\n const h = groups.map((g) => Number.parseInt(g, 16) || 0);\n\n // ::ffff:a.b.c.d in hex form.\n if (h.slice(0, 5).every((x) => x === 0) && h[5] === 0xffff) {\n return `${h[6] >> 8}.${h[6] & 255}.${h[7] >> 8}.${h[7] & 255}`;\n }\n return `${h\n .slice(0, 4)\n .map((g) => g.toString(16))\n .join(\":\")}::`;\n}\n\n/**\n * Cookieless visitor id, identical in the Worker and the instapay server.\n *\n * day_secret = HMAC-SHA256(key = utf8(masterSecret), msg = utf8(\"YYYY-MM-DD\")) // 32 raw bytes\n * visitor_id = base64url(HMAC-SHA256(key = day_secret, msg = utf8(ip + \"\\n\" + ua + \"\\n\" + projectId))).slice(0, 22)\n *\n * `dateUtc` is the UTC date of the request; `ip` is `normalizeIp(<client IP>)`;\n * `ua` is the raw `User-Agent` request header; `projectId` is the decimal\n * numeric project id.\n */\nexport async function computeVisitorId(\n masterSecret: string,\n dateUtc: string,\n ip: string,\n ua: string,\n projectId: number | string,\n): Promise<string> {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(dateUtc)) {\n throw new Error(`dateUtc must be YYYY-MM-DD, got ${dateUtc}`);\n }\n const daySecret = await hmacSha256(encoder.encode(masterSecret), dateUtc);\n const mac = await hmacSha256(daySecret, `${ip}\\n${ua}\\n${projectId}`);\n return base64url(mac).slice(0, 22);\n}\n\n/**\n * The `bs_vid_<projectKey>` cookie name. `projectKey` is the bare public key\n * (like `consentCookieName`): consent is per project, so is the client id.\n */\nexport function clientIdCookieName(projectKey: string): string {\n return `bs_vid_${projectKey}`;\n}\n\n/** Value of the `bs_vid_<projectKey>` cookie: 16 random bytes, base64url without padding. */\nexport const CLIENT_ID_RE = /^[A-Za-z0-9_-]{22}$/;\n\n/**\n * Stable visitor id of a browser that granted analytics consent (contract §6).\n *\n * consented_visitor_id = \"p_\" + base64url(HMAC-SHA256(key = utf8(masterSecret),\n * msg = utf8(\"client\\n\" + clientId + \"\\n\" + projectId))).slice(0, 22)\n *\n * 24 characters; daily ids are 22, so `isConsentedVisitorId` tells them apart.\n * `clientId` is the `bs_vid_<projectKey>` cookie value and is never stored.\n */\nexport async function computeConsentedVisitorId(\n masterSecret: string,\n clientId: string,\n projectId: number | string,\n): Promise<string> {\n if (!CLIENT_ID_RE.test(clientId)) {\n throw new Error(\"clientId must be 22 base64url characters\");\n }\n const mac = await hmacSha256(\n encoder.encode(masterSecret),\n `client\\n${clientId}\\n${projectId}`,\n );\n return `p_${base64url(mac).slice(0, 22)}`;\n}\n\n/** Whether `visitorId` came from `computeConsentedVisitorId` (not a daily id). */\nexport function isConsentedVisitorId(visitorId: string): boolean {\n return visitorId.length === 24 && visitorId.startsWith(\"p_\");\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport type ValidationResult = { ok: true } | { ok: false; reason: string };\n\nconst UUID_V7 =\n /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst PAGE_ID_RE = /^[A-Za-z0-9_-]{8,32}$/;\n/** A letter TLD is required: `bitsnap-react@1.9.0` and `v@1.2` are not addresses. */\nconst EMAIL_LIKE = /[^\\s@]+@[^\\s@]+\\.[A-Za-z]{2,}\\b/;\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction nullableString(\n e: Record<string, unknown>,\n key: string,\n max: number,\n): string | null {\n const v = e[key];\n if (v === undefined || v === null) return null;\n if (typeof v !== \"string\") return `bad_${key}`;\n return v.length > max ? `too_long_${key}` : null;\n}\n\nfunction checkPropValue(spec: string, value: unknown): boolean {\n const optional = spec.endsWith(\"?\");\n const type = optional ? spec.slice(0, -1) : spec;\n if (type.startsWith(\"enum:\")) {\n return typeof value === \"string\" && type.slice(5).split(\"|\").includes(value);\n }\n switch (type) {\n case \"string\":\n return typeof value === \"string\" && value.length <= LIMITS.maxPropString;\n case \"number\":\n return typeof value === \"number\" && Number.isFinite(value);\n case \"boolean\":\n return typeof value === \"boolean\";\n case \"string[]\":\n return (\n Array.isArray(value) &&\n value.length <= LIMITS.maxPropArray &&\n value.every((x) => typeof x === \"string\" && x.length <= LIMITS.maxPropString)\n );\n case \"number[]\":\n return (\n Array.isArray(value) &&\n value.length <= LIMITS.maxPropArray &&\n value.every((x) => typeof x === \"number\" && Number.isFinite(x))\n );\n case \"line_items\":\n return (\n Array.isArray(value) &&\n value.length <= LIMITS.maxPropArray &&\n value.every(\n (x) =>\n isRecord(x) &&\n typeof x.product_id === \"string\" &&\n ID_RE.test(x.product_id) &&\n isNonNegativeSafeInteger(x.qty) &&\n isNonNegativeSafeInteger(x.value_minor),\n )\n );\n default:\n return false;\n }\n}\n\nfunction isNonNegativeSafeInteger(value: unknown): boolean {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\n/** True when `value` looks like an email address (also exported for the collector's re-checks). */\nexport function looksLikeEmail(value: string): boolean {\n // A well-formed `<package>@<version>` client id is never an address.\n if (parseClientHeader(value) !== null) return false;\n return EMAIL_LIKE.test(value);\n}\n\nfunction hasEmailLike(value: unknown): boolean {\n if (typeof value === \"string\") return looksLikeEmail(value);\n if (Array.isArray(value)) return value.some(hasEmailLike);\n if (isRecord(value)) return Object.values(value).some(hasEmailLike);\n return false;\n}\n\n/**\n * Validates `props` against the catalogue and returns a copy without keys the\n * catalogue does not know (forward compatibility: a newer SDK adding an\n * optional prop must not get its events dropped by an older collector).\n * Fails on missing required props, wrong types, bad enum values, oversize\n * props and string values that look like an email address.\n */\nexport function sanitizeProps(\n event: string,\n props: unknown,\n): { ok: true; props: Record<string, unknown> } | { ok: false; reason: string } {\n if (!isEventName(event)) return { ok: false, reason: \"unknown_event\" };\n const spec = (EVENT_SPEC as Record<string, Record<string, string>>)[event];\n if (!spec) return { ok: false, reason: \"unknown_event\" };\n if (!isRecord(props)) return { ok: false, reason: \"bad_props\" };\n const out: Record<string, unknown> = {};\n for (const [key, type] of Object.entries(spec)) {\n const value = props[key];\n if (value === undefined || value === null) {\n if (!type.endsWith(\"?\")) return { ok: false, reason: `props_missing_${key}` };\n continue;\n }\n if (!checkPropValue(type, value)) return { ok: false, reason: `props_bad_${key}` };\n if (hasEmailLike(value)) return { ok: false, reason: `props_pii_${key}` };\n out[key] =\n type.startsWith(\"line_items\") && Array.isArray(value)\n ? value.map((x) => ({ product_id: x.product_id, qty: x.qty, value_minor: x.value_minor }))\n : value;\n }\n if (JSON.stringify(out).length > LIMITS.maxPropsChars) {\n return { ok: false, reason: \"props_too_large\" };\n }\n return { ok: true, props: out };\n}\n\nexport interface ValidateOptions {\n /**\n * Who sent it. `browser` (default) is POST /e: the event must belong to\n * `storefront_events` or `app_events`, `consent_updated` and `consent_shown`\n * are refused (only POST /consent writes them) and `source` must fit the\n * stream. `server` is the instapay emitter: any stream, `source` must fit the\n * stream.\n */\n from?: \"browser\" | \"server\";\n}\n\n/**\n * Validates the emitter-controlled part of an event: names, types, enums,\n * lengths, the event/source/stream pairing and `props`. It does not check\n * that `ts` is plausible (use `clampTs`), origins or project keys.\n */\nexport function validateEnvelope(\n e: unknown,\n options: ValidateOptions = {},\n): ValidationResult {\n const from = options.from ?? \"browser\";\n const fail = (reason: string): ValidationResult => ({ ok: false, reason });\n if (!isRecord(e)) return fail(\"not_object\");\n\n if (typeof e.event_id !== \"string\" || !UUID_V7.test(e.event_id)) {\n return fail(\"bad_event_id\");\n }\n if (!isEventName(e.event)) return fail(\"unknown_event\");\n const stream = STREAM_FOR_EVENT[e.event as EventName];\n if (from === \"browser\") {\n if (stream === \"business_events\") return fail(\"server_only_event\");\n if (e.event === \"consent_updated\" || e.event === \"consent_shown\") {\n return fail(\"consent_via_consent_endpoint\");\n }\n }\n if (\n typeof e.ts !== \"number\" ||\n !Number.isInteger(e.ts) ||\n e.ts <= 0 ||\n e.ts > 4e12\n ) {\n return fail(\"bad_ts\");\n }\n if (e.schema_version !== SCHEMA_VERSION) return fail(\"bad_schema_version\");\n if (!ENVS.includes(e.env as Env)) return fail(\"bad_env\");\n if (!SOURCES.includes(e.source as Source)) return fail(\"bad_source\");\n if (!SOURCES_FOR_STREAM[stream].includes(e.source as Source)) {\n return fail(\"source_not_allowed_for_event\");\n }\n if (!CHANNELS.includes(e.channel as Channel)) return fail(\"bad_channel\");\n\n if (e.sdk != null) {\n if (typeof e.sdk !== \"string\" || parseClientHeader(e.sdk) === null) {\n return fail(\"bad_sdk\");\n }\n }\n if (e.page_id != null) {\n if (typeof e.page_id !== \"string\" || !PAGE_ID_RE.test(e.page_id)) {\n return fail(\"bad_page_id\");\n }\n }\n if (e.page_type != null && !PAGE_TYPES.includes(e.page_type as PageType)) {\n return fail(\"bad_page_type\");\n }\n if (from === \"browser\") {\n if (typeof e.host !== \"string\" || e.host.length === 0) return fail(\"bad_host\");\n if (typeof e.path !== \"string\" || !e.path.startsWith(\"/\")) return fail(\"bad_path\");\n }\n if (typeof e.path === \"string\" && e.path.includes(\"?\")) return fail(\"path_has_query\");\n if (typeof e.path === \"string\" && e.path.includes(\"#\")) return fail(\"path_has_fragment\");\n\n const lengths: Array<[string, number]> = [\n [\"host\", LIMITS.host],\n [\"path\", LIMITS.path],\n [\"referrer_host\", LIMITS.referrerHost],\n [\"utm_source\", LIMITS.utm],\n [\"utm_medium\", LIMITS.utm],\n [\"utm_campaign\", LIMITS.utm],\n [\"utm_content\", LIMITS.utm],\n [\"utm_term\", LIMITS.utm],\n [\"ref_code\", LIMITS.refCode],\n [\"product_id\", LIMITS.id],\n [\"variant_id\", LIMITS.id],\n [\"order_ref\", LIMITS.id],\n ];\n for (const [key, max] of lengths) {\n const problem = nullableString(e, key, max);\n if (problem) return fail(problem);\n }\n if (e.visitor_id != null) {\n if (typeof e.visitor_id !== \"string\" || !/^[A-Za-z0-9_-]{22}$/.test(e.visitor_id)) {\n return fail(\"bad_visitor_id\");\n }\n }\n if (e.client_id != null) {\n if (typeof e.client_id !== \"string\" || !CLIENT_ID_RE.test(e.client_id)) {\n return fail(\"bad_client_id\");\n }\n }\n\n const props = sanitizeProps(e.event, e.props);\n if (!props.ok) return fail(props.reason);\n return { ok: true };\n}\n\n/** Client `ts` as stored: replaced by `receivedAt` when more than 24 h away from it. */\nexport function clampTs(ts: number, receivedAt: number): number {\n return Math.abs(ts - receivedAt) > LIMITS.tsSkewMs ? receivedAt : ts;\n}\n"]}
1
+ {"version":3,"sources":["../src/analytics/contract.ts"],"names":["LIMITS","STREAMS","ENVS","SOURCES","CHANNELS","PAGE_TYPES","SOURCES_FOR_STREAM","MONEY","STOREFRONT_EVENT_SPEC","APP_EVENT_SPEC","TX","SUB","BUSINESS_EVENT_SPEC","EVENT_SPEC","EVENT_NAMES","STREAM_FOR_EVENT","stream","name","isEventName","CONSENT_COOKIE_MAX_AGE_SECONDS","CONSENT_SHOWN_ACTION","normalizeProjectKey","key","bare","CLIENT_RE","parseClientHeader","value","m","MAX_QUERY_VALUE","cleanValue","v","max","t","sanitizePath","pathname","joined","seg"],"mappings":"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","file":"/home/user/bitsnap-react-payment-release/dist/chunk-W3RGQYPD.js","sourcesContent":["/**\n * Bitsnap merchant analytics: the wire contract.\n *\n * SOURCE OF TRUTH: instapay `apps/collector/src/contract.ts` (prose version:\n * `docs/merchant-analytics-contract.md`). This file is a verbatim copy of it\n * (everything below the next comment block). Do not edit it here: change\n * instapay's file and copy it over. `computeVisitorId` and\n * `computeConsentedVisitorId` are pure but need the server secret; they are\n * server-only: the browser never calls them, so bundlers drop them.\n */\n\nexport const SCHEMA_VERSION = 1;\n\n// ---------------------------------------------------------------------------\n// Limits\n// ---------------------------------------------------------------------------\n\nexport const LIMITS = {\n /** Events in one POST /e. */\n maxBatchEvents: 50,\n /** Body of one POST /e or /consent, in bytes. */\n maxBodyBytes: 64 * 1024,\n /** `JSON.stringify(props)` of one event, in UTF-16 code units. */\n maxPropsChars: 4096,\n maxPropString: 200,\n maxPropArray: 50,\n host: 253,\n path: 512,\n referrerHost: 253,\n utm: 100,\n refCode: 64,\n id: 64,\n sdk: 64,\n pageId: 32,\n region: 64,\n osBrowser: 32,\n /** Collector replaces a client `ts` farther than this from `received_at`. */\n tsSkewMs: 24 * 60 * 60 * 1000,\n} as const;\n\n// ---------------------------------------------------------------------------\n// Enumerations\n// ---------------------------------------------------------------------------\n\nexport const STREAMS = [\n \"storefront_events\",\n \"app_events\",\n \"business_events\",\n] as const;\nexport type Stream = (typeof STREAMS)[number];\n\nexport const ENVS = [\"live\", \"test\"] as const;\nexport type Env = (typeof ENVS)[number];\n\nexport const SOURCES = [\n \"storefront\",\n \"sdk_react\",\n \"script\",\n \"server\",\n \"dashboard\",\n] as const;\nexport type Source = (typeof SOURCES)[number];\n\nexport const CHANNELS = [\n \"hosted\",\n \"custom_domain\",\n \"embed\",\n \"api\",\n \"panel\",\n] as const;\nexport type Channel = (typeof CHANNELS)[number];\n\nexport const PAGE_TYPES = [\n \"shop\",\n \"catalog\",\n \"product\",\n \"cart\",\n \"checkout\",\n \"payment\",\n \"panel\",\n \"course\",\n \"custom_page\",\n \"order\",\n \"returns\",\n \"app\",\n \"other\",\n] as const;\nexport type PageType = (typeof PAGE_TYPES)[number];\n\nexport const DEVICE_TYPES = [\"desktop\", \"mobile\", \"tablet\", \"other\"] as const;\nexport type DeviceType = (typeof DEVICE_TYPES)[number];\n\n/** Sources a browser may claim, per stream. `business_events` is server-only. */\nexport const SOURCES_FOR_STREAM: Record<Stream, readonly Source[]> = {\n storefront_events: [\"storefront\", \"sdk_react\", \"script\"],\n app_events: [\"dashboard\"],\n business_events: [\"server\"],\n};\n\n// ---------------------------------------------------------------------------\n// Event catalogue\n//\n// Each prop is `<type>[?]`: type is `string`, `number`, `boolean`, `string[]`,\n// `number[]` or `enum:a|b|c`; a trailing `?` makes the prop optional.\n// Money is always integer minor units (`*_minor`, grosze/cents) + `currency`\n// (ISO 4217, upper case). `product_id`, `variant_id` and `order_ref` live in\n// the envelope, never in props. Strings never hold PII (see the prose doc).\n// ---------------------------------------------------------------------------\n\nconst MONEY = { value_minor: \"number\", currency: \"string\" } as const;\n\n/** Browser events from hosted pages (H), bitsnap-react (R) and the script (S). */\nexport const STOREFRONT_EVENT_SPEC = {\n page_view: { landing: \"boolean\" },\n product_list_viewed: { list_id: \"string?\", item_count: \"number\" },\n product_impression: {\n list_id: \"string?\",\n product_ids: \"string[]\",\n positions: \"number[]\",\n },\n product_clicked: { list_id: \"string?\", position: \"number?\" },\n product_view: {\n price_minor: \"number\",\n currency: \"string\",\n availability: \"enum:in_stock|out_of_stock|preorder\",\n },\n variant_selected: {},\n add_to_cart: { qty: \"number\", ...MONEY },\n remove_from_cart: { qty: \"number\", ...MONEY },\n cart_opened: { item_count: \"number\", ...MONEY },\n checkout_started: {\n item_count: \"number\",\n checkout_type: \"enum:single|cart|link\",\n ...MONEY,\n },\n checkout_step_completed: {\n step: \"enum:contact|delivery|invoice|consents\",\n },\n checkout_validation_error: { field: \"string\", rule: \"string\" },\n coupon_applied: { coupon_id: \"string\" },\n coupon_rejected: { coupon_id: \"string?\", reason: \"string\" },\n delivery_method_selected: { method: \"string\" },\n payment_method_selected: { gateway: \"string\", method: \"string\" },\n payment_submitted: { gateway: \"string\", method: \"string\" },\n apple_pay_clicked: {},\n apple_pay_result: { outcome: \"enum:success|fail|cancel\" },\n payment_returned: {\n gateway: \"string\",\n method: \"string?\",\n outcome: \"enum:success|fail|cancel|pending\",\n error_code: \"string?\",\n },\n availability_signup: {},\n panel_login: {},\n panel_order_viewed: {},\n panel_download: {},\n return_started: {},\n return_submitted: { reason_code: \"string\", item_count: \"number\" },\n course_opened: { course_id: \"string\" },\n lesson_started: {\n course_id: \"string\",\n lesson_id: \"string\",\n position: \"number\",\n },\n lesson_completed: {\n course_id: \"string\",\n lesson_id: \"string\",\n position: \"number\",\n },\n video_progress: {\n course_id: \"string\",\n lesson_id: \"string\",\n /** 25, 50, 75 or 100. */\n milestone: \"number\",\n },\n test_submitted: {\n course_id: \"string\",\n lesson_id: \"string\",\n score_bucket: \"enum:0-24|25-49|50-74|75-99|100\",\n },\n lesson_rated: {\n course_id: \"string\",\n lesson_id: \"string\",\n /** 1..5. */\n rating: \"number\",\n },\n /** Written by the collector's POST /consent, never sent to POST /e. */\n consent_updated: {\n consent_id: \"string\",\n action: \"enum:accept_all|reject_all|custom|withdraw\",\n analytics: \"boolean\",\n marketing: \"boolean\",\n preferences: \"boolean\",\n banner_version: \"number\",\n },\n /**\n * Written by the collector's POST /consent (action `shown`), never sent to\n * POST /e. A banner impression: no consent id, no choice, no visitor.\n */\n consent_shown: {\n banner_version: \"number\",\n },\n} as const;\n\n/** Merchant behaviour in /app, sent through the same tracker core. */\nexport const APP_EVENT_SPEC = {\n app_page_view: { route: \"string\", previous_route: \"string?\" },\n insight_shown: { insight_type: \"string\", rank: \"number\", category: \"string\" },\n insight_clicked: {\n insight_type: \"string\",\n rank: \"number\",\n category: \"string\",\n },\n insight_dismissed: {\n insight_type: \"string\",\n rank: \"number\",\n category: \"string\",\n },\n checklist_step_viewed: { step: \"string\" },\n checklist_step_completed: { step: \"string\" },\n gateway_connect_started: { gateway: \"string\", step: \"string?\" },\n gateway_connect_completed: { gateway: \"string\", step: \"string?\" },\n gateway_connect_failed: {\n gateway: \"string\",\n step: \"string?\",\n error_code: \"string?\",\n },\n domain_connect_started: {},\n domain_connect_verified: {},\n domain_connect_failed: { error_code: \"string?\" },\n product_created: { product_type: \"string?\" },\n product_published: { product_type: \"string?\" },\n product_editor_section_opened: { section: \"string\" },\n feature_enabled: { feature: \"string\" },\n stats_viewed: { tab: \"string\" },\n stats_filter_changed: { tab: \"string\", filter: \"string\" },\n report_exported: { report: \"string\", format: \"string?\" },\n search_performed: { result_count: \"number\" },\n error_shown: { code: \"string\", route: \"string\" },\n help_opened: { topic: \"string?\" },\n ai_assistant_used: { topic: \"string?\" },\n member_invited: { role: \"string\" },\n} as const;\n\nconst TX = {\n gateway: \"string?\",\n method: \"string?\",\n value_minor: \"number?\",\n currency: \"string?\",\n} as const;\nconst SUB = {\n subscription_id: \"string?\",\n value_minor: \"number?\",\n currency: \"string?\",\n} as const;\n\n/**\n * Emitted by instapay only. The lower-cased `EventType` of\n * server/event-system/event.list.ts maps 1:1 to the first group.\n */\nexport const BUSINESS_EVENT_SPEC = {\n // Mirror of the event bus (EventType.X -> x.toLowerCase()).\n transaction_created: TX,\n transaction_success: TX,\n transaction_failure: { ...TX, error_code: \"string?\" },\n transaction_expired: TX,\n transaction_charge: TX,\n subscription_created: SUB,\n subscription_paused: SUB,\n subscription_resumed: SUB,\n subscription_updated: SUB,\n subscription_deleted: SUB,\n subscription_charge_paid: SUB,\n subscription_charge_failed: { ...SUB, error_code: \"string?\" },\n subscription_past_due: SUB,\n subscription_canceled: SUB,\n access_expires_in_3_days: {},\n access_expired: {},\n cart_recovery: { value_minor: \"number?\", currency: \"string?\" },\n testimonial_email_send: {},\n testimonial_fulfilled: {},\n partner_commission_earned: {\n partner_id: \"string\",\n commission_minor: \"number\",\n currency: \"string\",\n },\n // Added by the analytics work.\n checkout_session_created: {\n item_count: \"number\",\n checkout_type: \"enum:single|cart|link\",\n gateway: \"string?\",\n ...MONEY,\n },\n order_paid: {\n gateway: \"string\",\n method: \"string?\",\n item_count: \"number?\",\n /** UTC date (`YYYY-MM-DD`) the envelope `visitor_id` was computed for. */\n visitor_day: \"string?\",\n /** Every line of the order (public hashed product ids), at most 50. */\n items: \"line_items?\",\n ...MONEY,\n },\n refund_issued: {\n gateway: \"string?\",\n reason: \"string?\",\n ...MONEY,\n },\n return_requested: { item_count: \"number\", reason_code: \"string?\" },\n automation_run_completed: {\n automation_id: \"string\",\n status: \"string\",\n trigger: \"string?\",\n },\n notification_sent: { medium: \"string\", template: \"string?\" },\n notification_failed: {\n medium: \"string\",\n template: \"string?\",\n error_code: \"string?\",\n },\n recovery_email_sent: { step: \"number?\" },\n recovery_link_clicked: {},\n api_request: {\n /** Route template without ids or query, e.g. `/api/rpc/public.v1.PublicApiService/ListProducts`. */\n endpoint: \"string\",\n /** `X-Bitsnap-Client` value, absent when the caller sent none. */\n client: \"string?\",\n status: \"number\",\n latency_bucket: \"enum:lt_50|lt_200|lt_1000|gte_1000\",\n /** 1 for errors, <1 for sampled successes; rollups divide counts by it. */\n sample_rate: \"number\",\n },\n} as const;\n\nexport const EVENT_SPEC_BY_STREAM = {\n storefront_events: STOREFRONT_EVENT_SPEC,\n app_events: APP_EVENT_SPEC,\n business_events: BUSINESS_EVENT_SPEC,\n} as const;\n\nexport const EVENT_SPEC = {\n ...STOREFRONT_EVENT_SPEC,\n ...APP_EVENT_SPEC,\n ...BUSINESS_EVENT_SPEC,\n} as const;\n\nexport type StorefrontEventName = keyof typeof STOREFRONT_EVENT_SPEC;\nexport type AppEventName = keyof typeof APP_EVENT_SPEC;\nexport type BusinessEventName = keyof typeof BUSINESS_EVENT_SPEC;\nexport type EventName = StorefrontEventName | AppEventName | BusinessEventName;\n\nexport const EVENT_NAMES = {\n storefront_events: Object.keys(STOREFRONT_EVENT_SPEC) as StorefrontEventName[],\n app_events: Object.keys(APP_EVENT_SPEC) as AppEventName[],\n business_events: Object.keys(BUSINESS_EVENT_SPEC) as BusinessEventName[],\n} as const;\n\nexport const STREAM_FOR_EVENT: Record<EventName, Stream> = Object.fromEntries(\n STREAMS.flatMap((stream) =>\n (EVENT_NAMES[stream] as string[]).map((name) => [name, stream] as const),\n ),\n) as Record<EventName, Stream>;\n\n/** True for a catalogue event name; own keys only (`constructor`, `toString` are not events). */\nexport function isEventName(name: unknown): name is EventName {\n return typeof name === \"string\" && Object.hasOwn(STREAM_FOR_EVENT, name);\n}\n\n// -- props types, derived from the spec ------------------------------------\n\ntype PropPrimitives = {\n string: string;\n number: number;\n boolean: boolean;\n \"string[]\": string[];\n \"number[]\": number[];\n line_items: Array<{ product_id: string; qty: number; value_minor: number }>;\n};\ntype SplitEnum<S extends string> = S extends `${infer H}|${infer R}`\n ? H | SplitEnum<R>\n : S;\ntype StripOpt<S extends string> = S extends `${infer B}?` ? B : S;\ntype ResolveProp<S extends string> =\n StripOpt<S> extends `enum:${infer E}`\n ? SplitEnum<E>\n : StripOpt<S> extends keyof PropPrimitives\n ? PropPrimitives[StripOpt<S>]\n : never;\ntype PropsFromSpec<S extends Record<string, string>> = {\n [K in keyof S as S[K] extends `${string}?` ? never : K]: ResolveProp<S[K]>;\n} & {\n [K in keyof S as S[K] extends `${string}?` ? K : never]?: ResolveProp<S[K]>;\n};\n\nexport type EventProps<E extends EventName> = PropsFromSpec<\n (typeof EVENT_SPEC)[E]\n>;\n\n// ---------------------------------------------------------------------------\n// Envelope\n// ---------------------------------------------------------------------------\n\n/** Fields the emitter fills in. Everything else is derived by the collector. */\nexport interface ClientEvent<E extends EventName = EventName> {\n /** UUIDv7, generated by the emitter. Dedupe key. */\n event_id: string;\n event: E;\n /** Client clock, unix ms. */\n ts: number;\n schema_version: typeof SCHEMA_VERSION;\n env: Env;\n source: Source;\n channel: Channel;\n /** `<package>@<version>`, e.g. `bitsnap-react@1.9.0`. */\n sdk?: string | null;\n /** Random per page load, in memory only. */\n page_id?: string | null;\n page_type?: PageType | null;\n host?: string | null;\n /** Path without query string and fragment, already run through `sanitizePath`. */\n path?: string | null;\n referrer_host?: string | null;\n utm_source?: string | null;\n utm_medium?: string | null;\n utm_campaign?: string | null;\n utm_content?: string | null;\n utm_term?: string | null;\n ref_code?: string | null;\n product_id?: string | null;\n variant_id?: string | null;\n order_ref?: string | null;\n /** Object on the wire; the collector stores `JSON.stringify(props)`. */\n props: EventProps<E>;\n /**\n * Only honoured for `source: \"dashboard\"`: the hashed Clerk user id computed\n * by instapay and handed to the dashboard tracker. Ignored for every other\n * source (the collector computes `visitor_id` itself).\n */\n visitor_id?: string | null;\n /**\n * The value of the first-party `bs_vid_<projectKey>` cookie (`CLIENT_ID_RE`), sent only\n * while analytics consent is granted. The collector turns it into a stable\n * `consentedVisitorId` and never stores it.\n */\n client_id?: string | null;\n}\n\n/** One row as stored in Basin (all three streams share this shape). */\nexport interface StoredEvent {\n event_id: string;\n event: EventName;\n /** Unix ms, client clock after `clampTs`. */\n ts: number;\n /** Unix ms, collector clock. */\n received_at: number;\n schema_version: number;\n /** Numeric database id. Resolved by the collector, never taken from the client. */\n project_id: number;\n env: Env;\n source: Source;\n channel: Channel;\n sdk: string | null;\n visitor_id: string | null;\n page_id: string | null;\n page_type: PageType | null;\n host: string | null;\n path: string | null;\n referrer_host: string | null;\n utm_source: string | null;\n utm_medium: string | null;\n utm_campaign: string | null;\n utm_content: string | null;\n utm_term: string | null;\n ref_code: string | null;\n country: string | null;\n region: string | null;\n device_type: DeviceType | null;\n os: string | null;\n browser: string | null;\n product_id: string | null;\n variant_id: string | null;\n order_ref: string | null;\n /** `JSON.stringify` of the props object. */\n props: string;\n}\n\n/** POST /e body. */\nexport interface IngestBody {\n /** Project key, see `normalizeProjectKey`. */\n k: string;\n events: ClientEvent[];\n}\n\n// ---------------------------------------------------------------------------\n// Consent shapes\n// ---------------------------------------------------------------------------\n\nexport const CONSENT_TEXT_KEYS = [\n \"title\",\n \"description\",\n \"acceptAll\",\n \"rejectAll\",\n \"settings\",\n \"save\",\n \"close\",\n \"necessaryTitle\",\n \"necessaryDescription\",\n \"analyticsTitle\",\n \"analyticsDescription\",\n \"marketingTitle\",\n \"marketingDescription\",\n \"preferencesTitle\",\n \"preferencesDescription\",\n \"poweredBy\",\n] as const;\nexport type ConsentTextKey = (typeof CONSENT_TEXT_KEYS)[number];\nexport type ConsentTexts = Record<ConsentTextKey, string>;\n\nexport type ConsentCategory = \"analytics\" | \"marketing\" | \"preferences\";\nexport type ConsentChoice = Record<ConsentCategory, boolean>;\n\nexport type ConsentConfig = {\n version: number;\n theme: \"auto\" | \"light\" | \"dark\";\n accentColor?: string;\n position: \"bottom\" | \"bottom-left\" | \"bottom-right\";\n privacyPolicyUrl?: string;\n categories: { analytics: boolean; marketing: boolean; preferences: boolean };\n services: Array<{\n name: string;\n category: \"analytics\" | \"marketing\" | \"preferences\";\n cookies?: string[];\n }>;\n texts?: Partial<Record<\"pl\" | \"en\", Partial<ConsentTexts>>>;\n poweredBy: true;\n};\n\n/** Value of the consent cookie, JSON then base64url. */\nexport interface ConsentCookie {\n v: 1;\n /** Random consent id (also sent to POST /consent). */\n id: string;\n /** Unix seconds. */\n ts: number;\n /** Banner version (`ConsentConfig.version`) the visitor answered. */\n bv: number;\n c: ConsentChoice;\n}\n\nexport const CONSENT_COOKIE_NAME = \"bitsnap_consent\";\nexport const CONSENT_COOKIE_MAX_AGE_SECONDS = 365 * 24 * 60 * 60;\nexport const CONSENT_ACTIONS = [\n \"accept_all\",\n \"reject_all\",\n \"custom\",\n \"withdraw\",\n] as const;\nexport type ConsentAction = (typeof CONSENT_ACTIONS)[number];\n/** POST /consent `action` of a banner impression (not a choice, not in `CONSENT_ACTIONS`). */\nexport const CONSENT_SHOWN_ACTION = \"shown\";\n\n/** POST /consent body of a choice (`CONSENT_ACTIONS`). */\nexport interface ConsentLogBody {\n k: string;\n /** Same random id as `ConsentCookie.id`. 16 to 64 chars of `[A-Za-z0-9_-]`. */\n consent_id: string;\n action: ConsentAction;\n c: ConsentChoice;\n /** Banner version. */\n bv: number;\n /** Hostname the banner ran on. Collector overwrites it with the Origin host. */\n host: string;\n /** Unix SECONDS (like the cookie), not ms. */\n ts: number;\n}\n\n/**\n * POST /consent body of a banner impression: the banner opened by itself\n * because the visitor has no valid choice. Once per page load; no consent id\n * and no choice.\n */\nexport interface ConsentShownBody {\n k: string;\n action: typeof CONSENT_SHOWN_ACTION;\n /** Banner version. */\n bv: number;\n /** Hostname the banner ran on. Collector overwrites it with the Origin host. */\n host: string;\n /** Unix SECONDS (like the cookie), not ms. */\n ts: number;\n}\n\n/** Any POST /consent body; discriminate on `action`. */\nexport type ConsentBody = ConsentLogBody | ConsentShownBody;\n\n/** `bitsnap_consent`, or `bitsnap_consent_<projectKey>` for `data-scope=\"project\"`. */\nexport function consentCookieName(scope: \"site\" | \"project\", projectKey?: string): string {\n if (scope === \"project\") {\n if (!projectKey) throw new Error(\"projectKey required for project scope\");\n return `${CONSENT_COOKIE_NAME}_${normalizeProjectKey(projectKey)}`;\n }\n return CONSENT_COOKIE_NAME;\n}\n\n/**\n * Decodes the value of a consent cookie (§11.3). Null when it is not base64url\n * JSON of the documented shape (`v` 1 and a boolean per category).\n */\nexport function parseConsentCookie(value: string | null | undefined): ConsentCookie | null {\n if (!value || !/^[A-Za-z0-9_-]+$/.test(value)) return null;\n try {\n const padded = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const bin = atob(padded + \"=\".repeat((4 - (padded.length % 4)) % 4));\n const json: unknown = JSON.parse(\n new TextDecoder().decode(Uint8Array.from(bin, (ch) => ch.charCodeAt(0))),\n );\n if (!isRecord(json) || json.v !== 1) return null;\n const c = json.c;\n if (!isRecord(c)) return null;\n if (\n typeof c.analytics !== \"boolean\" ||\n typeof c.marketing !== \"boolean\" ||\n typeof c.preferences !== \"boolean\"\n ) {\n return null;\n }\n return json as unknown as ConsentCookie;\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Project key\n// ---------------------------------------------------------------------------\n\n/**\n * The project key is the existing public hashed project id\n * (`hashId(projectId)` in apps/bitsnap/queries/hashids.ts, the `projectID`\n * of bitsnap-react). A leading `pk_` is accepted and dropped so the\n * documented `pk_…` snippets work too. Returns null when it is not a plausible\n * key (hashids default alphabet).\n */\nexport function normalizeProjectKey(key: string): string | null {\n const bare = key.startsWith(\"pk_\") ? key.slice(3) : key;\n return /^[A-Za-z0-9]{1,32}$/.test(bare) ? bare : null;\n}\n\n// ---------------------------------------------------------------------------\n// X-Bitsnap-Client\n// ---------------------------------------------------------------------------\n\nconst CLIENT_RE = /^([a-z][a-z0-9-]{0,39})@(\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.+-]{1,20})?)$/;\n\n/** `<package>@<version>`, e.g. `bitsnap-react@1.9.0`. Also the shape of `sdk`. */\nexport function parseClientHeader(\n value: string | null | undefined,\n): { package: string; version: string } | null {\n if (!value || value.length > LIMITS.sdk) return null;\n const m = CLIENT_RE.exec(value);\n return m ? { package: m[1], version: m[2] } : null;\n}\n\n// ---------------------------------------------------------------------------\n// URL stripping\n// ---------------------------------------------------------------------------\n\nconst MAX_QUERY_VALUE = LIMITS.utm;\n\n/**\n * Campaign/ref value: trimmed, capped, null when empty or when it holds an \"@\"\n * (someone put an email in a tag). The collector runs every client-supplied\n * `utm_*` and `ref_code` through it again.\n */\nexport function cleanValue(v: string | null | undefined, max: number): string | null {\n if (v == null) return null;\n const t = v.trim();\n // An \"@\" means someone put an email in a campaign tag: drop the value.\n if (t.length === 0 || t.includes(\"@\")) return null;\n return t.slice(0, max);\n}\n\n/**\n * Path sanitiser: no query, no fragment, capped. Opaque segments (24+ chars of\n * `[A-Za-z0-9_-]`, i.e. tokens in order/panel links) become `:token` and\n * segments containing `@` become `:email`.\n */\nexport function sanitizePath(pathname: string): string {\n const segments = pathname.split(\"/\").map((seg) => {\n if (seg.includes(\"@\") || seg.includes(\"%40\")) return \":email\";\n if (/^[A-Za-z0-9_-]{24,}$/.test(seg)) return \":token\";\n return seg;\n });\n const joined = segments.join(\"/\") || \"/\";\n return (joined.startsWith(\"/\") ? joined : `/${joined}`).slice(0, LIMITS.path);\n}\n\nexport interface UrlParts {\n host: string;\n /** Sanitised path, no query. */\n path: string;\n utm_source: string | null;\n utm_medium: string | null;\n utm_campaign: string | null;\n utm_content: string | null;\n utm_term: string | null;\n /** The `ref` query parameter. */\n ref_code: string | null;\n}\n\n/**\n * Parses a URL and keeps only what may leave the browser: host, sanitised path\n * and the `utm_*` and `ref` query parameters. Returns null for non-http(s) or\n * unparseable input. `base` resolves relative URLs.\n */\nexport function parseUrl(url: string, base?: string): UrlParts | null {\n let u: URL;\n try {\n u = new URL(url, base);\n } catch {\n return null;\n }\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n const q = u.searchParams;\n return {\n host: u.hostname.toLowerCase().slice(0, LIMITS.host),\n path: sanitizePath(u.pathname),\n utm_source: cleanValue(q.get(\"utm_source\"), MAX_QUERY_VALUE),\n utm_medium: cleanValue(q.get(\"utm_medium\"), MAX_QUERY_VALUE),\n utm_campaign: cleanValue(q.get(\"utm_campaign\"), MAX_QUERY_VALUE),\n utm_content: cleanValue(q.get(\"utm_content\"), MAX_QUERY_VALUE),\n utm_term: cleanValue(q.get(\"utm_term\"), MAX_QUERY_VALUE),\n ref_code: cleanValue(q.get(\"ref\"), LIMITS.refCode),\n };\n}\n\n/**\n * Returns the URL with userinfo, fragment and every query parameter removed\n * except `utm_*` and `ref`. Null when `url` is not a usable http(s) URL.\n */\nexport function stripUrl(url: string, base?: string): string | null {\n let u: URL;\n try {\n u = new URL(url, base);\n } catch {\n return null;\n }\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n const keep = new URLSearchParams();\n for (const [key, value] of u.searchParams) {\n if (key !== \"ref\" && !key.startsWith(\"utm_\")) continue;\n const cleaned = cleanValue(value, MAX_QUERY_VALUE);\n if (cleaned != null) keep.append(key, cleaned);\n }\n const qs = keep.toString();\n return `${u.protocol}//${u.host}${sanitizePath(u.pathname)}${qs ? `?${qs}` : \"\"}`;\n}\n\nconst HOSTNAME_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/;\n\n/** A plain DNS hostname (lower-cased), or null: no scheme, port, path, userinfo or \"@\". */\nexport function cleanHostname(\n v: string | null | undefined,\n max: number = LIMITS.referrerHost,\n): string | null {\n if (typeof v !== \"string\") return null;\n const h = v.trim().toLowerCase();\n return h.length > 0 && h.length <= max && HOSTNAME_RE.test(h) ? h : null;\n}\n\n/** Public hashed ids (`product_id`, `variant_id`, `order_ref`): URL-safe, at most `LIMITS.id`. */\nexport const ID_RE = /^[A-Za-z0-9_-]{1,64}$/;\n\nexport function cleanId(v: string | null | undefined): string | null {\n return typeof v === \"string\" && ID_RE.test(v) ? v : null;\n}\n\n/** Host of a referrer URL, or null (also null for non-http(s) referrers). */\nexport function referrerHost(referrer: string | null | undefined): string | null {\n if (!referrer) return null;\n try {\n const u = new URL(referrer);\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n return u.hostname.toLowerCase().slice(0, LIMITS.referrerHost);\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Bot rule\n// ---------------------------------------------------------------------------\n\nconst BOT_UA =\n /bot\\b|crawl|spider|slurp|facebookexternalhit|bingpreview|headless|phantomjs|lighthouse|pagespeed|gtmetrix|pingdom|uptime|statuscake|monitor|preview|scrapy|curl\\/|wget|python-|go-http-client|java\\/|okhttp|axios|node-fetch|undici|libwww|httpclient|aiohttp|postman|insomnia/i;\n\n/** True when the User-Agent is empty or looks automated. Such events are dropped. */\nexport function isBotUserAgent(ua: string | null | undefined): boolean {\n if (!ua || ua.trim().length === 0) return true;\n return BOT_UA.test(ua);\n}\n\n// ---------------------------------------------------------------------------\n// visitor_id\n// ---------------------------------------------------------------------------\n\nconst encoder = new TextEncoder();\n\nasync function hmacSha256(\n key: Uint8Array,\n message: string,\n): Promise<Uint8Array> {\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key,\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n return new Uint8Array(\n await crypto.subtle.sign(\"HMAC\", cryptoKey, encoder.encode(message)),\n );\n}\n\nfunction base64url(bytes: Uint8Array): string {\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n return btoa(bin).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** `YYYY-MM-DD` of a unix-ms timestamp in UTC. */\nexport function utcDate(ms: number): string {\n return new Date(ms).toISOString().slice(0, 10);\n}\n\n/**\n * IP as hashed: lower-case; IPv4 unchanged; IPv4-mapped IPv6 (`::ffff:1.2.3.4`\n * or `::ffff:102:304`) becomes plain IPv4; any other IPv6, including one with\n * an embedded dotted quad (`64:ff9b::1.2.3.4`), is cut to its /64 (first four\n * hextets, canonical form `a:b:c:d::`). Both the Worker and the instapay\n * server MUST call this on the client IP before `computeVisitorId`.\n */\nexport function normalizeIp(ip: string): string {\n let s = ip.trim().toLowerCase();\n const zone = s.indexOf(\"%\");\n if (zone >= 0) s = s.slice(0, zone);\n if (!s.includes(\":\")) return s; // plain IPv4 (or not an IP at all)\n\n // Embedded dotted quad in the last 32 bits: turn it into two hextets.\n const quad = /^(.*:)(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(s);\n if (quad) {\n const o = [quad[2], quad[3], quad[4], quad[5]].map(Number);\n if (o.some((n) => n > 255)) return s;\n const hex = (hi: number, lo: number) => (hi * 256 + lo).toString(16);\n s = `${quad[1]}${hex(o[0], o[1])}:${hex(o[2], o[3])}`;\n }\n\n const [head, tail] = s.split(\"::\");\n const headParts = head ? head.split(\":\") : [];\n const tailParts = tail !== undefined && tail !== \"\" ? tail.split(\":\") : [];\n const fill =\n tail === undefined ? 0 : Math.max(0, 8 - headParts.length - tailParts.length);\n const groups = [...headParts, ...Array<string>(fill).fill(\"0\"), ...tailParts];\n if (groups.length !== 8) return s;\n const h = groups.map((g) => Number.parseInt(g, 16) || 0);\n\n // ::ffff:a.b.c.d in hex form.\n if (h.slice(0, 5).every((x) => x === 0) && h[5] === 0xffff) {\n return `${h[6] >> 8}.${h[6] & 255}.${h[7] >> 8}.${h[7] & 255}`;\n }\n return `${h\n .slice(0, 4)\n .map((g) => g.toString(16))\n .join(\":\")}::`;\n}\n\n/**\n * Cookieless visitor id, identical in the Worker and the instapay server.\n *\n * day_secret = HMAC-SHA256(key = utf8(masterSecret), msg = utf8(\"YYYY-MM-DD\")) // 32 raw bytes\n * visitor_id = base64url(HMAC-SHA256(key = day_secret, msg = utf8(ip + \"\\n\" + ua + \"\\n\" + projectId))).slice(0, 22)\n *\n * `dateUtc` is the UTC date of the request; `ip` is `normalizeIp(<client IP>)`;\n * `ua` is the raw `User-Agent` request header; `projectId` is the decimal\n * numeric project id.\n */\nexport async function computeVisitorId(\n masterSecret: string,\n dateUtc: string,\n ip: string,\n ua: string,\n projectId: number | string,\n): Promise<string> {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(dateUtc)) {\n throw new Error(`dateUtc must be YYYY-MM-DD, got ${dateUtc}`);\n }\n const daySecret = await hmacSha256(encoder.encode(masterSecret), dateUtc);\n const mac = await hmacSha256(daySecret, `${ip}\\n${ua}\\n${projectId}`);\n return base64url(mac).slice(0, 22);\n}\n\n/**\n * The `bs_vid_<projectKey>` cookie name. `projectKey` is the bare public key\n * (like `consentCookieName`): consent is per project, so is the client id.\n */\nexport function clientIdCookieName(projectKey: string): string {\n return `bs_vid_${projectKey}`;\n}\n\n/** Value of the `bs_vid_<projectKey>` cookie: 16 random bytes, base64url without padding. */\nexport const CLIENT_ID_RE = /^[A-Za-z0-9_-]{22}$/;\n\n/**\n * Stable visitor id of a browser that granted analytics consent (contract §6).\n *\n * consented_visitor_id = \"p_\" + base64url(HMAC-SHA256(key = utf8(masterSecret),\n * msg = utf8(\"client\\n\" + clientId + \"\\n\" + projectId))).slice(0, 22)\n *\n * 24 characters; daily ids are 22, so `isConsentedVisitorId` tells them apart.\n * `clientId` is the `bs_vid_<projectKey>` cookie value and is never stored.\n */\nexport async function computeConsentedVisitorId(\n masterSecret: string,\n clientId: string,\n projectId: number | string,\n): Promise<string> {\n if (!CLIENT_ID_RE.test(clientId)) {\n throw new Error(\"clientId must be 22 base64url characters\");\n }\n const mac = await hmacSha256(\n encoder.encode(masterSecret),\n `client\\n${clientId}\\n${projectId}`,\n );\n return `p_${base64url(mac).slice(0, 22)}`;\n}\n\n/** Whether `visitorId` came from `computeConsentedVisitorId` (not a daily id). */\nexport function isConsentedVisitorId(visitorId: string): boolean {\n return visitorId.length === 24 && visitorId.startsWith(\"p_\");\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport type ValidationResult = { ok: true } | { ok: false; reason: string };\n\nconst UUID_V7 =\n /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst PAGE_ID_RE = /^[A-Za-z0-9_-]{8,32}$/;\n/** A letter TLD is required: `bitsnap-react@1.9.0` and `v@1.2` are not addresses. */\nconst EMAIL_LIKE = /[^\\s@]+@[^\\s@]+\\.[A-Za-z]{2,}\\b/;\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction nullableString(\n e: Record<string, unknown>,\n key: string,\n max: number,\n): string | null {\n const v = e[key];\n if (v === undefined || v === null) return null;\n if (typeof v !== \"string\") return `bad_${key}`;\n return v.length > max ? `too_long_${key}` : null;\n}\n\nfunction checkPropValue(spec: string, value: unknown): boolean {\n const optional = spec.endsWith(\"?\");\n const type = optional ? spec.slice(0, -1) : spec;\n if (type.startsWith(\"enum:\")) {\n return typeof value === \"string\" && type.slice(5).split(\"|\").includes(value);\n }\n switch (type) {\n case \"string\":\n return typeof value === \"string\" && value.length <= LIMITS.maxPropString;\n case \"number\":\n return typeof value === \"number\" && Number.isFinite(value);\n case \"boolean\":\n return typeof value === \"boolean\";\n case \"string[]\":\n return (\n Array.isArray(value) &&\n value.length <= LIMITS.maxPropArray &&\n value.every((x) => typeof x === \"string\" && x.length <= LIMITS.maxPropString)\n );\n case \"number[]\":\n return (\n Array.isArray(value) &&\n value.length <= LIMITS.maxPropArray &&\n value.every((x) => typeof x === \"number\" && Number.isFinite(x))\n );\n case \"line_items\":\n return (\n Array.isArray(value) &&\n value.length <= LIMITS.maxPropArray &&\n value.every(\n (x) =>\n isRecord(x) &&\n typeof x.product_id === \"string\" &&\n ID_RE.test(x.product_id) &&\n isNonNegativeSafeInteger(x.qty) &&\n isNonNegativeSafeInteger(x.value_minor),\n )\n );\n default:\n return false;\n }\n}\n\nfunction isNonNegativeSafeInteger(value: unknown): boolean {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\n/** True when `value` looks like an email address (also exported for the collector's re-checks). */\nexport function looksLikeEmail(value: string): boolean {\n // A well-formed `<package>@<version>` client id is never an address.\n if (parseClientHeader(value) !== null) return false;\n return EMAIL_LIKE.test(value);\n}\n\nfunction hasEmailLike(value: unknown): boolean {\n if (typeof value === \"string\") return looksLikeEmail(value);\n if (Array.isArray(value)) return value.some(hasEmailLike);\n if (isRecord(value)) return Object.values(value).some(hasEmailLike);\n return false;\n}\n\n/**\n * Validates `props` against the catalogue and returns a copy without keys the\n * catalogue does not know (forward compatibility: a newer SDK adding an\n * optional prop must not get its events dropped by an older collector).\n * Fails on missing required props, wrong types, bad enum values, oversize\n * props and string values that look like an email address.\n */\nexport function sanitizeProps(\n event: string,\n props: unknown,\n): { ok: true; props: Record<string, unknown> } | { ok: false; reason: string } {\n if (!isEventName(event)) return { ok: false, reason: \"unknown_event\" };\n const spec = (EVENT_SPEC as Record<string, Record<string, string>>)[event];\n if (!spec) return { ok: false, reason: \"unknown_event\" };\n if (!isRecord(props)) return { ok: false, reason: \"bad_props\" };\n const out: Record<string, unknown> = {};\n for (const [key, type] of Object.entries(spec)) {\n const value = props[key];\n if (value === undefined || value === null) {\n if (!type.endsWith(\"?\")) return { ok: false, reason: `props_missing_${key}` };\n continue;\n }\n if (!checkPropValue(type, value)) return { ok: false, reason: `props_bad_${key}` };\n if (hasEmailLike(value)) return { ok: false, reason: `props_pii_${key}` };\n out[key] =\n type.startsWith(\"line_items\") && Array.isArray(value)\n ? value.map((x) => ({ product_id: x.product_id, qty: x.qty, value_minor: x.value_minor }))\n : value;\n }\n if (JSON.stringify(out).length > LIMITS.maxPropsChars) {\n return { ok: false, reason: \"props_too_large\" };\n }\n return { ok: true, props: out };\n}\n\nexport interface ValidateOptions {\n /**\n * Who sent it. `browser` (default) is POST /e: the event must belong to\n * `storefront_events` or `app_events`, `consent_updated` and `consent_shown`\n * are refused (only POST /consent writes them) and `source` must fit the\n * stream. `server` is the instapay emitter: any stream, `source` must fit the\n * stream.\n */\n from?: \"browser\" | \"server\";\n}\n\n/**\n * Validates the emitter-controlled part of an event: names, types, enums,\n * lengths, the event/source/stream pairing and `props`. It does not check\n * that `ts` is plausible (use `clampTs`), origins or project keys.\n */\nexport function validateEnvelope(\n e: unknown,\n options: ValidateOptions = {},\n): ValidationResult {\n const from = options.from ?? \"browser\";\n const fail = (reason: string): ValidationResult => ({ ok: false, reason });\n if (!isRecord(e)) return fail(\"not_object\");\n\n if (typeof e.event_id !== \"string\" || !UUID_V7.test(e.event_id)) {\n return fail(\"bad_event_id\");\n }\n if (!isEventName(e.event)) return fail(\"unknown_event\");\n const stream = STREAM_FOR_EVENT[e.event as EventName];\n if (from === \"browser\") {\n if (stream === \"business_events\") return fail(\"server_only_event\");\n if (e.event === \"consent_updated\" || e.event === \"consent_shown\") {\n return fail(\"consent_via_consent_endpoint\");\n }\n }\n if (\n typeof e.ts !== \"number\" ||\n !Number.isInteger(e.ts) ||\n e.ts <= 0 ||\n e.ts > 4e12\n ) {\n return fail(\"bad_ts\");\n }\n if (e.schema_version !== SCHEMA_VERSION) return fail(\"bad_schema_version\");\n if (!ENVS.includes(e.env as Env)) return fail(\"bad_env\");\n if (!SOURCES.includes(e.source as Source)) return fail(\"bad_source\");\n if (!SOURCES_FOR_STREAM[stream].includes(e.source as Source)) {\n return fail(\"source_not_allowed_for_event\");\n }\n if (!CHANNELS.includes(e.channel as Channel)) return fail(\"bad_channel\");\n\n if (e.sdk != null) {\n if (typeof e.sdk !== \"string\" || parseClientHeader(e.sdk) === null) {\n return fail(\"bad_sdk\");\n }\n }\n if (e.page_id != null) {\n if (typeof e.page_id !== \"string\" || !PAGE_ID_RE.test(e.page_id)) {\n return fail(\"bad_page_id\");\n }\n }\n if (e.page_type != null && !PAGE_TYPES.includes(e.page_type as PageType)) {\n return fail(\"bad_page_type\");\n }\n if (from === \"browser\") {\n if (typeof e.host !== \"string\" || e.host.length === 0) return fail(\"bad_host\");\n if (typeof e.path !== \"string\" || !e.path.startsWith(\"/\")) return fail(\"bad_path\");\n }\n if (typeof e.path === \"string\" && e.path.includes(\"?\")) return fail(\"path_has_query\");\n if (typeof e.path === \"string\" && e.path.includes(\"#\")) return fail(\"path_has_fragment\");\n\n const lengths: Array<[string, number]> = [\n [\"host\", LIMITS.host],\n [\"path\", LIMITS.path],\n [\"referrer_host\", LIMITS.referrerHost],\n [\"utm_source\", LIMITS.utm],\n [\"utm_medium\", LIMITS.utm],\n [\"utm_campaign\", LIMITS.utm],\n [\"utm_content\", LIMITS.utm],\n [\"utm_term\", LIMITS.utm],\n [\"ref_code\", LIMITS.refCode],\n [\"product_id\", LIMITS.id],\n [\"variant_id\", LIMITS.id],\n [\"order_ref\", LIMITS.id],\n ];\n for (const [key, max] of lengths) {\n const problem = nullableString(e, key, max);\n if (problem) return fail(problem);\n }\n if (e.visitor_id != null) {\n if (typeof e.visitor_id !== \"string\" || !/^[A-Za-z0-9_-]{22}$/.test(e.visitor_id)) {\n return fail(\"bad_visitor_id\");\n }\n }\n if (e.client_id != null) {\n if (typeof e.client_id !== \"string\" || !CLIENT_ID_RE.test(e.client_id)) {\n return fail(\"bad_client_id\");\n }\n }\n\n const props = sanitizeProps(e.event, e.props);\n if (!props.ok) return fail(props.reason);\n return { ok: true };\n}\n\n/** Client `ts` as stored: replaced by `receivedAt` when more than 24 h away from it. */\nexport function clampTs(ts: number, receivedAt: number): number {\n return Math.abs(ts - receivedAt) > LIMITS.tsSkewMs ? receivedAt : ts;\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import{C as Nn,F as In,G as Sn,H as En,I as Ln,J as Tn,K as Rn,a as lr,b as un,c as Lt,d as We,e as Rt,f as cn,h as pn,i as mn,j as fn,k as gn,p as vn,q as kn,r as xn,t as wn,u as Cn}from"./chunk-ZKT4N553.mjs";import{b as Pe,c as mt,d as yn,e as hn,f as Je}from"./chunk-5YN752OV.mjs";import{a as dr,g as ct,h as pt}from"./chunk-CUPG4B5W.mjs";import{a as nr,b as or,c as Nt,d as ar,e as an,f as sn,k as q,l as Ve,m as oe,q as I,r as Tt,t as bn,u as Ye,v as Pn}from"./chunk-VWA3ZCNI.mjs";import{a as j}from"./chunk-5R6AGO3Z.mjs";import{a as tr,b as on,c as rr,e as Q,f as dn}from"./chunk-62WDFH7K.mjs";import{h as ir,l as It,m as St,n as Ge,o as ln}from"./chunk-GKJURMDO.mjs";import{a as Et,c as Ee,e as sr,f as E}from"./chunk-OFPRIENJ.mjs";import{useAutoAnimate as ga}from"@formkit/auto-animate/react";import{useEffect as Un,useMemo as zn}from"react";import{jsx as ft}from"react/jsx-runtime";function Le({className:e,...t}){return ft("div",{"data-slot":"card",className:j("bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",e),...t})}function Ue({className:e,...t}){return ft("div",{"data-slot":"card-header",className:j("@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",e),...t})}function _e({className:e,...t}){return ft("div",{"data-slot":"card-title",className:j("leading-none font-semibold",e),...t})}function An({className:e,...t}){return ft("div",{"data-slot":"card-description",className:j("text-muted-foreground text-sm",e),...t})}function Te({className:e,...t}){return ft("div",{"data-slot":"card-content",className:j("px-6",e),...t})}import{CircleCheck as aa}from"lucide-react";import{useId as ia}from"react";import{jsx as F,jsxs as X}from"react/jsx-runtime";var sa="text-muted-foreground text-xs leading-5",la="dark:border-foreground/30 dark:focus-visible:border-foreground/70 dark:focus-visible:ring-foreground/25 dark:aria-invalid:border-destructive-foreground dark:aria-invalid:ring-destructive-foreground/30",da=new Set(["invalidEmail","emailNotFound","deliveryUnavailable"]),ur="inline-flex min-h-11 items-center px-1 text-sm underline underline-offset-4 hover:no-underline focus-visible:ring-[3px] focus-visible:ring-ring/50 rounded-sm outline-none disabled:opacity-50 disabled:no-underline";function Dn({login:e,texts:t,allowHaveCode:n=!0,emailPlaceholder:o,emailInputId:r,codeInputId:a,className:i,buttonClassName:d,children:u}){let l=ia(),b=r??`${l}-email`,P=a??`${l}-code`,w=`${l}-notice`,h=`${l}-hint`,{notice:y}=e,c=y?.kind==="error",m=e.busy==="send",p=e.busy==="verify",x=e.busy==="resend",U=j("h-11 w-full",d),le=y?.kind==="success",L=X("div",{id:w,className:"min-h-10 text-sm leading-5",children:[F("p",{role:"alert",className:"font-medium text-red-700 dark:text-red-400",children:c?y.text:null}),X("p",{role:"status",className:j("flex items-start gap-1.5",le?"font-medium text-emerald-700 dark:text-emerald-400":"text-foreground"),children:[le&&F(aa,{"aria-hidden":!0,className:"mt-0.5 size-4 shrink-0"}),F("span",{children:y!=null&&!c?y.text:null})]})]}),de=c&&e.step==="email"&&(y.failure==null||da.has(y.failure)),Ne=F("p",{className:"sr-only",role:"status","aria-live":"polite",children:e.announcement}),te=X("div",{className:"grid gap-2",children:[F(We,{htmlFor:b,children:t.emailLabel}),F(Tt,{id:b,ref:e.emailRef,name:"email",type:"email",autoComplete:"email",inputMode:"email",autoCapitalize:"none",autoCorrect:"off",spellCheck:!1,autoFocus:!0,required:!0,className:j("h-11 text-base disabled:opacity-100 disabled:text-foreground/70",la),placeholder:o??t.emailPlaceholder,value:e.email,disabled:e.isBusy,"aria-invalid":de?!0:void 0,"aria-describedby":w,onChange:Z=>e.setEmail(Z.target.value)})]});if(e.step==="email")return X("form",{noValidate:!0,className:j("flex flex-col gap-4",i),onSubmit:Z=>{Z.preventDefault(),e.sendCode()},children:[Ne,te,L,X(I,{type:"submit",disabled:e.isBusy,"aria-busy":m,className:U,children:[m&&F(Rt,{"aria-hidden":!0}),m?t.sending:t.sendCode]}),n&&X("p",{className:"flex flex-wrap items-center justify-center text-center text-sm",children:[t.haveCodePrompt!==""&&F("span",{children:t.haveCodePrompt}),F("button",{type:"button",className:ur,disabled:e.isBusy,onClick:e.haveCode,children:t.haveCode})]})]});let[A,fe]=t.codeSentTo.split("{email}"),Y=e.dead!=null,He=Y?t.resendNew:e.secondsLeft>0?mn(t.resendIn,{seconds:e.secondsLeft}):t.resend;return X("form",{noValidate:!0,className:j("flex flex-col gap-4",i),onSubmit:Z=>{Z.preventDefault(),e.submitCode()},children:[Ne,e.needsEmail?te:X("div",{className:"flex flex-wrap items-center justify-between gap-x-2",children:[X("p",{className:"min-w-0 flex-[1_1_14rem] text-sm leading-5 break-words",children:[A,F("strong",{className:"font-semibold",children:e.email}),"\u2060",fe]}),F("button",{type:"button",className:j(ur,"-ml-1 shrink-0"),disabled:e.isBusy,onClick:e.changeEmail,children:t.changeEmail})]}),u,X("div",{className:"grid gap-2",children:[F(We,{htmlFor:P,children:t.codeLabel}),F(gn,{id:P,name:"code",inputRef:e.codeRef,value:e.code,onChange:e.setCode,onComplete:Z=>void e.submitCode(Z),disabled:e.isBusy||Y,invalid:c&&!e.needsEmail,"aria-describedby":`${w} ${h}`}),X("p",{id:h,className:sa,children:[t.validity," ",t.spamHint]})]}),L,X(I,{type:"submit",disabled:e.isBusy||Y,"aria-busy":p,className:U,children:[p&&F(Rt,{"aria-hidden":!0}),p?t.verifying:t.verify]}),e.needsEmail?F("div",{className:"flex justify-center",children:F("button",{type:"button",className:ur,disabled:e.isBusy,onClick:e.changeEmail,children:t.noCode})}):X(I,{type:"button",variant:Y?"default":"outline",disabled:e.isBusy||!Y&&e.secondsLeft>0,"aria-busy":x,className:Y?U:"h-11 w-full",onClick:()=>void e.resend(),children:[x&&F(Rt,{"aria-hidden":!0}),He]})]})}function cr(e){switch(e){case 1:return"emailNotFound";case 2:return"invalidEmail";case 3:return"wrongCode";case 14:return"expired";case 15:return"tooManyAttempts";case 13:return"rateLimited";case 12:return"deliveryFailed";case 11:return"deliveryUnavailable";default:return"unknown"}}var ua={pl:{title:"Zaloguj si\u0119",description:"Wy\u015Blemy do Ciebie kod na maila, dzi\u0119ki kt\xF3remu si\u0119 zalogujesz.",codeTitle:"Wpisz kod z maila",codeDescription:"Kod ma 6 cyfr."},en:{title:"Sign in",description:"We will email you a code that signs you in.",codeTitle:"Enter the code from the email",codeDescription:"The code has 6 digits."}};function Mn(e=E(),t){return{...pn(e,t),...Et(ua,e),...ca(t,["title","description","codeTitle","codeDescription"])}}function ca(e,t){let n={};for(let o of t){let r=e?.[o];r!=null&&(n[o]=r)}return n}var pa="return_url",pr="__return_url",ma="accessToken";function gt(e){let t=new URLSearchParams(e).get(pa);return t?On(t):null}function yt(e){typeof window>"u"||(e?window.sessionStorage.setItem(pr,e):window.sessionStorage.removeItem(pr))}function Ze(){if(typeof window>"u")return null;let e=window.sessionStorage.getItem(pr);return e?On(e):null}function fa(e,t){return t.some(n=>{if(e===n)return!0;let o=new URL(n).hostname,r=new URL(e).hostname;return r.endsWith(`.${o}`)||r===o})}function On(e){try{let t=new URL(e);return t.protocol!=="https:"&&t.protocol!=="http:"||!fa(t.origin,pt())?null:t.toString()}catch{return null}}function Qe(e,t){let n=new URL(e);return n.searchParams.set(ma,t),n.toString()}import{jsx as ae,jsxs as _n}from"react/jsx-runtime";if(typeof window<"u"){let t=[window.location.origin,"https://bitsnap.pl","https://kursy.bitsnap.pl"];pt().length===0&&ct(Array.from(new Set(t)))}var ya=({texts:e,projectID:t,host:n,locale:o,logo:r})=>{let a=St(),{mutateAsync:i}=oe(q.publicApi.userPanelLogin),{mutateAsync:d}=oe(q.publicApi.userPanelLoginWithCode),u=zn(()=>({async send(h){try{let y=await i({email:h});return y.result.case==="success"?{ok:!0,retryIn:y.result.value.retryIn||void 0,challengeId:y.result.value.challengeId||void 0}:{ok:!1,kind:cr(y.result.case==="failure"?y.result.value:0)}}catch(y){return{ok:!1,kind:lr(y),cause:y}}},async verify({email:h,code:y,challengeId:c}){try{let m=await d({code:parseInt(y,10),email:h,challengeId:c});return m.result.case==="accessToken"&&m.result.value?{ok:!0,value:{accessToken:m.result.value}}:{ok:!1,kind:cr(m.result.case==="failure"?m.result.value:0)}}catch(m){return{ok:!1,kind:lr(m),cause:m}}}}),[i,d]),l=fn({adapter:u,texts:e,storageKey:cn("panel",t,n),onVerified:({accessToken:h},y)=>{a.track("panel_login",{}),yn(t,h,y,n);let c=typeof window<"u"?Ze():null;setTimeout(()=>{if(c){window.location.href=Qe(c,h);return}window.location.reload()},100)}}),b=l.step==="code",P=b&&!l.needsEmail?e.codeTitle:e.title,w=b&&!l.needsEmail?e.codeDescription:e.description;return ae("main",{className:"mx-auto flex w-full max-w-sm flex-1 flex-col justify-start pt-4 sm:pt-[12vh]",children:_n(Le,{children:[ae(Lt,{projectId:t,locale:o,className:"px-4 sm:px-6",...r}),_n(Ue,{className:"px-4 sm:px-6",children:[ae(_e,{role:"heading","aria-level":1,className:"text-2xl",children:P}),ae(An,{children:w})]}),ae(Te,{className:"px-4 sm:px-6",children:ae(Dn,{login:l,texts:e,emailInputId:"email",codeInputId:"verify-code"})})]})})},ha=({analytics:e,texts:t,locale:n,showLogo:o,logoUrl:r,logoDarkUrl:a})=>{let{theme:i,allowedReturnOrigins:d,projectID:u,host:l}=Pe(),b=Ge(u,e,"panel"),P=zn(()=>Mn(n??E(),t),[n,t]),w={"--button-background-color":i?.colors?.brand??"#FFFFFF","--button-background-color-dark":i?.colors?.brandDark??"#000000","--button-text-color":i?.colors?.brandDark??"#000000","--button-text-color-dark":i?.colors?.brand??"#FFFFFF"},[h]=ga({duration:300,easing:"ease-in-out",disrespectUserMotionPreference:!1});return Un(()=>{typeof window>"u"||mt(u,l)!=null&&(window.location.href=window.location.href.replaceAll("login",""))},[u,l]),Un(()=>{if(typeof window>"u"||window.parent!==window)return;let y=gt(window.location.search);y&&yt(y);let c=y??Ze();if(!c)return;let m=mt(u,l);m&&(window.location.href=Qe(c,m))},[d,u,l]),ae(It,{value:b,children:ae("div",{className:"bg-white text-black dark:bg-black dark:text-white",children:ae("div",{className:"font-inter flex min-h-screen w-full flex-col p-4",style:w,ref:h,children:ae(ya,{texts:P,projectID:u,host:l,locale:n,logo:{showLogo:o,logoUrl:r??i?.logoURL,logoDarkUrl:a??i?.logoDarkURL}})})})})},ba=(e={})=>ae(ha,{...e});import{useAutoAnimate as Zi}from"@formkit/auto-animate/react";import{useEffect as Ot,useState as xo}from"react";import{useState as Pa,useCallback as va,useEffect as ka}from"react";function jn(e){let[t,n]=Pa(()=>{if(typeof window>"u")return e;let r=new URLSearchParams(window.location.search),a={};return Object.keys(e).forEach(i=>{let d=r.get(i);if(d!==null)try{a[i]=JSON.parse(d)}catch{a[i]=d}}),{...e,...a}}),o=va(r=>{n(a=>{let i={...a,...r};if(typeof window<"u"){let d=new URLSearchParams;Object.keys(i).forEach(l=>{let b=i[l];b!=null&&d.set(l,JSON.stringify(b))});let u=`${window.location.pathname}?${d.toString()}`;window.history.pushState({},"",u)}return i})},[]);return ka(()=>{let r=()=>{let a=new URLSearchParams(window.location.search),i={};Object.keys(e).forEach(d=>{let u=a.get(d);if(u!==null)try{i[d]=JSON.parse(u)}catch{i[d]=u}}),n({...e,...i})};return window.addEventListener("popstate",r),()=>window.removeEventListener("popstate",r)},[e]),[t,o]}function Fn(e,t){if(e!=null)return e;let n=t?.trim();if(!(n==null||n===""))return{tokens:bn(n)}}var xa={pl:{returnsNavLabel:"Zwroty",openCourse:"Otw\xF3rz kurs",libraryNavLabel:"Biblioteka",ordersNavLabel:"Zam\xF3wienia",accountNavLabel:"Konto",navigationLabel:"Panel klienta",logout:"Wyloguj si\u0119",profileHeading:"Profil",emailLabel:"E-mail",noData:"Brak danych",languageLabel:"J\u0119zyk",polishLanguage:"Polski",englishLanguage:"English",plansHeading:"Plany",plansUnavailable:"Plany nie s\u0105 obecnie dost\u0119pne w panelu.",notificationsHeading:"Powiadomienia",notificationsUnavailable:"Ustawienia powiadomie\u0144 nie s\u0105 obecnie dost\u0119pne w panelu.",ordersHeading:"Historia zam\xF3wie\u0144",ordersDescription:"Twoje zam\xF3wienia",ordersEmpty:"Brak zam\xF3wie\u0144.",ordersError:"Nie uda\u0142o si\u0119 pobra\u0107 zam\xF3wie\u0144.",retry:"Spr\xF3buj ponownie",orderLabel:"Zam\xF3wienie",customerLabel:"Klient",dateLabel:"Data",ordersEnd:"To ju\u017C wszystkie Twoje zam\xF3wienia.",previousPage:"Poprzednia strona",nextPage:"Nast\u0119pna strona",paginationLabel:"Strony zam\xF3wie\u0144",statusDraft:"Szkic",statusUnpaid:"Nieop\u0142acone",statusPaid:"Op\u0142acone",statusOverdue:"Zaleg\u0142e",statusCancelled:"Anulowane",statusCompleted:"Zako\u0144czone",statusProcessing:"Przetwarzane",statusRefunded:"Zwr\xF3cone"},en:{returnsNavLabel:"Returns",openCourse:"Open the course",libraryNavLabel:"Library",ordersNavLabel:"Orders",accountNavLabel:"Account",navigationLabel:"Customer panel",logout:"Log out",profileHeading:"Profile",emailLabel:"Email",noData:"No data",languageLabel:"Language",polishLanguage:"Polski",englishLanguage:"English",plansHeading:"Plans",plansUnavailable:"Plans are currently unavailable in the panel.",notificationsHeading:"Notifications",notificationsUnavailable:"Notification settings are currently unavailable in the panel.",ordersHeading:"Order history",ordersDescription:"Your orders",ordersEmpty:"No orders yet.",ordersError:"Could not load your orders.",retry:"Try again",orderLabel:"Order",customerLabel:"Customer",dateLabel:"Date",ordersEnd:"You\u2019ve reached the end of your orders.",previousPage:"Previous page",nextPage:"Next page",paginationLabel:"Order pages",statusDraft:"Draft",statusUnpaid:"Unpaid",statusPaid:"Paid",statusOverdue:"Overdue",statusCancelled:"Cancelled",statusCompleted:"Completed",statusProcessing:"Processing",statusRefunded:"Refunded"}};function ce(e=E()){return Et(xa,e)}import{jsx as qn,jsxs as wa}from"react/jsx-runtime";function mr({}){let e=ce();return wa("section",{children:[qn("h3",{className:"text-2xl",children:e.notificationsHeading}),qn("p",{className:"mt-6 text-sm text-neutral-600 dark:text-neutral-400",children:e.notificationsUnavailable})]})}import{useState as Ca}from"react";import{Fragment as La,jsx as M,jsxs as V}from"react/jsx-runtime";var Na=e=>new Date(e*1e3).toLocaleDateString(E(),{year:"numeric",month:"short",day:"numeric"}),Ia=(e,t)=>new Intl.NumberFormat(E(),{style:"currency",currency:t.toUpperCase()}).format(e/100),Sa={draft:"text-neutral-600 dark:text-neutral-400",unpaid:"text-amber-700 dark:text-amber-300",paid:"text-green-700 dark:text-green-400",overdue:"text-red-700 dark:text-red-400",cancelled:"text-neutral-600 line-through dark:text-neutral-400",completed:"text-green-700 dark:text-green-400",processing:"text-blue-700 dark:text-blue-400",refunded:"text-purple-700 dark:text-purple-400"};function Ea({openOrderDetails:e,projectID:t,accessToken:n}){let o=ce(),r={draft:o.statusDraft,unpaid:o.statusUnpaid,paid:o.statusPaid,overdue:o.statusOverdue,cancelled:o.statusCancelled,completed:o.statusCompleted,processing:o.statusProcessing,refunded:o.statusRefunded},[a,i]=Ca(0),d=20,{data:u,isFetching:l,isError:b,refetch:P}=Ve(q.publicApi.getOrders,{projectId:t,accessToken:n,offset:a,limit:d}),w=u?.orders??[],h=u?.totalCount??0,y=Math.floor(a/d)+1,c=Math.ceil(h/d),m=p=>{i(p)};return V(La,{children:[M("h3",{className:"text-2xl",children:o.ordersHeading}),M("p",{className:"text-sm text-neutral-500 dark:text-neutral-400",children:o.ordersDescription}),l?M("div",{className:"mt-6 flex w-full flex-col gap-3",children:[...Array(5)].map((p,x)=>V("div",{className:"rounded-xl bg-white p-4 shadow-sm dark:bg-neutral-800",children:[V("div",{className:"flex items-center justify-between gap-3",children:[V("div",{className:"space-y-2",children:[M(Ye,{className:"h-4 w-24"}),M(Ye,{className:"h-3 w-32"})]}),V("div",{className:"space-y-2 text-right",children:[M(Ye,{className:"ml-auto h-4 w-16"}),M(Ye,{className:"ml-auto h-3 w-12"})]})]}),M("div",{className:"mt-3",children:M(Ye,{className:"h-3 w-40"})})]},x))}):b?V("div",{role:"alert",className:"mt-6 space-y-3",children:[M("p",{children:o.ordersError}),M(I,{onClick:()=>void P(),className:"min-h-11 focus-visible:outline-2 focus-visible:outline-current",children:o.retry})]}):w.length===0?M("div",{className:"mt-6 text-sm text-neutral-600 dark:text-neutral-400",children:o.ordersEmpty}):V("div",{children:[M("div",{className:"mt-6 flex w-full flex-col gap-3",children:w.map(p=>V("button",{onClick:()=>e(p.id),className:"block min-h-11 focus-visible:outline-2 focus-visible:outline-current rounded-xl bg-white p-4 text-left shadow-sm transition-colors hover:bg-neutral-50 dark:bg-neutral-800 dark:hover:bg-neutral-700",children:[V("div",{className:"flex items-center justify-between gap-3",children:[V("div",{className:"min-w-0 break-words",children:[V("p",{className:"font-medium",children:[o.orderLabel," #",p.id]}),M("p",{className:"text-xs text-neutral-500 dark:text-neutral-400",children:p.customerName||o.customerLabel})]}),V("div",{className:"shrink-0 text-right",children:[M("p",{className:"font-semibold",children:Ia(p.totalAmount,p.currency)}),M("p",{className:`text-xs font-medium ${Sa[p.status]??"text-neutral-400"}`,children:r[p.status]??p.status})]})]}),M("div",{className:"mt-2 flex items-center justify-between gap-3 text-xs text-neutral-500 dark:text-neutral-400",children:V("span",{children:[o.dateLabel,":"," ",p.createdAt?Na(Number(p.createdAt.seconds)):"-"]})})]},p.id))}),y>=c&&M("p",{className:"mt-6 text-center text-sm text-neutral-600 dark:text-neutral-400",children:o.ordersEnd}),c>1&&V("nav",{"aria-label":o.paginationLabel,className:"mt-4 flex flex-wrap items-center justify-center gap-2",children:[y>1&&M(I,{variant:"outline",className:"min-h-11",onClick:()=>m(a-d),children:o.previousPage}),Array.from(new Set([1,y-1,y,y+1,c])).filter(p=>p>0&&p<=c).sort((p,x)=>p-x).map(p=>M(I,{variant:p===y?"secondary":"ghost",className:"min-h-11 min-w-11","aria-current":p===y?"page":void 0,onClick:()=>m((p-1)*d),children:p},p)),y<c&&M(I,{variant:"outline",className:"min-h-11",onClick:()=>m(a+d),children:o.nextPage})]})]})]})}var Hn=Ea;import{jsx as $n,jsxs as Ta}from"react/jsx-runtime";function fr({projectID:e}){let t=ce();return Ta("section",{children:[$n("h3",{className:"text-2xl",children:t.plansHeading}),$n("p",{className:"mt-6 text-sm text-neutral-600 dark:text-neutral-400",children:t.plansUnavailable})]})}import{useEffect as Ra,useState as gr}from"react";import{jsx as ie,jsxs as Ma}from"react/jsx-runtime";function Aa(e,t,n,o){typeof window>"u"||(t&&Je(n,o),window.location.href=e)}function Da({projectID:e,host:t,loginURL:n,screen:o,params:r,setParams:a,setActiveScreen:i}){let{status:d,exchangeError:u}=wn("PanelReturns"),l=xn(),b=d==="anonymous"&&(u==null||vn(u));Ra(()=>{b&&Aa(n,u!=null,e,t)},[b,n,u,e,t]);let[P,w]=gr("orders"),[h,y]=gr({items:[],note:""}),[c,m]=gr();if(d==="anonymous"&&!b)return Ma("div",{role:"alert",className:"flex flex-col items-start gap-3",children:[ie("p",{className:"text-sm",children:l(kn(u))}),ie(I,{type:"button",onClick:()=>window.location.reload(),children:l("errorRetry")})]});if(d!=="authenticated")return ie(Nn,{});let p=x=>{w(x),a({state:"returns",orderId:void 0,returnId:void 0}),i("returns")};if(o==="return-details"&&r.returnId)return ie(Rn,{returnId:r.returnId,onBack:()=>p("myReturns")});if(P==="myReturns")return ie(Tn,{onBack:()=>p("orders"),onSelectReturn:x=>{a({state:"return-details",returnId:x,orderId:void 0}),i("return-details")}});if(P==="result"&&c!=null)return ie(Ln,{returnId:c,onContinue:()=>p("orders"),onOpenMyReturns:()=>p("myReturns")});if(r.orderId){let x=r.orderId;return P==="confirmation"?ie(En,{orderId:x,items:h.items,note:h.note,onBack:()=>w("orders"),onSubmitted:U=>{m(U),y({items:[],note:""}),w("result"),a({orderId:void 0})}}):ie(Sn,{orderId:x,initialItems:h.items.length>0?h.items:void 0,initialNote:h.note,onBack:()=>{y({items:[],note:""}),a({orderId:void 0})},onContinue:U=>{y(U),w("confirmation")}})}return ie(In,{showLogout:!1,onSelectOrder:x=>{y({items:[],note:""}),w("orders"),a({orderId:x})},onOpenMyReturns:()=>p("myReturns")})}function yr({accessToken:e,appearance:t,texts:n,...o}){return ie(Cn,{projectID:o.projectID,host:o.host,appearance:t,texts:n,panelAccessToken:e,children:ie(Da,{...o})})}import{lazy as vi,Suspense as ki,useEffect as wr,useState as xi}from"react";import{BookOpen as wi,Files as Ci,Headphones as Ni,Ticket as Ii}from"lucide-react";var Oa={hello:"Hej \u{1F44B}",intro:"Poni\u017Cej znajdziesz swoje produkty",loading:"\u0141adowanie produkt\xF3w\u2026",empty:"Nie masz jeszcze produkt\xF3w w tym sklepie. Twoje zakupy pojawi\u0105 si\u0119 tutaj.",audio:"Audio",files:"Pliki",course:"Kurs",ticket:"Bilet",listen:"S\u0142uchaj",openCourse:"Otw\xF3rz kurs",downloadFiles:"Pobierz pliki",showTicket:"Poka\u017C bilet",back:"Wr\xF3\u0107",yourFiles:"Twoje pliki",download:"Pobierz",retry:"Spr\xF3buj ponownie",fileError:"Nie uda\u0142o si\u0119 wczyta\u0107 plik\xF3w.",noFiles:"Brak plik\xF3w do pobrania.",ticketInfo:"Tw\xF3j zakupiony bilet",file:"Plik"},Ua={hello:"Hi \u{1F44B}",intro:"Your products are below",loading:"Loading products\u2026",empty:"You have no products in this shop yet. Your purchases will show up here.",audio:"Audio",files:"Files",course:"Course",ticket:"Ticket",listen:"Listen",openCourse:"Open course",downloadFiles:"Download files",showTicket:"Show ticket",back:"Back",yourFiles:"Your files",download:"Download",retry:"Try again",fileError:"Your files could not be loaded.",noFiles:"No files to download.",ticketInfo:"Your purchased ticket",file:"File"};function Xe(){return E().toLowerCase().startsWith("en")?Ua:Oa}import{jsx as Fa}from"react/jsx-runtime";var _a=/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g,za=e=>[...e.matchAll(_a)].map(n=>({url:n[0],startIndex:n.index,endIndex:n.index+n[0].length-1})),ja=(e,t)=>{let n="",o=0;t.sort((r,a)=>r.startIndex-a.startIndex);for(let{startIndex:r,endIndex:a,replacementText:i}of t)n+=e.slice(o,r),n+=i,o=a+1;return n+=e.slice(o),n},Bn=e=>{let t=za(e);return Fa("p",{dangerouslySetInnerHTML:{__html:ja(e,t.map(n=>(n.replacementText=`<a key=${n.url} href=${n.url} style="text-decoration: underline;" target="_blank">
2
+ ${n.url}
3
+ </a>`,n)))}})};import{fromJsonString as Si}from"@bufbuild/protobuf";import{useAutoAnimate as mi}from"@formkit/auto-animate/react";import{ChevronLeft as fi,Download as gi}from"lucide-react";import{useEffect as oo,useRef as ao,useState as Fe}from"react";import ei from"hls.js";import{Pause as ti,Play as ri,SkipBack as ni,SkipForward as oi}from"lucide-react";import{forwardRef as ai,useEffect as je,useImperativeHandle as ii,useRef as K,useState as ke}from"react";import{jsx as hr,jsxs as Ha}from"react/jsx-runtime";function qa(){return Ha("div",{className:"flex items-center gap-2",children:[hr("div",{className:"h-3 w-3 animate-bounce rounded-full bg-current [animation-delay:-0.3s]"}),hr("div",{className:"h-3 w-3 animate-bounce rounded-full bg-current [animation-delay:-0.15s]"}),hr("div",{className:"h-3 w-3 animate-bounce rounded-full bg-current"})]})}var ze=qa;import $a from"hls.js";var Ba=[401,403],Kn="networkError",Gn="mediaError";function Ka(e,t){if(e==null||e.fatal!==!0)return{action:"ignore"};let n=e.response?.code,o=e.type===Kn?"network":e.type===Gn?"media":"unknown",r=n==null?{kind:o}:{kind:o,status:n};return n!=null&&Ba.includes(n)?{action:"expired",error:{kind:"network",status:n}}:e.type===Kn&&!t.network?{action:"restart-load"}:e.type===Gn&&!t.media?{action:"recover-media"}:{action:"fail",error:r}}function Vn(e){let t=e.HlsCtor??$a,n=new t,o,r=!1,a=!1;return n.attachMedia(e.media),n.on(t.Events.ERROR,(i,d)=>{let u=Ka(d,{network:r,media:a});switch(u.action){case"expired":e.handlers?.onExpiredUrl?.(),e.handlers?.onError?.(u.error);break;case"restart-load":r=!0,n.startLoad();break;case"recover-media":a=!0,n.recoverMediaError();break;case"fail":e.handlers?.onError?.(u.error);break;case"ignore":break}}),{load(i){o=i,r=!1,a=!1,n.loadSource(i)},retry(){o!=null&&(r=!1,a=!1,n.loadSource(o))},destroy(){n.destroy()},get src(){return o}}}function Wn(e){try{return e.canPlayType("application/vnd.apple.mpegurl")!==""}catch{return!1}}function Jn(e){switch(e?.code){case 2:return{kind:"network"};case 3:case 4:return{kind:"media"};default:return{kind:"unknown"}}}var Ga={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",webp:"image/webp",gif:"image/gif",avif:"image/avif",svg:"image/svg+xml"},br="512x512";function et(){return typeof navigator<"u"&&typeof navigator.mediaSession<"u"}function Va(e){if(typeof e!="string"||e.length===0)return{src:e,sizes:br};let t=e.split(/[?#]/)[0],n=t.includes(".")?t.slice(t.lastIndexOf(".")+1).toLowerCase():"",o=Ga[n],r={src:e,sizes:br};return o!=null&&(r.type=o),r}function Wa(e){if(e==null)return;let t=Array.isArray(e)?e:[e],n=[];for(let o of t){if(typeof o=="string"){o.length>0&&n.push(Va(o));continue}o!=null&&o.src.length>0&&n.push({src:o.src,sizes:o.sizes??br,...o.type!=null?{type:o.type}:{}})}return n.length>0?n:void 0}function Pr(e){!et()||typeof MediaMetadata>"u"||(navigator.mediaSession.metadata=new MediaMetadata({title:e.title,album:e.album,artist:e.artist,artwork:Wa(e.artwork)}))}function Yn(){et()&&(navigator.mediaSession.playbackState="playing")}function Zn(){et()&&(navigator.mediaSession.playbackState="paused")}function Qn(e,t,n=1){if(!et()||e==null||!Number.isFinite(e)||e<=0||t!=null&&isNaN(t))return;let o=Math.min(Math.max(t??0,0),e),r=Number.isFinite(n)&&n>0?n:1;try{navigator.mediaSession.setPositionState({playbackRate:r,duration:e,position:o})}catch{}}var Xn=["play","pause","stop","seekbackward","seekforward","seekto","previoustrack","nexttrack"];function eo(e){if(et()){Pr({title:e.title,album:e.album,artist:e.artist,artwork:e.artwork});for(let t of Xn)try{navigator.mediaSession.setActionHandler(t,n=>{e.action(n)})}catch{}}}function to(){if(et()){navigator.mediaSession.metadata=null;for(let e of Xn)try{navigator.mediaSession.setActionHandler(e,null)}catch{}}}import{useEffect as Ja,useState as Ya}from"react";var Za={play:"Odtw\xF3rz",pause:"Wstrzymaj",previous:"Poprzedni rozdzia\u0142",next:"Nast\u0119pny rozdzia\u0142",rewind:"Cofnij o 10 sekund",forward:"Przewi\u0144 o 10 sekund",progress:"Post\u0119p odtwarzania",of:"z",speed:"Pr\u0119dko\u015B\u0107",sleep:"Wy\u0142\u0105cznik czasowy",off:"Wy\u0142\u0105czony",end:"Koniec rozdzia\u0142u",cancel:"Anuluj wy\u0142\u0105cznik",error:"Nie uda\u0142o si\u0119 odtworzy\u0107 nagrania.",retry:"Spr\xF3buj ponownie",left:"zosta\u0142o",book:"ca\u0142a ksi\u0105\u017Cka",chapter:"rozdzia\u0142",chapters:"Rozdzia\u0142y",loading:"\u0141adowanie rozdzia\u0142\xF3w\u2026",empty:"Brak rozdzia\u0142\xF3w do wy\u015Bwietlenia.",resume:"Kontynuuj",chapterName:"Rozdzia\u0142",download:"Pobierz rozdzia\u0142",playing:"Teraz odtwarzane",played:"Ods\u0142uchane"},Qa={play:"Play",pause:"Pause",previous:"Previous chapter",next:"Next chapter",rewind:"Rewind 10 seconds",forward:"Forward 10 seconds",progress:"Playback progress",of:"of",speed:"Speed",sleep:"Sleep timer",off:"Off",end:"End of chapter",cancel:"Cancel timer",error:"The recording could not be played.",retry:"Try again",left:"left",book:"whole book",chapter:"chapter",chapters:"Chapters",loading:"Loading chapters\u2026",empty:"No chapters to display.",resume:"Continue",chapterName:"Chapter",download:"Download chapter",playing:"Now playing",played:"Played"};function At(e){let[t,n]=Ya("pl");return Ja(()=>{try{n(E())}catch{}},[]),(e??t).toLowerCase().startsWith("en")?Qa:Za}function ve(e){let t=Number.isFinite(e)?Math.max(0,Math.floor(e)):0;return`${t>=3600?`${Math.floor(t/3600)}:`:""}${String(Math.floor(t/60)%60).padStart(2,"0")}:${String(t%60).padStart(2,"0")}`}var W={get(e){try{return localStorage.getItem(e)}catch{return null}},set(e,t){try{localStorage.setItem(e,t)}catch{}},remove(e){try{localStorage.removeItem(e)}catch{}}},vr="__player__speed",Dt=[.75,1,1.25,1.5,1.75,2];import{jsx as D,jsxs as H}from"react/jsx-runtime";var si=ai(({chapters:e,locale:t,styles:n,updateCurrentTime:o,setCurrentTimeHandler:r,title:a,imageURL:i,coverShownBeside:d,author:u,uniqueProductID:l,onChapterChange:b,onError:P,onExpiredUrl:w,onFinished:h},y)=>{let c=At(t),[m,p]=ke(1),x=K(1),[U,le]=ke(),[L,de]=ke("off"),[Ne,te]=ke(0),A=K({mode:"off",deadline:0});function fe(){A.current={mode:"off",deadline:0},de("off"),te(0)}function Y(s){let g=Number(s)*60;A.current={mode:s,deadline:Number.isFinite(g)?Date.now()+g*1e3:0},de(s),te(Number.isFinite(g)?g:0)}function He(s){Dt.includes(s)&&(p(s),x.current=s,W.set(vr,String(s)),_.current&&(_.current.playbackRate=s),B())}je(()=>{let s=Number(W.get(vr));Dt.includes(s)&&He(s);let g=setInterval(()=>{let{mode:k,deadline:T}=A.current;if(k==="off"||k==="chapter")return;let be=Math.max(0,Math.ceil((T-Date.now())/1e3));te(be),be===0&&(Oe.current=!1,xt(),fe())},1e3);return()=>clearInterval(g)},[]);let Z;(k=>(k[k.Playing=0]="Playing",k[k.Paused=1]="Paused"))(Z||={});let[Me,lt]=ke(1),[$t,Ie]=ke(void 0),[C,ge]=ke(void 0),[$e,ue]=ke(!1),[vt,$r]=ke(null),_=K(null),ye=K(null),kt=K(void 0),Zo=K(null),re=K(null),Bt=K(null),Oe=K(!1),Be=K(!1),dt=K(null),Kt=K(null),Gt=K(e),Br=K(null),ne=K({onChapterChange:b,onError:P,onExpiredUrl:w,onFinished:h,updateCurrentTime:o,title:a,imageURL:i,author:u});ne.current={onChapterChange:b,onError:P,onExpiredUrl:w,onFinished:h,updateCurrentTime:o,title:a,imageURL:i,author:u};function Vt(s){!Be.current||!Number.isFinite(s)||s<0||W.set(`__player__${l}_${re.current?.id}`,`${Math.floor(s)}`)}function Qo(){let s=W.get(`__player__${l}_${re.current?.id}`);if(s!=null)try{let g=parseInt(s);return isNaN(g)||g<0?void 0:g}catch{return}}function Xo(){let s=W.get(`__player__${l}_last_chapter`);if(s!=null)return s}function Kr(s){W.set(`__player__${l}_last_chapter`,s)}function Gr(s){W.remove(`__player__${l}_${s}`)}function Wt(s){Pr({title:s?.name??ne.current.title??"",album:ne.current.title,artist:ne.current.author,artwork:ne.current.imageURL})}function Vr(s){Bt.current=s,$r(s),ue(!1),ne.current.onError?.(s)}function Wr(){Bt.current=null,$r(null)}function Jr(){let s=_.current;if(s==null)return;let g=s.play();g!=null&&typeof g.catch=="function"&&g.catch(()=>{}),B()}function Yr(){Jr()}function xt(){_.current?.pause(),B()}function ea(){if(Me===0){xt();return}Yr()}function Se(s){let g=_.current;if(g==null||!Number.isFinite(s))return;let k=Number.isFinite(g.duration)?g.duration:0,T=k>0?Math.min(Math.max(s,0),k):Math.max(s,0);Ie(T),g.currentTime=T,B()}function wt(s){let g=_.current;if(g==null)return;let k=Number.isFinite(g.duration)?g.duration:void 0,T=Math.max(g.currentTime+s,0);k!=null&&T>k&&(T=k),Se(T)}function Jt(s){let g=_.current;if(g!=null){if(Wr(),ue(!0),Wn(g)){Yt(),g.src=s,g.load();return}if(ei.isSupported()){ye.current==null&&(ye.current=Vn({media:g,handlers:{onError:k=>{Vr(k)},onExpiredUrl:()=>{ne.current.onExpiredUrl?.()}}})),ye.current.load(s);return}Yt(),g.src=s,g.load()}}function Yt(){ye.current?.destroy(),ye.current=null}function Ct(s,g){let k=g?.play===!0;re.current&&_.current&&!_.current.ended&&Vt(_.current.currentTime),Be.current=!1,dt.current=null,Oe.current=k,re.current=s,le(s.id),Ie(0),ge(s.duration),Jt(s.publicUrl),Wt(s),ne.current.onChapterChange?.(s),Kr(s.id)}function Zt(s){if(s.length===0)return;let g=Xo(),k=(g!=null?s.find(T=>T.id===g):void 0)??s[0];Ct(k,{play:!1})}function Qt(){let s=Gt.current,g=re.current;if(s==null||s.length===0||g==null)return;let k=s.findIndex(be=>be.id===g.id);if(k===-1)return;let T=k+1;if(T>=s.length){ta(g);return}Ct(s[T],{play:!0})}function Zr(){let s=Gt.current,g=re.current;if(g==null)return;let k=_.current;if(k!=null&&k.currentTime>3){Se(0);return}let T=s==null?-1:s.findIndex(be=>be.id===g.id);if(T>0){Ct(s[T-1],{play:!0});return}Se(0)}function ta(s){Gr(s.id),Oe.current=!1,_.current?.pause(),lt(1),ne.current.onFinished?.()}function Qr(){let s=re.current;if(s!=null){if(W.set(`__player__${l}_${s.id}_completed`,"true"),Gr(s.id),A.current.mode==="chapter"){Oe.current=!1,xt(),fe();return}Qt(),B()}}function Xr(){let s=_.current;if(s!=null){if(ue(!1),s.playbackRate=x.current,Kt.current=null,!Be.current){Be.current=!0;let g=dt.current;if(dt.current=null,g!=null)Se(g);else{let k=Qo();k!=null&&Se(k)}}Oe.current&&(Oe.current=!1,Jr())}}function en(){let s=_.current?.error,g=re.current?.publicUrl;(s?.code===2||s?.code===4)&&ye.current==null&&g!=null&&Kt.current!==g&&(Kt.current=g,ne.current.onExpiredUrl?.()),Vr(Jn(s))}function tn(){let g=re.current?.publicUrl??ye.current?.src;if(g==null)return;let T=_.current?.currentTime??0;Wr(),Be.current=!1,dt.current=T>0?T:null,Ie(T),ye.current!=null?ye.current.retry():Jt(g)}function ra(s){switch(s.action){case"play":Yr();break;case"pause":case"stop":xt();break;case"seekbackward":wt(-(s.seekOffset??10));break;case"seekforward":wt(s.seekOffset??10);break;case"seekto":s.seekTime!=null&&Se(s.seekTime);break;case"previoustrack":Zr();break;case"nexttrack":Qt();break;default:break}}ii(y,()=>({selectChapter:s=>{Ct(s,{play:!0})},retry:tn,getError:()=>Bt.current}));function B(){let s=_.current;s!=null&&(lt(s.paused?1:0),ge(s.duration),Ie(s.currentTime),s.ended||Vt(s.currentTime),Qn(s.duration,s.currentTime,s.playbackRate),s.networkState===s.NETWORK_LOADING&&s.readyState<=s.HAVE_FUTURE_DATA?ue(!0):ue(!1),ne.current.updateCurrentTime?.(s.currentTime))}je(()=>(eo({title:a??"",album:a,artist:u,artwork:i,action:ra}),()=>{to()}),[]),je(()=>{Wt(re.current)},[a,u,i]),je(()=>{let s=_.current;if(s!=null)return s.addEventListener("loadeddata",Xr),s.addEventListener("ended",Qr),s.addEventListener("error",en),s.addEventListener("timeupdate",B),s.addEventListener("play",B),s.addEventListener("pause",B),s.addEventListener("ratechange",B),B(),kt.current=setInterval(B,500),()=>{s.removeEventListener("loadeddata",Xr),s.removeEventListener("ended",Qr),s.removeEventListener("error",en),s.removeEventListener("timeupdate",B),s.removeEventListener("play",B),s.removeEventListener("pause",B),s.removeEventListener("ratechange",B),kt.current!=null&&(clearInterval(kt.current),kt.current=void 0),s.ended||Vt(s.currentTime),Ie(void 0),s.pause(),Yt(),s.removeAttribute("src"),s.load()}},[]),je(()=>{r?.(Se)},[]);let Xt=e.map(s=>`${s.id}|${s.publicUrl??""}`).join(`
4
+ `);je(()=>{Gt.current=e;let s=Br.current;if(s===Xt)return;if(Br.current=Xt,s==null){Zt(e);return}let g=re.current;if(g==null){Zt(e);return}let k=e.find(T=>T.id===g.id);if(!(k!=null&&k.publicUrl===g.publicUrl)){if(k!=null){let T=_.current,be=T?.currentTime??0,oa=T!=null&&!T.paused;re.current=k,Be.current=!1,dt.current=be>0?be:null,Oe.current=oa,Jt(k.publicUrl),Wt(k),ne.current.onChapterChange?.(k),Kr(k.id);return}Zt(e)}},[Xt]),je(()=>{switch(Me){case 0:Yn();break;case 1:Zn();break}},[Me]);let Ke=e.findIndex(s=>s.id===U),he=Number.isFinite(C)&&C>0?C:e[Ke]?.duration??0,ut=Math.min(Math.max($t??0,0),he||1/0),rn=e.length>0&&e.every(s=>Number.isFinite(s.duration)&&s.duration>0),na=Math.max(0,he-ut+(rn?e.slice(Ke+1).reduce((s,g)=>s+g.duration,0):0))/m,er=Math.ceil(na/60),nn=`${Math.floor(er/60)>0?`${Math.floor(er/60)} h `:""}${er%60} min`;return H("div",{id:"audio-player-container",className:"bitsnap-audio-player flex min-w-0 flex-col gap-3 text-neutral-900 dark:text-neutral-100",style:{...n,"--seek-before-width":`${he>0?ut/he*100:0}%`},ref:Zo,"data-player-error":vt?.kind,children:[D("video",{ref:_,className:"hidden",poster:i,title:a}),H("div",{className:j("flex min-w-0 items-center gap-3",d&&"lg:hidden"),children:[i&&D("img",{src:i,alt:"",className:"h-16 w-16 shrink-0 rounded object-contain"}),H("div",{className:"min-w-0 break-words",children:[D("p",{className:"font-semibold",children:e[Ke]?.name??a}),u&&D("p",{className:"text-sm text-neutral-600 dark:text-neutral-300",children:u})]})]}),vt&&H("div",{role:"alert",className:"rounded-lg bg-red-50 p-3 text-red-800 dark:bg-red-950 dark:text-red-200",children:[D("p",{children:c.error}),D(I,{variant:"outline",onClick:tn,children:c.retry})]}),D("input",{type:"range",min:"0",max:he||100,value:ut,disabled:!he,"aria-label":c.progress,"aria-valuetext":`${ve(ut)} ${c.of} ${ve(he)}`,onChange:s=>Se(Number(s.target.value))}),H("section",{className:"flex w-full justify-between text-sm tabular-nums",children:[D("span",{id:"current-time",children:ve(ut)}),D("span",{id:"duration",children:ve(he)})]}),he>0&&H("p",{className:"text-sm text-neutral-600 dark:text-neutral-300",children:[c.left==="left"?`${nn} ${c.left}`:`${c.left} ${nn}`," ","\xB7 ",rn?c.book:c.chapter," (",m,"\xD7)"]}),H("div",{className:"flex flex-wrap items-center justify-center gap-2",children:[D(I,{variant:"outline",onClick:Zr,disabled:Ke<0,"aria-label":c.previous,children:D(ni,{className:"h-5 w-5"})}),H(I,{variant:"outline",onClick:()=>wt(-10),"aria-label":c.rewind,children:["\u2212",10]}),D(I,{variant:"outline",onClick:ea,"aria-label":Me===1?c.play:c.pause,children:Me===1?D(ri,{className:"h-5 w-5"}):D(ti,{className:"h-5 w-5"})}),H(I,{variant:"outline",onClick:()=>wt(10),"aria-label":c.forward,children:["+",10]}),D(I,{variant:"outline",onClick:Qt,disabled:Ke<0||Ke>=e.length-1,"aria-label":c.next,children:D(oi,{className:"h-5 w-5"})})]}),H("div",{className:"flex flex-wrap gap-3 md:grid md:grid-cols-2",children:[H("label",{className:"flex flex-1 items-center gap-2 text-sm md:flex-col md:items-start md:whitespace-nowrap",children:[c.speed,D("select",{"aria-label":c.speed,value:m,onChange:s=>He(Number(s.target.value)),children:Dt.map(s=>H("option",{value:s,children:[s,"\xD7"]},s))})]}),H("label",{className:"flex flex-1 items-center gap-2 text-sm md:flex-col md:items-start md:whitespace-nowrap",children:[c.sleep,H("select",{"aria-label":c.sleep,value:L,onChange:s=>Y(s.target.value),children:[D("option",{value:"off",children:c.off}),[15,30,45,60].map(s=>H("option",{value:s,children:[s," min"]},s)),D("option",{value:"chapter",children:c.end})]})]})]}),L!=="off"&&H("div",{className:"flex items-center justify-between gap-2 text-sm",children:[D("span",{role:"timer",children:L==="chapter"?c.end:ve(Ne)}),D(I,{variant:"outline",onClick:fe,children:c.cancel})]}),$e&&D("div",{role:"status",className:"flex justify-center",children:D(ze,{})})]})}),ro=si;import{Check as li,Download as di,Play as ui}from"lucide-react";import{useEffect as ci,useState as no}from"react";import{Fragment as pi,jsx as se,jsxs as rt}from"react/jsx-runtime";function kr({chapters:e,currentID:t,productID:n,onSelect:o,downloadable:r,onDownload:a,loading:i,locale:d}){let u=At(d),[l,b]=no(null),[P,w]=no([]);ci(()=>{let c=`__player__${n}_`,m=W.get(`${c}last_chapter`),p=Number(m&&W.get(`${c}${m}`));b(m&&p>0&&Number.isFinite(p)?{id:m,time:p}:null),w((e??[]).filter(x=>W.get(`${c}${x.id}_completed`)==="true"||Number(W.get(`${c}${x.id}`))>0).map(x=>x.id))},[e,n,t]);let h=e?.findIndex(c=>c.id===l?.id)??-1,y=e?.findIndex(c=>c.id===t)??-1;return rt("div",{className:"max-h-96 w-full overflow-y-auto",children:[se("h2",{className:"mb-3 text-xl font-semibold",children:u.chapters}),i?se("p",{role:"status",children:u.loading}):e?.length?rt(pi,{children:[l&&h>=0&&rt("button",{type:"button",className:"mb-3 min-h-11 rounded-lg border border-neutral-300 px-3 py-2 text-left dark:border-neutral-600",onClick:()=>o(e[h]),children:[u.resume,": ",u.chapterName," ",h+1,","," ",ve(l.time)]}),se("ul",{className:"flex w-full flex-col gap-2",children:e.map((c,m)=>{let p=c.id===t,x=m<y||P.includes(c.id);return rt("li",{className:"flex min-w-0 items-center gap-2",children:[rt("button",{type:"button","aria-current":p?"true":void 0,className:`min-h-11 min-w-0 flex-1 rounded-lg p-3 text-left hover:bg-neutral-200 dark:hover:bg-neutral-700 ${p?"bg-neutral-200 dark:bg-neutral-700":"bg-neutral-100 dark:bg-neutral-800"}`,onClick:()=>o(c),children:[rt("span",{className:"flex items-center gap-2",children:[p?se(ui,{className:"size-4 shrink-0","aria-label":u.playing}):x?se(li,{className:"size-4 shrink-0","aria-label":u.played}):null,se("span",{className:"min-w-0 flex-1 break-words text-sm font-medium",children:c.name}),!!c.duration&&se("span",{className:"shrink-0 text-xs tabular-nums text-neutral-600 dark:text-neutral-300",children:ve(c.duration)})]}),c.description&&se("span",{className:"mt-2 block text-xs",children:c.description})]}),r&&c.downloadableUrl&&se("a",{href:c.downloadableUrl,onClick:a,"aria-label":`${u.download} ${m+1}`,className:"inline-flex min-h-11 min-w-11 items-center justify-center rounded focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2",children:se(di,{className:"size-4","aria-hidden":"true"})})]},c.id)})})]}):se("p",{children:u.empty})]})}import{Fragment as Mt,jsx as N,jsxs as J}from"react/jsx-runtime";function xe(e,...t){console.warn(e,...t)}function xr(e){console.error(e)}var yi=({accessToken:e,product:t,styles:n,reveal:o})=>{let r=Xe(),a=t.productType,i=St(),d=()=>i.track("panel_download",{},{product_id:t.productId.length<=64?t.productId:null}),u=ao(null),[l]=mi(),[b,P]=Fe(!1),[w,h]=Fe(null),{mutateAsync:y,isPending:c}=oe(q.publicApi.userPanelGetFileDetails),m=ao(void 0),[p,x]=Fe(null),[U,le]=Fe(null),[L,de]=Fe(!1),{mutateAsync:Ne,isPending:te}=oe(q.publicApi.userPanelGetAudiobookDetails),{mutateAsync:A,isPending:fe}=oe(q.publicApi.userPanelGetAudiobookDetailsDownloadURLs),[Y,He]=Fe(null),[Z,Me]=Fe(null);async function lt(){P(!1);try{let C=await y({accessId:t.accessId,accessToken:e});if(C.result.case==="success"){h(C.result.value.files);return}else P(!0),xe("Pobranie plik\xF3w nie powiod\u0142o si\u0119. Zalecamy kontakt."),xe("Kod b\u0142\u0119du: ",C.result.value)}catch(C){P(!0),xe("Nieoczekiwany b\u0142\u0105d. Spr\xF3buj ponownie za chwil\u0119."),xr("B\u0142\u0105d podczas pobierania danych:"+C)}}async function $t(){try{let C=await Ne({accessId:t.accessId,accessToken:e});if(C.result.case==="audiobook"){x(C.result.value);return}else xe("Pobranie plik\xF3w nie powiod\u0142o si\u0119. Zalecamy kontakt."),xe("Kod b\u0142\u0119du: ",C.result.value)}catch(C){xe("Nieoczekiwany b\u0142\u0105d. Spr\xF3buj ponownie za chwil\u0119."),xr("B\u0142\u0105d podczas pobierania danych:"+C)}}async function Ie(){try{let C=await A({accessId:t.accessId,accessToken:e,isBrowser:!0});if(C.result.case==="success"){le(C.result.value.audiobookDownloadDetails),de(C.result.value.isAvailableToDownloadInMobileApp===!0);return}else xe("Pobranie plik\xF3w nie powiod\u0142o si\u0119. Zalecamy kontakt."),xe("Kod b\u0142\u0119du: ",C.result.value)}catch(C){xe("Nieoczekiwany b\u0142\u0105d. Spr\xF3buj ponownie za chwil\u0119."),xr("B\u0142\u0105d podczas pobierania danych:"+C)}}return oo(()=>{a===2&&lt(),a===1&&($t().then().catch(),Ie().then().catch())},[]),oo(()=>{if(p!=null&&U!=null){let C=p.chapters;if(!C)return;let ge=C.map($e=>{let ue=U?.find(vt=>vt.chapterId===$e.id);if(ue!=null)return{...$e,publicUrl:ue.publicUrl,downloadableUrl:ue.downloadableUrl,duration:ue.duration}}).filter($e=>$e!=null);ge!=null&&ge.length>0&&Me(ge)}},[p,U]),J("div",{children:[N("div",{className:"mb-3 space-y-4 rounded bg-white p-4 dark:bg-black",children:J(I,{onClick:()=>o(),variant:"ghost",className:"min-h-11 w-fit",children:[N(fi,{className:"h-6 w-6"}),N("span",{className:"font-inter text-sm font-medium",children:r.back})]})}),J("main",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2",children:[J("header",{className:"flex min-w-0 flex-col gap-4 rounded-xl border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-900 lg:row-span-2 lg:self-start",children:[N("img",{src:t.productImageUrl,alt:t.productName,width:384,height:384,draggable:!1,className:"aspect-square max-h-72 w-full object-contain"}),N("h2",{className:"text-2xl font-semibold",children:t.productName})]}),J("div",{className:"flex min-w-0 flex-col gap-6",children:[a===2&&J("section",{ref:l,className:"flex flex-col gap-4 rounded-xl border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-900",children:[N("h3",{className:"text-xl font-semibold",children:r.yourFiles}),c&&N("div",{role:"status","aria-label":r.loading,children:N(ze,{})}),b&&J("div",{role:"alert",children:[N("p",{children:r.fileError}),N(I,{className:"min-h-11",onClick:lt,children:r.retry})]}),w?.length===0&&N("p",{children:r.noFiles}),w&&N("ul",{className:"flex flex-col gap-3",children:w.map((C,ge)=>J("li",{className:"flex min-w-0 flex-wrap items-center justify-between gap-3",children:[N("span",{className:"min-w-0 break-all text-sm",children:io(C)||`${r.file} ${ge+1}`}),J("a",{target:"_blank",rel:"noopener noreferrer",href:C,download:!0,onClick:d,className:"inline-flex min-h-11 items-center gap-2 rounded-md bg-neutral-900 px-3 py-2 text-sm text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 dark:bg-neutral-100 dark:text-neutral-900","aria-label":`${r.download}: ${io(C)||`${r.file} ${ge+1}`}`,children:[r.download,N(gi,{className:"size-4","aria-hidden":"true"})]})]},C))})]}),a===3&&J("section",{className:"rounded-xl border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-900",children:[N("h3",{className:"text-lg font-semibold",children:r.ticket}),N("p",{className:"mt-2 font-medium",children:t.productName}),N("p",{className:"mt-2 text-sm text-neutral-600 dark:text-neutral-300",children:r.ticketInfo})]}),a===1&&N(Mt,{children:J("div",{className:"flex flex-col space-y-6 rounded-xl bg-white p-3 drop-shadow-xl dark:bg-neutral-900 dark:drop-shadow-none",children:[N("h4",{className:"text-xl font-semibold",children:Y?.name??"Odtwarzacz"}),Y?.description&&N("p",{className:"text-sm",children:Y?.description}),N(Mt,{children:te?J("div",{className:"flex gap-2",children:[N(ze,{}),N("p",{className:"text-xl font-semibold",children:"Trwa pobierania audiobooka..."})]}):N(Mt,{children:Z!=null?N(Mt,{children:N(ro,{ref:u,coverShownBeside:!0,chapters:Z,author:typeof p?.author=="string"?p.author:void 0,onExpiredUrl:()=>{Ie()},title:p?.name??t.productName??void 0,imageURL:p?.coverImage??t.productImageUrl??void 0,styles:n,setCurrentTimeHandler:C=>{m.current=C},uniqueProductID:t.productId,onChapterChange:C=>{He(C)}})}):N("p",{className:"mt-2",children:"Wybierz rozdzia\u0142, kt\xF3ry ci\u0119 interesuje."})})}),J("div",{className:"rounded-xl bg-neutral-100 p-3 dark:bg-neutral-800",children:[N("p",{className:"mt-3 mb-3 text-xs",children:L?"Mo\u017Cesz s\u0142ucha\u0107 tego audiobooka w aplikacji r\xF3wnie\u017C bez dost\u0119pu do internetu.":"Mo\u017Cesz s\u0142ucha\u0107 tego audiobooka w aplikacji."}),J("div",{className:"flex gap-3",children:[N("a",{href:"https://apps.apple.com/us/app/bitsnap/id6741902807",children:N("img",{width:"100",src:"https://bitsnap.pl/appstore.svg",alt:"Pobierz aplikacje z AppStore"})}),N("a",{href:"https://play.google.com/store/apps/details?id=com.bitsnap.Bitsnap",children:N("img",{width:"100",src:"https://bitsnap.pl/playstore.svg",alt:"Pobierz aplikacj\u0119 z GooglePlay"})})]})]})]})}),N("div",{className:"flex items-center justify-center rounded-xl bg-white p-3 drop-shadow-xl dark:bg-neutral-900 dark:drop-shadow-none",children:a===1&&N(kr,{chapters:Z,currentID:Y?.id,productID:t.productId,loading:te,downloadable:p?.isDownloadable===!0,onDownload:d,onSelect:C=>u.current?.selectChapter(C)})})]}),N("section",{className:"rounded-xl border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-900",children:N("p",{className:"whitespace-pre-wrap text-sm text-neutral-600 dark:text-neutral-300",children:t.productDescription})})]})]})},so=yi;function io(e){try{return decodeURIComponent(new URL(e,"https://bitsnap.pl").pathname.split("/").pop()||"")}catch{return""}}import{useTransport as hi}from"@connectrpc/connect-query";import{useEffect as bi,useState as Pi}from"react";function lo(e,t){let n=hi(),[o,r]=Pi({status:"loading"});return bi(()=>{if(!e){r({status:"hidden"});return}let a=!1;return r({status:"loading"}),import("./model-files-client-HHDXJDTS.mjs").then(({listModelFiles:i})=>i(n,e,t)).catch(()=>({status:"hidden"})).then(i=>{a||r(i)}),()=>{a=!0}},[n,e,t]),o}import{Fragment as po,jsx as O,jsxs as Re}from"react/jsx-runtime";var Ei=vi(()=>import("./PanelModelFiles-4B2HYGIE.mjs")),Li=({accessToken:e,projectID:t,loginURL:n,styles:o,activeScreen:r,params:a,setParams:i,openCourse:d})=>{let{host:u}=Pe(),{data:l,isLoading:b,error:P,refetch:w}=Ve(q.publicApi.userPanelGetProducts,{accessToken:e}),h=lo(e,t),y=Ti({products:b?{status:"loading"}:P!=null?{status:"error"}:l?.result.case==="success"?{status:"ok",count:l.result.value.products.length}:l?.result.case==="failure"?{status:"failure",unauthorized:l.result.value===9}:{status:"error"},modelFiles:h});if(wr(()=>{y.kind==="signed-out"&&(Je(t,u),window.location.href=n)},[y.kind,t,u,n]),y.kind==="loading"||y.kind==="signed-out")return O("div",{role:"status","aria-label":Xe().loading,"aria-busy":"true",className:"grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5",children:Array.from({length:6},(x,U)=>O("div",{"aria-hidden":"true",className:"h-72 rounded-xl bg-neutral-100 motion-safe:animate-pulse dark:bg-neutral-800"},U))});let c=l&&l.result.case==="success"?l.result.value.products:[],m=h.status==="ready"?h.models:[],p=m.length>0?O(ki,{fallback:null,children:O(Ei,{accessToken:e,models:m,buttonStyle:o})}):null;return y.kind==="error"?Re(po,{children:[O(Ai,{onRetry:()=>void w()}),p]}):y.kind==="empty"?O(Ri,{}):O(Di,{accessToken:e,products:c,styles:o,activeScreen:r,params:a,setParams:i,openCourse:d,filesSection:p})};function Ti({products:e,modelFiles:t}){if(e.status==="failure"&&e.unauthorized)return{kind:"signed-out"};if(e.status==="loading")return{kind:"loading"};if(e.status==="ok"&&e.count>0)return{kind:"list"};if(t.status==="loading")return{kind:"loading"};if(e.status==="failure"||e.status==="error")return t.status==="unauthorized"?{kind:"signed-out"}:{kind:"error"};let n=t.status==="ready"?t.models.length:0;return e.count===0&&n===0?{kind:"empty"}:{kind:"list"}}function Ri(){let e=Xe();return Re("div",{className:"flex flex-col items-start gap-1","data-testid":"panel-empty",children:[O("h3",{className:"text-2xl",children:e.hello}),O("p",{className:"text-sm text-neutral-500",children:e.empty})]})}function Ai({onRetry:e}){let t=E().toLowerCase().startsWith("en");return Re("div",{className:"flex flex-col items-start gap-3",role:"alert","data-testid":"panel-error",children:[O("p",{className:"text-sm text-neutral-600 dark:text-neutral-300",children:t?"Your products could not be loaded.":"Nie uda\u0142o si\u0119 wczyta\u0107 Twoich produkt\xF3w."}),O(I,{type:"button",onClick:e,className:"text-sm",children:t?"Try again":"Spr\xF3buj ponownie"})]})}var co=Li,Di=({accessToken:e,products:t,styles:n,filesSection:o,activeScreen:r,params:a,setParams:i,openCourse:d})=>{let u=Xe(),[l,b]=xi(()=>uo(a.product,t));wr(()=>{b(uo(a.product,t))},[a.product,t]);let P=h=>{b(h),i({product:h?h.accessId||h.productId:void 0,state:"products"})};wr(()=>{r==="products"&&l?.productType===4&&d(l.accessId)},[r,l,d]);function w(h){if(h.productType===4){d(h.accessId);return}P(h)}return r==="products"&&l?.productType===4?null:r==="products"&&l!=null?O(so,{accessToken:e,product:l,styles:n,reveal:P,onOpenCourse:d}):Re(po,{children:[O("h3",{className:"text-2xl",children:u.hello}),t.length>0&&O("p",{className:"text-sm text-neutral-500 dark:text-neutral-400",children:u.intro}),O("div",{className:"mt-6 grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5",children:t.map(h=>{let[y,c,m]=h.productType===1?[u.audio,u.listen,Ni]:h.productType===4?[u.course,u.openCourse,wi]:h.productType===3?[u.ticket,u.showTicket,Ii]:[u.files,u.downloadFiles,Ci];return Re("button",{type:"button",onClick:()=>w(h),className:"flex min-h-11 min-w-0 flex-col overflow-hidden rounded-xl border border-neutral-200 bg-white text-left text-neutral-900 transition-colors hover:border-neutral-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-neutral-500 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-50 dark:hover:border-neutral-500",children:[Re("span",{className:"flex w-full flex-col gap-3 bg-neutral-100 p-3 dark:bg-neutral-800",children:[Re("span",{className:"flex w-fit items-center gap-1.5 rounded-md bg-white px-2 py-1 text-xs font-medium dark:bg-neutral-900",children:[O(m,{className:"size-4","aria-hidden":"true"}),y]}),O("img",{src:h.productImageUrl,alt:h.productName,draggable:!1,className:"aspect-square w-full object-contain"})]}),Re("span",{className:"flex flex-1 flex-col gap-3 p-3",children:[O("span",{className:"line-clamp-2 font-semibold",children:h.productName}),O("span",{className:"line-clamp-2 text-sm text-neutral-600 dark:text-neutral-300",children:Bn(h.productDescription)}),O("span",{className:"mt-auto pt-2 text-sm font-medium underline underline-offset-4",children:c})]})]},h.accessId||h.productId)})}),o]})};function uo(e,t){if(!e)return;let n=t.find(o=>(o.accessId||o.productId)===e||o.productId===e);if(n)return n;try{let o=Si(an,e);return t.find(r=>o.accessId?r.accessId===o.accessId:r.productId===o.productId)}catch{return}}import{LogOut as zi}from"lucide-react";import{Library as Mi,Receipt as Oi,Undo2 as Ui,User as _i}from"lucide-react";var mo=[{screen:"products",label:"libraryNavLabel",icon:Mi},{screen:"orders",label:"ordersNavLabel",icon:Oi},{screen:"returns",label:"returnsNavLabel",icon:Ui},{screen:"profile",label:"accountNavLabel",icon:_i}];function fo(e){return e==="course"?"products":e==="order-details"?"orders":e==="return-details"?"returns":e}import{jsx as qe,jsxs as ht}from"react/jsx-runtime";function Cr({activeScreen:e,setActiveScreen:t,setParams:n,theme:o,logout:r,email:a,projectID:i}){let d=ce(),{data:u}=un(i??"",!!i);return ht("header",{className:"flex h-14 shrink-0 items-center border-b border-neutral-200 bg-white px-4 md:h-dvh md:w-56 md:flex-col md:items-stretch md:border-r md:border-b-0 md:py-5 dark:border-neutral-800 dark:bg-neutral-900",children:[ht("div",{className:"flex min-w-0 items-center gap-3 md:mb-6 md:flex-col md:items-start",children:[qe(Lt,{projectId:i,logoUrl:o?.logoURL,logoDarkUrl:o?.logoDarkURL,name:u?.name,className:"shrink-0"}),u?.name&&qe("span",{title:u.name,className:"truncate text-sm font-medium md:line-clamp-2 md:whitespace-normal",children:u.name})]}),qe("nav",{"aria-label":d.navigationLabel,className:"fixed inset-x-0 bottom-0 z-10 flex h-[calc(56px+env(safe-area-inset-bottom))] items-start justify-around border-t border-neutral-200 bg-white pb-[env(safe-area-inset-bottom)] md:static md:h-auto md:flex-1 md:flex-col md:justify-start md:gap-2 md:border-0 md:bg-transparent md:pb-0 dark:border-neutral-800 dark:bg-neutral-900",children:mo.map(({screen:l,label:b,icon:P})=>{let w=fo(e)===l;return ht("button",{type:"button","aria-current":w?"page":void 0,onClick:()=>{t(l),n({product:void 0,state:l})},className:j("flex h-14 min-h-11 min-w-0 flex-1 flex-col items-center justify-center gap-1 px-1 text-[11px] focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-current md:h-11 md:w-full md:flex-none md:flex-row md:justify-start md:gap-3 md:rounded-md md:px-3 md:text-sm",w?"bg-neutral-100 font-semibold text-black dark:bg-neutral-800 dark:text-white":"text-neutral-600 hover:bg-neutral-100 dark:text-neutral-400 dark:hover:bg-neutral-800"),children:[qe(P,{className:"h-5 w-5 shrink-0","aria-hidden":"true"}),qe("span",{children:d[b]})]},l)})}),ht("div",{className:"hidden border-t border-neutral-200 pt-4 md:block dark:border-neutral-800",children:[a&&qe("p",{title:a,className:"mb-3 truncate text-sm text-neutral-600 dark:text-neutral-400",children:a}),ht("button",{type:"button",onClick:r,className:"flex min-h-11 w-full items-center gap-3 rounded-md px-3 text-sm text-red-700 hover:bg-red-50 focus-visible:outline-2 focus-visible:outline-current dark:text-red-400 dark:hover:bg-neutral-800",children:[qe(zi,{className:"h-4 w-4","aria-hidden":"true"}),d.logout]})]})]})}import{useState as ji}from"react";import{LogOut as Fi}from"lucide-react";import{jsx as Ae,jsxs as nt}from"react/jsx-runtime";function Nr({email:e,logout:t,onLocaleChange:n}){let[o,r]=ji(E),a=ce(o);return nt("section",{className:"w-full max-w-xl",children:[Ae("h3",{className:"text-2xl",children:a.accountNavLabel}),Ae("h4",{className:"mt-6 mb-2 text-sm font-medium text-neutral-600 dark:text-neutral-400",children:a.profileHeading}),nt("div",{className:"divide-y divide-neutral-200 rounded-lg border border-neutral-200 bg-white dark:divide-neutral-800 dark:border-neutral-800 dark:bg-neutral-900",children:[nt("div",{className:"p-4",children:[Ae("p",{className:"text-sm text-neutral-600 dark:text-neutral-400",children:a.emailLabel}),Ae("p",{className:"mt-1 break-words",children:e||a.noData})]}),nt("label",{className:"flex min-h-11 flex-wrap items-center justify-between gap-3 p-4",children:[Ae("span",{children:a.languageLabel}),nt("select",{value:o.toLowerCase().startsWith("en")?"en-US":"pl-PL",onChange:i=>{sr(i.target.value),r(i.target.value),n?.()},className:"min-h-11 rounded-md border border-neutral-300 bg-white px-3 focus-visible:outline-2 focus-visible:outline-current dark:border-neutral-700 dark:bg-neutral-900",children:[Ae("option",{value:"pl-PL",children:a.polishLanguage}),Ae("option",{value:"en-US",children:a.englishLanguage})]})]})]}),nt("button",{type:"button",onClick:t,className:"mt-6 flex min-h-11 w-full items-center gap-3 rounded-lg border border-neutral-200 bg-white px-4 py-3 text-red-700 hover:bg-red-50 focus-visible:outline-2 focus-visible:outline-current dark:border-neutral-800 dark:bg-neutral-900 dark:text-red-400 dark:hover:bg-neutral-800",children:[Ae(Fi,{className:"h-5 w-5","aria-hidden":"true"}),a.logout]})]})}import{lazy as qi,Suspense as Hi}from"react";import{jsx as bt}from"react/jsx-runtime";var $i=qi(()=>import("./course.mjs").then(e=>({default:e.PanelCourse})));function Ir(e){return bt(Hi,{fallback:bt("div",{className:"flex items-center gap-2 p-2",role:"status",children:bt(ze,{})}),children:bt("div",{className:"[--course-mobile-bottom:calc(56px+env(safe-area-inset-bottom))] md:[--course-mobile-bottom:0px]",children:bt($i,{...e})})})}import{AlertCircle as Po,CheckCircle2 as go,ChevronLeft as Bi,Loader2 as Er,Lock as yo,Package as Ki,Truck as vo}from"lucide-react";import{useEffect as Gi,useState as Sr}from"react";import{Fragment as ko,jsx as f,jsxs as v}from"react/jsx-runtime";function Vi({status:e}){let t={created:{color:"bg-neutral-100 text-neutral-700",icon:null},paid:{color:"bg-green-100 text-green-700",icon:go},completed:{color:"bg-blue-100 text-blue-700",icon:go},canceled:{color:"bg-red-100 text-red-700",icon:Po},sent:{color:"bg-purple-100 text-purple-700",icon:vo},processing:{color:"bg-yellow-100 text-yellow-700",icon:Er}},n=t[e]||t.created,o=n.icon,r={created:"Utworzone",paid:"Op\u0142acone",completed:"Zako\u0144czone",canceled:"Anulowane",sent:"Wys\u0142ane",processing:"Przetwarzane"};return v("span",{className:`inline-flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium ${n.color}`,children:[o&&f(o,{className:"h-4 w-4"}),r[e]||e]})}function Wi({orderID:e,email:t}){let[n,o]=Sr(""),r=oe(q.publicApi.addPublicOrderComment);return v("form",{onSubmit:async i=>{if(i.preventDefault(),!!n.trim())try{await r.mutateAsync({projectId:"",orderId:e,message:n.trim(),accessToken:t}),o("")}catch(d){console.error("Failed to add comment:",d)}},className:"mt-4 space-y-2",children:[f(We,{htmlFor:"comment",children:"Dodaj komentarz"}),f(Pn,{id:"comment",value:n,onChange:i=>o(i.target.value),placeholder:"Wpisz komentarz...",rows:3,disabled:r.isPending}),f(I,{type:"submit",disabled:!n.trim()||r.isPending,children:r.isPending?v(ko,{children:[f(Er,{className:"mr-2 h-4 w-4 animate-spin"}),"Wysy\u0142anie..."]}):"Dodaj komentarz"})]})}function ho(e){return e?new Date(Number(e.seconds)*1e3).toLocaleDateString("pl-PL",{year:"numeric",month:"long",day:"numeric"}):"N/A"}function bo(e,t){return new Intl.NumberFormat("pl-PL",{style:"currency",currency:t.toUpperCase()}).format(e/100)}function Ji({orderID:e,initialEmail:t,onBack:n,accessToken:o,analytics:r}){let{theme:a,projectID:i}=Pe(),d=Ge(i,r,"order"),[u,l]=Sr(t||""),[b,P]=Sr(!1),{data:w,isLoading:h,error:y,refetch:c}=Ve(q.publicApi.getPublicOrderDetails,{projectId:i??"",orderId:e,email:u||void 0,accessToken:o},{enabled:!!e}),m=w?.result.case==="order"?w.result.value:null,p=m?.isVerified??!1,x=m!=null;Gi(()=>{x&&d.track("panel_order_viewed",{},{order_ref:null})},[d,x]);let U=()=>{c(),P(!1)},le={"--button-background-color":a?.colors?.brand??"#000000","--button-background-color-dark":a?.colors?.brandDark??"#ffffff","--button-text-color":a?.colors?.brandDark??"#000000","--button-text-color-dark":a?.colors?.brand??"#000000"};return h?f("div",{className:"flex min-h-screen items-center justify-center",children:v("div",{className:"text-center",children:[f(Er,{className:"mx-auto h-8 w-8 animate-spin text-neutral-400"}),f("p",{className:"mt-2 text-neutral-600 dark:text-neutral-400",children:"\u0141adowanie zam\xF3wienia..."})]})}):y||!m?f("div",{className:"flex min-h-screen items-center justify-center",children:f(Le,{className:"w-full max-w-md",children:f(Te,{className:"pt-6",children:v("div",{className:"text-center",children:[f(Po,{className:"mx-auto h-12 w-12 text-red-500"}),f("h2",{className:"mt-4 text-xl font-semibold",children:"Zam\xF3wienie nie znalezione"}),f("p",{className:"mt-2 text-neutral-600 dark:text-neutral-400",children:"Nie znaleziono zam\xF3wienia o podanym numerze."})]})})})}):f("div",{className:"w-full bg-white py-8 dark:bg-black",style:le,children:v("div",{className:"w-full px-4",children:[n&&v(I,{onClick:n,variant:"ghost",className:"mb-4 w-fit",children:[f(Bi,{className:"h-4 w-4"}),"Wr\xF3\u0107 do historii zam\xF3wie\u0144"]}),v("div",{className:"mb-6 flex items-center gap-4",children:[a?.logoURL&&v(ko,{children:[f("img",{src:a.logoURL,alt:"Project logo",className:`h-12 w-auto ${a.logoDarkURL?"dark:hidden":""}`}),a.logoDarkURL&&f("img",{src:a.logoDarkURL,alt:"Project logo",className:"hidden h-12 w-auto dark:block"})]}),v("div",{children:[f("h1",{className:"text-3xl font-bold",children:"Zam\xF3wienie"}),v("p",{className:"text-neutral-600 dark:text-neutral-400",children:["Numer zam\xF3wienia: #",m.orderId]})]})]}),v(Le,{className:"mb-6",children:[f(Ue,{children:v(_e,{className:"flex items-center",children:[f(Ki,{className:"mr-2 h-5 w-5"}),"Status zam\xF3wienia"]})}),v(Te,{className:"space-y-6",children:[v("div",{children:[v("div",{className:"flex items-center gap-2",children:[f(Vi,{status:m.status}),m.processingStatus&&v("span",{className:"text-sm text-neutral-600",children:["\xB7 ",m.processingStatus]})]}),v("p",{className:"mt-2 text-sm text-neutral-600",children:["Zam\xF3wienie z\u0142o\u017Cone ",ho(m.createdAt)]})]}),v("div",{className:"border-t pt-4",children:[f("h3",{className:"mb-3 font-semibold",children:"Dane klienta"}),v("div",{className:"space-y-2",children:[v("div",{children:[f("span",{className:"font-medium",children:"Imi\u0119 i nazwisko:"})," ",f("span",{className:p?"":"text-neutral-500",children:m.customerName})]}),v("div",{children:[f("span",{className:"font-medium",children:"Email:"})," ",f("span",{className:p?"":"text-neutral-500",children:m.customerEmail})]}),m.customerPhone&&v("div",{children:[f("span",{className:"font-medium",children:"Telefon:"})," ",f("span",{className:p?"":"text-neutral-500",children:m.customerPhone})]})]})]}),!p&&f("div",{className:"border-t pt-4",children:v(I,{onClick:()=>P(!0),variant:"outline",className:"w-full",children:[f(yo,{className:"mr-2 h-4 w-4"}),"Zweryfikuj sw\xF3j email"]})})]})]}),v(Le,{className:"mb-6",children:[f(Ue,{children:f(_e,{children:"Produkty"})}),v(Te,{className:"space-y-6",children:[f("div",{className:"space-y-4",children:m.items.map((L,de)=>v("div",{className:"flex items-center gap-4",children:[L.imageUrl&&f("img",{src:L.imageUrl,alt:L.name,className:"h-16 w-16 rounded object-cover"}),v("div",{className:"flex-1",children:[f("p",{className:"font-medium",children:L.name}),v("p",{className:"text-sm text-neutral-600",children:["Ilo\u015B\u0107: ",L.quantity]})]}),f("div",{className:"text-right",children:f("p",{className:"font-medium",children:bo(Number(L.price),L.currency)})})]},de))}),(m.deliveryAddress||m.deliveryMethod)&&v("div",{className:"border-t pt-4",children:[v("h3",{className:"mb-3 flex items-center font-semibold",children:[f(vo,{className:"mr-2 h-5 w-5"}),"Informacje o dostawie"]}),v("div",{className:"space-y-2",children:[m.deliveryAddress&&v("div",{children:[f("span",{className:"font-medium",children:"Adres:"})," ",f("span",{className:p?"":"text-neutral-500",children:m.deliveryAddress})]}),m.deliveryMethod&&v("div",{children:[f("span",{className:"font-medium",children:"Metoda:"})," ",m.deliveryMethod]}),m.trackingNumber&&p&&v("div",{children:[f("span",{className:"font-medium",children:"Tracking:"})," ",m.trackingNumber]})]})]}),f("div",{className:"border-t pt-4",children:v("div",{className:"flex justify-between text-lg font-bold",children:[f("span",{children:"Suma:"}),f("span",{children:bo(Number(m.totalAmount),m.currency)})]})})]})]}),v(Le,{children:[f(Ue,{children:v(_e,{children:["Komentarze ",m.commentCount>0&&`(${m.commentCount})`]})}),v(Te,{children:[m.comments.length>0?f("div",{className:"space-y-4",children:m.comments.map(L=>v("div",{className:"border-b pb-4 last:border-b-0",children:[v("div",{className:"mb-1 flex items-center gap-2",children:[f("span",{className:"font-medium",children:L.authorName||"System"}),f("span",{className:"text-xs text-neutral-500",children:ho(L.createdAt)}),L.authorType==="admin"&&f("span",{className:"rounded bg-blue-100 px-2 py-0.5 text-xs text-blue-700",children:"Admin"})]}),f("p",{className:p?"":"text-neutral-500",children:L.message})]},L.id))}):f("p",{className:"text-neutral-600",children:"Brak komentarzy."}),p?f(Wi,{orderID:m.orderId,email:u}):f("div",{className:"mt-4",children:v(I,{onClick:()=>P(!0),variant:"outline",className:"w-full",children:[f(yo,{className:"mr-2 h-4 w-4"}),"Zweryfikuj sw\xF3j email"]})})]})]}),b&&f("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",children:v(Le,{className:"w-full max-w-md",children:[f(Ue,{children:f(_e,{children:"Zweryfikuj sw\xF3j email"})}),v(Te,{className:"space-y-4",children:[f("p",{className:"text-sm text-neutral-700",children:"Podaj adres email u\u017Cyty przy sk\u0142adaniu zam\xF3wienia."}),v("div",{className:"space-y-2",children:[f(We,{htmlFor:"verify-email",children:"Adres email"}),f(Tt,{id:"verify-email",type:"email",placeholder:"twoj@email.com",value:u,onChange:L=>l(L.target.value)})]}),v("div",{className:"flex gap-2",children:[f(I,{variant:"outline",onClick:()=>P(!1),className:"flex-1",children:"Anuluj"}),f(I,{onClick:U,className:"flex-1",children:"Zweryfikuj"})]})]})]})})]})})}function Yi(e){return f(Ji,{...e})}var Lr=Yi;import{jsx as pe,jsxs as wo}from"react/jsx-runtime";var Qi=({returnsAppearance:e,returnsTexts:t,analytics:n}={})=>{let{projectID:o,theme:r,loginURL:a,host:i}=Pe(),[,d]=xo(0),u=Ge(o,n,"panel"),l=mt(o,i),b=hn(o,i),{mutateAsync:P}=oe(q.publicApi.userPanelLogout);async function w(){l&&await P({accessToken:l}),typeof window<"u"&&(Je(o,i),window.location.reload())}let[h]=Zi(),y=A=>["products","notifications","profile","plans","orders","order-details","returns","return-details","course"].includes(A),[c,m]=jn({product:void 0,state:"products",orderId:void 0,returnId:void 0,course:void 0,item:void 0}),[p,x]=xo(y(c.state)?c.state:"products"),U=A=>{m({state:"order-details",orderId:A}),x("order-details")},le=()=>{m({state:"orders",orderId:void 0}),x("orders")},L=A=>m({orderId:void 0,returnId:void 0,course:void 0,item:void 0,...A}),de=A=>{m({state:"course",course:A,item:void 0,product:void 0}),x("course")},Ne=()=>{m({state:"products",course:void 0,item:void 0,product:void 0}),x("products")};Ot(()=>{y(c.state)&&(c.state==="course"||p==="course")&&x(c.state)},[c.state]);let te={"--button-background-color":r?.colors?.brand??"#000000","--button-background-color-dark":r?.colors?.brandDark??"#ffffff","--button-text-color":r?.colors?.brandDark??"#000000","--button-text-color-dark":r?.colors?.brand??"#000000"};return Ot(()=>{if(l==null||l.length===0){window.location.href=a??"/panel/login";return}},[]),Ot(()=>{if(l==null||l.length===0){window.location.href=a??"/panel/login";return}},[p]),Ot(()=>{if(typeof window>"u"||window.parent!==window||!l)return;let A=gt(window.location.search);A&&yt(A);let fe=A??Ze();fe&&(window.location.href=Qe(fe,l))},[l]),pe(It,{value:u,children:wo("div",{ref:h,className:"font-inter relative flex h-dvh w-full flex-col bg-beige-100 text-black dark:bg-black dark:text-white md:flex-row",children:[pe(Cr,{activeScreen:p,setActiveScreen:x,setParams:L,styles:te,theme:r,logout:w,email:b,projectID:o}),wo("main",{className:"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto w-full p-5 pb-[calc(76px+env(safe-area-inset-bottom))] md:pb-5",children:[p==="products"&&pe(co,{projectID:o??"",accessToken:l,loginURL:a??"/panel/login",styles:te,activeScreen:p,params:c,setParams:m,openCourse:de}),p==="course"&&c.course&&l&&pe(Ir,{accessId:c.course,accessToken:l,theme:r,itemId:c.item,onItemChange:A=>m({item:A}),onBack:Ne}),p==="notifications"&&pe(mr,{}),p==="plans"&&pe(fr,{projectID:o??""}),p==="orders"&&pe(Hn,{projectID:o??"",accessToken:l??"",openOrderDetails:U}),p==="order-details"&&c.orderId&&pe(Lr,{orderID:c.orderId,onBack:le}),(p==="returns"||p==="return-details")&&l&&pe(yr,{projectID:o??"",host:i,accessToken:l,loginURL:a??"/panel/login",appearance:Fn(e,r?.colors?.brand),texts:t,screen:p,params:c,setParams:m,setActiveScreen:x}),p==="profile"&&pe(Nr,{email:b,logout:w,onLocaleChange:()=>d(A=>A+1)})]})]})})},Xi=Qi;import{create as we}from"@bufbuild/protobuf";import{QueryClient as hs,QueryClientProvider as bs}from"@tanstack/react-query";import{createContext as Ps,useContext as vs,useEffect as _o,useState as ks}from"react";import{createClient as es}from"@connectrpc/connect";import{createConnectTransport as ts}from"@connectrpc/connect-web";var me;(o=>{function e(r){return es(sn,n(r))}o.get=e;let t=new Map;function n(r){let a=t.get(r);return a==null&&(a=ts({useBinaryFormat:!0,baseUrl:r+"/api/rpc",interceptors:[on]}),t.set(r,a)),a}})(me||={});import R from"zod";import ee from"zod";function z(e,t=2){return+(Math.round(+(e+"e+"+t))+"e-"+t)}function Co(e,t){let n=typeof navigator>"u"?"pl-PL":navigator.language;return Intl.NumberFormat(n,{style:"currency",currency:t,currencyDisplay:"symbol"}).format(e/100)}var Kc=ee.object({event:ee.enum(["purchase","addToCart","customizeProduct","viewCart","removeFromCart","initiateCheckout","lead"]),step:ee.string().optional(),value:ee.number().optional(),currency:ee.string().optional(),content_name:ee.string().optional(),items:ee.array(ee.object({id:ee.string(),name:ee.string(),price:ee.number().default(0),currency:ee.string().default("PLN"),quantity:ee.number().default(1)})).optional()});function Tr(e){typeof window>"u"||(rs(e),os(e),as(e))}function rs(e){try{typeof window.dataLayer>"u"&&(window.dataLayer=[]);let t=ns(e);window.dataLayer.push(t)}catch(t){console.warn("cannot send google analytics event",t)}}function ns(e){let t=e.value??e.items?.reduce((a,i)=>a+(i.price||0)*(i.quantity||1),0)??0,n=e.items?.map(a=>({item_id:a.id,item_name:a.name||a.id,price:z((a.price||0)/100,2),quantity:a.quantity||1})),o={currency:e.currency||"PLN",value:z(t/100,2)};n&&n.length>0&&(o.items=n);let r;switch(e.event){case"purchase":r="purchase",o.transaction_id=e.step||`txn_${Date.now()}`;break;case"addToCart":r="add_to_cart";break;case"viewCart":r="view_cart";break;case"removeFromCart":r="remove_from_cart";break;case"initiateCheckout":r="begin_checkout";break;case"customizeProduct":r="customize_product";break;default:r=e.event}return{event:r,ecommerce:o,...e.step&&{step:e.step},...e.content_name&&{content_name:e.content_name}}}function os(e){if(typeof window.fbq>"u")return;let t="",n="",o={};switch(e.event){case"purchase":t="track",n="Purchase",o={category_name:e.step,...e};break;case"lead":t="track",n="Lead",o={category_name:e.step,...e};break;case"addToCart":t="track",n="Add to Cart",o={category_name:e.step,...e};break;case"customizeProduct":t="track",n="Customize Product",o={category_name:e.step,...e};break;case"viewCart":t="track",n="View Cart",o={category_name:e.step,...e};break;case"removeFromCart":t="track",n="Remove from Cart",o={category_name:e.step,...e};break;case"initiateCheckout":t="track",n="Initiate Checkout",o={category_name:e.step,...e};break;default:break}window.location.search.includes("analytics")&&console.log("Pushing FB event",t,n,o),window.fbq(t,n,o)}function as(e){try{if(typeof window.ttq>"u")return;let t=is(e);if(!t)return;window.location.search.includes("analytics")&&console.log("Pushing TikTok event",t.eventName,t.eventPayload),window.ttq.track(t.eventName,t.eventPayload)}catch(t){console.warn("cannot send tiktok analytics event",t)}}function is(e){let t=e.value??e.items?.reduce((a,i)=>a+(i.price||0)*(i.quantity||1),0)??0,n=e.items?.map(a=>({content_id:a.id,content_type:"product",content_name:a.name||a.id,quantity:a.quantity||1,price:z((a.price||0)/100,2)}))||[];n.length===0&&e.content_name&&n.push({content_id:e.step||"unknown",content_type:"product",content_name:e.content_name,quantity:1,price:z(t/100,2)});let o={currency:e.currency||"PLN",value:z(t/100,2)};n.length>0&&(o.contents=n);let r=null;switch(e.event){case"purchase":r="Purchase";break;case"addToCart":r="AddToCart";break;case"initiateCheckout":r="InitiateCheckout";break;case"customizeProduct":r="CustomizeProduct";break;case"viewCart":return;case"removeFromCart":return;case"lead":return;default:return null}return{eventName:r,eventPayload:o}}function No(e){let{items:t,googlePayConfig:n,checkout:o,result:r,cartRequiresShipping:a}=e,i=e.locale??E();if(r.totalAmount==null)return;let d=[];return a&&(d.push("SHIPPING_ADDRESS"),d.push("SHIPPING_OPTION")),{apiVersion:2,apiVersionMinor:0,callbackIntents:d,allowedPaymentMethods:[{type:"CARD",parameters:{allowedAuthMethods:["PAN_ONLY","CRYPTOGRAM_3DS"],allowedCardNetworks:["MASTERCARD","VISA"]},tokenizationSpecification:{type:"PAYMENT_GATEWAY",parameters:{gateway:n.gateway,gatewayMerchantId:n.gatewayId}}}],emailRequired:!0,shippingAddressParameters:{phoneNumberRequired:a},shippingAddressRequired:a,shippingOptionRequired:a,shippingOptionParameters:a?{shippingOptions:r.methods.slice(0,5).map(l=>({id:l.id,label:l.name+` - ${Co(l.amount,r.currency)}`,description:l.description??""})),defaultSelectedOptionId:r.selectedDeliveryMethod}:void 0,merchantInfo:{merchantId:n.merchantId+"",merchantName:n.merchantName},transactionInfo:{totalPriceStatus:"FINAL",totalPriceLabel:Ee("paymentForCart",i,e.texts),totalPrice:`${z(r.totalAmount/100,2)}`,currencyCode:r.currency,countryCode:r.country,checkoutOption:"COMPLETE_IMMEDIATE_PURCHASE",displayItems:ss(t,r.methods,r.selectedDeliveryMethod??(r.methods.length>0?r.methods[0].id:void 0),o.couponCode,r.couponValue,Ee("coupon",i,e.texts))}}}function ss(e,t,n,o,r,a="Coupon"){let i=[],d=0;for(let l of e){if(l.details==null)continue;let b=l.details.pricing?.effectivePrice??l.details.price;d+=b*l.quantity,i.push({label:l.details.name+" x "+l.quantity,price:`${z(b/100,2)}`,type:"LINE_ITEM",status:"FINAL"})}let u=t.find(l=>l.id===n);return u!=null&&i.push({label:u.name,price:`${z(u.amount/100,2)}`,type:"SHIPPING_OPTION",status:"FINAL"}),o!=null&&r!=null&&i.push({label:`${a} ${o}`,price:`${z(r/100,2)}`,type:"DISCOUNT",status:"FINAL"}),d>0&&i.push({label:"Subtotal",price:`${z(d/100,2)}`,type:"SUBTOTAL",status:"FINAL"}),i}function ot(e,t){return`${Q}/api/integrations/${e}/public-commerce${t}`}function De(e){return typeof e=="object"&&e!=null&&"ERR"in e}function $(e,t,n){return{ERR:!0,error:e,type:t,data:n}}function Io(e,t){return t?.find(n=>n.id===e||(n.variants?.some(o=>o.id===e)??!1))}function So(e,t){let n=new Set(t.map(o=>o.productID));return Array.from(new Set(e.filter(o=>!n.has(o))))}function Eo(e,t){let n=e?.trim();if(!(n==null||n.length===0))try{let o=new URL(n,t);return o.protocol!=="http:"&&o.protocol!=="https:"?void 0:o.href}catch{return}}import{create as ls}from"zustand";var at=ls(e=>({isCartVisible:!1,notice:void 0,setNotice:t=>e(n=>({...n,notice:t})),numberOfProductsInCart:0,showCart:()=>e(t=>({...t,isCartVisible:!0})),hideCart:()=>e(t=>({...t,isCartVisible:!1})),setNumberOfProductsInCart:t=>e(n=>({...n,numberOfProductsInCart:t}))}));import{createContext as ds,useContext as Rr,useMemo as Lo}from"react";import{jsx as us}from"react/jsx-runtime";var Ut=ds({});function ip({texts:e,locale:t,children:n}){let o=Lo(()=>({texts:e,locale:t}),[e,t]);return us(Ut.Provider,{value:o,children:n})}function To(){return Rr(Ut)}function sp(e){let{texts:t,locale:n}=Rr(Ut);return Ee(e,n??E(),t)}function lp(){let{texts:e,locale:t}=Rr(Ut),n=t??E();return Lo(()=>o=>Ee(o,n,e),[n,e])}var Dr="bitsnap-pending-order";function Do(e,t){let n=new Map;for(let r of t)n.set(r.id,(n.get(r.id)??0)+r.quantity);let o=[];for(let r of e){let a=n.get(r.id);a==null?o.push(r):r.quantity>a&&o.push({...r,quantity:r.quantity-a})}return o}var cs=60*1e3;function Mo(e,t=Date.now,n=cs){let o;return r=>{let a=`${r.orderId}:${r.ts}`,i=t();return o?.key===a&&i-o.at<n?Promise.reject(new Error("pending order was asked about recently")):(o={key:a,at:i},e(r))}}function ps(e){if(!(e==null||e.length===0))try{let t=new URL(e,"https://bitsnap.invalid").pathname,n=/\/payment\/common\/([^/]+)\/([^/]+)\/?$/.exec(t);return n==null?void 0:{projectId:decodeURIComponent(n[1]),orderId:decodeURIComponent(n[2])}}catch{return}}function ms(e){if(e==null||e.length===0)return!1;try{let t=new URL(e,"https://bitsnap.invalid").pathname;return/\/payment\/manualPayment\/[^/]+\/[^/]+\/?$/.test(t)}catch{return!1}}function fs(e,t=Date.now(),n={}){if(ms(e.url))return;let o=ps(e.url),r=Ro(e.orderId)??o?.orderId,a=Ro(e.projectId)??o?.projectId;if(!(r==null||a==null))return{orderId:r,projectId:a,...n.cartProjectId!=null?{cartProjectId:n.cartProjectId}:{},lines:n.lines??[],ts:t}}function cp(e,t={}){let n=fs(e,t.now,t);return n!=null&&gs(n,t.storage)}function Ro(e){return e!=null&&e.length>0?e:void 0}function _t(){try{return typeof localStorage>"u"?void 0:localStorage}catch{return}}function gs(e,t=_t()){try{return t?.setItem(Dr,JSON.stringify(e)),t!=null}catch{return!1}}function Ao(e=_t()){try{let t=e?.getItem(Dr);if(t==null)return;let n=JSON.parse(t);if(typeof n=="object"&&n!=null&&typeof n.orderId=="string"&&typeof n.projectId=="string"&&typeof n.ts=="number"&&n.orderId.length>0){let{orderId:o,projectId:r,cartProjectId:a,ts:i,lines:d}=n;return{orderId:o,projectId:r,...typeof a=="string"?{cartProjectId:a}:{},lines:Array.isArray(d)?d.filter(u=>typeof u?.id=="string"&&typeof u.quantity=="number"):[],ts:i}}}catch{}Ar(e)}function Ar(e=_t()){try{e?.removeItem(Dr)}catch{}}function Oo(e){let t=e.details?.status??ys(e.details?.$unknown);return t==="created"||t==="placed"||t==="paid"||t==="canceled"?t:"unknown"}function ys(e){if(Array.isArray(e)){for(let t of e)if(t?.no===3&&t.wireType===2&&t.data instanceof Uint8Array){let n=0,o=0;for(let r=0;o<t.data.length&&r<35;r+=7){let a=t.data[o++];if(n|=(a&127)<<r,!(a&128))break}if(o+n!==t.data.length)return;try{return new TextDecoder().decode(t.data.subarray(o))}catch{return}}}}async function Uo(e){let t=e.storage??_t(),n=Ao(t);if(n==null)return"none";if((e.now??Date.now)()-n.ts>864e5)return Ar(t),"expired";if(e.projectId!=null&&n.cartProjectId!=null&&n.cartProjectId!==e.projectId)return"pending";let r;try{r=await e.fetchStatus(n)}catch{return"pending"}let a=Ao(t);if(a?.orderId!==n.orderId||a.ts!==n.ts)return"pending";if(r==="paid"||r==="placed"){try{await e.removeLines(n.lines)}catch{return"pending"}return Ar(t),"paid"}return"pending"}import{Fragment as Os,jsx as Or}from"react/jsx-runtime";var xs="__m_a",$o=Ps(void 0),_r=void 0;function _p(e){dr({projectID:e}),_r=e,typeof window<"u"&&ct([window.location.origin])}function st(){return _r??document.querySelector('script[data-id][data-name="internal-cart"]')?.getAttribute("data-id")??void 0}function ws(){return document.querySelector('script[data-id][data-name="internal-cart"]')?.getAttribute("data-custom-host")??void 0}var Cs=({children:e,locale:t})=>{let[n]=ks(()=>new hs),o=To();_o(()=>{Ce()},[]);let r=st();if(_o(()=>{if(r==null)return;let i=()=>{Ss(r).then(u=>{u==="paid"&&n.invalidateQueries({queryKey:["cart"]})})},d=()=>{document.visibilityState==="visible"&&i()};return i(),window.addEventListener("pageshow",i),document.addEventListener("visibilitychange",d),()=>{window.removeEventListener("pageshow",i),document.removeEventListener("visibilitychange",d)}},[r,n]),r==null)return Or(Os,{});let a=Fr(r,t??o.locale,o.texts);return Or(bs,{client:n,children:Or($o.Provider,{value:a,children:e})})},Mr,Ns=Mo(async e=>Oo(await me.get(Q).getOrder({id:e.orderId,projectId:e.projectId})));function zp(){let{country:e,couponCode:t,selectedDeliveryMethod:n,postalCode:o}=S()??qt;return{country:e,couponCode:t,selectedDeliveryMethod:n,postalCode:o}}function jp(){return(S()?.products??[]).map(e=>({id:e.id,quantity:e.quantity}))}function Is(e){let t=S();G({...t,products:Do(t?.products??[],e)}),Ce()}function Ss(e){return Mr??=Uo({projectId:e,fetchStatus:Ns,removeLines:Is}).catch(t=>{console.warn("cannot check the pending order",t)}).finally(()=>{Mr=void 0}),Mr}var it=async(e,t)=>{let n=[];t?.items!=null&&t.items.length>0?n=t.items:n=S()?.products??[];let o=Array.from(new Set(n.map(i=>i.productID)));if(o.length===0)return[];let r=new URLSearchParams;r.set("ids",o.join(",")),r.set("locale",t?.locale??E());let a;try{let i=await fetch(rr(ot(e,`/products?${r.toString()}`)),{method:"GET"});if(i.status!=200)return $("products-load-failed","internal");a=await i.json()}catch(i){return console.warn("cannot load the products of the cart",i),$("products-load-failed","internal")}return n.flatMap(i=>{let d=Io(i.productID,a.result);return d==null?[]:[{...i,details:Ms(i.productID,d),catalogProductID:d.id}]})},Fp=()=>{let e=vs($o);if(e===void 0)throw new Error("useCartProvider must be used within a CartProvider");return e},qp=Cs,Es=R.object({isAvailable:R.boolean(),merchantId:R.string(),merchantName:R.string(),gateway:R.string(),gatewayId:R.string()}),Ls=R.object({id:R.string(),productID:R.string(),quantity:R.number(),priceVersion:R.string().optional(),metadata:R.record(R.string(),R.string().optional()).optional(),url:R.string().optional()}),Ts=R.object({country:R.string().optional(),couponCode:R.string().optional(),selectedDeliveryMethod:R.string().optional(),postalCode:R.string().optional(),email:R.string().optional(),products:R.array(Ls).optional(),googlePayConfig:Es.optional()}),qt={country:void 0,couponCode:void 0,email:void 0,selectedDeliveryMethod:void 0,postalCode:void 0,products:[],googlePayConfig:void 0},jr="checkout";function Rs(){return typeof localStorage>"u"?[]:(S().products??[]).map(e=>({...e}))}function Hp(){return Rs().map(e=>`${e.productID}:${e.quantity}`).sort().join(",")}function $p(e){let t=S();if(!(t.products==null||t.products.length===0))return{items:t.products.map(n=>({id:n.productID,quantity:n.quantity,...n.priceVersion!=null?{priceVersion:n.priceVersion}:{}})),...t.country!=null?{countries:[t.country]}:{},...t.couponCode!=null?{couponCode:t.couponCode}:{},...t.selectedDeliveryMethod!=null?{deliveryMethod:t.selectedDeliveryMethod}:{},locale:e}}function Bp(e){let t=S(),n=new Map;for(let o of t.products??[]){let r=n.get(o.productID)??[];r.push(o),n.set(o.productID,r)}t.products=e.map(o=>{let r=n.get(o.productId)?.shift();return{id:Math.random().toString(36).substring(7),productID:o.productId,quantity:o.quantity,...r?.priceVersion!=null?{priceVersion:r.priceVersion}:{},...r?.metadata!=null?{metadata:r.metadata}:{},...r?.url!=null?{url:r.url}:{}}}),G(t),Ce()}function Kp(e){let t=new Map;for(let r of e)t.set(r.id,(t.get(r.id)??0)+r.quantity);let n=S(),o=(n.products??[]).flatMap(r=>{let a=t.get(r.productID);return a==null?[r]:r.quantity<=a?[]:[{...r,quantity:r.quantity-a}]});G({...n,products:o}),Ce()}function Gp(e){let t=S();t.products=t.products??[];for(let n of e)t.products.push({id:Math.random().toString(36).substring(7),productID:n.id,quantity:n.quantity});G(t),Ce()}function S(){try{let e=localStorage.getItem(jr);return e==null?qt:Ts.parse(JSON.parse(e))}catch{return qt}}async function zo(e,t){let n=await it(e,{items:t.map((a,i)=>({...a,id:`price-check-${i}`}))});if(De(n))return n;let o=So(t.map(a=>a.productID),n);if(o.length>0)return $("item-ids-not-found","notFound",o);let r=S();r.products==null&&(r.products=[]),r.products.push(...t.map(a=>({id:Math.random().toString(36).substring(7),productID:a.productID,quantity:a.quantity,priceVersion:n.find(i=>i.productID===a.productID)?.details?.pricing?.priceVersion,metadata:a.metadata,url:Eo(a.url,typeof window<"u"?window.location.href:void 0)}))),As(t,n),Tr({event:"addToCart",currency:"PLN",items:t.map(a=>({id:a.productID,name:a.name??"",price:a.price??0,quantity:a.quantity,currency:a.currency??"PLN"}))}),G(r),Ce()}function As(e,t){for(let n of e)try{let o=t.find(d=>d.productID===n.productID),r=o?.details?.pricing?.effectivePrice??o?.details?.price??n.price,a=o?.details?.currency??n.currency;if(r==null||a==null)continue;let i=o?.catalogProductID??n.productID;(n.analytics??ln()).track("add_to_cart",{qty:n.quantity,value_minor:Math.round(r*n.quantity),currency:a},{product_id:i,variant_id:i!==n.productID?n.productID:null})}catch{}}function jo(e){let t=S(),n={...t,products:t?.products?.filter(o=>!e.includes(o.productID)&&!e.includes(o.id))};Tr({event:"removeFromCart",items:e.map(o=>({id:o,name:"",price:0,quantity:1,currency:"PLN"}))}),G(n),Ce()}function G(e){localStorage.setItem(jr,JSON.stringify(e)),Ko()}var jt=new Set,Bo=0,zt=!1;function Fo(e){e.key===jr&&Ko()}function Vp(e){return jt.add(e),!zt&&typeof window<"u"&&(window.addEventListener("storage",Fo),zt=!0),()=>{jt.delete(e),jt.size===0&&zt&&(window.removeEventListener("storage",Fo),zt=!1)}}function Wp(){return Bo}function Ko(){Bo+=1;for(let e of jt)try{e()}catch{}}function qo(e,t){if(e.products==null||e.products.length==0)return;let n=e.products.reduce((o,r)=>(r.metadata!=null&&Object.keys(r.metadata).forEach(a=>{let i=r.metadata?.[a];i!=null&&(o[a]=i)}),o),{});return{items:e.products.map(o=>({id:o.productID,quantity:o.quantity,priceVersion:o.priceVersion})),askForNote:!0,countries:e.country?[e.country]:void 0,metadata:n,locale:t}}var Fr=(e,t=E(),n)=>{let o=ws();return o!=null&&dn(o),{async checkIfApplePayIsAvailable(){if(typeof window>"u"||typeof document>"u"||!("ApplePaySession"in window))return!1;try{return(await me.get(Q).isOneClickPaymentAvailable({projectId:e})).applePay}catch(r){return console.error("Error checking if Apple Pay is available",r),!1}},async getGooglePayConfiguration(r){if(typeof window>"u"||typeof document>"u")return{isAvailable:!1};try{let a=await Ds(e);if(a?.isAvailable!=!0)return{isAvailable:!1};let i=S();if(i==null)return console.log("checkout is null"),{isAvailable:!1};let d=await it(e,{locale:t,items:r.items.map(P=>({id:Math.random().toString(36).substring(7),quantity:P.quantity,metadata:P.metadata,productID:P.productID}))});if(De(d))return{isAvailable:!1};let u=await me.get(Q).getPreOrderDetails({items:d.map(P=>we(Nt,{id:P.productID,quantity:P.quantity})),projectId:e,postCode:i.postalCode,couponCode:i.couponCode,countryCode:i.country,selectedDeliveryMethod:i.selectedDeliveryMethod});if(u.totalAmount==null)return{isAvailable:!1};let l=d.find(P=>P.details?.isDeliverable==!0)!=null,b=await No({items:d,googlePayConfig:a,checkout:i,cartRequiresShipping:l,result:u,locale:t,texts:n});return b==null?{isAvailable:!1}:{isAvailable:!0,config:b}}catch(a){return console.error("Error resolving Google Pay configuration",a),{isAvailable:!1}}},async clearCart(){let r=structuredClone(qt);r.country=S()?.country,G(r),Ce()},async getAvailableCountries(){let r=await fetch(rr(ot(e,"/countries")),{method:"GET"});if(r.status!=200)return[];try{return R.array(R.object({name:R.string(),code:R.string()})).parse(await r.json())}catch(a){return $(a.toString(),"internal")}},async getCountry(){let r=S()?.country;if(r==null){r="PL";let a=S();a.country=r,G(a)}return r},async getNumberOfElementsInCart(){return S()?.products?.reduce((r,a)=>r+a.quantity,0)??0},async getProducts(){return await it(e,{locale:t})},async removeProductFromCart(r){return jo([r.id])},async setCountry(r){let a=S();a.country=r,G(a)},async setCouponCodeIfPossible(r){let a=S();a.couponCode=r,G(a)},async setPostalCode(r){let a=S();a.postalCode=r,G(a)},async setDeliveryMethod(r){let a=S();a.selectedDeliveryMethod=r,G(a)},async setEmail(r){let a=S();a.email=r,G(a)},async addProduct(r){return await zo(e,[r])},async updateQuantity(r){let a=S();a.products=a.products?.map(i=>(i.id===r.id&&(i.quantity=r.quantity),i)),G(a),Ce()},async getPaymentMethodChoice(){let r=qo(S(),t);return r==null?null:Ho(r)},async redirectToNextStep(r){let a=qo(S(),t);if(a==null)return $("cart-is-empty","badInput");r?.paymentMethod!=null&&(a.paymentMethod=r.paymentMethod);let i=await Ur(a);return De(i)?(console.warn("cannot create payment URL",i.error),i):{url:i.url,...i.orderId!=null?{orderId:i.orderId}:{},...i.projectId!=null?{projectId:i.projectId}:{}}},async justRedirectToPayment(r){let a={items:[{id:r.productID,quantity:1}],askForNote:!1,details:r.email||r.name?{name:r.name,email:r.email}:void 0,locale:r.locale??t};a=zr(a),r.country==null&&(r.country="pl"),a.details==null&&(a.details={}),a.details.address==null&&(a.details.address={}),a.details.address.country=r.country,r.marketingAgreement===!0&&(a.additionalAgreements=[{id:xs,name:"",required:!0,answer:!0}]);let i=await Ur(a);return De(i)?i:{url:i.url}},async getApplePayPreview(r){let a=S();try{let i=await me.get(Q).getPreOrderDetails({items:r.items.map(d=>we(Nt,{id:d.productID,quantity:d.quantity})),projectId:e,postCode:a.postalCode,couponCode:a.couponCode,countryCode:a.country,selectedDeliveryMethod:a.selectedDeliveryMethod});return i.totalAmount==null||i.currency.length===0?$("pre-order-unavailable","internal"):{countryCode:i.country||a.country||"PL",currencyCode:i.currency,totalAmount:`${z(i.totalAmount/100,2)}`}}catch(i){return console.warn("cannot load the Apple Pay preview",i),$("pre-order-unavailable","internal")}},async completeApplePayPayment(r){let a=S();if(a==null)return $("Checkout not found");let i=await it(e,{locale:t});if(De(i))return i;try{let d=r.shippingContact?.givenName;r.shippingContact?.familyName!=null?d+=" "+r.shippingContact?.familyName:r.billingContact?.familyName!=null&&(d+=" "+r.billingContact?.familyName);let u={},l=Ft();l!=null&&(u.ref=l);let b=await me.get(Q).authorizeOneClickPayment({gateway:0,paymentData:JSON.stringify(r.token.paymentData),paymentMethod:JSON.stringify(r.token.paymentMethod),transactionIdentifier:r.token.transactionIdentifier,order:we(ar,{items:i.map(P=>({id:P.productID,quantity:P.quantity})),couponCode:a.couponCode,email:r.shippingContact?.emailAddress??r.billingContact?.emailAddress??a.email??void 0,phone:r.shippingContact?.phoneNumber??r.billingContact?.phoneNumber??void 0,selectedDeliveryMethod:a.selectedDeliveryMethod,postCode:a.postalCode,projectId:e}),shippingAddress:we(nr,{line1:r.shippingContact?.addressLines?.[0]??"",city:r.shippingContact?.locality??"",country:r.shippingContact?.countryCode??"",zipCode:r.shippingContact?.postalCode??"",name:d}),billingAddress:we(or,{name:r.billingContact?.givenName??" "+(r.billingContact?.familyName??""),line1:r.billingContact?.addressLines?.[0]??"",city:r.billingContact?.locality??"",country:r.billingContact?.countryCode??"",zipCode:r.billingContact?.postalCode??""}),metadata:Object.keys(u).length>0?JSON.stringify(u):void 0});return{isSuccess:b.isSuccess,redirectURL:b.redirectUrl}}catch(d){return console.error(d),$("Failed to authorize payment")}},async completeGooglePayPayment(r){let a=S();if(a==null)return $("Checkout not found");let i=await it(e,{locale:t});if(De(i))return i;try{let d=r.paymentData.shippingAddress?.name,u={},l=Ft();l!=null&&(u.ref=l);let b=await me.get(Q).authorizeOneClickPayment({gateway:1,paymentData:r.paymentData.paymentMethodData.tokenizationData.token,paymentMethod:r.paymentData.paymentMethodData.type,transactionIdentifier:"",order:we(ar,{items:i.map(P=>({id:P.productID,quantity:P.quantity})),couponCode:a.couponCode,email:r.paymentData.email??void 0,phone:r.paymentData.shippingAddress?.phoneNumber??void 0,selectedDeliveryMethod:r.paymentData.shippingOptionData?.id??a.selectedDeliveryMethod,postCode:r.paymentData.shippingAddress?.postalCode,projectId:e}),shippingAddress:we(nr,{line1:r.paymentData.shippingAddress?.address1??"",city:r.paymentData.shippingAddress?.locality??"",country:r.paymentData.shippingAddress?.countryCode??"",zipCode:r.paymentData.shippingAddress?.postalCode??"",name:d}),billingAddress:we(or,{name:r.paymentData.paymentMethodData.info?.billingAddress?.name,line1:r.paymentData.paymentMethodData.info?.billingAddress?.address1??"",city:r.paymentData.paymentMethodData.info?.billingAddress?.locality??"",country:r.paymentData.paymentMethodData.info?.billingAddress?.countryCode??"",zipCode:r.paymentData.paymentMethodData.info?.billingAddress?.postalCode??""}),metadata:Object.keys(u).length>0?JSON.stringify(u):void 0});return{isSuccess:b.isSuccess,redirectURL:b.redirectUrl}}catch(d){return console.error(d),$("Failed to authorize payment")}return{isSuccess:!0}},async getApplePayPaymentRequest(r){let a=S();if(a==null)return $("Checkout not found");r&&r.expectedItems!=null&&r.expectedItems.length>0&&(a.products&&jo(a.products.map(l=>l.productID)),await zo(e,r.expectedItems));let i=await it(e,{locale:t});if(De(i))return i;let d=await me.get(Q).getPreOrderDetails({items:i.map(l=>we(Nt,{id:l.productID,quantity:l.quantity})),projectId:e,postCode:a.postalCode,couponCode:a.couponCode,countryCode:a.country,selectedDeliveryMethod:a.selectedDeliveryMethod}),u=i.map(l=>({amount:`${z(l.quantity*(l.details?.pricing?.effectivePrice??l.details?.price??0)/100,2)}`,label:l.details?.name+" - "+l.quantity,type:"final"}));if(d.selectedDeliveryMethod!=null){let l=d.methods.find(b=>b.id==d.selectedDeliveryMethod);l!=null&&u.push({amount:`${z(l.amount/100,2)}`,label:l.name,type:"final"})}return d.couponCode!=null&&d.couponValue!=null&&u.push({amount:`-${z(d.couponValue/100,2)}`,label:d.couponCode,type:"final"}),{countryCode:d.country||a.country||"PL",merchantCapabilities:["supports3DS","supportsCredit","supportsDebit"],supportedNetworks:["visa","masterCard"],total:{amount:`${z((d.totalAmount??0)/100,2)}`,label:Ee("paymentForCart",t,n),type:"final"},shippingMethods:d.methods.map(l=>({amount:`${z(l.amount/100,2)}`,detail:l.description??"",identifier:l.id,label:l.name,dateComponentsRange:{startDateComponents:{days:l.minDays??1,hours:0,months:0,years:0},endDateComponents:{days:l.maxDays??14,hours:0,months:0,years:0}}})),lineItems:u,currencyCode:d.currency||i[0]?.details?.currency||"PLN"}}}};async function Ds(e){let t=S();if(t.googlePayConfig?.isAvailable!=!0){let n=await me.get(Q).isOneClickPaymentAvailable({projectId:e});n.googlePay==!0&&n.googlePayConfig!=null?t.googlePayConfig={isAvailable:!0,gateway:n.googlePayConfig.gateway,gatewayId:n.googlePayConfig.gatewayMerchantId,merchantName:n.googlePayConfig.merchantName,merchantId:n.googlePayConfig.merchantId}:t.googlePayConfig={isAvailable:!1,gateway:"",gatewayId:"",merchantName:"",merchantId:""}}return G(t),t.googlePayConfig}function Ms(e,t){if(e==t.id){let o=t.variants?.findIndex(r=>r.id===e);if(o!=null&&o!=-1){let r=t.variants[o];return{...t,availableQuantity:r.availableQuantity,isDeliverable:r.isDeliverable,images:r.images??t.images,name:t.name+" "+r.name,baseName:t.name,variantName:r.name,price:r.price,currency:r.currency,pricing:r.pricing}}return t}let n=t.variants?.find(o=>o.id===e);return n==null?t:{...t,id:n.id,name:t.name+" "+n.name,baseName:t.name,variantName:n.name,price:n.price,currency:n.currency,pricing:n.pricing,metadata:t.metadata,availableQuantity:n.availableQuantity,isDeliverable:n.isDeliverable,images:n.images??t.images}}function Ce(){let e=S(),t=0;if(e==null){at.setState(n=>({...n,numberOfProductsInCart:t}));return}t=e.products?.reduce((n,o)=>n+o.quantity,0)??0,at.setState(n=>({...n,numberOfProductsInCart:t}))}var Us=200,_s="item-ids-not-found",Pt="internal-error",Go={"no-payment-gateway":"noPaymentGateway","gateway-not-configured":"gatewayNotConfigured","shipping-not-configured":"shippingNotConfigured","mixed-recurring":"mixedRecurring","currency-unsupported":"currencyUnsupported","price-changed":"priceChanged","product-not-found":"unavailableProducts","product-not-available":"unavailableProducts"},zs=new Set(["internal","invalid-request"]),js=new Set(["product-not-available","product-not-found"]);function Fs(e){return typeof e=="string"&&Object.hasOwn(Go,e)?Go[e]:void 0}function qs(e){return/<\/?[a-z!?][^>]*>/i.test(e)}function Hs(e){return/^[A-Za-z][A-Za-z0-9]*(?:[-_.:][A-Za-z0-9]+)*$/.test(e)&&!/^[A-Z][a-z]+$/.test(e)||/^\[object \w+\]$|^(?:undefined|null)$/.test(e)}function $s(e){return/Error:/.test(e)||/\n\s+at /.test(e)}function qr(e){let t=e.trim();if(!(t.length===0||t.length>Us||/[\r\n]/.test(t)||qs(t)||Hs(t)||$s(t)))return t}var Bs=3;function Ht(e,t=0){if(typeof e=="object"&&e!=null){if(Array.isArray(e)||t>=Bs)return{};let n=e,o=Ht(n.error,t+1);if(o.message==null&&n.message!=null){let r=Ht(n.message,t+1);o={...r,code:o.code??r.code}}return typeof n.code=="string"&&n.code.length>0&&(o.code=n.code),o}if(typeof e!="string")return{};try{let n=JSON.parse(e);return typeof n=="object"&&n!=null?Ht(n,t+1):{}}catch{}return{message:qr(e)}}function Ks(e){let t;try{t=JSON.parse(e)}catch{return{code:Pt,message:qr(e)}}if(typeof t=="string")return{code:Pt,message:qr(t)};if(typeof t!="object"||t==null)return{code:Pt};let n=t,{message:o,code:r}=Ht(n.error),a={code:typeof n.code=="string"&&n.code.length>0?n.code:r??Pt,message:o};return Array.isArray(n.itemIds)&&(a.itemIds=n.itemIds.filter(i=>typeof i=="string")),a}function Hr(e,t){let{code:n,message:o,itemIds:r}=Ks(t),a=r!=null&&r.length>0;if(a&&(n===Pt||js.has(n)))return $(_s,"badInput",r);let i={message:o};return a&&(i.itemIds=r),$(n,e>=500?"internal":"badInput",i)}function Xp(e,t){let n=Fs(e.error);if(n!=null)return t(n);if(e.type==="internal"||typeof e.error=="string"&&zs.has(e.error))return t("checkoutFailed");let o=e.data?.message;return typeof o=="string"&&o.length>0?o:t("checkoutFailed")}var Gs=["online","manual","cod"],Vs=["bankTransfer","blik"];function Vo(e,t){if(!Array.isArray(e))return[];let n=[];for(let o of e)t.includes(o)&&!n.includes(o)&&n.push(o);return n}function Ws(e){if(typeof e!="object"||e==null)return null;let t=e.choice;if(typeof t!="object"||t==null)return null;let n=Vo(t.methods,Gs);return n.length<2?null:{methods:n,manualAccountTypes:Vo(t.manualAccountTypes,Vs)}}function tm(e){if(e==null)return null;let t=e.methods.filter(n=>n!=="cod");return t.length<2?null:{...e,methods:t}}function rm(e,t){return t!=null&&e.methods.includes(t)?t:e.methods[0]}function nm(e){let t=e.includes("bankTransfer"),n=e.includes("blik");return n&&!t?"paymentMethodManualBlik":t&&!n?"paymentMethodManualTransfer":"paymentMethodManualBoth"}async function Wo(e,t,n=5e3){let o=typeof AbortController>"u"?void 0:new AbortController,r=setTimeout(()=>o?.abort(),n);try{let a=await fetch(e,{method:"POST",headers:t.headers,body:t.body,signal:o?.signal});return a.ok?Ws(await a.json()):null}catch{return null}finally{clearTimeout(r)}}var Js;(o=>{async function e(r,a=1,i,d){let u=st();if(u==null)throw new Error("No project ID found");let b=await Fr(u).addProduct({productID:r,quantity:a,metadata:i,...d});if(b!=null)return b}o.addProductToCart=e;function t(){at.setState({isCartVisible:!0})}o.showCart=t;function n(){at.setState({isCartVisible:!1})}o.hideCart=n})(Js||={});async function Jo(e){try{return await e.text()}catch{return""}}function Yo(e,t){return t=zr(t),t.locale??=E(),{headers:{...tr,...ir(e),"Content-Type":"application/json"},body:JSON.stringify(t)}}async function Ho(e){let t=st();return t==null?null:Wo(ot(t,"/payment-methods"),Yo(t,e))}async function Ur(e){let t=st();if(t==null)throw new Error("No project ID found");let n=await fetch(ot(t,"/buy"),{method:"POST",...Yo(t,e)});if(n.status!=200){let r=Hr(n.status,await Jo(n));return console.warn("cannot create payment URL",n.status,r.error),r}let o=await n.json();return{url:o.url,...o.orderId!=null?{orderId:o.orderId}:{},...o.projectId!=null?{projectId:o.projectId}:{}}}async function mm(e){let t=st();if(t==null)throw new Error("No project ID found");let n={...tr,...ir(t),"Content-Type":"application/json",...e.apiKey!=null?{Authorization:`Bearer ${e.apiKey}`}:{}},o=e.testMode?`/api/payment/link/auto/${t}/test`:`/api/payment/link/auto/${t}`;delete e.apiKey,delete e.testMode,e.locale??=E();let r=await fetch(Q+o,{method:"POST",headers:n,body:JSON.stringify(e)});return r.ok?{status:"ok",redirectURL:(await r.json()).url}:{...Hr(r.status,await Jo(r)),status:"error"}}function Ft(){if(typeof localStorage>"u")return;let e=localStorage.getItem("bitsnap-ref");if(e!=null)return e}function zr(e){let t=Ft();return t==null||(e.metadata==null&&(e.metadata={}),e.metadata.ref=t),e}export{me as a,Le as b,Ue as c,_e as d,Te as e,Dn as f,gt as g,yt as h,Ze as i,Qe as j,ba as k,Lr as l,Xi as m,z as n,Co as o,Tr as p,De as q,_s as r,Xp as s,tm as t,rm as u,nm as v,at as w,Js as x,Ho as y,Ur as z,mm as A,Ft as B,zr as C,ip as D,sp as E,lp as F,cp as G,xs as H,_r as I,_p as J,st as K,zp as L,jp as M,Ss as N,Fp as O,qp as P,Rs as Q,Hp as R,$p as S,Bp as T,Kp as U,Gp as V,Vp as W,Wp as X,Fr as Y};
5
+ //# sourceMappingURL=chunk-YGE2223J.mjs.map