@occluze/tether 0.9.3 → 0.9.5

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 (71) hide show
  1. package/README.md +1 -1
  2. package/dist/esm/astro.js +1 -1
  3. package/dist/esm/chunks/account-3CDDXYNB.js +1 -0
  4. package/dist/esm/chunks/{account-pages-OZHK5HHY.js → account-pages-OWJGEQ4R.js} +1 -1
  5. package/dist/esm/chunks/{analytics-QHX2YHZS.js → analytics-HOGB5FTF.js} +1 -1
  6. package/dist/esm/chunks/{chunk-NF5H2Q7V.js → chunk-646NGAEM.js} +1 -1
  7. package/dist/esm/chunks/chunk-7BUJ3442.js +1 -0
  8. package/dist/esm/chunks/{chunk-ZB4FBE6W.js → chunk-DO7NXPVP.js} +1 -1
  9. package/dist/esm/chunks/{chunk-SOLTIZAI.js → chunk-F3OXGENC.js} +1 -1
  10. package/dist/esm/chunks/{chunk-A3GZFAB3.js → chunk-FRJ3O7I3.js} +1 -1
  11. package/dist/esm/chunks/{chunk-WHNUPECA.js → chunk-GZIUGZVZ.js} +1 -1
  12. package/dist/esm/chunks/{chunk-74SGIWQE.js → chunk-HMSUZ3KF.js} +1 -1
  13. package/dist/esm/chunks/chunk-P2CFLEGO.js +1 -0
  14. package/dist/esm/chunks/chunk-RBXZXOSD.js +1 -0
  15. package/dist/esm/chunks/{chunk-GCGRUVYO.js → chunk-RGDDFRKU.js} +1 -1
  16. package/dist/esm/chunks/{chunk-LSB7RVRZ.js → chunk-RULKN77R.js} +1 -1
  17. package/dist/esm/chunks/chunk-SKYDS3DT.js +1 -0
  18. package/dist/esm/chunks/chunk-TMPLGTXB.js +1 -0
  19. package/dist/esm/chunks/{chunk-RVWHBZAF.js → chunk-YLQXC6QC.js} +1 -1
  20. package/dist/esm/chunks/chunk-YW3ZIFWB.js +1 -0
  21. package/dist/esm/chunks/chunk-YYWS6QKJ.js +1 -0
  22. package/dist/esm/chunks/{diagnose-O3QCZTHT.js → diagnose-ULHFOMN5.js} +1 -1
  23. package/dist/esm/chunks/extras-FTL2WPUG.js +1 -0
  24. package/dist/esm/chunks/lists-OFICUJ4T.js +1 -0
  25. package/dist/esm/chunks/{markets-ui-V2ROBFZP.js → markets-ui-CZ6DAHEE.js} +1 -1
  26. package/dist/esm/chunks/search-U2KQ54KS.js +1 -0
  27. package/dist/esm/index.js +1 -1
  28. package/dist/esm/server.js +1 -1
  29. package/dist/tether.account-pages.js +1 -1
  30. package/dist/tether.account-pages.min.js +1 -1
  31. package/dist/tether.account.js +16 -13
  32. package/dist/tether.account.min.js +1 -1
  33. package/dist/tether.analytics.js +1 -1
  34. package/dist/tether.analytics.min.js +1 -1
  35. package/dist/tether.diagnose.js +1 -1
  36. package/dist/tether.diagnose.min.js +1 -1
  37. package/dist/tether.extras.js +32 -10
  38. package/dist/tether.extras.min.js +1 -1
  39. package/dist/tether.js +165 -88
  40. package/dist/tether.lists.js +1 -1
  41. package/dist/tether.lists.min.js +1 -1
  42. package/dist/tether.markets.js +1 -1
  43. package/dist/tether.markets.min.js +1 -1
  44. package/dist/tether.min.js +1 -1
  45. package/dist/tether.min.js.map +4 -4
  46. package/dist/tether.search.js +56 -17
  47. package/dist/tether.search.min.js +1 -1
  48. package/dist/types/src/account/server-client.d.ts +2 -1
  49. package/dist/types/src/analytics-queue.d.ts +9 -0
  50. package/dist/types/src/cart/checkout.d.ts +2 -2
  51. package/dist/types/src/cart/drawer.d.ts +9 -4
  52. package/dist/types/src/cart/store.d.ts +2 -0
  53. package/dist/types/src/cart.d.ts +1 -1
  54. package/dist/types/src/client.d.ts +6 -0
  55. package/dist/types/src/dom.d.ts +14 -1
  56. package/dist/types/src/extras.d.ts +2 -0
  57. package/dist/types/src/index.d.ts +1 -1
  58. package/dist/types/src/search.d.ts +1 -1
  59. package/dist/types/src/version.d.ts +1 -1
  60. package/package.json +1 -1
  61. package/dist/esm/chunks/account-3MYRPPTR.js +0 -1
  62. package/dist/esm/chunks/chunk-24KD36UC.js +0 -1
  63. package/dist/esm/chunks/chunk-2G6U6ZYV.js +0 -1
  64. package/dist/esm/chunks/chunk-A6BZFYZY.js +0 -1
  65. package/dist/esm/chunks/chunk-EYG7QGPA.js +0 -1
  66. package/dist/esm/chunks/chunk-FX7EJ6RB.js +0 -1
  67. package/dist/esm/chunks/chunk-PZERNTCD.js +0 -1
  68. package/dist/esm/chunks/chunk-SJNNEEDX.js +0 -1
  69. package/dist/esm/chunks/extras-O6ZRL5FK.js +0 -1
  70. package/dist/esm/chunks/lists-XF33XENI.js +0 -1
  71. package/dist/esm/chunks/search-ZLKIFARH.js +0 -1
package/dist/tether.js CHANGED
@@ -313,22 +313,29 @@
313
313
  debug: false
314
314
  };
315
315
  var cfg = { ...DEFAULTS };
316
+ function refuseChange(key) {
317
+ warn(`Tether.config is read-only (${String(key)}): pass options to Tether.init() instead`);
318
+ return false;
319
+ }
320
+ var readOnlyViews = /* @__PURE__ */ new WeakMap();
321
+ var READ_ONLY = {
322
+ get(object, key) {
323
+ const value = Reflect.get(object, key);
324
+ return typeof value === "object" && value !== null ? readOnlyView(value) : value;
325
+ },
326
+ set: (_object, key) => refuseChange(key),
327
+ deleteProperty: (_object, key) => refuseChange(key),
328
+ defineProperty: (_object, key) => refuseChange(key)
329
+ };
316
330
  function readOnlyView(target) {
317
- const refuse = (key) => {
318
- warn(`Tether.config is read-only (${String(key)}): pass options to Tether.init() instead`);
319
- return false;
320
- };
321
- return new Proxy(target, {
322
- get(object, key) {
323
- const value = Reflect.get(object, key);
324
- return typeof value === "object" && value !== null ? readOnlyView(value) : value;
325
- },
326
- set: (_object, key) => refuse(key),
327
- deleteProperty: (_object, key) => refuse(key),
328
- defineProperty: (_object, key) => refuse(key)
329
- });
331
+ let view = readOnlyViews.get(target);
332
+ if (!view) {
333
+ view = new Proxy(target, READ_ONLY);
334
+ readOnlyViews.set(target, view);
335
+ }
336
+ return view;
330
337
  }
331
- var configView = readOnlyView(cfg);
338
+ var configView = new Proxy(cfg, READ_ONLY);
332
339
  var PREFIX = /^[a-z][a-z0-9-]*$/;
333
340
  var SWITCH_OPTIONS = [
334
341
  "revalidate",
@@ -1168,13 +1175,36 @@
1168
1175
  }
1169
1176
  el.style.display = "none";
1170
1177
  }
