@tagadapay/headless-sdk 1.5.5 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +30 -0
  2. package/dist/core/client.d.ts +7 -0
  3. package/dist/core/client.d.ts.map +1 -1
  4. package/dist/core/client.js +3 -1
  5. package/dist/core/client.js.map +1 -1
  6. package/dist/core/index.d.ts +2 -1
  7. package/dist/core/index.d.ts.map +1 -1
  8. package/dist/core/index.js +1 -0
  9. package/dist/core/index.js.map +1 -1
  10. package/dist/core/modules/checkout.d.ts +80 -0
  11. package/dist/core/modules/checkout.d.ts.map +1 -1
  12. package/dist/core/modules/checkout.js +92 -1
  13. package/dist/core/modules/checkout.js.map +1 -1
  14. package/dist/core/modules/funnel.d.ts +38 -0
  15. package/dist/core/modules/funnel.d.ts.map +1 -0
  16. package/dist/core/modules/funnel.js +138 -0
  17. package/dist/core/modules/funnel.js.map +1 -0
  18. package/dist/core/modules/offers.d.ts +55 -2
  19. package/dist/core/modules/offers.d.ts.map +1 -1
  20. package/dist/core/modules/offers.js +49 -1
  21. package/dist/core/modules/offers.js.map +1 -1
  22. package/dist/core/modules/payment.d.ts +59 -0
  23. package/dist/core/modules/payment.d.ts.map +1 -1
  24. package/dist/core/modules/payment.js +92 -4
  25. package/dist/core/modules/payment.js.map +1 -1
  26. package/dist/core/types.d.ts +45 -0
  27. package/dist/core/types.d.ts.map +1 -1
  28. package/dist/react/hooks/useOffers.d.ts +62 -14
  29. package/dist/react/hooks/useOffers.d.ts.map +1 -1
  30. package/dist/react/hooks/useOffers.js +110 -11
  31. package/dist/react/hooks/useOffers.js.map +1 -1
  32. package/dist/react/hooks/usePayment.d.ts.map +1 -1
  33. package/dist/react/hooks/usePayment.js +6 -0
  34. package/dist/react/hooks/usePayment.js.map +1 -1
  35. package/dist/react/internal/redirectGuard.d.ts +9 -0
  36. package/dist/react/internal/redirectGuard.d.ts.map +1 -0
  37. package/dist/react/internal/redirectGuard.js +25 -0
  38. package/dist/react/internal/redirectGuard.js.map +1 -0
  39. package/dist/tagada-headless-react.min.js +2 -2
  40. package/dist/tagada-headless-react.min.js.map +4 -4
  41. package/dist/tagada-headless.js +386 -8
  42. package/dist/tagada-headless.min.js +2 -2
  43. package/dist/tagada-headless.min.js.map +4 -4
  44. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @tagadapay/headless-sdk v1.5.5
2
+ * @tagadapay/headless-sdk v1.7.0
3
3
  * Headless checkout, payments, offers, and CRM
4
4
  * @license MIT
5
5
  */
