@occluze/tether 0.9.1 → 0.9.3

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 (61) hide show
  1. package/README.md +1 -1
  2. package/dist/esm/astro.js +2 -2
  3. package/dist/esm/chunks/account-3MYRPPTR.js +1 -0
  4. package/dist/esm/chunks/{account-pages-3C5KTPQV.js → account-pages-OZHK5HHY.js} +1 -1
  5. package/dist/esm/chunks/{analytics-VWSZOX2D.js → analytics-QHX2YHZS.js} +1 -1
  6. package/dist/esm/chunks/chunk-24KD36UC.js +1 -0
  7. package/dist/esm/chunks/{chunk-F2BYVA7V.js → chunk-2G6U6ZYV.js} +1 -1
  8. package/dist/esm/chunks/{chunk-MJNPD6LB.js → chunk-74SGIWQE.js} +1 -1
  9. package/dist/esm/chunks/{chunk-3UCVDDK6.js → chunk-A3GZFAB3.js} +1 -1
  10. package/dist/esm/chunks/chunk-A6BZFYZY.js +1 -0
  11. package/dist/esm/chunks/{chunk-HROQXZYN.js → chunk-EYG7QGPA.js} +1 -1
  12. package/dist/esm/chunks/{chunk-P6DV24RG.js → chunk-FX7EJ6RB.js} +1 -1
  13. package/dist/esm/chunks/{chunk-OURC3H6L.js → chunk-GCGRUVYO.js} +1 -1
  14. package/dist/esm/chunks/{chunk-2IGCUTG5.js → chunk-LSB7RVRZ.js} +1 -1
  15. package/dist/esm/chunks/{chunk-S5BUUIB6.js → chunk-NF5H2Q7V.js} +1 -1
  16. package/dist/esm/chunks/chunk-PZERNTCD.js +1 -0
  17. package/dist/esm/chunks/chunk-RVWHBZAF.js +1 -0
  18. package/dist/esm/chunks/chunk-SJNNEEDX.js +1 -0
  19. package/dist/esm/chunks/{chunk-XU27NSXT.js → chunk-SOLTIZAI.js} +1 -1
  20. package/dist/esm/chunks/{chunk-ZBV2JSHE.js → chunk-WHNUPECA.js} +1 -1
  21. package/dist/esm/chunks/{chunk-2A2GN3Z7.js → chunk-ZB4FBE6W.js} +1 -1
  22. package/dist/esm/chunks/{diagnose-TE72GNOO.js → diagnose-O3QCZTHT.js} +1 -1
  23. package/dist/esm/chunks/{extras-7GTMJMOZ.js → extras-O6ZRL5FK.js} +1 -1
  24. package/dist/esm/chunks/lists-XF33XENI.js +1 -0
  25. package/dist/esm/chunks/{markets-ui-AAQM4PEE.js → markets-ui-V2ROBFZP.js} +1 -1
  26. package/dist/esm/chunks/search-ZLKIFARH.js +1 -0
  27. package/dist/esm/index.js +1 -1
  28. package/dist/esm/server.js +2 -2
  29. package/dist/tether.account-pages.js +2 -2
  30. package/dist/tether.account-pages.min.js +1 -1
  31. package/dist/tether.account.js +4 -7
  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 +1 -1
  38. package/dist/tether.extras.min.js +1 -1
  39. package/dist/tether.js +110 -64
  40. package/dist/tether.lists.js +11 -7
  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 +4 -6
  47. package/dist/tether.search.min.js +1 -1
  48. package/dist/types/server/src/shared/metafield-ref.d.ts +15 -0
  49. package/dist/types/src/dom.d.ts +12 -0
  50. package/dist/types/src/server.d.ts +5 -2
  51. package/dist/types/src/shopify-values.d.ts +2 -0
  52. package/dist/types/src/version.d.ts +1 -1
  53. package/package.json +2 -2
  54. package/dist/esm/chunks/account-LCMJ7QU5.js +0 -1
  55. package/dist/esm/chunks/chunk-D3MRWOFI.js +0 -1
  56. package/dist/esm/chunks/chunk-EUCFOBIT.js +0 -1
  57. package/dist/esm/chunks/chunk-P73VN3B6.js +0 -1
  58. package/dist/esm/chunks/chunk-SOFWDTR7.js +0 -1
  59. package/dist/esm/chunks/chunk-YJC3CSEG.js +0 -1
  60. package/dist/esm/chunks/lists-ZMVRGD6L.js +0 -1
  61. package/dist/esm/chunks/search-PWF4YZQO.js +0 -1
