@numueg/theme-sdk 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createContext, forwardRef, useState, useImperativeHandle, useEffect, useCallback, useMemo, useRef, useContext, StrictMode, createElement, Component } from 'react';
2
- import { createRoot } from 'react-dom/client';
2
+ import { hydrateRoot, createRoot } from 'react-dom/client';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
 
5
5
  // src/types/theme.ts
@@ -940,6 +940,29 @@ function useRelatedProducts(productId, options = {}) {
940
940
  }, [productId, limit]);
941
941
  return { items, loading, error };
942
942
  }
943
+ function useProductSizeChart(productOverride) {
944
+ const ctxProduct = useProductOptional();
945
+ const product = productOverride ?? ctxProduct;
946
+ const shop = useShop();
947
+ const storeSettings = shop?.settings;
948
+ return useMemo(
949
+ () => resolveSizeChart(product?.attributes, storeSettings),
950
+ [product?.attributes, storeSettings]
951
+ );
952
+ }
953
+ function hasRows(c) {
954
+ return !!c && typeof c === "object" && Array.isArray(c.rows) && c.rows.length > 0;
955
+ }
956
+ function resolveSizeChart(productAttributes, storeSettings) {
957
+ const product = productAttributes?.size_chart;
958
+ const storeDefault = storeSettings?.size_chart;
959
+ if (product?.mode === "off") return null;
960
+ if (product?.mode === "custom") return hasRows(product) ? product : null;
961
+ if (product?.mode === "default") return hasRows(storeDefault) ? storeDefault : null;
962
+ if (hasRows(product)) return product;
963
+ if (hasRows(storeDefault)) return storeDefault;
964
+ return null;
965
+ }
943
966
  var COOKIE_NAME = "numu_currency";
944
967
  var COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
945
968
  function readCookie(name) {
@@ -1455,6 +1478,12 @@ function normalizeCartFromServer(cart) {
1455
1478
  items: Array.isArray(cart.items) ? cart.items.map((it) => ({ ...it, price: toMajor(it.price) })) : []
1456
1479
  };
1457
1480
  }
1481
+ function unwrapCart(json) {
1482
+ if (json && typeof json === "object" && "data" in json && json.data && typeof json.data === "object") {
1483
+ return json.data;
1484
+ }
1485
+ return json;
1486
+ }
1458
1487
  function readCsrfCookie() {
1459
1488
  if (typeof document === "undefined") return null;
1460
1489
  const match = document.cookie.match(/(?:^|;\s*)numu_csrf=([^;]+)/);
@@ -1474,8 +1503,8 @@ async function postCartMutation(endpoint, body, applyCart, reserveToken) {
1474
1503
  body: body === void 0 ? void 0 : JSON.stringify(body)
1475
1504
  });
1476
1505
  if (!res.ok) return;
1477
- const data = await res.json();
1478
- applyCart(data);
1506
+ const json = await res.json();
1507
+ applyCart(unwrapCart(json));
1479
1508
  }