1178
+ var CHECKABLE = 'input[type="radio"],input[type="checkbox"]';
1179
+ var CHECKED_ROLES = ["radio", "checkbox", "switch", "menuitemradio", "menuitemcheckbox"];
1180
+ var BUTTON_INPUTS = ["button", "submit", "reset"];
1181
+ function chosenState(el) {
1182
+ const role = el.getAttribute("role");
1183
+ if (role === "button") return "aria-pressed";
1184
+ if (role && CHECKED_ROLES.includes(role)) return "aria-checked";
1185
+ if (role === "option" || role === "tab") return "aria-selected";
1186
+ if (role) return null;
1187
+ if (isInput(el)) return BUTTON_INPUTS.includes(el.type) ? "aria-pressed" : null;
1188
+ return el.querySelector(CHECKABLE) ? null : "aria-pressed";
1189
+ }
1171
1190
  function setSelected(el, selected) {
1172
1191
  el.classList.toggle("is-selected", selected);
1173
- el.setAttribute("aria-pressed", selected ? "true" : "false");
1174
- if (isInput(el) && (el.type === "radio" || el.type === "checkbox")) el.checked = selected;
1175
- const input = el.querySelector('input[type="radio"],input[type="checkbox"]');
1192
+ const state = chosenState(el);
1193
+ if (state === "aria-pressed" && el.tagName !== "BUTTON" && !isInput(el)) {
1194
+ el.setAttribute("role", "button");
1195
+ if (!el.hasAttribute("tabindex")) el.setAttribute("tabindex", "0");
1196
+ }
1197
+ if (state) el.setAttribute(state, String(selected));
1198
+ if (isInput(el) && el.matches(CHECKABLE)) el.checked = selected;
1199
+ const input = el.querySelector(CHECKABLE);
1176
1200
  if (input && isInput(input)) input.checked = selected;
1177
1201
  }
1202
+ function setUnavailable(el, unavailable) {
1203
+ el.classList.toggle("is-unavailable", unavailable);
1204
+ const isControl = chosenState(el) !== null || isInput(el);
1205
+ const control = isControl ? el : el.querySelector(CHECKABLE);
1206
+ control?.setAttribute("aria-disabled", String(unavailable));
1207
+ }
1178
1208
  var layoutTimer;
1179
1209
  var pageGlobal = (name) => Reflect.get(window, name);