package/dist/tether.js CHANGED
@@ -28,9 +28,19 @@
28
28
  return isRecord(value) ? value[key] : void 0;
29
29
  }
30
30
 
31
- // src/config-sections.ts
32
- var METAFIELD_PART = /^[A-Za-z0-9_.-]+$/;
31
+ // server/src/shared/metafield-ref.ts
32
+ var METAFIELD_KEY = /^[A-Za-z0-9_.-]+$/;
33
33
  var METAFIELD_NAMESPACE = /^(\$app(:[A-Za-z0-9_-]+)?|[A-Za-z0-9_.-]+)$/;
34
+ var isMetafieldIdentifier = (namespace, key) => METAFIELD_NAMESPACE.test(namespace) && METAFIELD_KEY.test(key);
35
+ function metafieldIdentifierOf(ref) {
36
+ const dot = ref.indexOf(".");
37
+ if (dot <= 0) return null;
38
+ const namespace = ref.slice(0, dot);
39
+ const key = ref.slice(dot + 1);
40
+ return isMetafieldIdentifier(namespace, key) ? { namespace, key } : null;
41
+ }
42
+
43
+ // src/config-sections.ts
34
44
  var HOSTNAME = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
35
45
  var COOKIE_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
36
46
  var GLOBAL_NAME = /^[A-Za-z_$][\w$]*$/;
@@ -99,18 +109,12 @@
99
109
  return origins;
100
110
  }
101
111
  function toMetafieldIdentifier(ref) {
102
- let namespace;
103
- let key;
104
- if (typeof ref === "string") {
105
- const dot = ref.indexOf(".");
106
- namespace = dot > 0 ? ref.slice(0, dot) : "";
107
- key = ref.slice(dot + 1);
108
- } else if (typeof ref === "object" && ref !== null) {
109
- namespace = Reflect.get(ref, "namespace");
110
- key = Reflect.get(ref, "key");
111
- }
112
+ if (typeof ref === "string") return metafieldIdentifierOf(ref);
113
+ if (typeof ref !== "object" || ref === null) return null;
114
+ const namespace = Reflect.get(ref, "namespace");
115
+ const key = Reflect.get(ref, "key");
112
116
  if (typeof namespace !== "string" || typeof key !== "string") return null;
113
- return METAFIELD_NAMESPACE.test(namespace) && METAFIELD_PART.test(key) ? { namespace, key } : null;
117
+ return isMetafieldIdentifier(namespace, key) ? { namespace, key } : null;
114
118
  }