1480
1509
  function NuMuProvider({
1481
1510
  store,
@@ -1655,7 +1684,8 @@ function NuMuProvider({
1655
1684
  cache: "no-store"
1656
1685
  });
1657
1686
  if (!res.ok || cancelled) return;
1658
- const data = await res.json();
1687
+ const json = await res.json();
1688
+ const data = unwrapCart(json);
1659
1689
  if (data && typeof data === "object") {
1660
1690
  setCart(normalizeCartFromServer(data));
1661
1691
  }
@@ -1702,11 +1732,32 @@ function NuMuProvider({
1702
1732
  );
1703
1733
  const addItem = useCallback(
1704
1734
  async (productId, variantId, quantity) => {
1735
+ const eventId = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}`;
1736
+ const qty = quantity || 1;
1705
1737
  await mutate("/api/cart/add", {
1706
1738
  product_id: productId,
1707
1739
  variant_id: variantId,
1708
- quantity: quantity || 1
1740
+ quantity: qty,
1741
+ _event_id: eventId
1709
1742
  });
1743
+ try {
1744
+ if (typeof window !== "undefined") {
1745
+ window.dispatchEvent(
1746
+ new CustomEvent("numu:analytics:event", {
1747
+ detail: {
1748
+ event: "add_to_cart",
1749
+ payload: {
1750
+ content_ids: [productId],
1751
+ content_type: "product",
1752
+ num_items: qty
1753
+ },
1754
+ event_id: eventId
1755
+ }
1756
+ })
1757
+ );
1758
+ }
1759
+ } catch {
1760
+ }
1710
1761
  },
1711
1762
  [mutate]
1712
1763
  );
@@ -1961,6 +2012,9 @@ function injectFontLink(href) {
1961
2012
  link.setAttribute("data-numu-font", "");
1962
2013
  document.head.appendChild(link);
1963
2014
  }
2015
+ function lookupFontStack(value) {
2016
+ return FONT_REGISTRY[value]?.stack ?? value;
2017
+ }
1964
2018
  function resolveFontStack(value) {
1965
2019
  const entry = FONT_REGISTRY[value];
1966
2020
  if (entry) {
@@ -1969,39 +2023,69 @@ function resolveFontStack(value) {
1969
2023
  }
1970
2024
  return value;
1971
2025
  }
1972
- function applyGlobalStyleTokens(globalSettings, el) {
1973
- if (!el || !globalSettings || typeof globalSettings !== "object") return;
1974
- const style = el.style;
2026
+ function computeGlobalStyleTokens(globalSettings) {
2027
+ const cssVars = {};
2028
+ const fontHrefs = [];
2029
+ if (!globalSettings || typeof globalSettings !== "object") {
2030
+ return { cssVars, fontHrefs };
2031
+ }
2032
+ const pushHref = (href) => {
2033
+ if (href && !fontHrefs.includes(href)) fontHrefs.push(href);
2034
+ };
1975
2035
  for (const [key, value] of Object.entries(globalSettings)) {
1976
2036
  if (!key || key.startsWith("__")) continue;
1977
2037
  if (value && typeof value === "object" && !Array.isArray(value)) {
1978
2038
  for (const [role, c] of Object.entries(value)) {
1979
- if (isColorValue(c)) style.setProperty(`--scheme-${key}-${role}`, c);
2039
+ if (isColorValue(c)) cssVars[`--scheme-${key}-${role}`] = c;
1980
2040
  }
1981
2041
  continue;
1982
2042
  }
1983
2043
  if (isColorValue(value)) {
1984
- style.setProperty(`--theme-${key}`, value.trim());
2044
+ cssVars[`--theme-${key}`] = value.trim();
1985
2045
  const role = COLOR_ROLE_ALIASES[key];
1986
- if (role) style.setProperty(`--theme-color-${role}`, value.trim());
2046
+ if (role) cssVars[`--theme-color-${role}`] = value.trim();
1987
2047
  continue;
1988
2048
  }
1989
2049
  if (isFontToken(value)) {
1990
- const stack = resolveFontStack(value);
1991
- style.setProperty(`--theme-${key}`, stack);
2050
+ const entry = FONT_REGISTRY[value];
2051
+ cssVars[`--theme-${key}`] = entry.stack;
1992
2052
  const role = FONT_ROLE_ALIASES[key];
1993
- if (role) style.setProperty(`--theme-font-${role}`, stack);
2053
+ if (role) cssVars[`--theme-font-${role}`] = entry.stack;
2054
+ pushHref(entry.href);
1994
2055
  continue;
1995
2056
  }
1996
2057
  if (typeof value === "string" || typeof value === "number") {
1997
2058
  const v = String(value).trim();
1998
- if (v) style.setProperty(`--theme-${key}`, v);
2059
+ if (v) cssVars[`--theme-${key}`] = v;
2060
+ }
2061
+ }
2062
+ for (const id of ["heading_font", "body_font"]) {
2063
+ const value = globalSettings[id];
2064
+ if (typeof value === "string" && value.trim()) {
2065
+ cssVars[`--theme-${id}`] = lookupFontStack(value);
2066
+ pushHref(FONT_REGISTRY[value]?.href);
1999
2067
  }
2000
2068
  }
2069
+ return { cssVars, fontHrefs };
2070
+ }
2071
+ function applyGlobalStyleTokens(globalSettings, el) {
2072
+ if (!el || !globalSettings || typeof globalSettings !== "object") return;
2073
+ const { cssVars, fontHrefs } = computeGlobalStyleTokens(globalSettings);
2074
+ const style = el.style;
2075
+ for (const [prop, value] of Object.entries(cssVars)) {
2076
+ style.setProperty(prop, value);
2077
+ }
2078
+ for (const href of fontHrefs) injectFontLink(href);
2001
2079
  }
2002
2080
  function pickStore(ctx) {
2003
2081
  const s = ctx.storeData ?? ctx.store;
2004
- if (s) return s;
2082
+ if (s) {
2083
+ const raw = s;
2084
+ if (!raw.currency && raw.default_currency) {
2085
+ return { ...raw, currency: raw.default_currency };
2086
+ }
2087
+ return s;
2088
+ }
2005
2089
  return {
2006
2090
  id: "unknown",
2007
2091
  name: "Store",
@@ -2036,19 +2120,9 @@ var ThemeMountBridge = forwardRef(function ThemeMountBridge2({ ctx, mountEl, ren
2036
2120
  []
2037
2121
  );
2038
2122
  useEffect(() => {
2123
+ if (!mountEl) return;
2039
2124
  const gs = themeSettings.global_settings ?? {};
2040
2125
  applyGlobalStyleTokens(gs, mountEl);
2041
- const headingFont = gs.heading_font;
2042
- if (typeof headingFont === "string" && headingFont.trim()) {
2043
- mountEl.style.setProperty(
2044
- "--theme-heading_font",
2045
- resolveFontStack(headingFont)
2046
- );
2047
- }
2048
- const bodyFont = gs.body_font;
2049
- if (typeof bodyFont === "string" && bodyFont.trim()) {
2050
- mountEl.style.setProperty("--theme-body_font", resolveFontStack(bodyFont));
2051
- }
2052
2126
  }, [themeSettings, mountEl]);
2053
2127
  const store = pickStore(ctx);
2054
2128
  const template = pickTemplate(ctx);
@@ -2078,22 +2152,22 @@ var ThemeMountBridge = forwardRef(function ThemeMountBridge2({ ctx, mountEl, ren
2078
2152
  }
2079
2153
  );
2080
2154
  });
2155
+ function buildThemeElement(ctx, mountEl, renderApp, ref) {
2156
+ return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(ThemeMountBridge, { ctx, mountEl, renderApp, ref }) });
2157
+ }
2081
2158
  function mountTheme(el, ctx, renderApp) {
2082
- const root = createRoot(el);
2083
2159
  const handleRef = { current: null };
2084
- root.render(
2085
- /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(
2086
- ThemeMountBridge,
2087
- {
2088
- ctx,
2089
- mountEl: el,
2090
- renderApp,
2091
- ref: (h) => {
2092
- handleRef.current = h;
2093
- }
2094
- }
2095
- ) })
2096
- );
2160
+ const element = buildThemeElement(ctx, el, renderApp, (h) => {
2161
+ handleRef.current = h;
2162
+ });
2163
+ const shouldHydrate = ctx.hydrate === true && el.firstElementChild !== null;
2164
+ let root;
2165
+ if (shouldHydrate) {
2166
+ root = hydrateRoot(el, element);
2167
+ } else {
2168
+ root = createRoot(el);
2169
+ root.render(element);
2170
+ }
2097
2171
  return {
2098
2172
  applyDraft: (next) => handleRef.current?.applyDraft(next),
2099
2173
  cleanup: () => {
@@ -2102,6 +2176,14 @@ function mountTheme(el, ctx, renderApp) {
2102
2176
  }
2103
2177
  };
2104
2178
  }
2179
+
2180
+ // src/entry.tsx
2181
+ function defineThemeEntry(renderApp) {
2182
+ return {
2183
+ mount: (el, ctx) => mountTheme(el, ctx, renderApp),
2184
+ createApp: (ctx) => buildThemeElement(ctx, null, renderApp)
2185
+ };
2186
+ }
2105
2187
  function CollectionProvider({ collection, children }) {
2106
2188
  return /* @__PURE__ */ jsx(CollectionContext.Provider, { value: collection, children });
2107
2189
  }
@@ -2131,6 +2213,46 @@ function Money({
2131
2213
  children
2132
2214
  );
2133
2215
  }
2216
+
2217
+ // src/utils/imageTransform.ts
2218
+ var _clampT = (n, lo, hi) => Math.min(hi, Math.max(lo, Number.isFinite(n) ? n : lo));
2219
+ function asImageTransform(v) {
2220
+ if (v && typeof v === "object" && "transform" in v) {
2221
+ const t = v.transform;
2222
+ if (t && typeof t === "object") return t;
2223
+ }
2224
+ return void 0;
2225
+ }
2226
+ function applyImageTransform(t, fit = "cover") {
2227
+ if (!t) return { objectFit: fit };
2228
+ const fx = Math.round(_clampT(t.focal?.x ?? 0.5, 0, 1) * 1e4) / 100;
2229
+ const fy = Math.round(_clampT(t.focal?.y ?? 0.5, 0, 1) * 1e4) / 100;
2230
+ const zoom = _clampT(t.zoom ?? 1, 1, 4);
2231
+ const rot = ((t.rotation ?? 0) % 360 + 360) % 360;
2232
+ const effFit = t.fit ?? fit;
2233
+ const style = {
2234
+ transform: `scale(${zoom}) rotate(${rot}deg)`,
2235
+ transformOrigin: `${fx}% ${fy}%`,
2236
+ objectFit: effFit
2237
+ };
2238
+ if (effFit === "cover") style.objectPosition = `${fx}% ${fy}%`;
2239
+ return style;
2240
+ }
2241
+ var clamp01 = (n) => Math.min(1, Math.max(0, n));
2242
+ function focalSrc(url, options = {}) {
2243
+ if (!url) return "";
2244
+ if (url.startsWith("data:") || /[?&](fp-x|fp-y)=/.test(url)) return url;
2245
+ const p = new URLSearchParams();
2246
+ p.set("url", url);
2247
+ if (options.width) p.set("w", String(Math.round(options.width)));
2248
+ if (options.focal?.x != null) p.set("fp-x", String(clamp01(options.focal.x)));
2249
+ if (options.focal?.y != null) p.set("fp-y", String(clamp01(options.focal.y)));
2250
+ if (options.aspect) p.set("ar", options.aspect);
2251
+ if (options.fit) p.set("fit", options.fit);
2252
+ if (options.quality) p.set("q", String(Math.min(100, Math.max(1, Math.round(options.quality)))));
2253
+ if (options.format) p.set("f", options.format.toLowerCase());
2254
+ return `/api/image-transform?${p.toString()}`;
2255
+ }
2134
2256
  var DEFAULT_WIDTHS2 = [320, 480, 640, 768, 1024, 1280, 1600, 1920];
2135
2257
  function buildSrcSet(src, widths = DEFAULT_WIDTHS2) {
2136
2258
  if (/[?&]w=\d+/.test(src)) return "";
@@ -2143,27 +2265,48 @@ function Image({
2143
2265
  sizes = "(min-width: 1024px) 25vw, (min-width: 640px) 50vw, 100vw",
2144
2266
  responsive = true,
2145
2267
  loading = "lazy",
2268
+ aspectRatio,
2269
+ objectFit,
2270
+ objectPosition,
2271
+ transform,
2146
2272
  className,
2147
2273
  style,
2148
2274
  ...rest
2149
2275
  }) {
2276
+ const framed = Boolean(aspectRatio);
2150
2277
  if (!src) {
2151
- return /* @__PURE__ */ jsx(
2278
+ const placeholder = /* @__PURE__ */ jsx(
2152
2279
  "div",
2153
2280
  {
2154
- className,
2281
+ className: framed ? void 0 : className,
2155
2282
  role: "img",
2156
2283
  "aria-label": alt,
2157
2284
  style: {
2158
2285
  backgroundColor: "rgba(0,0,0,0.05)",
2159
2286
  display: "block",
2160
- ...style
2287
+ width: "100%",
2288
+ height: framed ? "100%" : void 0,
2289
+ ...framed ? {} : style
2161
2290
  }
2162
2291
  }
2163
2292
  );
2293
+ if (!framed) return placeholder;
2294
+ return /* @__PURE__ */ jsx(
2295
+ "span",
2296
+ {
2297
+ className,
2298
+ style: { display: "block", aspectRatio, overflow: "hidden", ...style },
2299
+ children: placeholder
2300
+ }
2301
+ );
2164
2302
  }
2165
2303
  const srcSet = responsive ? buildSrcSet(src) : void 0;
2166
- return /* @__PURE__ */ jsx(
2304
+ const effFit = objectFit ?? (framed ? "cover" : void 0);
2305
+ const fitStyle = transform ? applyImageTransform(transform, effFit === "contain" ? "contain" : "cover") : {
2306
+ ...effFit ? { objectFit: effFit } : {},
2307
+ ...objectPosition ? { objectPosition } : {}
2308
+ };
2309
+ const img = /* @__PURE__ */ jsx(
2167
2310
  "img",
2168
2311
  {
2169
2312
  src,
@@ -2172,11 +2315,27 @@ function Image({
2172
2315
  sizes: srcSet ? sizes : void 0,
2173
2316
  loading,
2174
2317
  decoding: "async",
2175
- className,
2176
- style,
2318
+ className: framed ? void 0 : className,
2319
+ style: framed ? { width: "100%", height: "100%", display: "block", ...fitStyle } : { ...fitStyle, ...style },
2177
2320
  ...rest
2178
2321
  }
2179
2322
  );
2323
+ if (!framed) return img;
2324
+ return /* @__PURE__ */ jsx(
2325
+ "span",
2326
+ {
2327
+ className,
2328
+ style: {
2329
+ display: "block",
2330
+ position: "relative",
2331
+ width: "100%",
2332
+ aspectRatio,
2333
+ overflow: "hidden",
2334
+ ...style
2335
+ },
2336
+ children: img
2337
+ }
2338
+ );
2180
2339
  }
2181
2340
  var ABSOLUTE_URL = /^[a-z]+:|^\/\//i;
2182
2341
  function Link({ to, children, ...rest }) {
@@ -2648,7 +2807,14 @@ function sanitizeHtmlServer(input) {
2648
2807
  return s;
2649
2808
  }
2650
2809
  function RichText({ html, className, as = "div" }) {
2651
- const safe = useMemo(() => sanitizeHtml(html || ""), [html]);
2810
+ const [domReady, setDomReady] = useState(false);
2811
+ useEffect(() => {
2812
+ setDomReady(true);
2813
+ }, []);
2814
+ const safe = useMemo(
2815
+ () => domReady ? sanitizeHtml(html || "") : sanitizeHtmlServer(html || ""),
2816
+ [html, domReady]
2817
+ );
2652
2818
  if (!safe) return null;
2653
2819
  const Tag = as;
2654
2820
  return /* @__PURE__ */ jsx(
@@ -3314,8 +3480,13 @@ function collectBlocks(modules) {
3314
3480
 
3315
3481
  // src/utils/assetUrl.ts
3316
3482
  function getRuntime() {
3317
- if (typeof window === "undefined") return {};
3318
- return window;
3483
+ if (typeof window !== "undefined") {
3484
+ return window;
3485
+ }
3486
+ if (typeof globalThis !== "undefined") {
3487
+ return globalThis;
3488
+ }
3489
+ return {};
3319
3490
  }
3320
3491
  function assetUrl(name) {
3321
3492
  if (!name) return "";
@@ -3332,23 +3503,6 @@ function assetUrl(name) {
3332
3503
  return `${cleanBase}${filename}`;
3333
3504
  }
3334
3505
 
3335
- // src/utils/imageTransform.ts
3336
- var clamp01 = (n) => Math.min(1, Math.max(0, n));
3337
- function focalSrc(url, options = {}) {
3338
- if (!url) return "";
3339
- if (url.startsWith("data:") || /[?&](fp-x|fp-y)=/.test(url)) return url;
3340
- const p = new URLSearchParams();
3341
- p.set("url", url);
3342
- if (options.width) p.set("w", String(Math.round(options.width)));
3343
- if (options.focal?.x != null) p.set("fp-x", String(clamp01(options.focal.x)));
3344
- if (options.focal?.y != null) p.set("fp-y", String(clamp01(options.focal.y)));
3345
- if (options.aspect) p.set("ar", options.aspect);
3346
- if (options.fit) p.set("fit", options.fit);
3347
- if (options.quality) p.set("q", String(Math.min(100, Math.max(1, Math.round(options.quality)))));
3348
- if (options.format) p.set("f", options.format.toLowerCase());
3349
- return `/api/image-transform?${p.toString()}`;
3350
- }
3351
-
3352
3506
  // src/utils/locales.ts
3353
3507
  function flattenMessages(source, prefix = "") {
3354
3508
  const out = {};
@@ -3393,6 +3547,6 @@ function buildLocaleBundle(modules) {
3393
3547
  return bundle;
3394
3548
  }
3395
3549
 
3396
- export { AddToCartButton, Block, CartContext, CollectionCard, CollectionContext, CollectionProvider, CurrencySwitcher, CustomerContext, EditableImage, EditableText, Form, ICON_NAMES, Icon, IconMap, Image, Link, LocaleSwitcher, LocalizationContext, MAX_BLOCK_DEPTH, Money, NavigationContext, NuMuProvider, PageContext, ProductCard, ProductContext, ProductProvider, RichText, Section, SectionContext, ShopContext, ThemeSettingsContext, applyGlobalStyleTokens, assetUrl, availableValues, buildLocaleBundle, clearSdkSingleton, collectBlocks, collectSections, defaultVariant, defineBlock, defineSection, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSourcePath, resolveThemeSettings, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
3550
+ export { AddToCartButton, Block, CartContext, CollectionCard, CollectionContext, CollectionProvider, CurrencySwitcher, CustomerContext, EditableImage, EditableText, Form, ICON_NAMES, Icon, IconMap, Image, Link, LocaleSwitcher, LocalizationContext, MAX_BLOCK_DEPTH, Money, NavigationContext, NuMuProvider, PageContext, ProductCard, ProductContext, ProductProvider, RichText, Section, SectionContext, ShopContext, ThemeSettingsContext, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, buildThemeElement, clearSdkSingleton, collectBlocks, collectSections, computeGlobalStyleTokens, defaultVariant, defineBlock, defineSection, defineThemeEntry, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSizeChart, resolveSourcePath, resolveThemeSettings, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProductSizeChart, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
3397
3551
  //# sourceMappingURL=index.mjs.map
3398
3552
  //# sourceMappingURL=index.mjs.map