@@ -48,6 +48,7 @@ var TagadaHeadlessBundle = (() => {
48
48
  CheckoutModule: () => CheckoutModule,
49
49
  CurrencyUtils: () => CurrencyUtils,
50
50
  CustomerModule: () => CustomerModule,
51
+ FunnelModule: () => FunnelModule,
51
52
  GoogleAutocompleteCore: () => GoogleAutocompleteCore,
52
53
  HeadlessClient: () => HeadlessClient,
53
54
  HttpClient: () => HttpClient,
@@ -236,6 +237,15 @@ var TagadaHeadlessBundle = (() => {
236
237
  this.storeId = storeId;
237
238
  this.onTokenChange = onTokenChange;
238
239
  }
240
+ /**
241
+ * Returns the most recently loaded `CheckoutSession`, if any.
242
+ *
243
+ * Populated by `loadSession()`. Returns `undefined` if the SDK has not
244
+ * loaded a session yet. Used by `funnel.navigate()` to source the cart.
245
+ */
246
+ getCurrentSession() {
247
+ return this._currentSession;
248
+ }
239
249
  /**
240
250
  * Load an existing checkout session by its checkout token.
241
251
  *
@@ -265,7 +275,9 @@ var TagadaHeadlessBundle = (() => {
265
275
  token: this.sessionToken
266
276
  }
267
277
  );
268
- return this.normalizeSession(raw);
278
+ const session = this.normalizeSession(raw);
279
+ this._currentSession = session;
280
+ return session;
269
281
  }
270
282
  /**
271
283
  * Create a new checkout session.
@@ -310,6 +322,85 @@ var TagadaHeadlessBundle = (() => {
310
322
  customerId: res.customerId
311
323
  };
312
324
  }
325
+ /**
326
+ * Create a session and produce a self-hosted redirect URL.
327
+ *
328
+ * Convenience wrapper around `createSession()`. Builds a URL of the
329
+ * form `${origin}${checkoutPath}?checkoutToken=...&sessionToken=...`
330
+ * that you can navigate to from a Cart page. The receiving page reads
331
+ * the params via {@link CheckoutModule.parseTokensFromUrl} and calls
332
+ * {@link CheckoutModule.loadSession}.
333
+ *
334
+ * For Tagada-hosted checkouts use the `checkoutUrl` returned by
335
+ * `createSession()` directly — this helper is for **self-hosted**
336
+ * checkout pages.
337
+ *
338
+ * @example
339
+ * ```ts
340
+ * const { url } = await tagada.checkout.createSessionUrl({
341
+ * items: [{ variantId, quantity: 1 }],
342
+ * checkoutPath: '/checkout',
343
+ * });
344
+ * window.location.href = url;
345
+ * ```
346
+ */
347
+ async createSessionUrl(opts) {
348
+ const session = await this.createSession({
349
+ items: opts.items,
350
+ currency: opts.currency,
351
+ returnUrl: opts.returnUrl,
352
+ customerEmail: opts.customerEmail,
353
+ customerFirstName: opts.customerFirstName,
354
+ customerLastName: opts.customerLastName
355
+ });
356
+ const origin = opts.origin ?? (typeof window !== "undefined" ? window.location.origin : "");
357
+ const checkoutPath = opts.checkoutPath ?? "/checkout";
358
+ const params = new URLSearchParams({
359
+ checkoutToken: session.checkoutToken,
360
+ sessionToken: session.sessionToken
361
+ });
362
+ const url = `${origin}${checkoutPath}?${params.toString()}`;
363
+ return { ...session, url };
364
+ }
365
+ /**
366
+ * Read `checkoutToken` and session token from a URL.
367
+ *
368
+ * Recognizes both the SDK convention (`?sessionToken=`) and the
369
+ * Tagada-hosted convention (`?token=`), so the same checkout page
370
+ * works whether the user came from `createSessionUrl()` or directly
371
+ * from a Tagada-hosted redirect.
372
+ *
373
+ * Returns `null` if `checkoutToken` is missing.
374
+ *
375
+ * @example
376
+ * ```ts
377
+ * const tokens = CheckoutModule.parseTokensFromUrl();
378
+ * if (!tokens) {
379
+ * window.location.href = '/cart';
380
+ * return;
381
+ * }
382
+ * const session = await tagada.checkout.loadSession(
383
+ * tokens.checkoutToken,
384
+ * tokens.sessionToken,
385
+ * );
386
+ * ```
387
+ */
388
+ static parseTokensFromUrl(url) {
389
+ if (typeof url === "undefined" && typeof window === "undefined")
390
+ return null;
391
+ const href = url ?? window.location.href;
392
+ let parsed;
393
+ try {
394
+ parsed = new URL(href);
395
+ } catch {
396
+ return null;
397
+ }
398
+ const checkoutToken = parsed.searchParams.get("checkoutToken");
399
+ if (!checkoutToken)
400
+ return null;
401
+ const sessionToken = parsed.searchParams.get("sessionToken") ?? parsed.searchParams.get("token") ?? "";
402
+ return { checkoutToken, sessionToken };
403
+ }
313
404
  /**
314
405
  * Replace the cart items for an existing session.
315
406
  *
@@ -922,21 +1013,38 @@ var TagadaHeadlessBundle = (() => {
922
1013
  * ```
923
1014
  */
924
1015
  async processPayment(opts) {
925
- var _a, _b;
926
1016
  if (!opts.returnUrl && typeof window !== "undefined") {
927
1017
  opts = { ...opts, returnUrl: window.location.href };
928
1018
  }
929
1019
  const payResult = await this.pay(opts);
930
- const payment = payResult.payment;
1020
+ return this.finalize(payResult, { returnUrl: opts.returnUrl });
1021
+ }
1022
+ /**
1023
+ * Resolve a raw `PayResult` (from any pay endpoint — `pay()`, `payDirect()`,
1024
+ * `processApplePay()`, `offers.payPreviewedOffer()`, …) into a typed
1025
+ * `ProcessPaymentResult` (`succeeded` / `requires_redirect` / `failed`
1026
+ * / `pending`).
1027
+ *
1028
+ * Handles 3DS routing (modal challenge via core-js, or bank redirect)
1029
+ * and async polling until the payment reaches a terminal status.
1030
+ *
1031
+ * This is the same logic `processPayment()` runs after `pay()` — exposed
1032
+ * so callers (and the offers module) that already have a raw `PayResult`
1033
+ * don't need to re-pay.
1034
+ */
1035
+ async finalize(input, opts) {
1036
+ var _a, _b;
1037
+ const payment = input.payment;
1038
+ const returnUrl = (opts == null ? void 0 : opts.returnUrl) ?? (typeof window !== "undefined" ? window.location.href : void 0);
931
1039
  if (payment.status === "succeeded") {
932
- return { status: "succeeded", payment, order: payResult.order };
1040
+ return { status: "succeeded", payment, order: input.order };
933
1041
  }
934
1042
  if (payment.status === "failed" || payment.status === "declined") {
935
1043
  const msg = ((_a = payment.requireActionData) == null ? void 0 : _a.message) || ((_b = payment.requireActionData) == null ? void 0 : _b.errorCode) || `Payment ${payment.status}`;
936
1044
  return { status: "failed", error: msg, payment };
937
1045
  }
938
1046
  if (payment.requireAction && payment.requireAction !== "none" && payment.requireActionData) {
939
- return this.handlePaymentAction(payment, opts);
1047
+ return this.handlePaymentAction(payment, { returnUrl });
940
1048
  }
941
1049
  return this.pollUntilDone(payment.id);
942
1050
  }
@@ -949,6 +1057,77 @@ var TagadaHeadlessBundle = (() => {
949
1057
  async resumeAfterRedirect(paymentId) {
950
1058
  return this.pollUntilDone(paymentId);
951
1059
  }
1060
+ /**
1061
+ * Detect a return from a 3DS / processor redirect by inspecting the
1062
+ * current page URL, then poll the payment to completion.
1063
+ *
1064
+ * The post-3DS URL convention used by Tagada-routed processors is
1065
+ * `?paymentAction=requireAction&paymentActionStatus=completed&paymentId=pay_xxx`.
1066
+ * If those params are present, this method polls the payment, cleans the
1067
+ * URL (so a refresh doesn't re-trigger), and returns the resolved
1068
+ * `ProcessPaymentResult`. Otherwise it returns `null`.
1069
+ *
1070
+ * Use this in vanilla apps as the first thing on page load. The React
1071
+ * `usePayment` hook does the same automatically — don't call this when
1072
+ * also using `usePayment`, you'll double-poll.
1073
+ *
1074
+ * @example
1075
+ * ```ts
1076
+ * const tagada = createHeadlessClient({ storeId, environment });
1077
+ *
1078
+ * const resumed = await tagada.payment.maybeResumeFromUrl();
1079
+ * if (resumed?.status === 'succeeded') {
1080
+ * window.location.href = `/thank-you?orderId=${resumed.order?.id}`;
1081
+ * return;
1082
+ * }
1083
+ * if (resumed?.status === 'failed') {
1084
+ * showError(resumed.error);
1085
+ * return;
1086
+ * }
1087
+ * // No 3DS return — render the normal page.
1088
+ * ```
1089
+ */
1090
+ async maybeResumeFromUrl(opts) {
1091
+ if (typeof window === "undefined" && !(opts == null ? void 0 : opts.url))
1092
+ return null;
1093
+ const href = (opts == null ? void 0 : opts.url) ?? window.location.href;
1094
+ let url;
1095
+ try {
1096
+ url = new URL(href);
1097
+ } catch {
1098
+ return null;
1099
+ }
1100
+ const action = url.searchParams.get("paymentAction");
1101
+ const actionStatus = url.searchParams.get("paymentActionStatus");
1102
+ const paymentId = url.searchParams.get("paymentId");
1103
+ if (action !== "requireAction" || actionStatus !== "completed" || !paymentId) {
1104
+ return null;
1105
+ }
1106
+ const result = await this.resumeAfterRedirect(paymentId);
1107
+ if ((opts == null ? void 0 : opts.cleanUrl) !== false && typeof window !== "undefined" && !(opts == null ? void 0 : opts.url)) {
1108
+ const cleanParams = new URLSearchParams(window.location.search);
1109
+ [
1110
+ "paymentAction",
1111
+ "paymentActionStatus",
1112
+ "paymentId",
1113
+ "payment_intent",
1114
+ "payment_intent_client_secret",
1115
+ "source_type",
1116
+ "redirect_status",
1117
+ "sessionId"
1118
+ ].forEach((k) => cleanParams.delete(k));
1119
+ const search = cleanParams.toString();
1120
+ try {
1121
+ window.history.replaceState(
1122
+ {},
1123
+ document.title,
1124
+ window.location.pathname + (search ? "?" + search : "")
1125
+ );
1126
+ } catch {
1127
+ }
1128
+ }
1129
+ return result;
1130
+ }
952
1131
  // ---------------------------------------------------------------------------
953
1132
  // Status polling
954
1133
  // ---------------------------------------------------------------------------
@@ -1162,9 +1341,10 @@ var TagadaHeadlessBundle = (() => {
1162
1341
 
1163
1342
  // src/core/modules/offers.ts
1164
1343
  var OffersModule = class {
1165
- constructor(http, storeId) {
1344
+ constructor(http, storeId, payment) {
1166
1345
  this.http = http;
1167
1346
  this.storeId = storeId;
1347
+ this.payment = payment;
1168
1348
  }
1169
1349
  // ---------------------------------------------------------------------------
1170
1350
  // Offer loading
@@ -1203,6 +1383,10 @@ var TagadaHeadlessBundle = (() => {
1203
1383
  /**
1204
1384
  * Pay a previously previewed offer (one-click charge).
1205
1385
  * Used after a main order so the stored payment instrument is reused.
1386
+ *
1387
+ * **Low-level API.** Returns the raw `OfferPayResult` — `requireAction`,
1388
+ * polling, and 3DS redirects are NOT handled. For most cases, use
1389
+ * {@link processOfferPayment} which orchestrates the full lifecycle.
1206
1390
  */
1207
1391
  async payPreviewedOffer(opts) {
1208
1392
  return this.http.post(`/api/v1/offers/${opts.offerId}/pay-preview`, {
@@ -1214,6 +1398,53 @@ var TagadaHeadlessBundle = (() => {
1214
1398
  paymentInstrumentId: opts.paymentInstrumentId
1215
1399
  });
1216
1400
  }
1401
+ /**
1402
+ * One-click upsell with full lifecycle handling.
1403
+ *
1404
+ * Like `payment.processPayment()` but for previewed offers: charges the
1405
+ * stored instrument from `mainOrderId`, runs any 3DS challenge or bank
1406
+ * redirect, polls until terminal, and returns a typed
1407
+ * `ProcessPaymentResult` (`succeeded` / `requires_redirect` /
1408
+ * `failed` / `pending`).
1409
+ *
1410
+ * Use this instead of the lower-level `payPreviewedOffer()` whenever you
1411
+ * don't need to inspect the raw `OfferPayResult` shape — which is most
1412
+ * of the time.
1413
+ *
1414
+ * @example
1415
+ * ```ts
1416
+ * const result = await tagada.offers.processOfferPayment({
1417
+ * offerId: 'offer_xxx',
1418
+ * mainOrderId: order.id,
1419
+ * returnUrl: window.location.href,
1420
+ * });
1421
+ *
1422
+ * switch (result.status) {
1423
+ * case 'succeeded':
1424
+ * window.location.href = '/upsell-2';
1425
+ * break;
1426
+ * case 'requires_redirect':
1427
+ * window.location.href = result.redirectUrl;
1428
+ * break;
1429
+ * case 'failed':
1430
+ * showError(result.error);
1431
+ * break;
1432
+ * }
1433
+ * ```
1434
+ */
1435
+ async processOfferPayment(opts) {
1436
+ if (!this.payment) {
1437
+ throw new Error(
1438
+ "OffersModule: no PaymentModule injected. Use createHeadlessClient() instead of constructing OffersModule directly."
1439
+ );
1440
+ }
1441
+ const returnUrl = opts.returnUrl ?? (typeof window !== "undefined" ? window.location.href : void 0);
1442
+ const payResult = await this.payPreviewedOffer({ ...opts, returnUrl });
1443
+ return this.payment.finalize(
1444
+ { payment: payResult.payment, order: payResult.order },
1445
+ { returnUrl }
1446
+ );
1447
+ }
1217
1448
  // ---------------------------------------------------------------------------
1218
1449
  // Order bumps (checkout-session scoped)
1219
1450
  // ---------------------------------------------------------------------------
@@ -1354,6 +1585,147 @@ var TagadaHeadlessBundle = (() => {
1354
1585
  }
1355
1586
  };
1356
1587
 
1588
+ // src/core/modules/funnel.ts
1589
+ var FunnelModule = class {
1590
+ constructor(http, storeId, checkout, accountId) {
1591
+ this.http = http;
1592
+ this.storeId = storeId;
1593
+ this.checkout = checkout;
1594
+ this.accountId = accountId;
1595
+ }
1596
+ async navigate(input) {
1597
+ var _a;
1598
+ const session = this.checkout.getCurrentSession();
1599
+ if (!session) {
1600
+ throw new TagadaError(
1601
+ "No checkout session loaded. Call sdk.checkout.loadSession(...) before sdk.funnel.navigate(...).",
1602
+ "no_cart_loaded"
1603
+ );
1604
+ }
1605
+ const accountId = input.accountId ?? this.accountId;
1606
+ if (!accountId) {
1607
+ throw new TagadaError(
1608
+ "accountId is required for funnel.navigate(). Set it on createHeadlessClient({ accountId }) or pass it per call.",
1609
+ "missing_account_id"
1610
+ );
1611
+ }
1612
+ const currentUrl = input.currentUrl ?? (typeof globalThis !== "undefined" ? (_a = globalThis.location) == null ? void 0 : _a.href : void 0);
1613
+ await this.ensureCmsSession(session, accountId, input);
1614
+ const funnelSessionId = await this.initializeFunnel({
1615
+ funnelId: input.funnelId,
1616
+ stepId: input.stepId,
1617
+ accountId,
1618
+ currentUrl
1619
+ });
1620
+ const url = await this.runNavigate({
1621
+ funnelSessionId,
1622
+ stepId: input.stepId,
1623
+ session,
1624
+ input,
1625
+ currentUrl
1626
+ });
1627
+ return { url, funnelSessionId };
1628
+ }
1629
+ // -------------------------------------------------------------------------
1630
+ // Internals
1631
+ // -------------------------------------------------------------------------
1632
+ async ensureCmsSession(session, accountId, input) {
1633
+ var _a, _b, _c;
1634
+ if (this._cmsToken && this._cmsSessionId && this._cmsCustomerId)
1635
+ return;
1636
+ const anon = await this.http.post(
1637
+ "/api/v1/cms/session/anonymous",
1638
+ { storeId: this.storeId, role: "anonymous", draft: false }
1639
+ );
1640
+ this._cmsToken = anon.token;
1641
+ this._cmsSessionId = anon.sessionId;
1642
+ const init = await this.http.post(
1643
+ "/api/v1/cms/session/v2/init",
1644
+ {
1645
+ storeId: this.storeId,
1646
+ accountId,
1647
+ customerId: "anon_placeholder",
1648
+ browserLocale: ((_a = input.customer) == null ? void 0 : _a.locale) ?? defaultLocale(),
1649
+ userAgent: defaultUserAgent(),
1650
+ queryCurrency: ((_b = input.customer) == null ? void 0 : _b.currency) ?? session.currency,
1651
+ queryLocale: (_c = input.customer) == null ? void 0 : _c.locale
1652
+ },
1653
+ { token: this._cmsToken }
1654
+ );
1655
+ this._cmsCustomerId = init.customer.id;
1656
+ }
1657
+ async initializeFunnel(args) {
1658
+ const res = await this.http.post(
1659
+ "/api/v1/funnel/initialize",
1660
+ {
1661
+ cmsSession: {
1662
+ customerId: this._cmsCustomerId,
1663
+ sessionId: this._cmsSessionId,
1664
+ storeId: this.storeId,
1665
+ accountId: args.accountId
1666
+ },
1667
+ funnelId: args.funnelId,
1668
+ entryStepId: args.stepId,
1669
+ funnelStepId: args.stepId,
1670
+ currentUrl: args.currentUrl,
1671
+ draft: false
1672
+ },
1673
+ { token: this._cmsToken }
1674
+ );
1675
+ return res.context.sessionId;
1676
+ }
1677
+ async runNavigate(args) {
1678
+ var _a, _b, _c, _d;
1679
+ const { funnelSessionId, stepId, session, input, currentUrl } = args;
1680
+ const lineItems = session.items.map((i) => ({
1681
+ variantId: i.variantId,
1682
+ priceId: i.priceId,
1683
+ quantity: i.quantity
1684
+ }));
1685
+ const discountCodes = input.discountCodes ?? (session.promotionCode ? [session.promotionCode] : void 0);
1686
+ const customer = {
1687
+ email: ((_a = input.customer) == null ? void 0 : _a.email) ?? ((_b = session.customer) == null ? void 0 : _b.email),
1688
+ currency: ((_c = input.customer) == null ? void 0 : _c.currency) ?? session.currency,
1689
+ locale: (_d = input.customer) == null ? void 0 : _d.locale
1690
+ };
1691
+ const res = await this.http.post(
1692
+ "/api/v1/funnel/navigate",
1693
+ {
1694
+ sessionId: funnelSessionId,
1695
+ currentUrl,
1696
+ funnelStepId: stepId,
1697
+ fireAndForget: false,
1698
+ event: {
1699
+ type: "INIT_CHECKOUT",
1700
+ data: {
1701
+ checkoutInit: {
1702
+ cartToken: session.id,
1703
+ lineItems,
1704
+ customer,
1705
+ returnUrl: input.returnUrl,
1706
+ storeId: this.storeId,
1707
+ metadata: input.metadata,
1708
+ discountCodes
1709
+ }
1710
+ }
1711
+ }
1712
+ },
1713
+ { token: this._cmsToken }
1714
+ );
1715
+ return res.result.url;
1716
+ }
1717
+ };
1718
+ function defaultLocale() {
1719
+ if (typeof navigator !== "undefined" && navigator.language)
1720
+ return navigator.language;
1721
+ return "en-US";
1722
+ }
1723
+ function defaultUserAgent() {
1724
+ if (typeof navigator !== "undefined" && navigator.userAgent)
1725
+ return navigator.userAgent;
1726
+ return "tagadapay-headless-sdk";
1727
+ }
1728
+
1357
1729
  // src/core/client.ts
1358
1730
  var HeadlessClient = class {
1359
1731
  constructor(config) {
@@ -1376,9 +1748,15 @@ var TagadaHeadlessBundle = (() => {
1376
1748
  };
1377
1749
  this.checkout = new CheckoutModule(this.http, this.config.storeId, setToken);
1378
1750
  this.payment = new PaymentModule(this.http, this.config.storeId, environment);
1379
- this.offers = new OffersModule(this.http, this.config.storeId);
1751
+ this.offers = new OffersModule(this.http, this.config.storeId, this.payment);
1380
1752
  this.customer = new CustomerModule(this.http, this.config.storeId);
1381
1753
  this.catalog = new CatalogModule(this.http, this.config.storeId);
1754
+ this.funnel = new FunnelModule(
1755
+ this.http,
1756
+ this.config.storeId,
1757
+ this.checkout,
1758
+ this.config.accountId
1759
+ );
1382
1760
  }
1383
1761
  /** Manually set the session token (e.g. from URL params on page load). */
1384
1762
  setSessionToken(token) {
@@ -1,8 +1,8 @@
1
1
  /**
2
- * @tagadapay/headless-sdk v1.5.5
2
+ * @tagadapay/headless-sdk v1.7.0
3
3
  * Headless checkout, payments, offers, and CRM
4
4
  * @license MIT
5
5
  */
6
- "use strict";var TagadaHeadlessBundle=(()=>{var ie=Object.create;var H=Object.defineProperty;var oe=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var ce=Object.getPrototypeOf,de=Object.prototype.hasOwnProperty;var W=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var ue=(n,e)=>{for(var t in e)H(n,t,{get:e[t],enumerable:!0})},Z=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ae(e))!de.call(n,s)&&s!==t&&H(n,s,{get:()=>e[s],enumerable:!(r=oe(e,s))||r.enumerable});return n};var Q=(n,e,t)=>(t=n!=null?ie(ce(n)):{},Z(e||!n||!n.__esModule?H(t,"default",{value:n,enumerable:!0}):t,n)),le=n=>Z(H({},"__esModule",{value:!0}),n);var Ie={};ue(Ie,{AVAILABLE_LANGUAGES:()=>U,CatalogModule:()=>O,CheckoutModule:()=>b,CurrencyUtils:()=>S,CustomerModule:()=>x,GoogleAutocompleteCore:()=>N,HeadlessClient:()=>D,HttpClient:()=>k,ISODataCore:()=>q,OffersModule:()=>L,PaymentModule:()=>T,TagadaAuthError:()=>v,TagadaError:()=>f,TagadaNetworkError:()=>I,TagadaNotFoundError:()=>A,TagadaPaymentError:()=>K,TagadaRateLimitError:()=>R,TagadaValidationError:()=>C,createHeadlessClient:()=>ee,ensureGeoDataLoaded:()=>$,formatMoney:()=>Y,getCountries:()=>E,getStatesForCountry:()=>M,isLanguageLoaded:()=>G,loadGoogleMapsScript:()=>z});var f=class extends Error{constructor(e,t,r,s){super(e),this.name="TagadaError",this.code=t,this.statusCode=r,this.details=s}},v=class extends f{constructor(e="Authentication failed. Check your API key or checkout token."){super(e,"auth_error",401),this.name="TagadaAuthError"}},C=class extends f{constructor(e,t=[]){super(e,"validation_error",422,{errors:t}),this.name="TagadaValidationError",this.errors=t}},A=class extends f{constructor(e,t){super(`${e} "${t}" not found.`,"not_found",404),this.name="TagadaNotFoundError"}},R=class extends f{constructor(e=1e3){super(`Rate limited. Retry after ${e}ms.`,"rate_limit",429),this.name="TagadaRateLimitError",this.retryAfterMs=e}},K=class extends f{constructor(e,t){super(e,"payment_error",void 0,t==null?void 0:t.details),this.name="TagadaPaymentError",this.paymentId=t==null?void 0:t.paymentId,this.requireAction=t==null?void 0:t.requireAction}},I=class extends f{constructor(e="Network request failed. Check your connection."){super(e,"network_error"),this.name="TagadaNetworkError"}};var X={production:"https://api.tagada.io",development:"https://api.tagada.dev",local:"http://localhost:3000"},k=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.timeout=e.timeout,this.apiKey=e.apiKey,this.getToken=e.getToken}static resolveBaseUrl(e,t){return t??X[e]??X.production}async request(e,t={}){var m;let{method:r="GET",body:s,headers:i={},params:o,token:a,signal:u}=t,p=`${this.baseUrl}${e}`;if(o){let c=new URLSearchParams;for(let[P,w]of Object.entries(o))w!==void 0&&c.set(P,String(w));let y=c.toString();y&&(p+=`?${y}`)}let h={"Content-Type":"application/json",...i},l=a??this.apiKey??((m=this.getToken)==null?void 0:m.call(this));l&&(h["x-cms-token"]=l);let g=new AbortController,d=setTimeout(()=>g.abort(),this.timeout);try{let c=await fetch(p,{method:r,headers:h,body:s!=null?JSON.stringify(s):void 0,signal:u??g.signal});if(clearTimeout(d),c.ok){let y=await c.text();return y?JSON.parse(y):{}}throw await this.handleErrorResponse(c,e),new f("Unexpected error","unknown",c.status)}catch(c){throw clearTimeout(d),c instanceof f?c:c instanceof DOMException&&c.name==="AbortError"?new I(`Request to ${e} timed out after ${this.timeout}ms.`):new I(c instanceof Error?c.message:"Network request failed.")}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,r){return this.request(e,{...r,method:"POST",body:t})}patch(e,t,r){return this.request(e,{...r,method:"PATCH",body:t})}put(e,t,r){return this.request(e,{...r,method:"PUT",body:t})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}async handleErrorResponse(e,t){let r={};try{r=await e.json()}catch{}let s=r.message??r.error??`Request failed: ${e.status} ${e.statusText} on ${t}`;switch(e.status){case 401:case 403:throw new v(s);case 404:throw new A(t,"");case 422:{let i=Array.isArray(r.errors)?r.errors:[];throw new C(s,i)}case 429:{let i=Number(e.headers.get("Retry-After")??"1")*1e3;throw new R(i)}default:throw new f(s,"api_error",e.status,r)}}};var b=class{constructor(e,t,r){this.http=e;this.storeId=t;this.onTokenChange=r}async loadSession(e,t,r){var o;t&&(this.sessionToken=t,(o=this.onTokenChange)==null||o.call(this,t));let s={skipAsyncWait:"false"};r!=null&&r.currency&&(s.currency=r.currency);let i=await this.http.get(`/api/v1/checkout-sessions/${e}/v2`,{params:s,token:this.sessionToken});return this.normalizeSession(i)}async createSession(e){var u;let t=e.items.map(p=>({variantId:p.variantId,priceId:p.priceId,quantity:p.quantity})),r={storeId:this.storeId,lineItems:t};e.returnUrl&&(r.returnUrl=e.returnUrl);let s={};e.currency&&(s.currency=e.currency),e.customerEmail&&(s.email=e.customerEmail,s.firstName=e.customerFirstName,s.lastName=e.customerLastName),Object.keys(s).length>0&&(r.customer=s);let i=await this.http.post("/api/v1/checkout/session/init",r),a=new URL(i.checkoutUrl).searchParams.get("token")??"";return this.sessionToken=a,a&&((u=this.onTokenChange)==null||u.call(this,a)),{checkoutUrl:i.checkoutUrl,checkoutToken:i.checkoutToken,sessionToken:a,customerId:i.customerId}}async updateCart(e,t){return this.http.post(`/api/v1/checkout-sessions/${e}/line-items`,{items:t},{token:this.sessionToken})}async updateCustomer(e,t){t.email&&(this.customerEmail=t.email),t.firstName&&(this.customerFirstName=t.firstName),t.lastName&&(this.customerLastName=t.lastName),t.phone&&(this.customerPhone=t.phone)}async updateAddress(e,t){let r=this.mapAddress(t.shippingAddress),s=this.mapAddress(t.billingAddress),i=r??s??{},o=s??r,a=!!(t.billingAddress&&t.shippingAddress);await this.http.post(`/api/v1/checkout-sessions/${e}/customer-and-session-info`,{checkoutSessionId:e,customerData:{email:this.customerEmail},shippingAddress:i,billingAddress:o??{},differentBillingAddress:a},{token:this.sessionToken})}async updateCustomerAndAddress(e,t){t.customer.email&&(this.customerEmail=t.customer.email),t.customer.firstName&&(this.customerFirstName=t.customer.firstName),t.customer.lastName&&(this.customerLastName=t.customer.lastName),t.customer.phone&&(this.customerPhone=t.customer.phone);let r=this.mapAddress(t.shippingAddress),s=this.mapAddress(t.billingAddress),i=r??s??{},o=s??r,a=!!(t.billingAddress&&t.shippingAddress);await this.http.post(`/api/v1/checkout-sessions/${e}/customer-and-session-info`,{checkoutSessionId:e,customerData:{email:this.customerEmail},shippingAddress:i,billingAddress:o??{},differentBillingAddress:a},{token:this.sessionToken})}mapAddress(e){if(e)return me({firstName:e.firstName??this.customerFirstName,lastName:e.lastName??this.customerLastName,phone:e.phone??this.customerPhone,address1:e.line1,address2:e.line2,city:e.city,state:e.state,postal:e.postalCode,country:e.country})}async applyPromoCode(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/promotions/apply`,{checkoutSessionId:e,code:t},{token:this.sessionToken})}async removePromoCode(e,t){let r=t??"default";await this.http.delete(`/api/v1/checkout-sessions/${e}/promotions/${r}`,{token:this.sessionToken})}async getShippingRates(e){return((await this.http.get(`/api/v1/checkout-sessions/${e}/shipping-rates`,{token:this.sessionToken})).rates??[]).map(r=>this.normalizeShippingRate(r))}normalizeShippingRate(e){return{id:e.id,name:e.name??e.shippingRateName??"",description:e.description??void 0,amount:e.amount??0,currency:e.currency??"USD",estimatedDays:e.estimatedDays??e.estimatedDeliveryTime??void 0}}async selectShippingRate(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/shipping-rate`,{checkoutSessionId:e,shippingRateId:t},{token:this.sessionToken})}normalizeSession(e){var h;let t=e.checkoutSession,r=t.orderSummaries??[],s=e.summary??t.summary??r[0]??{},i=t.sessionLineItems??[],o=t.customer,a=(h=s.currency??t.selectedPresentmentCurrency)==null?void 0:h.toUpperCase(),u=i.map(l=>{let g=l.price,d=l.variant??(g==null?void 0:g.variant)??{},m=l.product??d.product??{},c=(g==null?void 0:g.currencyOptions)??{},y=(a?c[a]:void 0)??c[Object.keys(c)[0]],P=(y==null?void 0:y.amount)??0;return{id:l.id,variantId:l.variantId,priceId:l.priceId,productName:m.name??"",variantName:d.name??"",quantity:l.quantity??1,unitAmount:P,totalAmount:P*(l.quantity??1),currency:a??"USD",imageUrl:d.imageUrl??m.imageUrl??""}}),p=s.items??[];return{id:t.id,storeId:t.storeId,checkoutToken:t.checkoutToken,currency:a??"USD",items:u,totals:{subtotal:s.subtotalAmount??0,discount:s.totalPromotionAmount??0,shipping:s.shippingCost??0,tax:s.totalTaxAmount??0,total:s.totalAmount??p.reduce((l,g)=>l+(g.amount??0),0),currency:a??"USD"},customer:o?{id:o.id,email:o.email,firstName:o.firstName,lastName:o.lastName,phone:o.phone}:void 0,shippingAddress:this.normalizeAddress(t.shippingAddress),billingAddress:this.normalizeAddress(t.billingAddress),selectedShippingRateId:t.shippingRateId??null,metadata:t.metadata}}normalizeAddress(e){if(!e||typeof e!="object")return;let t=e,r={firstName:t.firstName,lastName:t.lastName,line1:t.line1??t.address1,line2:t.line2??t.address2,city:t.city,state:t.state,postalCode:t.postalCode??t.postal,country:t.country,phone:t.phone};return Object.values(r).some(s=>s!==void 0&&s!=="")?r:void 0}};function me(n){let e={};for(let[t,r]of Object.entries(n))r!=null&&r!==""&&(e[t]=r);return Object.keys(e).length>0?e:void 0}var T=class{constructor(e,t,r){this.http=e;this.storeId=t;this.environment=r}async getPaymentSetup(e,t){if(t!=null&&t.paymentSetupConfig)return t.paymentSetupConfig;let r=this.readInjectedStepConfig();if(r)return r;let s=await this.http.get("/api/v1/payment-methods",{params:{checkoutSessionId:e}}),i={};for(let o of s.methods??[]){let a=o.provider?`${o.method}:${o.provider}`:o.method;i[a]=o}return i}async getExpressMethods(e,t){var i,o,a,u,p,h,l,g,d;let r=await this.getPaymentSetup(e,t),s={};for(let[m,c]of Object.entries(r)){if(!c.enabled)continue;if(m.startsWith("express_checkout:")&&c.methods){let w={available:!0,processorId:c.processorId,publishableKey:c.publishableKey,metadata:c.metadata};if((i=c.methods.apple_pay)!=null&&i.enabled){let ne=typeof window<"u"&&"ApplePaySession"in window&&((a=(o=window.ApplePaySession)==null?void 0:o.canMakePayments)==null?void 0:a.call(o));s.applePay={...w,type:"apple_pay",available:!!ne}}(u=c.methods.google_pay)!=null&&u.enabled&&(s.googlePay={...w,type:"google_pay"}),(p=c.methods.paypal)!=null&&p.enabled&&(s.paypal={...w,type:"paypal"}),(h=c.methods.link)!=null&&h.enabled&&(s.link={...w,type:"link"}),(l=c.methods.klarna_express)!=null&&l.enabled&&(s.klarna={...w,type:"klarna_express"});continue}if(!c.express)continue;let y=c.method,P={type:y,available:!0,processorId:c.processorId,publishableKey:c.publishableKey,metadata:c.metadata};if(y==="apple_pay"||c.type==="apple_pay"){let w=typeof window<"u"&&"ApplePaySession"in window&&((d=(g=window.ApplePaySession)==null?void 0:g.canMakePayments)==null?void 0:d.call(g));s.applePay={...P,available:!!w}}else y==="google_pay"||c.type==="google_pay"?s.googlePay=P:y==="paypal"?s.paypal=P:y==="klarna"||y==="klarna_express"?s.klarna=P:y==="link"&&(s.link=P)}return s}async getStoreConfig(){let e=await this.http.get("/api/v1/checkout/config",{params:{storeId:this.storeId}});return e.config??e}async getEnabledMethods(e,t){let r=await this.getPaymentSetup(e,t);return Object.entries(r).filter(([,s])=>s.enabled).map(([s])=>s)}async tokenizeCard(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let s={cardNumber:e.cardNumber,expiryDate:e.expiryDate,cvc:e.cvc};e.cardholderName&&(s.cardholderName=e.cardholderName);let i=await r.tokenizeCardRaw(s);return{tagadaToken:t.createTagadaToken(i,r.getProvider().getProviderName()),rawToken:i}}async createInstrument(e){return this.http.post("/api/v1/payment/create-instrument-from-token",{tagadaToken:e.tagadaToken})}async create3dsSession(e){return this.http.post("/api/public/v1/threeds/create-session",{provider:e.provider??"basis_theory",storeId:this.storeId,paymentInstrumentId:e.paymentInstrumentId,sessionData:e.sessionData})}async pay(e){return e.tagadaToken&&!e.paymentInstrumentId?this.http.post("/api/v1/payment/pay-with-token",{tagadaToken:e.tagadaToken,checkoutSessionId:e.checkoutSessionId,returnUrl:e.returnUrl,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,metadata:e.metadata}):this.http.post("/api/public/v1/checkout/pay-v2",{checkoutSessionId:e.checkoutSessionId,paymentInstrumentId:e.paymentInstrumentId,storeId:this.storeId,paymentFlowId:e.paymentFlowId,threedsSessionId:e.threedsSessionId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,metadata:e.metadata})}async payDirect(e){return this.http.post("/api/public/v1/checkout/pay-v2",{checkoutSessionId:e.checkoutSessionId,paymentInstrumentId:e.paymentInstrumentId??"",storeId:this.storeId,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,threedsSessionId:e.threedsSessionId})}async processApplePay(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let{tagadaToken:s}=await r.tokenizeApplePay(e.applePayToken);return this.pay({checkoutSessionId:e.checkoutSessionId,tagadaToken:s,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:"apple_pay",isExpress:!0})}async processGooglePay(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let{tagadaToken:s}=await r.tokenizeGooglePay(e.googlePayToken);return this.pay({checkoutSessionId:e.checkoutSessionId,tagadaToken:s,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:"google_pay",isExpress:!0})}async processApm(e){return this.payDirect({checkoutSessionId:e.checkoutSessionId,paymentMethod:e.paymentMethod,processorId:e.processorId,paymentFlowId:e.paymentFlowId})}async processStripeExpress(e){return this.payDirect({checkoutSessionId:e.checkoutSessionId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:!0})}async processPayment(e){var s,i;!e.returnUrl&&typeof window<"u"&&(e={...e,returnUrl:window.location.href});let t=await this.pay(e),r=t.payment;return r.status==="succeeded"?{status:"succeeded",payment:r,order:t.order}:r.status==="failed"||r.status==="declined"?{status:"failed",error:((s=r.requireActionData)==null?void 0:s.message)||((i=r.requireActionData)==null?void 0:i.errorCode)||`Payment ${r.status}`,payment:r}:r.requireAction&&r.requireAction!=="none"&&r.requireActionData?this.handlePaymentAction(r,e):this.pollUntilDone(r.id)}async resumeAfterRedirect(e){return this.pollUntilDone(e)}async getPaymentStatus(e){return this.http.get(`/api/v1/payments/${e}`)}async pollPaymentStatus(e,t){let r=(t==null?void 0:t.intervalMs)??1500,s=(t==null?void 0:t.timeoutMs)??6e4,i=Date.now();for(;Date.now()-i<s;){let o=await this.getPaymentStatus(e);if(o.status==="succeeded"||o.status==="failed"||o.status==="declined")return o;await new Promise(a=>setTimeout(a,r))}throw new Error(`Payment ${e} did not reach terminal status within ${s}ms.`)}async completeAfter3ds(e){return this.http.post("/api/v1/payments/complete-after-3ds",{paymentId:e})}async markActionProcessed(e){try{await this.http.post("/api/v1/payments/require-action/processed",{paymentId:e})}catch{}}async handlePaymentAction(e,t){let r=e.requireActionData;switch(await this.markActionProcessed(e.id),r.type){case"threeds_auth":return this.handleThreedsAuth(e,t);case"processor_auth":case"redirect_to_payment":return this.extractRedirect(e,r);case"redirect":return this.extractRedirect(e,r);case"error":return{status:"failed",error:r.message||r.errorCode||"Payment failed",payment:e};default:return this.extractRedirect(e,r)}}extractRedirect(e,t){var i,o;let r=(i=t.metadata)==null?void 0:i.redirect,s=(r==null?void 0:r.redirectUrl)||t.redirectUrl;return s?{status:"requires_redirect",redirectUrl:s,method:((o=r==null?void 0:r.method)==null?void 0:o.toUpperCase())||"GET",postData:r==null?void 0:r.data,paymentId:e.id}:{status:"failed",error:`Payment requires action (${t.type}) but no redirect URL was provided`,payment:e}}async handleThreedsAuth(e,t){var i,o;let r=(o=(i=e.requireActionData)==null?void 0:i.metadata)==null?void 0:o.threedsSession;if(!(r!=null&&r.externalSessionId))return this.extractRedirect(e,e.requireActionData);let s;try{s=await import("@tagadapay/core-js")}catch{return r.acsChallengeUrl?{status:"requires_redirect",redirectUrl:r.acsChallengeUrl,paymentId:e.id}:this.extractRedirect(e,e.requireActionData)}try{let a=new s.ThreedsManager({provider:"basis_theory"});return await a.initialize({apiKey:void 0}),await a.startChallenge({sessionId:r.externalSessionId,acsChallengeUrl:r.acsChallengeUrl,acsTransactionId:r.acsTransID,threeDSVersion:r.messageVersion}),await this.completeAfter3ds(e.id),this.pollUntilDone(e.id)}catch{return r.acsChallengeUrl?{status:"requires_redirect",redirectUrl:r.acsChallengeUrl,paymentId:e.id}:{status:"failed",error:"3D Secure authentication failed",payment:e}}}async pollUntilDone(e,t){let r=(t==null?void 0:t.intervalMs)??1500,s=(t==null?void 0:t.timeoutMs)??6e4,i=Date.now(),o=0;for(;Date.now()-i<s;){let a;try{a=await this.getPaymentStatus(e),o=0}catch{if(o++,o>=3)return{status:"failed",error:"Payment verification failed due to network errors"};await new Promise(u=>setTimeout(u,r));continue}if(a.status==="succeeded"||a.status==="pending"&&a.subStatus==="authorized")return{status:"succeeded",payment:a,order:a.order};if(a.status==="failed"||a.status==="declined")return{status:"failed",error:a.status,payment:a};if(a.requireAction&&a.requireAction!=="none"&&a.requireActionData&&!a.requireActionData.processed)return this.handlePaymentAction(a,{});await new Promise(u=>setTimeout(u,r))}return{status:"pending",paymentId:e}}readInjectedStepConfig(){if(typeof window>"u")return null;let e=window.__TGD_STEP_CONFIG__;if(!e)return null;try{let t=typeof e=="string"?JSON.parse(e):e;return(t==null?void 0:t.paymentSetupConfig)??null}catch{return null}}async loadCoreJs(){try{return await import("@tagadapay/core-js")}catch{throw new Error("This method requires @tagadapay/core-js. Install it: npm install @tagadapay/core-js")}}};var L=class{constructor(e,t){this.http=e;this.storeId=t}async getOffer(e){return this.http.get(`/api/v1/offers/${e}`)}async listOffers(e){var i;let t=`/api/v1/stores/${this.storeId}/offers`,r=[];if(e!=null&&e.type&&r.push(`type=${encodeURIComponent(e.type)}`),(i=e==null?void 0:e.ids)!=null&&i.length)for(let o of e.ids)r.push(`ids=${encodeURIComponent(o)}`);return r.length&&(t+=`?${r.join("&")}`),(await this.http.get(t)).offers??[]}async previewOffer(e){return this.http.post(`/api/v1/offers/${e.offerId}/preview`,{offerId:e.offerId,currency:e.currency??"",lineItems:e.lineItems})}async payPreviewedOffer(e){return this.http.post(`/api/v1/offers/${e.offerId}/pay-preview`,{offerId:e.offerId,currency:e.currency??"",lineItems:e.lineItems,returnUrl:e.returnUrl??(typeof window<"u"?window.location.href:""),mainOrderId:e.mainOrderId,paymentInstrumentId:e.paymentInstrumentId})}async toggleOrderBump(e){return this.http.post(`/api/v1/checkout-sessions/${e.checkoutSessionId}/toggle-order-bump`,{orderBumpOfferId:e.orderBumpOfferId,selected:e.selected})}async listPostPurchaseOffers(e){let t=await this.http.get(`/api/v1/post-purchase/${e}/offers`);return Array.isArray(t)?t:[]}async acceptPostPurchaseOffer(e){return this.http.post(`/api/v1/orders/${e.orderId}/post-purchase-offers/${e.offerId}/accept`,{items:e.items??[]})}async declinePostPurchaseOffer(e){return this.http.post(`/api/v1/orders/${e.orderId}/post-purchase-offers/${e.offerId}/decline`)}};var x=class{constructor(e,t){this.http=e;this.storeId=t}async getProfile(e){return(await this.http.get(`/api/v1/customers/${e}`,{params:{storeId:this.storeId}})).customer}async getByEmail(e){try{return(await this.http.get("/api/v1/customers/by-email",{params:{email:e,storeId:this.storeId}})).customer}catch{return null}}async updateProfile(e,t){return(await this.http.patch(`/api/v1/customers/${e}`,{storeId:this.storeId,...t})).customer}async getOrders(e,t){return this.http.get(`/api/v1/customers/${e}/orders`,{params:{storeId:this.storeId,limit:t==null?void 0:t.limit,offset:t==null?void 0:t.offset}})}async getOrder(e){return(await this.http.get(`/api/v1/orders/${e}`,{params:{storeId:this.storeId}})).order}async getSubscriptions(e){return(await this.http.get(`/api/v1/customers/${e}/subscriptions`,{params:{storeId:this.storeId}})).subscriptions}async getSubscription(e){return(await this.http.get(`/api/v1/subscriptions/${e}`,{params:{storeId:this.storeId}})).subscription}};var O=class{constructor(e,t){this.http=e;this.storeId=t}async getProducts(e){var s,i;let t={storeId:this.storeId,includeVariants:!0,includePrices:!0};return(s=e==null?void 0:e.productIds)!=null&&s.length&&(t.productIds=e.productIds),(i=e==null?void 0:e.variantIds)!=null&&i.length&&(t.variantIds=e.variantIds),(await this.http.post("/api/v1/products",t)).items??[]}async getProduct(e){return(await this.getProducts({productIds:[e]}))[0]??null}};var D=class{constructor(e){let t=e.environment??"production",r=k.resolveBaseUrl(t,e.baseUrl);this.config={...e,environment:t,baseUrl:r,timeout:e.timeout??3e4},this.http=new k({baseUrl:r,timeout:this.config.timeout,apiKey:e.apiKey,getToken:()=>this._sessionToken});let s=i=>{this._sessionToken=i};this.checkout=new b(this.http,this.config.storeId,s),this.payment=new T(this.http,this.config.storeId,t),this.offers=new L(this.http,this.config.storeId),this.customer=new x(this.http,this.config.storeId),this.catalog=new O(this.http,this.config.storeId)}setSessionToken(e){this._sessionToken=e}};function ee(n){return new D(n)}var te=!1,re=!1,F=[];function B(){re=!0;for(let n of F)n();F.length=0}function z(n,e={}){var t,r;return re||(r=(t=window.google)==null?void 0:t.maps)!=null&&r.places?(B(),Promise.resolve()):te?new Promise(s=>F.push(s)):(te=!0,new Promise((s,i)=>{if(F.push(s),document.querySelector('script[src*="maps.googleapis.com"]')){let p=()=>{var h,l;(l=(h=window.google)==null?void 0:h.maps)!=null&&l.places?B():setTimeout(p,100)};p();return}let a=new URLSearchParams({key:n,libraries:"places",v:e.version??"weekly"});e.language&&a.set("language",e.language),e.region&&a.set("region",e.region);let u=document.createElement("script");u.src=`https://maps.googleapis.com/maps/api/js?${a}`,u.async=!0,u.defer=!0,u.onload=()=>B(),u.onerror=()=>i(new Error("Failed to load Google Maps script")),document.head.appendChild(u)}))}var N=class n{static async searchPlaces(e,t={}){var s,i;if(!((i=(s=window.google)==null?void 0:s.maps)!=null&&i.places)||!e.trim())return[];let r=new window.google.maps.places.AutocompleteService;return new Promise(o=>{r.getPlacePredictions({input:e,types:t.types??["address"],componentRestrictions:t.componentRestrictions},(a,u)=>{var p,h,l;o(u===((l=(h=(p=window.google)==null?void 0:p.maps)==null?void 0:h.places)==null?void 0:l.PlacesServiceStatus.OK)&&a?a:[])})})}static async getPlaceDetails(e){var r,s;if(!((s=(r=window.google)==null?void 0:r.maps)!=null&&s.places))return null;let t=new window.google.maps.places.PlacesService(document.createElement("div"));return new Promise(i=>{t.getDetails({placeId:e,fields:["place_id","formatted_address","address_components","geometry"]},(o,a)=>{var u,p,h;i(a===((h=(p=(u=window.google)==null?void 0:u.maps)==null?void 0:p.places)==null?void 0:h.PlacesServiceStatus.OK)&&o?o:null)})})}static extractAddressComponents(e){let t={subpremise:"",streetNumber:"",route:"",locality:"",administrativeAreaLevel1:"",administrativeAreaLevel1Long:"",administrativeAreaLevel2:"",administrativeAreaLevel2Long:"",country:"",postalCode:"",fullStreetAddress:""},r="",s="",i="",o="",a="",u="",p="",h="";for(let d of e.address_components??[]){let m=d.types;m.includes("subpremise")&&(t.subpremise=d.long_name),m.includes("street_number")&&(t.streetNumber=d.long_name),m.includes("premise")&&(r=d.long_name),m.includes("route")&&(t.route=d.long_name),m.includes("neighborhood")&&(s=d.long_name),m.includes("sublocality_level_5")&&(i=d.long_name),m.includes("sublocality_level_4")&&(o=d.long_name),m.includes("sublocality_level_3")&&(a=d.long_name),m.includes("sublocality_level_2")&&(u=d.long_name),m.includes("sublocality_level_1")&&(p=d.long_name),m.includes("locality")&&(t.locality=d.long_name),m.includes("postal_town")&&(h=d.long_name),m.includes("administrative_area_level_2")&&(t.administrativeAreaLevel2=d.short_name,t.administrativeAreaLevel2Long=d.long_name),m.includes("administrative_area_level_1")&&(t.administrativeAreaLevel1=d.short_name,t.administrativeAreaLevel1Long=d.long_name),m.includes("country")&&(t.country=d.short_name),m.includes("postal_code")&&(t.postalCode=d.long_name)}t.locality||(t.locality=h||u||p||""),!t.administrativeAreaLevel1&&t.administrativeAreaLevel2&&(t.administrativeAreaLevel1=t.administrativeAreaLevel2Long||t.administrativeAreaLevel2,t.administrativeAreaLevel1Long=t.administrativeAreaLevel2Long);let l=t.streetNumber||r,g=t.route||i||o||a||s;if(t.subpremise&&l&&g)t.fullStreetAddress=`${t.subpremise}/${l} ${g}`;else if(l&&g)if(r&&o&&a){let d=`${a}-${o}-${r}`;u&&(d=`${d} ${u}`),t.fullStreetAddress=d}else t.fullStreetAddress=`${l} ${g}`;else g?t.fullStreetAddress=g:l&&(t.fullStreetAddress=l);return t.fullStreetAddress=t.fullStreetAddress.trim(),t}static extractFormattedAddress(e){let t=n.extractAddressComponents(e);return{address1:t.fullStreetAddress,city:t.locality,country:t.country,state:t.administrativeAreaLevel1,postal:t.postalCode}}};var se="https://cvwnizdbugpz6jwk.public.blob.vercel-storage.com/geodata/v1",U=["en","ru","de","da","fr","es","zh","hi","pt","ja","ar","it","he"],_=new Map,j=new Map,J=new Map,V=new Map;async function pe(n){let e=_.get(n);if(e)return e;let t=J.get(n);return t||(t=(async()=>{let r=`${se}/${n}/countries.json`,s=await fetch(r);if(!s.ok)throw new Error(`Geodata fetch failed: ${r} (${s.status})`);let i=await s.json();return _.set(n,i),J.delete(n),i})(),J.set(n,t),t)}async function ge(n){let e=j.get(n);if(e)return e;let t=V.get(n);return t||(t=(async()=>{let r=`${se}/${n}/regions.json`,s=await fetch(r);if(!s.ok)throw new Error(`Geodata fetch failed: ${r} (${s.status})`);let i=await s.json();return j.set(n,i),V.delete(n),i})(),V.set(n,t),t)}function he(n){return _.get(n)||_.get("en")||{}}function ye(n){return j.get(n)||j.get("en")||{}}async function $(n="en"){await Promise.all([pe(n),ge(n)])}var E=(n="en")=>{let e=he(n);return Object.entries(e).map(([t,r])=>({code:t,name:r.n,iso3:r.i3,numeric:r.nu})).sort((t,r)=>t.name.localeCompare(r.name))},M=(n,e="en")=>{let r=ye(e)[n];return r?r.map(([s,i])=>({code:s,name:i,countryCode:n})).sort((s,i)=>s.name.localeCompare(i.name)):[]};function G(n){return _.has(n)}var q=class n{static ensureLoaded(e="en"){return $(e)}static getCountries(e="en"){let t=E(e),r={};for(let s of t)r[s.code]={iso:s.code,iso3:s.iso3??"",numeric:s.numeric??0,name:s.name};return r}static getCountryOptions(e="en"){return E(e).map(t=>({value:t.code,label:t.name}))}static getRegions(e,t="en"){return M(e,t).map(r=>({iso:r.code,name:r.name}))}static getRegionOptions(e,t="en"){return n.getRegions(e,t).map(r=>({value:r.iso,label:r.name}))}static findRegion(e,t,r="en"){return n.getRegions(e,r).find(s=>s.iso===t)??null}static mapGoogleToISO(e,t,r,s="en"){let i=n.getRegions(r,s);if(i.length===0)return null;let o=i.find(a=>a.iso===e);return o||(o=i.find(a=>a.name.toLowerCase()===e.toLowerCase()),o)||(o=i.find(a=>a.name.toLowerCase()===t.toLowerCase()),o)?o:(o=i.find(a=>a.name.toLowerCase().includes(t.toLowerCase())||t.toLowerCase().includes(a.name.toLowerCase())),o??null)}static isLanguageLoaded(e){return G(e)}static getAvailableLanguages(){return U}};var fe={USD:"$",EUR:"\u20AC",GBP:"\xA3",JPY:"\xA5",CAD:"C$",AUD:"A$",CHF:"CHF",CNY:"\xA5",SEK:"kr",NOK:"kr",DKK:"kr",PLN:"z\u0142",CZK:"K\u010D",HUF:"Ft",RON:"lei",BGN:"\u043B\u0432",HRK:"kn",RUB:"\u20BD",UAH:"\u20B4",TRY:"\u20BA",BRL:"R$",MXN:"$",ZAR:"R",INR:"\u20B9",KRW:"\u20A9",THB:"\u0E3F",VND:"\u20AB",IDR:"Rp",MYR:"RM",SGD:"S$",PHP:"\u20B1",TWD:"NT$",HKD:"HK$",ILS:"\u20AA",AED:"\u062F.\u0625",SAR:"\u0631.\u0633",QAR:"\u0631.\u0642",KWD:"\u062F.\u0643",BHD:"\u062F.\u0628",OMR:"\u0631.\u0639.",EGP:"\xA3",NGN:"\u20A6",KES:"KSh",GHS:"\u20B5",COP:"$",ARS:"$",CLP:"$",PEN:"S/",CRC:"\u20A1",DOP:"RD$",JMD:"J$",BOB:"Bs",PYG:"\u20B2",GTQ:"Q",NIO:"C$",PAB:"B/.",PKR:"\u20A8",BDT:"\u09F3",LKR:"\u20A8",NPR:"\u20A8",GEL:"\u20BE",AMD:"\u058F",AZN:"\u20BC",KZT:"\u20B8"},Pe={USD:"US Dollar",EUR:"Euro",GBP:"British Pound",JPY:"Japanese Yen",CAD:"Canadian Dollar",AUD:"Australian Dollar",CHF:"Swiss Franc",CNY:"Chinese Yuan",SEK:"Swedish Krona",NOK:"Norwegian Krone",DKK:"Danish Krone",PLN:"Polish Zloty",CZK:"Czech Koruna",HUF:"Hungarian Forint",BRL:"Brazilian Real",MXN:"Mexican Peso",INR:"Indian Rupee",KRW:"South Korean Won",THB:"Thai Baht",SGD:"Singapore Dollar",HKD:"Hong Kong Dollar",TWD:"Taiwan Dollar",ILS:"Israeli Shekel",AED:"UAE Dirham",SAR:"Saudi Riyal",ZAR:"South African Rand",TRY:"Turkish Lira",RUB:"Russian Ruble",NGN:"Nigerian Naira"},we=new Set(["JPY","KRW","VND","IDR","LAK","KHR","MMK","PYG"]),S=class n{static getSymbol(e){return fe[e]??e}static getName(e){return Pe[e]??e}static getDecimalPlaces(e){return we.has(e)?0:2}static getCurrency(e){return{code:e,symbol:n.getSymbol(e),name:n.getName(e),decimalPlaces:n.getDecimalPlaces(e)}}};function Y(n,e="USD",t="en-US"){let r=S.getDecimalPlaces(e),s=n/(r===0?100:Math.pow(10,r));try{return new Intl.NumberFormat(t,{style:"currency",currency:e,minimumFractionDigits:r,maximumFractionDigits:r}).format(s)}catch{return`${S.getSymbol(e)}${s.toFixed(r)}`}}return le(Ie);})();
6
+ "use strict";var TagadaHeadlessBundle=(()=>{var oe=Object.create;var G=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var ce=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,de=Object.prototype.hasOwnProperty;var Z=(i=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(i,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):i)(function(i){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+i+'" is not supported')});var le=(i,e)=>{for(var t in e)G(i,t,{get:e[t],enumerable:!0})},Q=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ce(e))!de.call(i,n)&&n!==t&&G(i,n,{get:()=>e[n],enumerable:!(r=ae(e,n))||r.enumerable});return i};var X=(i,e,t)=>(t=i!=null?oe(ue(i)):{},Q(e||!i||!i.__esModule?G(t,"default",{value:i,enumerable:!0}):t,i)),me=i=>Q(G({},"__esModule",{value:!0}),i);var Se={};le(Se,{AVAILABLE_LANGUAGES:()=>M,CatalogModule:()=>x,CheckoutModule:()=>b,CurrencyUtils:()=>v,CustomerModule:()=>_,FunnelModule:()=>O,GoogleAutocompleteCore:()=>E,HeadlessClient:()=>U,HttpClient:()=>k,ISODataCore:()=>H,OffersModule:()=>L,PaymentModule:()=>T,TagadaAuthError:()=>S,TagadaError:()=>f,TagadaNetworkError:()=>w,TagadaNotFoundError:()=>A,TagadaPaymentError:()=>K,TagadaRateLimitError:()=>R,TagadaValidationError:()=>C,createHeadlessClient:()=>te,ensureGeoDataLoaded:()=>$,formatMoney:()=>W,getCountries:()=>N,getStatesForCountry:()=>F,isLanguageLoaded:()=>q,loadGoogleMapsScript:()=>J});var f=class extends Error{constructor(e,t,r,n){super(e),this.name="TagadaError",this.code=t,this.statusCode=r,this.details=n}},S=class extends f{constructor(e="Authentication failed. Check your API key or checkout token."){super(e,"auth_error",401),this.name="TagadaAuthError"}},C=class extends f{constructor(e,t=[]){super(e,"validation_error",422,{errors:t}),this.name="TagadaValidationError",this.errors=t}},A=class extends f{constructor(e,t){super(`${e} "${t}" not found.`,"not_found",404),this.name="TagadaNotFoundError"}},R=class extends f{constructor(e=1e3){super(`Rate limited. Retry after ${e}ms.`,"rate_limit",429),this.name="TagadaRateLimitError",this.retryAfterMs=e}},K=class extends f{constructor(e,t){super(e,"payment_error",void 0,t==null?void 0:t.details),this.name="TagadaPaymentError",this.paymentId=t==null?void 0:t.paymentId,this.requireAction=t==null?void 0:t.requireAction}},w=class extends f{constructor(e="Network request failed. Check your connection."){super(e,"network_error"),this.name="TagadaNetworkError"}};var ee={production:"https://api.tagada.io",development:"https://api.tagada.dev",local:"http://localhost:3000"},k=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.timeout=e.timeout,this.apiKey=e.apiKey,this.getToken=e.getToken}static resolveBaseUrl(e,t){return t??ee[e]??ee.production}async request(e,t={}){var p;let{method:r="GET",body:n,headers:s={},params:o,token:a,signal:u}=t,m=`${this.baseUrl}${e}`;if(o){let c=new URLSearchParams;for(let[I,P]of Object.entries(o))P!==void 0&&c.set(I,String(P));let y=c.toString();y&&(m+=`?${y}`)}let h={"Content-Type":"application/json",...s},l=a??this.apiKey??((p=this.getToken)==null?void 0:p.call(this));l&&(h["x-cms-token"]=l);let g=new AbortController,d=setTimeout(()=>g.abort(),this.timeout);try{let c=await fetch(m,{method:r,headers:h,body:n!=null?JSON.stringify(n):void 0,signal:u??g.signal});if(clearTimeout(d),c.ok){let y=await c.text();return y?JSON.parse(y):{}}throw await this.handleErrorResponse(c,e),new f("Unexpected error","unknown",c.status)}catch(c){throw clearTimeout(d),c instanceof f?c:c instanceof DOMException&&c.name==="AbortError"?new w(`Request to ${e} timed out after ${this.timeout}ms.`):new w(c instanceof Error?c.message:"Network request failed.")}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,r){return this.request(e,{...r,method:"POST",body:t})}patch(e,t,r){return this.request(e,{...r,method:"PATCH",body:t})}put(e,t,r){return this.request(e,{...r,method:"PUT",body:t})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}async handleErrorResponse(e,t){let r={};try{r=await e.json()}catch{}let n=r.message??r.error??`Request failed: ${e.status} ${e.statusText} on ${t}`;switch(e.status){case 401:case 403:throw new S(n);case 404:throw new A(t,"");case 422:{let s=Array.isArray(r.errors)?r.errors:[];throw new C(n,s)}case 429:{let s=Number(e.headers.get("Retry-After")??"1")*1e3;throw new R(s)}default:throw new f(n,"api_error",e.status,r)}}};var b=class{constructor(e,t,r){this.http=e;this.storeId=t;this.onTokenChange=r}getCurrentSession(){return this._currentSession}async loadSession(e,t,r){var a;t&&(this.sessionToken=t,(a=this.onTokenChange)==null||a.call(this,t));let n={skipAsyncWait:"false"};r!=null&&r.currency&&(n.currency=r.currency);let s=await this.http.get(`/api/v1/checkout-sessions/${e}/v2`,{params:n,token:this.sessionToken}),o=this.normalizeSession(s);return this._currentSession=o,o}async createSession(e){var u;let t=e.items.map(m=>({variantId:m.variantId,priceId:m.priceId,quantity:m.quantity})),r={storeId:this.storeId,lineItems:t};e.returnUrl&&(r.returnUrl=e.returnUrl);let n={};e.currency&&(n.currency=e.currency),e.customerEmail&&(n.email=e.customerEmail,n.firstName=e.customerFirstName,n.lastName=e.customerLastName),Object.keys(n).length>0&&(r.customer=n);let s=await this.http.post("/api/v1/checkout/session/init",r),a=new URL(s.checkoutUrl).searchParams.get("token")??"";return this.sessionToken=a,a&&((u=this.onTokenChange)==null||u.call(this,a)),{checkoutUrl:s.checkoutUrl,checkoutToken:s.checkoutToken,sessionToken:a,customerId:s.customerId}}async createSessionUrl(e){let t=await this.createSession({items:e.items,currency:e.currency,returnUrl:e.returnUrl,customerEmail:e.customerEmail,customerFirstName:e.customerFirstName,customerLastName:e.customerLastName}),r=e.origin??(typeof window<"u"?window.location.origin:""),n=e.checkoutPath??"/checkout",s=new URLSearchParams({checkoutToken:t.checkoutToken,sessionToken:t.sessionToken}),o=`${r}${n}?${s.toString()}`;return{...t,url:o}}static parseTokensFromUrl(e){if(typeof e>"u"&&typeof window>"u")return null;let t=e??window.location.href,r;try{r=new URL(t)}catch{return null}let n=r.searchParams.get("checkoutToken");if(!n)return null;let s=r.searchParams.get("sessionToken")??r.searchParams.get("token")??"";return{checkoutToken:n,sessionToken:s}}async updateCart(e,t){return this.http.post(`/api/v1/checkout-sessions/${e}/line-items`,{items:t},{token:this.sessionToken})}async updateCustomer(e,t){t.email&&(this.customerEmail=t.email),t.firstName&&(this.customerFirstName=t.firstName),t.lastName&&(this.customerLastName=t.lastName),t.phone&&(this.customerPhone=t.phone)}async updateAddress(e,t){let r=this.mapAddress(t.shippingAddress),n=this.mapAddress(t.billingAddress),s=r??n??{},o=n??r,a=!!(t.billingAddress&&t.shippingAddress);await this.http.post(`/api/v1/checkout-sessions/${e}/customer-and-session-info`,{checkoutSessionId:e,customerData:{email:this.customerEmail},shippingAddress:s,billingAddress:o??{},differentBillingAddress:a},{token:this.sessionToken})}async updateCustomerAndAddress(e,t){t.customer.email&&(this.customerEmail=t.customer.email),t.customer.firstName&&(this.customerFirstName=t.customer.firstName),t.customer.lastName&&(this.customerLastName=t.customer.lastName),t.customer.phone&&(this.customerPhone=t.customer.phone);let r=this.mapAddress(t.shippingAddress),n=this.mapAddress(t.billingAddress),s=r??n??{},o=n??r,a=!!(t.billingAddress&&t.shippingAddress);await this.http.post(`/api/v1/checkout-sessions/${e}/customer-and-session-info`,{checkoutSessionId:e,customerData:{email:this.customerEmail},shippingAddress:s,billingAddress:o??{},differentBillingAddress:a},{token:this.sessionToken})}mapAddress(e){if(e)return pe({firstName:e.firstName??this.customerFirstName,lastName:e.lastName??this.customerLastName,phone:e.phone??this.customerPhone,address1:e.line1,address2:e.line2,city:e.city,state:e.state,postal:e.postalCode,country:e.country})}async applyPromoCode(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/promotions/apply`,{checkoutSessionId:e,code:t},{token:this.sessionToken})}async removePromoCode(e,t){let r=t??"default";await this.http.delete(`/api/v1/checkout-sessions/${e}/promotions/${r}`,{token:this.sessionToken})}async getShippingRates(e){return((await this.http.get(`/api/v1/checkout-sessions/${e}/shipping-rates`,{token:this.sessionToken})).rates??[]).map(r=>this.normalizeShippingRate(r))}normalizeShippingRate(e){return{id:e.id,name:e.name??e.shippingRateName??"",description:e.description??void 0,amount:e.amount??0,currency:e.currency??"USD",estimatedDays:e.estimatedDays??e.estimatedDeliveryTime??void 0}}async selectShippingRate(e,t){await this.http.post(`/api/v1/checkout-sessions/${e}/shipping-rate`,{checkoutSessionId:e,shippingRateId:t},{token:this.sessionToken})}normalizeSession(e){var h;let t=e.checkoutSession,r=t.orderSummaries??[],n=e.summary??t.summary??r[0]??{},s=t.sessionLineItems??[],o=t.customer,a=(h=n.currency??t.selectedPresentmentCurrency)==null?void 0:h.toUpperCase(),u=s.map(l=>{let g=l.price,d=l.variant??(g==null?void 0:g.variant)??{},p=l.product??d.product??{},c=(g==null?void 0:g.currencyOptions)??{},y=(a?c[a]:void 0)??c[Object.keys(c)[0]],I=(y==null?void 0:y.amount)??0;return{id:l.id,variantId:l.variantId,priceId:l.priceId,productName:p.name??"",variantName:d.name??"",quantity:l.quantity??1,unitAmount:I,totalAmount:I*(l.quantity??1),currency:a??"USD",imageUrl:d.imageUrl??p.imageUrl??""}}),m=n.items??[];return{id:t.id,storeId:t.storeId,checkoutToken:t.checkoutToken,currency:a??"USD",items:u,totals:{subtotal:n.subtotalAmount??0,discount:n.totalPromotionAmount??0,shipping:n.shippingCost??0,tax:n.totalTaxAmount??0,total:n.totalAmount??m.reduce((l,g)=>l+(g.amount??0),0),currency:a??"USD"},customer:o?{id:o.id,email:o.email,firstName:o.firstName,lastName:o.lastName,phone:o.phone}:void 0,shippingAddress:this.normalizeAddress(t.shippingAddress),billingAddress:this.normalizeAddress(t.billingAddress),selectedShippingRateId:t.shippingRateId??null,metadata:t.metadata}}normalizeAddress(e){if(!e||typeof e!="object")return;let t=e,r={firstName:t.firstName,lastName:t.lastName,line1:t.line1??t.address1,line2:t.line2??t.address2,city:t.city,state:t.state,postalCode:t.postalCode??t.postal,country:t.country,phone:t.phone};return Object.values(r).some(n=>n!==void 0&&n!=="")?r:void 0}};function pe(i){let e={};for(let[t,r]of Object.entries(i))r!=null&&r!==""&&(e[t]=r);return Object.keys(e).length>0?e:void 0}var T=class{constructor(e,t,r){this.http=e;this.storeId=t;this.environment=r}async getPaymentSetup(e,t){if(t!=null&&t.paymentSetupConfig)return t.paymentSetupConfig;let r=this.readInjectedStepConfig();if(r)return r;let n=await this.http.get("/api/v1/payment-methods",{params:{checkoutSessionId:e}}),s={};for(let o of n.methods??[]){let a=o.provider?`${o.method}:${o.provider}`:o.method;s[a]=o}return s}async getExpressMethods(e,t){var s,o,a,u,m,h,l,g,d;let r=await this.getPaymentSetup(e,t),n={};for(let[p,c]of Object.entries(r)){if(!c.enabled)continue;if(p.startsWith("express_checkout:")&&c.methods){let P={available:!0,processorId:c.processorId,publishableKey:c.publishableKey,metadata:c.metadata};if((s=c.methods.apple_pay)!=null&&s.enabled){let ie=typeof window<"u"&&"ApplePaySession"in window&&((a=(o=window.ApplePaySession)==null?void 0:o.canMakePayments)==null?void 0:a.call(o));n.applePay={...P,type:"apple_pay",available:!!ie}}(u=c.methods.google_pay)!=null&&u.enabled&&(n.googlePay={...P,type:"google_pay"}),(m=c.methods.paypal)!=null&&m.enabled&&(n.paypal={...P,type:"paypal"}),(h=c.methods.link)!=null&&h.enabled&&(n.link={...P,type:"link"}),(l=c.methods.klarna_express)!=null&&l.enabled&&(n.klarna={...P,type:"klarna_express"});continue}if(!c.express)continue;let y=c.method,I={type:y,available:!0,processorId:c.processorId,publishableKey:c.publishableKey,metadata:c.metadata};if(y==="apple_pay"||c.type==="apple_pay"){let P=typeof window<"u"&&"ApplePaySession"in window&&((d=(g=window.ApplePaySession)==null?void 0:g.canMakePayments)==null?void 0:d.call(g));n.applePay={...I,available:!!P}}else y==="google_pay"||c.type==="google_pay"?n.googlePay=I:y==="paypal"?n.paypal=I:y==="klarna"||y==="klarna_express"?n.klarna=I:y==="link"&&(n.link=I)}return n}async getStoreConfig(){let e=await this.http.get("/api/v1/checkout/config",{params:{storeId:this.storeId}});return e.config??e}async getEnabledMethods(e,t){let r=await this.getPaymentSetup(e,t);return Object.entries(r).filter(([,n])=>n.enabled).map(([n])=>n)}async tokenizeCard(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let n={cardNumber:e.cardNumber,expiryDate:e.expiryDate,cvc:e.cvc};e.cardholderName&&(n.cardholderName=e.cardholderName);let s=await r.tokenizeCardRaw(n);return{tagadaToken:t.createTagadaToken(s,r.getProvider().getProviderName()),rawToken:s}}async createInstrument(e){return this.http.post("/api/v1/payment/create-instrument-from-token",{tagadaToken:e.tagadaToken})}async create3dsSession(e){return this.http.post("/api/public/v1/threeds/create-session",{provider:e.provider??"basis_theory",storeId:this.storeId,paymentInstrumentId:e.paymentInstrumentId,sessionData:e.sessionData})}async pay(e){return e.tagadaToken&&!e.paymentInstrumentId?this.http.post("/api/v1/payment/pay-with-token",{tagadaToken:e.tagadaToken,checkoutSessionId:e.checkoutSessionId,returnUrl:e.returnUrl,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,metadata:e.metadata}):this.http.post("/api/public/v1/checkout/pay-v2",{checkoutSessionId:e.checkoutSessionId,paymentInstrumentId:e.paymentInstrumentId,storeId:this.storeId,paymentFlowId:e.paymentFlowId,threedsSessionId:e.threedsSessionId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,metadata:e.metadata})}async payDirect(e){return this.http.post("/api/public/v1/checkout/pay-v2",{checkoutSessionId:e.checkoutSessionId,paymentInstrumentId:e.paymentInstrumentId??"",storeId:this.storeId,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:e.isExpress,threedsSessionId:e.threedsSessionId})}async processApplePay(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let{tagadaToken:n}=await r.tokenizeApplePay(e.applePayToken);return this.pay({checkoutSessionId:e.checkoutSessionId,tagadaToken:n,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:"apple_pay",isExpress:!0})}async processGooglePay(e){let t=await this.loadCoreJs(),r=new t.Tokenizer({environment:this.environment});await r.initialize();let{tagadaToken:n}=await r.tokenizeGooglePay(e.googlePayToken);return this.pay({checkoutSessionId:e.checkoutSessionId,tagadaToken:n,paymentFlowId:e.paymentFlowId,processorId:e.processorId,paymentMethod:"google_pay",isExpress:!0})}async processApm(e){return this.payDirect({checkoutSessionId:e.checkoutSessionId,paymentMethod:e.paymentMethod,processorId:e.processorId,paymentFlowId:e.paymentFlowId})}async processStripeExpress(e){return this.payDirect({checkoutSessionId:e.checkoutSessionId,processorId:e.processorId,paymentMethod:e.paymentMethod,isExpress:!0})}async processPayment(e){!e.returnUrl&&typeof window<"u"&&(e={...e,returnUrl:window.location.href});let t=await this.pay(e);return this.finalize(t,{returnUrl:e.returnUrl})}async finalize(e,t){var s,o;let r=e.payment,n=(t==null?void 0:t.returnUrl)??(typeof window<"u"?window.location.href:void 0);return r.status==="succeeded"?{status:"succeeded",payment:r,order:e.order}:r.status==="failed"||r.status==="declined"?{status:"failed",error:((s=r.requireActionData)==null?void 0:s.message)||((o=r.requireActionData)==null?void 0:o.errorCode)||`Payment ${r.status}`,payment:r}:r.requireAction&&r.requireAction!=="none"&&r.requireActionData?this.handlePaymentAction(r,{returnUrl:n}):this.pollUntilDone(r.id)}async resumeAfterRedirect(e){return this.pollUntilDone(e)}async maybeResumeFromUrl(e){if(typeof window>"u"&&!(e!=null&&e.url))return null;let t=(e==null?void 0:e.url)??window.location.href,r;try{r=new URL(t)}catch{return null}let n=r.searchParams.get("paymentAction"),s=r.searchParams.get("paymentActionStatus"),o=r.searchParams.get("paymentId");if(n!=="requireAction"||s!=="completed"||!o)return null;let a=await this.resumeAfterRedirect(o);if((e==null?void 0:e.cleanUrl)!==!1&&typeof window<"u"&&!(e!=null&&e.url)){let u=new URLSearchParams(window.location.search);["paymentAction","paymentActionStatus","paymentId","payment_intent","payment_intent_client_secret","source_type","redirect_status","sessionId"].forEach(h=>u.delete(h));let m=u.toString();try{window.history.replaceState({},document.title,window.location.pathname+(m?"?"+m:""))}catch{}}return a}async getPaymentStatus(e){return this.http.get(`/api/v1/payments/${e}`)}async pollPaymentStatus(e,t){let r=(t==null?void 0:t.intervalMs)??1500,n=(t==null?void 0:t.timeoutMs)??6e4,s=Date.now();for(;Date.now()-s<n;){let o=await this.getPaymentStatus(e);if(o.status==="succeeded"||o.status==="failed"||o.status==="declined")return o;await new Promise(a=>setTimeout(a,r))}throw new Error(`Payment ${e} did not reach terminal status within ${n}ms.`)}async completeAfter3ds(e){return this.http.post("/api/v1/payments/complete-after-3ds",{paymentId:e})}async markActionProcessed(e){try{await this.http.post("/api/v1/payments/require-action/processed",{paymentId:e})}catch{}}async handlePaymentAction(e,t){let r=e.requireActionData;switch(await this.markActionProcessed(e.id),r.type){case"threeds_auth":return this.handleThreedsAuth(e,t);case"processor_auth":case"redirect_to_payment":return this.extractRedirect(e,r);case"redirect":return this.extractRedirect(e,r);case"error":return{status:"failed",error:r.message||r.errorCode||"Payment failed",payment:e};default:return this.extractRedirect(e,r)}}extractRedirect(e,t){var s,o;let r=(s=t.metadata)==null?void 0:s.redirect,n=(r==null?void 0:r.redirectUrl)||t.redirectUrl;return n?{status:"requires_redirect",redirectUrl:n,method:((o=r==null?void 0:r.method)==null?void 0:o.toUpperCase())||"GET",postData:r==null?void 0:r.data,paymentId:e.id}:{status:"failed",error:`Payment requires action (${t.type}) but no redirect URL was provided`,payment:e}}async handleThreedsAuth(e,t){var s,o;let r=(o=(s=e.requireActionData)==null?void 0:s.metadata)==null?void 0:o.threedsSession;if(!(r!=null&&r.externalSessionId))return this.extractRedirect(e,e.requireActionData);let n;try{n=await import("@tagadapay/core-js")}catch{return r.acsChallengeUrl?{status:"requires_redirect",redirectUrl:r.acsChallengeUrl,paymentId:e.id}:this.extractRedirect(e,e.requireActionData)}try{let a=new n.ThreedsManager({provider:"basis_theory"});return await a.initialize({apiKey:void 0}),await a.startChallenge({sessionId:r.externalSessionId,acsChallengeUrl:r.acsChallengeUrl,acsTransactionId:r.acsTransID,threeDSVersion:r.messageVersion}),await this.completeAfter3ds(e.id),this.pollUntilDone(e.id)}catch{return r.acsChallengeUrl?{status:"requires_redirect",redirectUrl:r.acsChallengeUrl,paymentId:e.id}:{status:"failed",error:"3D Secure authentication failed",payment:e}}}async pollUntilDone(e,t){let r=(t==null?void 0:t.intervalMs)??1500,n=(t==null?void 0:t.timeoutMs)??6e4,s=Date.now(),o=0;for(;Date.now()-s<n;){let a;try{a=await this.getPaymentStatus(e),o=0}catch{if(o++,o>=3)return{status:"failed",error:"Payment verification failed due to network errors"};await new Promise(u=>setTimeout(u,r));continue}if(a.status==="succeeded"||a.status==="pending"&&a.subStatus==="authorized")return{status:"succeeded",payment:a,order:a.order};if(a.status==="failed"||a.status==="declined")return{status:"failed",error:a.status,payment:a};if(a.requireAction&&a.requireAction!=="none"&&a.requireActionData&&!a.requireActionData.processed)return this.handlePaymentAction(a,{});await new Promise(u=>setTimeout(u,r))}return{status:"pending",paymentId:e}}readInjectedStepConfig(){if(typeof window>"u")return null;let e=window.__TGD_STEP_CONFIG__;if(!e)return null;try{let t=typeof e=="string"?JSON.parse(e):e;return(t==null?void 0:t.paymentSetupConfig)??null}catch{return null}}async loadCoreJs(){try{return await import("@tagadapay/core-js")}catch{throw new Error("This method requires @tagadapay/core-js. Install it: npm install @tagadapay/core-js")}}};var L=class{constructor(e,t,r){this.http=e;this.storeId=t;this.payment=r}async getOffer(e){return this.http.get(`/api/v1/offers/${e}`)}async listOffers(e){var s;let t=`/api/v1/stores/${this.storeId}/offers`,r=[];if(e!=null&&e.type&&r.push(`type=${encodeURIComponent(e.type)}`),(s=e==null?void 0:e.ids)!=null&&s.length)for(let o of e.ids)r.push(`ids=${encodeURIComponent(o)}`);return r.length&&(t+=`?${r.join("&")}`),(await this.http.get(t)).offers??[]}async previewOffer(e){return this.http.post(`/api/v1/offers/${e.offerId}/preview`,{offerId:e.offerId,currency:e.currency??"",lineItems:e.lineItems})}async payPreviewedOffer(e){return this.http.post(`/api/v1/offers/${e.offerId}/pay-preview`,{offerId:e.offerId,currency:e.currency??"",lineItems:e.lineItems,returnUrl:e.returnUrl??(typeof window<"u"?window.location.href:""),mainOrderId:e.mainOrderId,paymentInstrumentId:e.paymentInstrumentId})}async processOfferPayment(e){if(!this.payment)throw new Error("OffersModule: no PaymentModule injected. Use createHeadlessClient() instead of constructing OffersModule directly.");let t=e.returnUrl??(typeof window<"u"?window.location.href:void 0),r=await this.payPreviewedOffer({...e,returnUrl:t});return this.payment.finalize({payment:r.payment,order:r.order},{returnUrl:t})}async toggleOrderBump(e){return this.http.post(`/api/v1/checkout-sessions/${e.checkoutSessionId}/toggle-order-bump`,{orderBumpOfferId:e.orderBumpOfferId,selected:e.selected})}async listPostPurchaseOffers(e){let t=await this.http.get(`/api/v1/post-purchase/${e}/offers`);return Array.isArray(t)?t:[]}async acceptPostPurchaseOffer(e){return this.http.post(`/api/v1/orders/${e.orderId}/post-purchase-offers/${e.offerId}/accept`,{items:e.items??[]})}async declinePostPurchaseOffer(e){return this.http.post(`/api/v1/orders/${e.orderId}/post-purchase-offers/${e.offerId}/decline`)}};var _=class{constructor(e,t){this.http=e;this.storeId=t}async getProfile(e){return(await this.http.get(`/api/v1/customers/${e}`,{params:{storeId:this.storeId}})).customer}async getByEmail(e){try{return(await this.http.get("/api/v1/customers/by-email",{params:{email:e,storeId:this.storeId}})).customer}catch{return null}}async updateProfile(e,t){return(await this.http.patch(`/api/v1/customers/${e}`,{storeId:this.storeId,...t})).customer}async getOrders(e,t){return this.http.get(`/api/v1/customers/${e}/orders`,{params:{storeId:this.storeId,limit:t==null?void 0:t.limit,offset:t==null?void 0:t.offset}})}async getOrder(e){return(await this.http.get(`/api/v1/orders/${e}`,{params:{storeId:this.storeId}})).order}async getSubscriptions(e){return(await this.http.get(`/api/v1/customers/${e}/subscriptions`,{params:{storeId:this.storeId}})).subscriptions}async getSubscription(e){return(await this.http.get(`/api/v1/subscriptions/${e}`,{params:{storeId:this.storeId}})).subscription}};var x=class{constructor(e,t){this.http=e;this.storeId=t}async getProducts(e){var n,s;let t={storeId:this.storeId,includeVariants:!0,includePrices:!0};return(n=e==null?void 0:e.productIds)!=null&&n.length&&(t.productIds=e.productIds),(s=e==null?void 0:e.variantIds)!=null&&s.length&&(t.variantIds=e.variantIds),(await this.http.post("/api/v1/products",t)).items??[]}async getProduct(e){return(await this.getProducts({productIds:[e]}))[0]??null}};var O=class{constructor(e,t,r,n){this.http=e;this.storeId=t;this.checkout=r;this.accountId=n}async navigate(e){var a;let t=this.checkout.getCurrentSession();if(!t)throw new f("No checkout session loaded. Call sdk.checkout.loadSession(...) before sdk.funnel.navigate(...).","no_cart_loaded");let r=e.accountId??this.accountId;if(!r)throw new f("accountId is required for funnel.navigate(). Set it on createHeadlessClient({ accountId }) or pass it per call.","missing_account_id");let n=e.currentUrl??(typeof globalThis<"u"?(a=globalThis.location)==null?void 0:a.href:void 0);await this.ensureCmsSession(t,r,e);let s=await this.initializeFunnel({funnelId:e.funnelId,stepId:e.stepId,accountId:r,currentUrl:n});return{url:await this.runNavigate({funnelSessionId:s,stepId:e.stepId,session:t,input:e,currentUrl:n}),funnelSessionId:s}}async ensureCmsSession(e,t,r){var o,a,u;if(this._cmsToken&&this._cmsSessionId&&this._cmsCustomerId)return;let n=await this.http.post("/api/v1/cms/session/anonymous",{storeId:this.storeId,role:"anonymous",draft:!1});this._cmsToken=n.token,this._cmsSessionId=n.sessionId;let s=await this.http.post("/api/v1/cms/session/v2/init",{storeId:this.storeId,accountId:t,customerId:"anon_placeholder",browserLocale:((o=r.customer)==null?void 0:o.locale)??ge(),userAgent:he(),queryCurrency:((a=r.customer)==null?void 0:a.currency)??e.currency,queryLocale:(u=r.customer)==null?void 0:u.locale},{token:this._cmsToken});this._cmsCustomerId=s.customer.id}async initializeFunnel(e){return(await this.http.post("/api/v1/funnel/initialize",{cmsSession:{customerId:this._cmsCustomerId,sessionId:this._cmsSessionId,storeId:this.storeId,accountId:e.accountId},funnelId:e.funnelId,entryStepId:e.stepId,funnelStepId:e.stepId,currentUrl:e.currentUrl,draft:!1},{token:this._cmsToken})).context.sessionId}async runNavigate(e){var l,g,d,p;let{funnelSessionId:t,stepId:r,session:n,input:s,currentUrl:o}=e,a=n.items.map(c=>({variantId:c.variantId,priceId:c.priceId,quantity:c.quantity})),u=s.discountCodes??(n.promotionCode?[n.promotionCode]:void 0),m={email:((l=s.customer)==null?void 0:l.email)??((g=n.customer)==null?void 0:g.email),currency:((d=s.customer)==null?void 0:d.currency)??n.currency,locale:(p=s.customer)==null?void 0:p.locale};return(await this.http.post("/api/v1/funnel/navigate",{sessionId:t,currentUrl:o,funnelStepId:r,fireAndForget:!1,event:{type:"INIT_CHECKOUT",data:{checkoutInit:{cartToken:n.id,lineItems:a,customer:m,returnUrl:s.returnUrl,storeId:this.storeId,metadata:s.metadata,discountCodes:u}}}},{token:this._cmsToken})).result.url}};function ge(){return typeof navigator<"u"&&navigator.language?navigator.language:"en-US"}function he(){return typeof navigator<"u"&&navigator.userAgent?navigator.userAgent:"tagadapay-headless-sdk"}var U=class{constructor(e){let t=e.environment??"production",r=k.resolveBaseUrl(t,e.baseUrl);this.config={...e,environment:t,baseUrl:r,timeout:e.timeout??3e4},this.http=new k({baseUrl:r,timeout:this.config.timeout,apiKey:e.apiKey,getToken:()=>this._sessionToken});let n=s=>{this._sessionToken=s};this.checkout=new b(this.http,this.config.storeId,n),this.payment=new T(this.http,this.config.storeId,t),this.offers=new L(this.http,this.config.storeId,this.payment),this.customer=new _(this.http,this.config.storeId),this.catalog=new x(this.http,this.config.storeId),this.funnel=new O(this.http,this.config.storeId,this.checkout,this.config.accountId)}setSessionToken(e){this._sessionToken=e}};function te(i){return new U(i)}var re=!1,ne=!1,j=[];function z(){ne=!0;for(let i of j)i();j.length=0}function J(i,e={}){var t,r;return ne||(r=(t=window.google)==null?void 0:t.maps)!=null&&r.places?(z(),Promise.resolve()):re?new Promise(n=>j.push(n)):(re=!0,new Promise((n,s)=>{if(j.push(n),document.querySelector('script[src*="maps.googleapis.com"]')){let m=()=>{var h,l;(l=(h=window.google)==null?void 0:h.maps)!=null&&l.places?z():setTimeout(m,100)};m();return}let a=new URLSearchParams({key:i,libraries:"places",v:e.version??"weekly"});e.language&&a.set("language",e.language),e.region&&a.set("region",e.region);let u=document.createElement("script");u.src=`https://maps.googleapis.com/maps/api/js?${a}`,u.async=!0,u.defer=!0,u.onload=()=>z(),u.onerror=()=>s(new Error("Failed to load Google Maps script")),document.head.appendChild(u)}))}var E=class i{static async searchPlaces(e,t={}){var n,s;if(!((s=(n=window.google)==null?void 0:n.maps)!=null&&s.places)||!e.trim())return[];let r=new window.google.maps.places.AutocompleteService;return new Promise(o=>{r.getPlacePredictions({input:e,types:t.types??["address"],componentRestrictions:t.componentRestrictions},(a,u)=>{var m,h,l;o(u===((l=(h=(m=window.google)==null?void 0:m.maps)==null?void 0:h.places)==null?void 0:l.PlacesServiceStatus.OK)&&a?a:[])})})}static async getPlaceDetails(e){var r,n;if(!((n=(r=window.google)==null?void 0:r.maps)!=null&&n.places))return null;let t=new window.google.maps.places.PlacesService(document.createElement("div"));return new Promise(s=>{t.getDetails({placeId:e,fields:["place_id","formatted_address","address_components","geometry"]},(o,a)=>{var u,m,h;s(a===((h=(m=(u=window.google)==null?void 0:u.maps)==null?void 0:m.places)==null?void 0:h.PlacesServiceStatus.OK)&&o?o:null)})})}static extractAddressComponents(e){let t={subpremise:"",streetNumber:"",route:"",locality:"",administrativeAreaLevel1:"",administrativeAreaLevel1Long:"",administrativeAreaLevel2:"",administrativeAreaLevel2Long:"",country:"",postalCode:"",fullStreetAddress:""},r="",n="",s="",o="",a="",u="",m="",h="";for(let d of e.address_components??[]){let p=d.types;p.includes("subpremise")&&(t.subpremise=d.long_name),p.includes("street_number")&&(t.streetNumber=d.long_name),p.includes("premise")&&(r=d.long_name),p.includes("route")&&(t.route=d.long_name),p.includes("neighborhood")&&(n=d.long_name),p.includes("sublocality_level_5")&&(s=d.long_name),p.includes("sublocality_level_4")&&(o=d.long_name),p.includes("sublocality_level_3")&&(a=d.long_name),p.includes("sublocality_level_2")&&(u=d.long_name),p.includes("sublocality_level_1")&&(m=d.long_name),p.includes("locality")&&(t.locality=d.long_name),p.includes("postal_town")&&(h=d.long_name),p.includes("administrative_area_level_2")&&(t.administrativeAreaLevel2=d.short_name,t.administrativeAreaLevel2Long=d.long_name),p.includes("administrative_area_level_1")&&(t.administrativeAreaLevel1=d.short_name,t.administrativeAreaLevel1Long=d.long_name),p.includes("country")&&(t.country=d.short_name),p.includes("postal_code")&&(t.postalCode=d.long_name)}t.locality||(t.locality=h||u||m||""),!t.administrativeAreaLevel1&&t.administrativeAreaLevel2&&(t.administrativeAreaLevel1=t.administrativeAreaLevel2Long||t.administrativeAreaLevel2,t.administrativeAreaLevel1Long=t.administrativeAreaLevel2Long);let l=t.streetNumber||r,g=t.route||s||o||a||n;if(t.subpremise&&l&&g)t.fullStreetAddress=`${t.subpremise}/${l} ${g}`;else if(l&&g)if(r&&o&&a){let d=`${a}-${o}-${r}`;u&&(d=`${d} ${u}`),t.fullStreetAddress=d}else t.fullStreetAddress=`${l} ${g}`;else g?t.fullStreetAddress=g:l&&(t.fullStreetAddress=l);return t.fullStreetAddress=t.fullStreetAddress.trim(),t}static extractFormattedAddress(e){let t=i.extractAddressComponents(e);return{address1:t.fullStreetAddress,city:t.locality,country:t.country,state:t.administrativeAreaLevel1,postal:t.postalCode}}};var se="https://cvwnizdbugpz6jwk.public.blob.vercel-storage.com/geodata/v1",M=["en","ru","de","da","fr","es","zh","hi","pt","ja","ar","it","he"],D=new Map,B=new Map,V=new Map,Y=new Map;async function ye(i){let e=D.get(i);if(e)return e;let t=V.get(i);return t||(t=(async()=>{let r=`${se}/${i}/countries.json`,n=await fetch(r);if(!n.ok)throw new Error(`Geodata fetch failed: ${r} (${n.status})`);let s=await n.json();return D.set(i,s),V.delete(i),s})(),V.set(i,t),t)}async function fe(i){let e=B.get(i);if(e)return e;let t=Y.get(i);return t||(t=(async()=>{let r=`${se}/${i}/regions.json`,n=await fetch(r);if(!n.ok)throw new Error(`Geodata fetch failed: ${r} (${n.status})`);let s=await n.json();return B.set(i,s),Y.delete(i),s})(),Y.set(i,t),t)}function Ie(i){return D.get(i)||D.get("en")||{}}function Pe(i){return B.get(i)||B.get("en")||{}}async function $(i="en"){await Promise.all([ye(i),fe(i)])}var N=(i="en")=>{let e=Ie(i);return Object.entries(e).map(([t,r])=>({code:t,name:r.n,iso3:r.i3,numeric:r.nu})).sort((t,r)=>t.name.localeCompare(r.name))},F=(i,e="en")=>{let r=Pe(e)[i];return r?r.map(([n,s])=>({code:n,name:s,countryCode:i})).sort((n,s)=>n.name.localeCompare(s.name)):[]};function q(i){return D.has(i)}var H=class i{static ensureLoaded(e="en"){return $(e)}static getCountries(e="en"){let t=N(e),r={};for(let n of t)r[n.code]={iso:n.code,iso3:n.iso3??"",numeric:n.numeric??0,name:n.name};return r}static getCountryOptions(e="en"){return N(e).map(t=>({value:t.code,label:t.name}))}static getRegions(e,t="en"){return F(e,t).map(r=>({iso:r.code,name:r.name}))}static getRegionOptions(e,t="en"){return i.getRegions(e,t).map(r=>({value:r.iso,label:r.name}))}static findRegion(e,t,r="en"){return i.getRegions(e,r).find(n=>n.iso===t)??null}static mapGoogleToISO(e,t,r,n="en"){let s=i.getRegions(r,n);if(s.length===0)return null;let o=s.find(a=>a.iso===e);return o||(o=s.find(a=>a.name.toLowerCase()===e.toLowerCase()),o)||(o=s.find(a=>a.name.toLowerCase()===t.toLowerCase()),o)?o:(o=s.find(a=>a.name.toLowerCase().includes(t.toLowerCase())||t.toLowerCase().includes(a.name.toLowerCase())),o??null)}static isLanguageLoaded(e){return q(e)}static getAvailableLanguages(){return M}};var we={USD:"$",EUR:"\u20AC",GBP:"\xA3",JPY:"\xA5",CAD:"C$",AUD:"A$",CHF:"CHF",CNY:"\xA5",SEK:"kr",NOK:"kr",DKK:"kr",PLN:"z\u0142",CZK:"K\u010D",HUF:"Ft",RON:"lei",BGN:"\u043B\u0432",HRK:"kn",RUB:"\u20BD",UAH:"\u20B4",TRY:"\u20BA",BRL:"R$",MXN:"$",ZAR:"R",INR:"\u20B9",KRW:"\u20A9",THB:"\u0E3F",VND:"\u20AB",IDR:"Rp",MYR:"RM",SGD:"S$",PHP:"\u20B1",TWD:"NT$",HKD:"HK$",ILS:"\u20AA",AED:"\u062F.\u0625",SAR:"\u0631.\u0633",QAR:"\u0631.\u0642",KWD:"\u062F.\u0643",BHD:"\u062F.\u0628",OMR:"\u0631.\u0639.",EGP:"\xA3",NGN:"\u20A6",KES:"KSh",GHS:"\u20B5",COP:"$",ARS:"$",CLP:"$",PEN:"S/",CRC:"\u20A1",DOP:"RD$",JMD:"J$",BOB:"Bs",PYG:"\u20B2",GTQ:"Q",NIO:"C$",PAB:"B/.",PKR:"\u20A8",BDT:"\u09F3",LKR:"\u20A8",NPR:"\u20A8",GEL:"\u20BE",AMD:"\u058F",AZN:"\u20BC",KZT:"\u20B8"},ke={USD:"US Dollar",EUR:"Euro",GBP:"British Pound",JPY:"Japanese Yen",CAD:"Canadian Dollar",AUD:"Australian Dollar",CHF:"Swiss Franc",CNY:"Chinese Yuan",SEK:"Swedish Krona",NOK:"Norwegian Krone",DKK:"Danish Krone",PLN:"Polish Zloty",CZK:"Czech Koruna",HUF:"Hungarian Forint",BRL:"Brazilian Real",MXN:"Mexican Peso",INR:"Indian Rupee",KRW:"South Korean Won",THB:"Thai Baht",SGD:"Singapore Dollar",HKD:"Hong Kong Dollar",TWD:"Taiwan Dollar",ILS:"Israeli Shekel",AED:"UAE Dirham",SAR:"Saudi Riyal",ZAR:"South African Rand",TRY:"Turkish Lira",RUB:"Russian Ruble",NGN:"Nigerian Naira"},ve=new Set(["JPY","KRW","VND","IDR","LAK","KHR","MMK","PYG"]),v=class i{static getSymbol(e){return we[e]??e}static getName(e){return ke[e]??e}static getDecimalPlaces(e){return ve.has(e)?0:2}static getCurrency(e){return{code:e,symbol:i.getSymbol(e),name:i.getName(e),decimalPlaces:i.getDecimalPlaces(e)}}};function W(i,e="USD",t="en-US"){let r=v.getDecimalPlaces(e),n=i/(r===0?100:Math.pow(10,r));try{return new Intl.NumberFormat(t,{style:"currency",currency:e,minimumFractionDigits:r,maximumFractionDigits:r}).format(n)}catch{return`${v.getSymbol(e)}${n.toFixed(r)}`}}return me(Se);})();
7
7
  if(typeof window!=="undefined"&&TagadaHeadlessBundle){ window.TagadaHeadless=TagadaHeadlessBundle; window.TagadaHeadless.create=TagadaHeadlessBundle.createHeadlessClient;}
8
8
  //# sourceMappingURL=tagada-headless.min.js.map