115
119
  function metafieldsOption(value, invalid) {
116
120
  if (!Array.isArray(value)) {
@@ -220,6 +224,45 @@
220
224
  return LANGUAGE.test(primary) ? primary : null;
221
225
  }
222
226
 
227
+ // src/shopify-values.ts
228
+ var MAX_CONNECTION_SIZE = 250;
229
+ function isHttpsUrl(url2) {
230
+ if (typeof url2 !== "string") return false;
231
+ try {
232
+ return new URL(url2).protocol === "https:";
233
+ } catch {
234
+ return false;
235
+ }
236
+ }
237
+ function formatMoney(money, locale) {
238
+ if (!money) return "";
239
+ const amount = parseFloat(money.amount);
240
+ if (Number.isNaN(amount)) return "";
241
+ try {
242
+ return new Intl.NumberFormat(locale || void 0, { style: "currency", currency: money.currencyCode }).format(
243
+ amount
244
+ );
245
+ } catch {
246
+ return `${money.currencyCode} ${amount.toFixed(2)}`;
247
+ }
248
+ }
249
+ function productUrl(productPath, handle, id) {
250
+ if (!/\{(handle|id)\}/.test(productPath)) {
251
+ return handle ? `${productPath.replace(/\/$/, "")}/${encodeURIComponent(handle)}` : null;
252
+ }
253
+ const numericId2 = id ? id.split("/").at(-1) ?? "" : "";
254
+ if (productPath.includes("{handle}") && !handle) return null;
255
+ if (productPath.includes("{id}") && !numericId2) return null;
256
+ return productPath.replace(/\{handle\}/g, encodeURIComponent(handle ?? "")).replace(/\{id\}/g, encodeURIComponent(numericId2));
257
+ }
258
+ function productKey(raw) {
259
+ const value = String(raw ?? "").trim();
260
+ if (!value) return null;
261
+ if (value.startsWith("gid://")) return value;
262
+ if (/^\d+$/.test(value)) return `gid://shopify/Product/${value}`;
263
+ return /\/products\/([^/?#]+)/.exec(value)?.[1] ?? value;
264
+ }
265
+
223
266
  // src/config.ts
224
267
  var DEFAULTS = {
225
268
  domain: "",
@@ -297,7 +340,7 @@
297
340
  "astro",
298
341
  "debug"
299
342
  ];
300
- var TEXT_OPTIONS = ["token", "productPath", "collectionPath", "cartDrawerOpenClass"];
343
+ var TEXT_OPTIONS = ["token", "productPath", "collectionPath"];
301
344
  var COUNT_OPTIONS = [
302
345
  "imagesFirst",
303
346
  "variantsFirst",
@@ -330,7 +373,7 @@
330
373
  }
331
374
  function warnUnknownKeys(options) {
332
375
  for (const key of Object.keys(options)) {
333
- if (!(key in DEFAULTS)) warn(`unknown option ${JSON.stringify(key)}: ignored`);
376
+ if (!Object.hasOwn(DEFAULTS, key)) warn(`unknown option ${JSON.stringify(key)}: ignored`);
334
377
  }
335
378
  }
336
379
  function setHook(config, name, value) {
@@ -342,15 +385,25 @@
342
385
  }
343
386
  var MAX_TIMER_MS = 2147483647;
344
387
  var MAX_RETRIES = 10;
345
- var COUNT_MAXIMUMS = {
346
- requestTimeout: MAX_TIMER_MS,
347
- searchDelay: MAX_TIMER_MS,
348
- retries: MAX_RETRIES
388
+ var CONNECTION_RANGE = { min: 1, max: MAX_CONNECTION_SIZE };
389
+ var COUNT_RANGES = {
390
+ imagesFirst: CONNECTION_RANGE,
391
+ variantsFirst: CONNECTION_RANGE,
392
+ sellingPlanGroupsFirst: CONNECTION_RANGE,
393
+ sellingPlansFirst: CONNECTION_RANGE,
394
+ collectionFirst: CONNECTION_RANGE,
395
+ requestTimeout: { max: MAX_TIMER_MS },
396
+ searchDelay: { max: MAX_TIMER_MS },
397
+ retries: { max: MAX_RETRIES }
349
398
  };
350
399
  function countOption(name, value) {
351
- const maximum = COUNT_MAXIMUMS[name] ?? Number.POSITIVE_INFINITY;
352
- if (typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= maximum) return value;
353
- return invalidOption(name, value, DEFAULTS[name]);
400
+ const { min = 0, max: maximum } = COUNT_RANGES[name] ?? {};
401
+ if (typeof value !== "number" || !Number.isInteger(value) || value < min) {
402
+ return invalidOption(name, value, DEFAULTS[name]);
403
+ }
404
+ if (maximum === void 0 || value <= maximum) return value;
405
+ warn(`${name} ${String(value)} is more than its maximum: using ${String(maximum)}`);
406
+ return maximum;
354
407
  }
355
408
  function switchOption(name, value) {
356
409
  return typeof value === "boolean" ? value : invalidOption(name, value, DEFAULTS[name]);
@@ -358,6 +411,10 @@
358
411
  function textOption(name, value) {
359
412
  return typeof value === "string" ? value : invalidOption(name, value, DEFAULTS[name]);
360
413
  }
414
+ var CLASS_TOKEN = /^\S+$/;
415
+ function classOption(name, value) {
416
+ return typeof value === "string" && CLASS_TOKEN.test(value) ? value : invalidOption(name, value, DEFAULTS[name]);
417
+ }
361
418
  function localeOption(value) {
362
419
  if (value === void 0 || value === null || value === "") return void 0;
363
420
  try {
@@ -404,7 +461,8 @@
404
461
  metafields: metafieldsOption(options.metafields ?? [], dropped),
405
462
  embedOrigins: embedOriginsOption(options.embedOrigins ?? [], dropped),
406
463
  checkoutTarget: choiceOption("checkoutTarget", options.checkoutTarget, ["_self", "_blank"]),
407
- defaultPurchase: choiceOption("defaultPurchase", options.defaultPurchase, ["one-time", "subscription"])
464
+ defaultPurchase: choiceOption("defaultPurchase", options.defaultPurchase, ["one-time", "subscription"]),
465
+ cartDrawerOpenClass: classOption("cartDrawerOpenClass", options.cartDrawerOpenClass)
408
466
  };
409
467
  for (const name of COUNT_OPTIONS) resolved[name] = countOption(name, options[name]);
410
468
  for (const name of SWITCH_OPTIONS) resolved[name] = switchOption(name, options[name]);
@@ -877,44 +935,6 @@
877
935
  return template.content;
878
936
  }
879
937
 
880
- // src/shopify-values.ts
881
- function isHttpsUrl(url2) {
882
- if (typeof url2 !== "string") return false;
883
- try {
884
- return new URL(url2).protocol === "https:";
885
- } catch {
886
- return false;
887
- }
888
- }
889
- function formatMoney(money, locale) {
890
- if (!money) return "";
891
- const amount = parseFloat(money.amount);
892
- if (Number.isNaN(amount)) return "";
893
- try {
894
- return new Intl.NumberFormat(locale || void 0, { style: "currency", currency: money.currencyCode }).format(
895
- amount
896
- );
897
- } catch {
898
- return `${money.currencyCode} ${amount.toFixed(2)}`;
899
- }
900
- }
901
- function productUrl(productPath, handle, id) {
902
- if (!/\{(handle|id)\}/.test(productPath)) {
903
- return handle ? `${productPath.replace(/\/$/, "")}/${encodeURIComponent(handle)}` : null;
904
- }
905
- const numericId2 = id ? id.split("/").at(-1) ?? "" : "";
906
- if (productPath.includes("{handle}") && !handle) return null;
907
- if (productPath.includes("{id}") && !numericId2) return null;
908
- return productPath.replace(/\{handle\}/g, encodeURIComponent(handle ?? "")).replace(/\{id\}/g, encodeURIComponent(numericId2));
909
- }
910
- function productKey(raw) {
911
- const value = String(raw ?? "").trim();
912
- if (!value) return null;
913
- if (value.startsWith("gid://")) return value;
914
- if (/^\d+$/.test(value)) return `gid://shopify/Product/${value}`;
915
- return /\/products\/([^/?#]+)/.exec(value)?.[1] ?? value;
916
- }
917
-
918
938
  // src/images.ts
919
939
  function imageUrl(url2, { width, height, crop } = {}) {
920
940
  if (!url2) return url2;
@@ -1205,6 +1225,31 @@
1205
1225
  return null;
1206
1226
  }
1207
1227
  }
1228
+ var INTEGER_TEXT = /^-?\d+$/;
1229
+ var invalidIntegerAttributes = /* @__PURE__ */ new WeakMap();
1230
+ function warnInvalidAttribute(el, name, message) {
1231
+ const warned = invalidIntegerAttributes.get(el) ?? /* @__PURE__ */ new Set();
1232
+ invalidIntegerAttributes.set(el, warned);
1233
+ if (warned.has(name)) return;
1234
+ warned.add(name);
1235
+ warn(`${attr(name)} ${message}`, el);
1236
+ }
1237
+ function integerAttribute(el, name, { min, max, fallback }) {
1238
+ const raw = get(el, name)?.trim();
1239
+ if (!raw) return fallback;
1240
+ const value = INTEGER_TEXT.test(raw) ? Number(raw) : Number.NaN;
1241
+ if (Number.isNaN(value) || value < min) {
1242
+ warnInvalidAttribute(
1243
+ el,
1244
+ name,
1245
+ `${JSON.stringify(raw)} is not a whole number from ${String(min)}: using ${String(fallback)}`
1246
+ );
1247
+ return fallback;
1248
+ }
1249
+ if (max === void 0 || value <= max) return value;
1250
+ warnInvalidAttribute(el, name, `${raw} is more than its maximum: using ${String(max)}`);
1251
+ return max;
1252
+ }
1208
1253
  function attributeText(value) {
1209
1254
  if (value === null || value === void 0) return "";
1210
1255
  if (typeof value === "string") return value;
@@ -3436,7 +3481,7 @@
3436
3481
  }
3437
3482
 
3438
3483
  // src/part-integrity.ts
3439
- var PART_INTEGRITY = { "tether.diagnose.js": "sha384-6b98ZqhqrOFydwTyklda6rjvyWrgz1OnmffApLQ3+gg6VPSU1Yy3LhR1OT4lprfa", "tether.markets.js": "sha384-f9ZeUfc/tMICwVFPrC44Sa1oxm9c6jTQASJdNhHWDk55thsEVScodDBKSYUiuDgr", "tether.search.js": "sha384-kNQI7aVmvUyNgV2e6+PRy53xmbKiZi2n1hhYmHUDFCGU3BR6SoGpGKVKVbPE0ZtG", "tether.lists.js": "sha384-MfQgl9RjiTn6vr80fQymnFikrsDXh3wcmT8cu858s7z9p/oByQaJUKZo92qhjX1P", "tether.extras.js": "sha384-H4CWsEibHw/99UiBAi366ctyaNZrVMkK6Y1YJYYcGDbNthy5eQdS+RRcrlm1clmQ", "tether.account.js": "sha384-UeOp/wddJlVjmlYcVqqO9hU7ANLYEtY/TtK/y5cFkQ6J+SPBmqI/VReaAh+reCMC", "tether.account-pages.js": "sha384-jBeU+vF/U13v+9LZxg5R8lQb/PDHTXPVvu1EmsdDUrlh7BmIntbZJh2+iT6YykTy", "tether.analytics.js": "sha384-4gJ/lcu+S+sfpEHu64+0m2zbXpvNsyOxKDQchPEIb1SFg3ky1JlXODNSdRoodST9" };
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" };
3440
3485
 
3441
3486
  // src/part-registry.ts
3442
3487
  function isTetherInternals(value) {
@@ -3444,7 +3489,7 @@
3444
3489
  }
3445
3490
 
3446
3491
  // src/version.ts
3447
- var VERSION = "0.9.1";
3492
+ var VERSION = "0.9.3";
3448
3493
 
3449
3494
  // src/lazy-iife.ts
3450
3495
  var coreModules = {
@@ -3466,6 +3511,7 @@
3466
3511
  get,
3467
3512
  has,
3468
3513
  hasTemplate,
3514
+ integerAttribute,
3469
3515
  isOwnEvent,
3470
3516
  notifyLayoutChanged,
3471
3517
  parseJSONAttr,
@@ -3511,7 +3557,7 @@
3511
3557
  return [setCountry];
3512
3558
  },
3513
3559
  get "shopify-values.ts"() {
3514
- return [isHttpsUrl];
3560
+ return [isHttpsUrl, MAX_CONNECTION_SIZE];
3515
3561
  },
3516
3562
  // Parts that load other parts (account → account-pages) use this same loader.
3517
3563
  get "lazy.ts"() {
@@ -25,7 +25,7 @@
25
25
 
26
26
  // tether-core:dom.ts
27
27
  var m3 = window.Tether.__core["dom.ts"];
28
- var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m3;
28
+ var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, integerAttribute, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m3;
29
29
 
30
30
  // tether-core:fragments.ts
31
31
  var m4 = window.Tether.__core["fragments.ts"];
@@ -71,6 +71,10 @@
71
71
  var m7 = window.Tether.__core["collection.ts"];
72
72
  var [listSelector] = m7;
73
73
 
74
+ // tether-core:shopify-values.ts
75
+ var m8 = window.Tether.__core["shopify-values.ts"];
76
+ var [isHttpsUrl, MAX_CONNECTION_SIZE] = m8;
77
+
74
78
  // src/lists.ts
75
79
  var URL_QUERY_SOURCE = "url:";
76
80
  var COLLECTION_QUERY = `query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${collectionFields()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`;
@@ -126,7 +130,7 @@
126
130
  return list;
127
131
  }
128
132
  var isElement = (target) => target instanceof window.Element;
129
- var toLimit = (raw) => parseInt(raw ?? "", 10) || void 0;
133
+ var listLimit = (root, fallback) => integerAttribute(root, "limit", { min: 1, max: MAX_CONNECTION_SIZE, fallback });
130
134
  var toIntent = (raw) => raw === "COMPLEMENTARY" ? "COMPLEMENTARY" : "RELATED";
131
135
  var ListScope = class {
132
136
  constructor(root) {
@@ -151,9 +155,10 @@
151
155
  /** The collection or search query of the list's attributes. */
152
156
  options() {
153
157
  const { root } = this;
154
- const query = { reverse: get(root, "reverse") === "true" };
155
- const first = toLimit(get(root, "limit"));
156
- if (first) query.first = first;
158
+ const query = {
159
+ reverse: get(root, "reverse") === "true",
160
+ first: listLimit(root, cfg.collectionFirst)
161
+ };
157
162
  const sortKey = get(root, "sort");
158
163
  if (sortKey) query.sortKey = sortKey;
159
164
  if (has(root, "collection")) {
@@ -185,8 +190,7 @@
185
190
  if (has(this.root, "recommendations")) {
186
191
  const recommendations = await this.loadRecommendations();
187
192
  if (stale()) return;
188
- const limit = toLimit(get(this.root, "limit"));
189
- this.products = limit ? recommendations.slice(0, limit) : recommendations;
193
+ this.products = recommendations.slice(0, listLimit(this.root, recommendations.length));
190
194
  } else {
191
195
  const page = await getProducts({ ...this.options(), after: more ? this.pageInfo?.endCursor ?? null : null });
192
196
  if (stale()) return;
@@ -1 +1 @@
1
- (()=>{var O=Object.defineProperty;var et=(e,t,o)=>t in e?O(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var ot=(e,t)=>{for(var o in t)O(e,o,{get:t[o],enumerable:!0})};var a=(e,t,o)=>et(e,typeof t!="symbol"?t+"":t,o);var S={};ot(S,{getProducts:()=>J,getRecommendations:()=>Z,loadList:()=>ht});var rt=window.Tether.__core["config.ts"],[b,yt,Pt,Tt,Et,A,xt]=rt;var nt=window.Tether.__core["client.ts"],[$t,l,st,P,u,T]=nt;var it=window.Tether.__core["dom.ts"],[Ct,E,kt,L,p,Nt,St,i,m,_t,Ot,K,bt,At,Lt,M,U,c,q,F,x,f]=it;var ct=window.Tether.__core["fragments.ts"],[D]=ct;var at=window.Tether.__core["loader.ts"],[Ut,qt,v,h,g]=at;function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var R={amount:"string",currencyCode:"string"},H={id:"string",handle:"string",title:"string",options:["object"],images:{nodes:["object"]},priceRange:{minVariantPrice:R,maxVariantPrice:R},variants:{nodes:[{id:"string",price:R,selectedOptions:["object"]}]}},Q={nodes:[H],pageInfo:{hasNextPage:"boolean"}};var Y=u({collection:P({handle:"string",products:Q})}),j=u({products:Q}),z=u({productRecommendations:P([H])});var dt=window.Tether.__core["status.ts"],[jt,$,I,C]=dt;var lt=window.Tether.__core["collection.ts"],[k]=lt;var B="url:",ut=`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}}}}`,pt="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 J({collection:e,query:t,first:o=b.collectionFirst,after:r=null,sortKey:n,reverse:s=!1,filters:X}={}){if(e){let _=await l(g(ut),{handle:e,first:o,after:r,sortKey:n||void 0,reverse:s,filters:X??void 0},Y);if(!_.collection)throw new T(`Collection not found: ${e}`,{code:"NOT_FOUND"});let{products:y,...tt}=_.collection;return y.nodes.forEach(h),{collection:tt,products:y.nodes,pageInfo:y.pageInfo}}let w=await l(g(pt),{first:o,after:r,query:t||void 0,sortKey:n||void 0,reverse:s},j);return w.products.nodes.forEach(h),{collection:null,products:w.products.nodes,pageInfo:w.products.pageInfo}}async function Z(e,t="RELATED"){let o=v(typeof e=="object"?e?.id:e);if(!o)throw new T("No product for recommendations",{code:"NOT_FOUND"});let r=o.startsWith("gid://"),s=(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},z)).productRecommendations??[];return s.forEach(h),s}var mt=e=>e instanceof window.Element,V=e=>parseInt(e??"",10)||void 0,ft=e=>e==="COMPLEMENTARY"?"COMPLEMENTARY":"RELATED",N=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(!mt(o.target))return;let r=o.target.closest(c("load-more"));r?.closest(k())===t&&(o.preventDefault(),L(r,()=>this.load(!0)))})}$(t){return U(this.root,t,k())}options(){let{root:t}=this,o={reverse:i(t,"reverse")==="true"},r=V(i(t,"limit"));r&&(o.first=r);let n=i(t,"sort");if(n&&(o.sortKey=n),m(t,"collection"))return o.collection=i(t,"collection")??"",o;let s=i(t,"products")??"";return o.query=s.startsWith(B)?new URL(window.location.href).searchParams.get(s.slice(B.length))||"":s,o}async loadRecommendations(){let{key:t}=I(this.root,window.location,"recommendations"),o=this.root.closest(c("product"));return!t&&o&&({key:t}=I(o)),Z(t,ft(i(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;let s=V(i(this.root,"limit"));this.products=s?n.slice(0,s):n}else{let n=await J({...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(),C(this.root,"ready"),p("list-ready",{products:this.products,collection:this.collection},this.root)}catch(n){if(r())return;t||C(this.root,$(n)?"not-found":"error",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(i(r,"collection-bind")??""){case"title":x(r,t?.title??"");break;case"description":F(r,t?.descriptionHtml);break;case"image":q(r,t?.image?.url,t?.image?.altText||t?.title);break;case"count":x(r,this.products.length);break}}),this.$(c("list")).forEach(r=>{M(r,this.products,(n,s)=>{n.setAttribute(E("product"),s.handle),n.removeAttribute(E("state"))}),p("list-rendered",{container:r},this.root)});let o=this.products.length===0;this.$(c("show")).forEach(r=>{let n=i(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")}},W=new WeakMap;function ht(e){let t=W.get(e);return t||(t=new N(e),W.set(e,t)),t.load()}function gt(e){return d(e)&&d(e.__core)&&d(e.__parts)}function G(e,t){let o=Reflect.get(window,"Tether");if(!gt(o))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);o.__parts[e]=t}G("lists",S);})();
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);})();
@@ -36,7 +36,7 @@
36
36
 
37
37
  // tether-core:dom.ts
38
38
  var m6 = window.Tether.__core["dom.ts"];
39
- var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m6;
39
+ var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, integerAttribute, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m6;
40
40
 
41
41
  // tether-core:mounting.ts
42
42
  var m7 = window.Tether.__core["mounting.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"],[c,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,w,at,ct,it,ut]=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=()=>`${c.prefix}:market:${c.domain}`,j={getItem:e=>U(e)};function ce(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:j,global:e?window:{}}}function ie(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(ie(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"),i=n("tether-country")||de(t.document,e.cookie||ae);return{country:a||i,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 i=h(e.locales,o)??h(e.locales,o.split("-")[0]);if(i)return{locale:o,...i};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=c.markets,t=ce()){let n=(e===c.markets?e:S(e))??{};if(n.detect===!1)return{};let a={},o={sources:a};for(let i of pe(n.detect)){let r=me(i,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=i),l&&!o.language&&(o.language=l,a.language=i),f&&!o.locale&&(o.locale=f,a.locale=i)}return o}function $(e){if(c.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),i=o.length?o.map(r=>t.find(u=>u.isoCode===r)).filter(r=>r!==void 0):t;e.replaceChildren(...i.map(r=>new Option(Le(a,r),r.isoCode))),e.value=n,e.value!==n&&(e.selectedIndex=-1),e.disabled=i.length<2&&!e.hasAttribute(m("always-enabled"))}function Me(e,t,n){let a=(c.country||n.country.isoCode).toUpperCase(),o=[...n.availableCountries].sort((r,u)=>r.name.localeCompare(u.name,c.locale||void 0)),i=o.find(r=>r.isoCode===a)??n.country;e.forEach(r=>{be(r,o,a)}),t.forEach(r=>{r.textContent=Y(i,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(c.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:c.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 i=Se(o),r=n||i?.locale,u=r||c.locale,l=xe(t,i),f=o!==c.country||l!==c.language||u!==c.locale;if(c.country=o,c.language=l||void 0,c.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:c.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]=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);})();