1180
1210
  function refreshScrollTrigger() {
@@ -1475,28 +1505,43 @@
1475
1505
  var FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
1476
1506
  var FOCUS_AFTER_OPEN_MS = 60;
1477
1507
  var openWithoutDrawer = false;
1508
+ var announcedOpen = false;
1478
1509
  var returnFocus = null;
1510
+ var classWatcher = null;
1479
1511
  var isFocusable = (el) => el !== null && "focus" in el;
1480
1512
  var focusables = (drawer) => qsa(drawer, FOCUSABLE).filter((el) => el.offsetParent !== null || el === document.activeElement);
1481
1513
  var drawers = () => qsa(document, sel("cart-drawer"));
1482
1514
  var isOpenDrawer = (drawer) => drawer.classList.contains(cfg.cartDrawerOpenClass);
1515
+ var hasFocusInside = (all) => all.some((drawer) => drawer.contains(document.activeElement));
1516
+ var isManual = (drawer) => get(drawer, "cart-drawer") === "manual";
1483
1517
  function isOpen() {
1484
1518
  const all = drawers();
1485
1519
  return all.length ? all.some(isOpenDrawer) : openWithoutDrawer;
1486
1520
  }
1487
- function syncDrawerAria(open) {
1521
+ function watchOpenClass(drawer) {
1522
+ classWatcher ?? (classWatcher = new MutationObserver(() => {
1523
+ const open = isOpen();
1524
+ if (open === announcedOpen) return;
1525
+ const all = drawers();
1526
+ if (open) announceOpen(all.filter(isOpenDrawer));
1527
+ else announceClosed(all, hasFocusInside(all));
1528
+ }));
1529
+ classWatcher.observe(drawer, { attributes: true, attributeFilter: ["class"] });
1530
+ }
1531
+ function syncDrawerAria() {
1488
1532
  qsa(document, sel("cart-open")).forEach((button) => {
1489
- button.setAttribute("aria-expanded", String(open));
1533
+ button.setAttribute("aria-expanded", String(isOpen()));
1490
1534
  });
1491
1535
  drawers().forEach((drawer) => {
1492
1536
  if (!drawer.hasAttribute("role")) drawer.setAttribute("role", "dialog");
1493
1537
  if (!drawer.hasAttribute("aria-label") && !drawer.hasAttribute("aria-labelledby")) {
1494
1538
  drawer.setAttribute("aria-label", get(drawer, "cart-label") || "Cart");
1495
1539
  }
1540
+ const open = isOpenDrawer(drawer);
1496
1541
  drawer.setAttribute("aria-modal", String(open));
1497
- if (isOpenDrawer(drawer)) return;
1498
- drawer.setAttribute("aria-hidden", "true");
1499
- if (cfg.cartFocus) drawer.inert = true;
1542
+ drawer.setAttribute("aria-hidden", String(!open));
1543
+ drawer.inert = !open;
1544
+ watchOpenClass(drawer);
1500
1545
  });
1501
1546
  }
1502
1547
  function focusInto(drawer) {
@@ -1504,16 +1549,9 @@
1504
1549
  if (target === drawer && !drawer.hasAttribute("tabindex")) drawer.tabIndex = -1;
1505
1550
  target.focus({ preventScroll: true });
1506
1551
  }
1507
- function openCart() {
1508
- if (isOpen()) return;
1509
- openWithoutDrawer = true;
1510
- const opened = drawers().filter((drawer) => get(drawer, "cart-drawer") !== "manual");
1511
- opened.forEach((drawer) => {
1512
- drawer.inert = false;
1513
- drawer.classList.add(cfg.cartDrawerOpenClass);
1514
- drawer.setAttribute("aria-hidden", "false");
1515
- });
1516
- syncDrawerAria(true);
1552
+ function announceOpen(opened) {
1553
+ announcedOpen = true;
1554
+ syncDrawerAria();
1517
1555
  const [first] = opened;
1518
1556
  if (cfg.cartFocus && first) {
1519
1557
  returnFocus = isFocusable(document.activeElement) ? document.activeElement : null;
@@ -1524,21 +1562,34 @@
1524
1562
  cfg.onCartOpen?.(opened);
1525
1563
  emit("cart-toggled", { open: true });
1526
1564
  }
1565
+ function announceClosed(all, hadFocus) {
1566
+ announcedOpen = false;
1567
+ syncDrawerAria();
1568
+ if (hadFocus && returnFocus?.isConnected) returnFocus.focus({ preventScroll: true });
1569
+ returnFocus = null;
1570
+ cfg.onCartClose?.(all);
1571
+ emit("cart-toggled", { open: false });
1572
+ }
1573
+ function openCart() {
1574
+ if (isOpen()) return;
1575
+ const all = drawers();
1576
+ const opened = all.filter((drawer) => !isManual(drawer));
1577
+ if (all.length && !opened.length) return;
1578
+ openWithoutDrawer = true;
1579
+ opened.forEach((drawer) => {
1580
+ drawer.classList.add(cfg.cartDrawerOpenClass);
1581
+ });
1582
+ announceOpen(opened);
1583
+ }
1527
1584
  function closeCart() {
1528
1585
  if (!isOpen()) return;
1529
1586
  openWithoutDrawer = false;
1530
1587
  const all = drawers();
1531
- const hadFocus = all.some((drawer) => drawer.contains(document.activeElement));
1588
+ const hadFocus = hasFocusInside(all);
1532
1589
  all.forEach((drawer) => {
1533
1590
  drawer.classList.remove(cfg.cartDrawerOpenClass);
1534
- drawer.setAttribute("aria-hidden", "true");
1535
- if (cfg.cartFocus) drawer.inert = true;
1536
1591
  });
1537
- syncDrawerAria(false);
1538
- if (hadFocus && returnFocus?.isConnected) returnFocus.focus({ preventScroll: true });
1539
- returnFocus = null;
1540
- cfg.onCartClose?.(all);
1541
- emit("cart-toggled", { open: false });
1592
+ announceClosed(all, hadFocus);
1542
1593
  }
1543
1594
  function toggleCart() {
1544
1595
  if (isOpen()) closeCart();
@@ -2010,7 +2061,7 @@
2010
2061
  function renderCart(view) {
2011
2062
  const { cart } = view;
2012
2063
  const money = (key) => cart ? formatMoney2(cart.cost[key]) : "";
2013
- syncDrawerAria(isOpen());
2064
+ syncDrawerAria();
2014
2065
  qsa(document, sel("cart-count")).forEach((el) => {
2015
2066
  setTextTracked(el, cart?.totalQuantity ?? 0);
2016
2067
  });
@@ -2323,14 +2374,22 @@
2323
2374
  } catch {
2324
2375
  }
2325
2376
  }
2326
- async function checkout(target = cfg.checkoutTarget) {
2327
- const cartId = savedCartId();
2377
+ function cartToCheckOut() {
2328
2378
  const cart = currentCart();
2329
- if (!cartId || cart && !cart.totalQuantity) return null;
2379
+ return cart && !cart.totalQuantity ? null : savedCartId();
2380
+ }
2381
+ async function checkout(target = cfg.checkoutTarget) {
2382
+ if (!cartToCheckOut()) return null;
2330
2383
  const tab = target === "_blank" ? window.open("", "_blank") : null;
2331
2384
  if (tab) detachOpenerIfAllowed(tab);
2332
2385
  try {
2333
- const url2 = await checkoutUrl(cartId);
2386
+ await runInOrder(() => Promise.resolve());
2387
+ const cartId = cartToCheckOut();
2388
+ const url2 = cartId && await checkoutUrl(cartId);
2389
+ if (!url2) {
2390
+ tab?.close();
2391
+ return null;
2392
+ }
2334
2393
  if (!isHttpsUrl(url2)) throw new TetherError("The checkout URL is not https: not opened");
2335
2394
  emit("checkout", { url: url2, cart: currentCart() });
2336
2395
  if (tab && !tab.closed) tab.location.href = url2;
@@ -2573,7 +2632,8 @@
2573
2632
  *
2574
2633
  * @throws {TetherError} `INVALID_DISCOUNT` (rejected) when Shopify doesn't accept the code.
2575
2634
  */
2576
- async applyDiscount(code) {
2635
+ async applyDiscount(typed) {
2636
+ const code = typed.trim();
2577
2637
  const cart = await Cart.setDiscountCodes((current) => [.../* @__PURE__ */ new Set([...current, code])]);
2578
2638
  const wanted = code.toLowerCase();
2579
2639
  const applied = (cart?.discountCodes ?? []).find((discount) => discount.code.toLowerCase() === wanted);
@@ -2586,7 +2646,7 @@
2586
2646
  throw new TetherError(`Discount code not valid: ${code}`, { code: "INVALID_DISCOUNT" });
2587
2647
  },
2588
2648
  removeDiscount(code) {
2589
- const unwanted = code.toLowerCase();
2649
+ const unwanted = code.trim().toLowerCase();
2590
2650
  return Cart.setDiscountCodes((current) => current.filter((existing) => existing.toLowerCase() !== unwanted));
2591
2651
  },
2592
2652
  /**
@@ -2844,7 +2904,7 @@
2844
2904
  const value = get(node, "option-value") ?? "";
2845
2905
  setSelected(node, view.selected[name] === value);
2846
2906
  const unavailable = !isValueAvailable(product, view.selected, name, value);
2847
- node.classList.toggle("is-unavailable", unavailable);
2907
+ setUnavailable(node, unavailable);
2848
2908
  node.setAttribute("data-unavailable", unavailable ? "true" : "false");
2849
2909
  });
2850
2910
  });
@@ -2864,13 +2924,12 @@
2864
2924
  }
2865
2925
  const mode = get(el, "purchase");
2866
2926
  setSelected(el, mode === purchase.kind);
2867
- const unavailable = mode === "subscription" ? !view.subscriptionAvailable : scope.product.requiresSellingPlan;
2868
- el.classList.toggle("is-unavailable", unavailable);
2927
+ setUnavailable(el, mode === "subscription" ? !view.subscriptionAvailable : scope.product.requiresSellingPlan);
2869
2928
  });
2870
2929
  scope.$(sel("plan-value")).forEach((node) => {
2871
2930
  const planId = get(node, "plan-value") ?? "";
2872
2931
  setSelected(node, line.kind === "subscription" && planId === line.planId);
2873
- node.classList.toggle("is-unavailable", !allocationFor(variant, planId));
2932
+ setUnavailable(node, !allocationFor(variant, planId));
2874
2933
  const plan = scope.plans.find((candidate) => candidate.id === planId);
2875
2934
  const texts = planBindTexts(variant, planId, plan, FORMAT);
2876
2935
  qsa(node, sel("plan-bind")).forEach((el) => {
@@ -2990,6 +3049,14 @@
2990
3049
  onAddClick(scope, add);
2991
3050
  }
2992
3051
  }
3052
+ function onKeydown(event, target) {
3053
+ const { key } = event;
3054
+ const presses = key === " " || key === "Enter" && !target.matches("a[href]");
3055
+ const pressable = `:is(${sel("option-value")},${sel("plan-value")},${sel("purchase")})[role=button]:not(button,input)`;
3056
+ if (!presses || event.defaultPrevented || !target.matches(pressable)) return;
3057
+ event.preventDefault();
3058
+ target.click();
3059
+ }
2993
3060
  var purchaseKind = (value) => value === "subscription" ? "subscription" : "one-time";
2994
3061
  function onChange(scope, target) {
2995
3062
  const value = isField(target) ? target.value : "";
@@ -3010,6 +3077,9 @@
3010
3077
  scope.root.addEventListener("click", (event) => {
3011
3078
  if (isElement(event.target)) onClick(scope, event, event.target);
3012
3079
  });
3080
+ scope.root.addEventListener("keydown", (event) => {
3081
+ if (event.target instanceof window.HTMLElement) onKeydown(event, event.target);
3082
+ });
3013
3083
  scope.root.addEventListener("change", (event) => {
3014
3084
  const { target } = event;
3015
3085
  if (isElement(target) && target.closest(productSelector()) === scope.root) onChange(scope, target);
@@ -3264,7 +3334,12 @@
3264
3334
  function applyPageTitle(el, product) {
3265
3335
  const template = get(el, "page-title");
3266
3336
  if (!template || typeof document === "undefined") return;
3267
- document.title = template.replace(/\{title\}/g, product.title).replace(/\{vendor\}/g, product.vendor || "").replace(/\{type\}/g, product.productType || "");
3337
+ const fields = /* @__PURE__ */ new Map([
3338
+ ["title", product.title],
3339
+ ["vendor", product.vendor || ""],
3340
+ ["type", product.productType || ""]
3341
+ ]);
3342
+ document.title = template.replace(/\{(\w+)\}/g, (placeholder, name) => fields.get(name) ?? placeholder);
3268
3343
  }
3269
3344
  function mountWithoutKey(el, { fromUrl, raw }) {
3270
3345
  if (fromUrl) {
@@ -3481,7 +3556,7 @@
3481
3556
  }
3482
3557
 
3483
3558
  // src/part-integrity.ts
3484
- var PART_INTEGRITY = { "tether.diagnose.js": "sha384-V4pclvaqH/qR/arn2rEkiL09rESoS1Z5AEE01ZSaFNlDU+sXXpOhKprwno6MT998", "tether.markets.js": "sha384-5wg1XGIKHX3Q4SX9E1xoYiJT653F0uCs7WCJ36Rf+YX6o1VJhuK6m59ZuUuqgxXw", "tether.search.js": "sha384-KMmZKdaQq6+LzU7kFva2DYZ7dh425RhHClXfVPHp8dNDGn1eG2UEMuPooowJOQtt", "tether.lists.js": "sha384-L/+3bMN1EifET4EcFWBk5IAFywRaC0uilAX3eYLeGqmX9zkPFjS/SvVSklpRwSSA", "tether.extras.js": "sha384-/SMjz6qCFAOV0wwvEVNhQxtT/1pyx4hRxDJHOxHB6M3uclAvItSULKZqJvaehH+i", "tether.account.js": "sha384-CVXd+K/5Wc9mSdfMM6cE1BYN4kjFWCXpEfoLq/jU0zy1C+V4SXfyTCyXloVFMMs7", "tether.account-pages.js": "sha384-bUUsp/0dKGSGzjctzF1FgLcCvgBGh+wQw95IhbjU+ckMo78vzetzlI2+QuNQugaI", "tether.analytics.js": "sha384-DBXy5gOU7crMr0xSS4TjnZN1Q8Slz3h18Ih/jLBjwYRVFE1fGzdR9PBuHnKOxc0E" };
3559
+ var PART_INTEGRITY = { "tether.diagnose.js": "sha384-CqtXzvWbLD8aIgyTM43+KMXEFA7r7lhG+0XyQAw3Sp7B5qrzPsxlA9QfzBjoPqZz", "tether.markets.js": "sha384-WjowbRhM7OzzZOrCPZWSZqN7EjIiiR7u9cGmdI+9kgFVgmEQS8lVGWjgx+8jILOf", "tether.search.js": "sha384-fLQ7eKc5XOv0Cg2FfrZyeFAkRR4wDMjUWFpwvKrfPRnT2NvTuhKg80+KVu8Qce/G", "tether.lists.js": "sha384-l2uyr96zTetjo2WWhGsBamd1ZYkC3OB3G3+OScLEvxdok0c8k9GXLAh1WRALUr4S", "tether.extras.js": "sha384-qx7paZ/rjwtn1Yy9TgszulmBuJsIQ9y4eZ590AArnZ+IDB8IzwJ5dNOFJ+yMHPdb", "tether.account.js": "sha384-XUPSX/7R9chq2KlQ1RzLiV7jYcWGe7o5tj4rLZMnf8MEa2aDOOCW2269Bj/ZkbmX", "tether.account-pages.js": "sha384-ND3kIaRypgnHG3QMDb8CqDxt7fuukDCdHsIAHoOUUsz3+FjvBqXgRDV4Mjp6x8jr", "tether.analytics.js": "sha384-jnLesn/+edWBSPuXLj7VX1kSAGwEqtb0VbHjuU//ofqgxkndHlDFsS8Bc8htlGt8" };
3485
3560
 
3486
3561
  // src/part-registry.ts
3487
3562
  function isTetherInternals(value) {
@@ -3489,7 +3564,7 @@
3489
3564
  }
3490
3565
 
3491
3566
  // src/version.ts
3492
- var VERSION = "0.9.3";
3567
+ var VERSION = "0.9.5";
3493
3568
 
3494
3569
  // src/lazy-iife.ts
3495
3570
  var coreModules = {
@@ -3497,7 +3572,7 @@
3497
3572
  return [cfg, isConfigured, log, MARKET_SOURCES, parseMarkets, reportError, warn];
3498
3573
  },
3499
3574
  get "client.ts"() {
3500
- return [endpoint, gql, matches, orNull, shaped, TetherError];
3575
+ return [endpoint, gql, matches, orNull, shaped, TetherError, withTimeout];
3501
3576
  },
3502
3577
  get "dom.ts"() {
3503
3578
  return [
@@ -3647,6 +3722,23 @@
3647
3722
  };
3648
3723
  }
3649
3724
 
3725
+ // src/analytics-queue.ts
3726
+ function queueAnalyticsEvents(load) {
3727
+ const queue = [];
3728
+ const listening = new window.AbortController();
3729
+ const options = { signal: listening.signal };
3730
+ ANALYTICS_EVENTS.forEach((name) => {
3731
+ document.addEventListener(`${cfg.prefix}:${name}`, (event) => queue.push(event), options);
3732
+ });
3733
+ document.addEventListener("astro:page-load", (event) => queue.push(event), options);
3734
+ load().then((part) => part.startAnalytics(queue)).catch((error) => {
3735
+ listening.abort();
3736
+ queue.length = 0;
3737
+ reportError(error, "analytics");
3738
+ });
3739
+ return queue;
3740
+ }
3741
+
3650
3742
  // src/account-marks.ts
3651
3743
  var hintKey = () => `${cfg.prefix}:account-hint:${cfg.domain}`;
3652
3744
  function removeFromBothAreas(key) {
@@ -3777,12 +3869,21 @@
3777
3869
  line.setAttribute("aria-busy", "true");
3778
3870
  reportFailure(change, context);
3779
3871
  }
3872
+ function onQuantityInput(input, { line, id }) {
3873
+ const typed = input.value.trim();
3874
+ if (INTEGER_TEXT.test(typed)) {
3875
+ showLineBusy(line, Cart.updateLine(id, Number(typed)), "cart line");
3876
+ return;
3877
+ }
3878
+ const current = Cart.lines.find((candidate) => candidate.id === id);
3879
+ if (current) input.value = String(Cart.quantityOf(current));
3880
+ }
3780
3881
  function onChange2(event) {
3781
3882
  const { target } = event;
3782
3883
  if (!isElement2(target)) return;
3783
3884
  const found = lineOf(target);
3784
3885
  if (found && target instanceof window.HTMLInputElement && target.matches(sel("line", "quantity"))) {
3785
- showLineBusy(found.line, Cart.updateLine(found.id, parseInt(target.value, 10) || 0), "cart line");
3886
+ onQuantityInput(target, found);
3786
3887
  } else if (found && target instanceof window.HTMLSelectElement && target.matches(sel("line-plan"))) {
3787
3888
  showLineBusy(found.line, Cart.updateLine(found.id, { sellingPlanId: target.value || null }), "cart line plan");
3788
3889
  } else if (hasValue(target) && target.matches(sel("cart-note"))) {
@@ -3790,7 +3891,7 @@
3790
3891
  }
3791
3892
  }
3792
3893
  var hasValue = (target) => target instanceof window.HTMLInputElement || target instanceof window.HTMLTextAreaElement || target instanceof window.HTMLSelectElement;
3793
- function onKeydown(event) {
3894
+ function onKeydown2(event) {
3794
3895
  if (!Cart.isOpen()) return;
3795
3896
  if (event.key === "Escape") {
3796
3897
  Cart.close();
@@ -3801,7 +3902,7 @@
3801
3902
  function bindCartControls() {
3802
3903
  document.addEventListener("click", onClick2);
3803
3904
  document.addEventListener("change", onChange2);
3804
- document.addEventListener("keydown", onKeydown);
3905
+ document.addEventListener("keydown", onKeydown2);
3805
3906
  }
3806
3907
 
3807
3908
  // src/controls/discount.ts
@@ -3810,23 +3911,6 @@
3810
3911
  const input = form.querySelector(sel("discount-input")) ?? form.querySelector("input");
3811
3912
  return input instanceof window.HTMLInputElement ? input : null;
3812
3913
  }
3813
- function markInvalid(form, input, invalid) {
3814
- form.classList.toggle("is-invalid", invalid);
3815
- if (invalid) input?.setAttribute("aria-invalid", "true");
3816
- else input?.removeAttribute("aria-invalid");
3817
- }
3818
- async function applyCode(form, input, code) {
3819
- try {
3820
- await Cart.applyDiscount(code);
3821
- markInvalid(form, input, false);
3822
- emit("discount-applied", { code }, form);
3823
- if (input) input.value = "";
3824
- } catch (error) {
3825
- markInvalid(form, input, true);
3826
- if (error instanceof TetherError && error.code === "INVALID_DISCOUNT") emit("discount-invalid", { code }, form);
3827
- else reportError(error, "discount");
3828
- }
3829
- }
3830
3914
  function onSubmit(event) {
3831
3915
  const { target } = event;
3832
3916
  const form = isElement3(target) ? target.closest(sel("discount-form")) : null;
@@ -3835,7 +3919,11 @@
3835
3919
  const input = codeInputOf(form);
3836
3920
  const code = input?.value.trim();
3837
3921
  if (!code) return;
3838
- void busy(form, () => applyCode(form, input, code));
3922
+ busy(form, () => loadPart("extras").then((part) => part.applyDiscountCode(form, input, code))).catch(
3923
+ (error) => {
3924
+ reportError(error, "discount");
3925
+ }
3926
+ );
3839
3927
  }
3840
3928
  function onInput(event) {
3841
3929
  const { target } = event;
@@ -4033,17 +4121,6 @@
4033
4121
  bindExtrasControls();
4034
4122
  bindNavigation({ ready: () => initPromise ?? Promise.resolve(null), mount, unmount });
4035
4123
  }
4036
- function startAnalyticsQueue() {
4037
- const queue = [];
4038
- analyticsQueue = queue;
4039
- ANALYTICS_EVENTS.forEach((name) => {
4040
- document.addEventListener(`${cfg.prefix}:${name}`, (event) => queue.push(event));
4041
- });
4042
- document.addEventListener("astro:page-load", (event) => queue.push(event));
4043
- loadPart("analytics").then((part) => part.startAnalytics(queue)).catch((error) => {
4044
- reportError(error, "analytics");
4045
- });
4046
- }
4047
4124
  async function cartInPageMarket(cart) {
4048
4125
  const country = cfg.country;
4049
4126
  const cartCountry = cart?.buyerIdentity.countryCode;
@@ -4066,7 +4143,7 @@
4066
4143
  forgetBrowserModeTokens();
4067
4144
  bindControls();
4068
4145
  if (cfg.observe) startObserver();
4069
- if (cfg.analytics && !analyticsQueue) startAnalyticsQueue();
4146
+ if (cfg.analytics) analyticsQueue ?? (analyticsQueue = queueAnalyticsEvents(() => loadPart("analytics")));
4070
4147
  initPromise = applyStartMarket(overrides).then(() => Cart.init()).then(cartInPageMarket).then((cart) => {
4071
4148
  emit("ready", { cart });
4072
4149
  return api;
@@ -21,7 +21,7 @@
21
21
 
22
22
  // tether-core:client.ts
23
23
  var m2 = window.Tether.__core["client.ts"];
24
- var [endpoint, gql, matches, orNull, shaped, TetherError] = m2;
24
+ var [endpoint, gql, matches, orNull, shaped, TetherError, withTimeout] = m2;
25
25
 
26
26
  // tether-core:dom.ts
27
27
  var m3 = window.Tether.__core["dom.ts"];
@@ -1 +1 @@
1
- (()=>{var b=Object.defineProperty;var rt=(e,t,o)=>t in e?b(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var nt=(e,t)=>{for(var o in t)b(e,o,{get:t[o],enumerable:!0})};var a=(e,t,o)=>rt(e,typeof t!="symbol"?t+"":t,o);var O={};nt(O,{getProducts:()=>X,getRecommendations:()=>G,loadList:()=>yt});var st=window.Tether.__core["config.ts"],[P,Et,xt,It,Ct,A,Nt]=st;var it=window.Tether.__core["client.ts"],[$t,l,ct,T,u,E]=it;var at=window.Tether.__core["dom.ts"],[kt,x,Ot,L,p,St,bt,s,m,At,M,Lt,K,Mt,Kt,Ut,U,F,c,q,v,I,f]=at;var dt=window.Tether.__core["fragments.ts"],[D]=dt;var lt=window.Tether.__core["loader.ts"],[vt,Dt,H,h,g]=lt;function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var C={amount:"string",currencyCode:"string"},Q={id:"string",handle:"string",title:"string",options:["object"],images:{nodes:["object"]},priceRange:{minVariantPrice:C,maxVariantPrice:C},variants:{nodes:[{id:"string",price:C,selectedOptions:["object"]}]}},Y={nodes:[Q],pageInfo:{hasNextPage:"boolean"}};var j=u({collection:T({handle:"string",products:Y})}),z=u({products:Y}),B=u({productRecommendations:T([Q])});var ut=window.Tether.__core["status.ts"],[Vt,N,R,$]=ut;var pt=window.Tether.__core["collection.ts"],[_]=pt;var mt=window.Tether.__core["shopify-values.ts"],[Jt,V]=mt;var W="url:",ft=`query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${D()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`,ht="query TetherSearch($first:Int!,$after:String,$query:String,$sortKey:ProductSortKeys,$reverse:Boolean){products(first:$first,after:$after,query:$query,sortKey:$sortKey,reverse:$reverse){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}";async function X({collection:e,query:t,first:o=P.collectionFirst,after:r=null,sortKey:n,reverse:i=!1,filters:et}={}){if(e){let S=await l(g(ft),{handle:e,first:o,after:r,sortKey:n||void 0,reverse:i,filters:et??void 0},j);if(!S.collection)throw new E(`Collection not found: ${e}`,{code:"NOT_FOUND"});let{products:y,...ot}=S.collection;return y.nodes.forEach(h),{collection:ot,products:y.nodes,pageInfo:y.pageInfo}}let w=await l(g(ht),{first:o,after:r,query:t||void 0,sortKey:n||void 0,reverse:i},z);return w.products.nodes.forEach(h),{collection:null,products:w.products.nodes,pageInfo:w.products.pageInfo}}async function G(e,t="RELATED"){let o=H(typeof e=="object"?e?.id:e);if(!o)throw new E("No product for recommendations",{code:"NOT_FOUND"});let r=o.startsWith("gid://"),i=(await l(g(`query TetherRecs(${r?"$id: ID!":"$handle: String!"},$intent:ProductRecommendationIntent){productRecommendations(${r?"productId: $id":"productHandle: $handle"},intent:$intent){...TetherProduct}}`),r?{id:o,intent:t}:{handle:o,intent:t},B)).productRecommendations??[];return i.forEach(h),i}var gt=e=>e instanceof window.Element,Z=(e,t)=>M(e,"limit",{min:1,max:V,fallback:t}),wt=e=>e==="COMPLEMENTARY"?"COMPLEMENTARY":"RELATED",k=class{constructor(t){a(this,"root");a(this,"products",[]);a(this,"pageInfo",null);a(this,"collection",null);a(this,"loadToken",0);this.root=t,t.addEventListener("click",o=>{if(!gt(o.target))return;let r=o.target.closest(c("load-more"));r?.closest(_())===t&&(o.preventDefault(),L(r,()=>this.load(!0)))})}$(t){return F(this.root,t,_())}options(){let{root:t}=this,o={reverse:s(t,"reverse")==="true",first:Z(t,P.collectionFirst)},r=s(t,"sort");if(r&&(o.sortKey=r),m(t,"collection"))return o.collection=s(t,"collection")??"",o;let n=s(t,"products")??"";return o.query=n.startsWith(W)?new URL(window.location.href).searchParams.get(n.slice(W.length))||"":n,o}async loadRecommendations(){let{key:t}=R(this.root,window.location,"recommendations"),o=this.root.closest(c("product"));return!t&&o&&({key:t}=R(o)),G(t,wt(s(this.root,"intent")))}async load(t=!1){this.loadToken+=1;let o=this.loadToken,r=()=>o!==this.loadToken;try{if(m(this.root,"recommendations")){let n=await this.loadRecommendations();if(r())return;this.products=n.slice(0,Z(this.root,n.length))}else{let n=await X({...this.options(),after:t?this.pageInfo?.endCursor??null:null});if(r())return;this.collection=n.collection,this.pageInfo=n.pageInfo,this.products=t?[...this.products,...n.products]:n.products}this.render(),$(this.root,"ready"),p("list-ready",{products:this.products,collection:this.collection},this.root)}catch(n){if(r())return;t||$(this.root,N(n)?"not-found":"error",n),N(n)&&m(this.root,"recommendations")||A(n,"list load failed"),p("error",{error:n,context:"list"},this.root)}}render(){let{collection:t}=this;this.$(c("collection-bind")).forEach(r=>{switch(s(r,"collection-bind")??""){case"title":I(r,t?.title??"");break;case"description":v(r,t?.descriptionHtml);break;case"image":q(r,t?.image?.url,t?.image?.altText||t?.title);break;case"count":I(r,this.products.length);break}}),this.$(c("list")).forEach(r=>{U(r,this.products,(n,i)=>{n.setAttribute(x("product"),i.handle),n.removeAttribute(x("state"))}),p("list-rendered",{container:r},this.root)});let o=this.products.length===0;this.$(c("show")).forEach(r=>{let n=s(r,"show");n==="list-empty"&&f(r,o),n==="list-filled"&&f(r,!o)}),this.$(c("load-more")).forEach(r=>{f(r,!!this.pageInfo?.hasNextPage)}),K("list")}},J=new WeakMap;function yt(e){let t=J.get(e);return t||(t=new k(e),J.set(e,t)),t.load()}function Pt(e){return d(e)&&d(e.__core)&&d(e.__parts)}function tt(e,t){let o=Reflect.get(window,"Tether");if(!Pt(o))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);o.__parts[e]=t}tt("lists",O);})();
1
+ (()=>{var b=Object.defineProperty;var rt=(e,t,o)=>t in e?b(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var nt=(e,t)=>{for(var o in t)b(e,o,{get:t[o],enumerable:!0})};var a=(e,t,o)=>rt(e,typeof t!="symbol"?t+"":t,o);var O={};nt(O,{getProducts:()=>X,getRecommendations:()=>G,loadList:()=>yt});var st=window.Tether.__core["config.ts"],[P,Et,xt,It,Ct,A,Nt]=st;var it=window.Tether.__core["client.ts"],[$t,l,ct,T,u,E,_t]=it;var at=window.Tether.__core["dom.ts"],[Ot,x,St,L,m,bt,At,s,p,Lt,M,Mt,K,Kt,Ut,Ft,U,F,c,q,v,I,f]=at;var dt=window.Tether.__core["fragments.ts"],[D]=dt;var lt=window.Tether.__core["loader.ts"],[Dt,Ht,H,h,g]=lt;function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var C={amount:"string",currencyCode:"string"},Q={id:"string",handle:"string",title:"string",options:["object"],images:{nodes:["object"]},priceRange:{minVariantPrice:C,maxVariantPrice:C},variants:{nodes:[{id:"string",price:C,selectedOptions:["object"]}]}},Y={nodes:[Q],pageInfo:{hasNextPage:"boolean"}};var j=u({collection:T({handle:"string",products:Y})}),z=u({products:Y}),B=u({productRecommendations:T([Q])});var ut=window.Tether.__core["status.ts"],[Wt,N,R,$]=ut;var mt=window.Tether.__core["collection.ts"],[_]=mt;var pt=window.Tether.__core["shopify-values.ts"],[Xt,V]=pt;var W="url:",ft=`query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${D()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`,ht="query TetherSearch($first:Int!,$after:String,$query:String,$sortKey:ProductSortKeys,$reverse:Boolean){products(first:$first,after:$after,query:$query,sortKey:$sortKey,reverse:$reverse){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}";async function X({collection:e,query:t,first:o=P.collectionFirst,after:r=null,sortKey:n,reverse:i=!1,filters:et}={}){if(e){let S=await l(g(ft),{handle:e,first:o,after:r,sortKey:n||void 0,reverse:i,filters:et??void 0},j);if(!S.collection)throw new E(`Collection not found: ${e}`,{code:"NOT_FOUND"});let{products:y,...ot}=S.collection;return y.nodes.forEach(h),{collection:ot,products:y.nodes,pageInfo:y.pageInfo}}let w=await l(g(ht),{first:o,after:r,query:t||void 0,sortKey:n||void 0,reverse:i},z);return w.products.nodes.forEach(h),{collection:null,products:w.products.nodes,pageInfo:w.products.pageInfo}}async function G(e,t="RELATED"){let o=H(typeof e=="object"?e?.id:e);if(!o)throw new E("No product for recommendations",{code:"NOT_FOUND"});let r=o.startsWith("gid://"),i=(await l(g(`query TetherRecs(${r?"$id: ID!":"$handle: String!"},$intent:ProductRecommendationIntent){productRecommendations(${r?"productId: $id":"productHandle: $handle"},intent:$intent){...TetherProduct}}`),r?{id:o,intent:t}:{handle:o,intent:t},B)).productRecommendations??[];return i.forEach(h),i}var gt=e=>e instanceof window.Element,Z=(e,t)=>M(e,"limit",{min:1,max:V,fallback:t}),wt=e=>e==="COMPLEMENTARY"?"COMPLEMENTARY":"RELATED",k=class{constructor(t){a(this,"root");a(this,"products",[]);a(this,"pageInfo",null);a(this,"collection",null);a(this,"loadToken",0);this.root=t,t.addEventListener("click",o=>{if(!gt(o.target))return;let r=o.target.closest(c("load-more"));r?.closest(_())===t&&(o.preventDefault(),L(r,()=>this.load(!0)))})}$(t){return F(this.root,t,_())}options(){let{root:t}=this,o={reverse:s(t,"reverse")==="true",first:Z(t,P.collectionFirst)},r=s(t,"sort");if(r&&(o.sortKey=r),p(t,"collection"))return o.collection=s(t,"collection")??"",o;let n=s(t,"products")??"";return o.query=n.startsWith(W)?new URL(window.location.href).searchParams.get(n.slice(W.length))||"":n,o}async loadRecommendations(){let{key:t}=R(this.root,window.location,"recommendations"),o=this.root.closest(c("product"));return!t&&o&&({key:t}=R(o)),G(t,wt(s(this.root,"intent")))}async load(t=!1){this.loadToken+=1;let o=this.loadToken,r=()=>o!==this.loadToken;try{if(p(this.root,"recommendations")){let n=await this.loadRecommendations();if(r())return;this.products=n.slice(0,Z(this.root,n.length))}else{let n=await X({...this.options(),after:t?this.pageInfo?.endCursor??null:null});if(r())return;this.collection=n.collection,this.pageInfo=n.pageInfo,this.products=t?[...this.products,...n.products]:n.products}this.render(),$(this.root,"ready"),m("list-ready",{products:this.products,collection:this.collection},this.root)}catch(n){if(r())return;t||$(this.root,N(n)?"not-found":"error",n),N(n)&&p(this.root,"recommendations")||A(n,"list load failed"),m("error",{error:n,context:"list"},this.root)}}render(){let{collection:t}=this;this.$(c("collection-bind")).forEach(r=>{switch(s(r,"collection-bind")??""){case"title":I(r,t?.title??"");break;case"description":v(r,t?.descriptionHtml);break;case"image":q(r,t?.image?.url,t?.image?.altText||t?.title);break;case"count":I(r,this.products.length);break}}),this.$(c("list")).forEach(r=>{U(r,this.products,(n,i)=>{n.setAttribute(x("product"),i.handle),n.removeAttribute(x("state"))}),m("list-rendered",{container:r},this.root)});let o=this.products.length===0;this.$(c("show")).forEach(r=>{let n=s(r,"show");n==="list-empty"&&f(r,o),n==="list-filled"&&f(r,!o)}),this.$(c("load-more")).forEach(r=>{f(r,!!this.pageInfo?.hasNextPage)}),K("list")}},J=new WeakMap;function yt(e){let t=J.get(e);return t||(t=new k(e),J.set(e,t)),t.load()}function Pt(e){return d(e)&&d(e.__core)&&d(e.__parts)}function tt(e,t){let o=Reflect.get(window,"Tether");if(!Pt(o))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);o.__parts[e]=t}tt("lists",O);})();
@@ -20,7 +20,7 @@
20
20
 
21
21
  // tether-core:client.ts
22
22
  var m2 = window.Tether.__core["client.ts"];
23
- var [endpoint, gql, matches, orNull, shaped, TetherError] = m2;
23
+ var [endpoint, gql, matches, orNull, shaped, TetherError, withTimeout] = m2;
24
24
 
25
25
  // tether-core:cart.ts
26
26
  var m3 = window.Tether.__core["cart.ts"];
@@ -1 +1 @@
1
- (()=>{var G=Object.defineProperty;var V=(e,t)=>{for(var n in t)G(e,n,{get:t[n],enumerable:!0})};var b={};V(b,{detectMarket:()=>K,getLocalization:()=>J,renderCountrySelects:()=>L,setCountry:()=>Ee});var Z=window.Tether.__core["config.ts"],[i,Ae,Ne,M,S,C,ve]=Z;var Q=window.Tether.__core["client.ts"],[Ie,x,ze,Re,T,E]=Q;var X=window.Tether.__core["cart.ts"],[g]=X;var ee=window.Tether.__core["collection.ts"],[P]=ee;var te=window.Tether.__core["loader.ts"],[_,De,je,Ke,$e]=te;var ne=window.Tether.__core["dom.ts"],[Je,m,Ye,Be,A,We,Ge,N,Ve,Ze,Qe,Xe,et,tt,nt,ot,rt,at,w,it,ct,ut,lt]=ne;var oe=window.Tether.__core["mounting.ts"],[v,O,I,z,R,k]=oe;var re=window.Tether.__core["market-codes.ts"],[s,d]=re;function U(e,t="localStorage"){try{return window[t].getItem(e)}catch{return null}}function H(e,t,n="localStorage"){try{window[n].setItem(e,t)}catch{}}function F(e){try{return decodeURIComponent(e)}catch(t){if(t instanceof URIError)return e;throw t}}var ae="tether_country",D=()=>`${i.prefix}:market:${i.domain}`,j={getItem:e=>U(e)};function ie(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:j,global:e?window:{}}}function ce(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function ue(e){if(typeof e!="object"||e===null)return null;let t=s(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:d(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}var le=e=>ue(ce(e));function se(e=j){let t=e.getItem(D());return t?le(t):null}function de(e,t){if(!e||!t)return null;let n=e.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(`${t}=`));return n?F(n.slice(t.length+1)):null}function h(e,t){if(!e||!t)return null;let n=t.toLowerCase(),a=Object.keys(e).find(o=>o.toLowerCase()===n);return a?e[a]??null:null}function ge(e,t){let n=r=>t.document?.querySelector(`meta[name="${r}"]`)?.getAttribute("content"),a=Reflect.get(t.global,"TETHER_COUNTRY"),o=Reflect.get(t.global,"TETHER_LANGUAGE"),c=n("tether-country")||de(t.document,e.cookie||ae);return{country:a||c,language:o||n("tether-language")}}function fe(e,t){let n=(t.location?.pathname??"/").split("/").find(u=>u!==""),a=h(e.locales,n);if(a)return a;let o=t.document?.documentElement.getAttribute("lang");if(!o)return null;let c=h(e.locales,o)??h(e.locales,o.split("-")[0]);if(c)return{locale:o,...c};if(e.locales&&e.strict)return null;let r=o.split("-")[1];return{language:o,country:r?.length===2?r:null,locale:o}}function me(e,t,n){switch(e){case"saved":return t.remember===!1?null:se(n.storage);case"server":return ge(t,n);case"webflow":return fe(t,n)}}function pe(e){return e?e===!0?M:e:["saved"]}function K(e=i.markets,t=ie()){let n=(e===i.markets?e:S(e))??{};if(n.detect===!1)return{};let a={},o={sources:a};for(let c of pe(n.detect)){let r=me(c,n,t);if(!r)continue;let u=s(r.country),l=d(r.language),f=typeof r.locale=="string"&&r.locale?r.locale:null;u&&!o.country&&(o.country=u,a.country=c),l&&!o.language&&(o.language=l,a.language=c),f&&!o.locale&&(o.locale=f,a.locale=c)}return o}function $(e){if(i.markets?.remember===!1)return;let t={country:e.country,language:e.language||void 0,locale:e.locale||void 0};H(D(),JSON.stringify(t))}var ye="{name} ({currency})",Ce="name",p=null;function we(){p=null}var ke="query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}",q={isoCode:"string",name:"string",currency:"object"},he=T({localization:{country:q,availableCountries:[q]}});function J(){return p??(p=x(ke,{},he).then(e=>e.localization,e=>{throw p=null,e})),p}function Y(e,t){switch(t){case"name":return e.name;case"code":return e.isoCode;case"currency":return e.currency.isoCode;case"symbol":return e.currency.symbol;default:return""}}var Le=(e,t)=>e.replace(/\{(name|code|currency|symbol)\}/g,(n,a)=>Y(t,a));function be(e,t,n){let a=e.getAttribute(m("country-label"))||ye,o=(e.getAttribute(m("countries"))||"").toUpperCase().split(/[\s,]+/).filter(Boolean),c=o.length?o.map(r=>t.find(u=>u.isoCode===r)).filter(r=>r!==void 0):t;e.replaceChildren(...c.map(r=>new Option(Le(a,r),r.isoCode))),e.value=n,e.value!==n&&(e.selectedIndex=-1),e.disabled=c.length<2&&!e.hasAttribute(m("always-enabled"))}function Me(e,t,n){let a=(i.country||n.country.isoCode).toUpperCase(),o=[...n.availableCountries].sort((r,u)=>r.name.localeCompare(u.name,i.locale||void 0)),c=o.find(r=>r.isoCode===a)??n.country;e.forEach(r=>{be(r,o,a)}),t.forEach(r=>{r.textContent=Y(c,N(r,"country-bind")||Ce)})}function L(e=document){let t=k(e,`select${w("country-select")}`),n=k(e,w("country-bind"));return!t.length&&!n.length?Promise.resolve():J().then(a=>{Me(t,n,a)}).catch(a=>{C(a,"country select")})}var Se=e=>Object.values(i.markets?.locales??{}).find(t=>s(t.country)===e);function xe(e,t){return e!==void 0?d(e):t?t.language?d(t.language):void 0:i.language}function Te(e){_();let t=[];return g.id()&&t.push(g.setBuyerIdentity({countryCode:e},{create:!1}).catch(n=>{C(n,"cart country")})),R(),v.forEach(n=>t.push(n.load())),O.forEach(n=>{n.closest(P())||(I.delete(n),z(n))}),t}async function Ee(e,{language:t,locale:n,remember:a=!0}={}){let o=s(e);if(!o)throw new E(`Not a country code: ${e}`,{code:"INVALID_COUNTRY"});let c=Se(o),r=n||c?.locale,u=r||i.locale,l=xe(t,c),f=o!==i.country||l!==i.language||u!==i.locale;if(i.country=o,i.language=l||void 0,i.locale=u,a&&$({country:o,language:l,locale:r}),!f)return L(),g.state;t!==void 0&&we();let W=Te(o);return L(),A("country-changed",{country:o,language:i.language}),await Promise.all(W),g.state}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Pe(e){return y(e)&&y(e.__core)&&y(e.__parts)}function B(e,t){let n=Reflect.get(window,"Tether");if(!Pe(n))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);n.__parts[e]=t}B("markets",b);})();
1
+ (()=>{var G=Object.defineProperty;var V=(e,t)=>{for(var n in t)G(e,n,{get:t[n],enumerable:!0})};var b={};V(b,{detectMarket:()=>K,getLocalization:()=>J,renderCountrySelects:()=>L,setCountry:()=>Ee});var Z=window.Tether.__core["config.ts"],[i,Ae,Ne,M,S,C,ve]=Z;var Q=window.Tether.__core["client.ts"],[Ie,x,ze,Re,T,E,Ue]=Q;var X=window.Tether.__core["cart.ts"],[g]=X;var ee=window.Tether.__core["collection.ts"],[P]=ee;var te=window.Tether.__core["loader.ts"],[_,je,Ke,$e,qe]=te;var ne=window.Tether.__core["dom.ts"],[Ye,m,Be,We,A,Ge,Ve,N,Ze,Qe,Xe,et,tt,nt,ot,rt,at,it,w,ct,ut,lt,st]=ne;var oe=window.Tether.__core["mounting.ts"],[v,O,I,z,R,k]=oe;var re=window.Tether.__core["market-codes.ts"],[s,d]=re;function U(e,t="localStorage"){try{return window[t].getItem(e)}catch{return null}}function H(e,t,n="localStorage"){try{window[n].setItem(e,t)}catch{}}function F(e){try{return decodeURIComponent(e)}catch(t){if(t instanceof URIError)return e;throw t}}var ae="tether_country",D=()=>`${i.prefix}:market:${i.domain}`,j={getItem:e=>U(e)};function ie(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:j,global:e?window:{}}}function ce(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function ue(e){if(typeof e!="object"||e===null)return null;let t=s(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:d(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}var le=e=>ue(ce(e));function se(e=j){let t=e.getItem(D());return t?le(t):null}function de(e,t){if(!e||!t)return null;let n=e.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(`${t}=`));return n?F(n.slice(t.length+1)):null}function h(e,t){if(!e||!t)return null;let n=t.toLowerCase(),a=Object.keys(e).find(o=>o.toLowerCase()===n);return a?e[a]??null:null}function ge(e,t){let n=r=>t.document?.querySelector(`meta[name="${r}"]`)?.getAttribute("content"),a=Reflect.get(t.global,"TETHER_COUNTRY"),o=Reflect.get(t.global,"TETHER_LANGUAGE"),c=n("tether-country")||de(t.document,e.cookie||ae);return{country:a||c,language:o||n("tether-language")}}function fe(e,t){let n=(t.location?.pathname??"/").split("/").find(u=>u!==""),a=h(e.locales,n);if(a)return a;let o=t.document?.documentElement.getAttribute("lang");if(!o)return null;let c=h(e.locales,o)??h(e.locales,o.split("-")[0]);if(c)return{locale:o,...c};if(e.locales&&e.strict)return null;let r=o.split("-")[1];return{language:o,country:r?.length===2?r:null,locale:o}}function me(e,t,n){switch(e){case"saved":return t.remember===!1?null:se(n.storage);case"server":return ge(t,n);case"webflow":return fe(t,n)}}function pe(e){return e?e===!0?M:e:["saved"]}function K(e=i.markets,t=ie()){let n=(e===i.markets?e:S(e))??{};if(n.detect===!1)return{};let a={},o={sources:a};for(let c of pe(n.detect)){let r=me(c,n,t);if(!r)continue;let u=s(r.country),l=d(r.language),f=typeof r.locale=="string"&&r.locale?r.locale:null;u&&!o.country&&(o.country=u,a.country=c),l&&!o.language&&(o.language=l,a.language=c),f&&!o.locale&&(o.locale=f,a.locale=c)}return o}function $(e){if(i.markets?.remember===!1)return;let t={country:e.country,language:e.language||void 0,locale:e.locale||void 0};H(D(),JSON.stringify(t))}var ye="{name} ({currency})",Ce="name",p=null;function we(){p=null}var ke="query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}",q={isoCode:"string",name:"string",currency:"object"},he=T({localization:{country:q,availableCountries:[q]}});function J(){return p??(p=x(ke,{},he).then(e=>e.localization,e=>{throw p=null,e})),p}function Y(e,t){switch(t){case"name":return e.name;case"code":return e.isoCode;case"currency":return e.currency.isoCode;case"symbol":return e.currency.symbol;default:return""}}var Le=(e,t)=>e.replace(/\{(name|code|currency|symbol)\}/g,(n,a)=>Y(t,a));function be(e,t,n){let a=e.getAttribute(m("country-label"))||ye,o=(e.getAttribute(m("countries"))||"").toUpperCase().split(/[\s,]+/).filter(Boolean),c=o.length?o.map(r=>t.find(u=>u.isoCode===r)).filter(r=>r!==void 0):t;e.replaceChildren(...c.map(r=>new Option(Le(a,r),r.isoCode))),e.value=n,e.value!==n&&(e.selectedIndex=-1),e.disabled=c.length<2&&!e.hasAttribute(m("always-enabled"))}function Me(e,t,n){let a=(i.country||n.country.isoCode).toUpperCase(),o=[...n.availableCountries].sort((r,u)=>r.name.localeCompare(u.name,i.locale||void 0)),c=o.find(r=>r.isoCode===a)??n.country;e.forEach(r=>{be(r,o,a)}),t.forEach(r=>{r.textContent=Y(c,N(r,"country-bind")||Ce)})}function L(e=document){let t=k(e,`select${w("country-select")}`),n=k(e,w("country-bind"));return!t.length&&!n.length?Promise.resolve():J().then(a=>{Me(t,n,a)}).catch(a=>{C(a,"country select")})}var Se=e=>Object.values(i.markets?.locales??{}).find(t=>s(t.country)===e);function xe(e,t){return e!==void 0?d(e):t?t.language?d(t.language):void 0:i.language}function Te(e){_();let t=[];return g.id()&&t.push(g.setBuyerIdentity({countryCode:e},{create:!1}).catch(n=>{C(n,"cart country")})),R(),v.forEach(n=>t.push(n.load())),O.forEach(n=>{n.closest(P())||(I.delete(n),z(n))}),t}async function Ee(e,{language:t,locale:n,remember:a=!0}={}){let o=s(e);if(!o)throw new E(`Not a country code: ${e}`,{code:"INVALID_COUNTRY"});let c=Se(o),r=n||c?.locale,u=r||i.locale,l=xe(t,c),f=o!==i.country||l!==i.language||u!==i.locale;if(i.country=o,i.language=l||void 0,i.locale=u,a&&$({country:o,language:l,locale:r}),!f)return L(),g.state;t!==void 0&&we();let W=Te(o);return L(),A("country-changed",{country:o,language:i.language}),await Promise.all(W),g.state}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Pe(e){return y(e)&&y(e.__core)&&y(e.__parts)}function B(e,t){let n=Reflect.get(window,"Tether");if(!Pe(n))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);n.__parts[e]=t}B("markets",b);})();