@occluze/tether 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -110
- package/dist/esm/astro.js +1 -1
- package/dist/esm/chunks/{account-CXMA5RPZ.js → account-5X563BON.js} +1 -1
- package/dist/esm/chunks/{account-pages-IZO7FEOZ.js → account-pages-XR6QZ3DX.js} +1 -1
- package/dist/esm/chunks/analytics-JSFHDBU3.js +1 -0
- package/dist/esm/chunks/{chunk-BBVUVPMO.js → chunk-255K6OZ7.js} +1 -1
- package/dist/esm/chunks/chunk-3OEIEDTK.js +1 -0
- package/dist/esm/chunks/chunk-55OHYO66.js +1 -0
- package/dist/esm/chunks/chunk-A3GXCQJ4.js +1 -0
- package/dist/esm/chunks/chunk-EW3GKRT4.js +1 -0
- package/dist/esm/chunks/{chunk-N3V45JPS.js → chunk-FM7ZLLVP.js} +1 -1
- package/dist/esm/chunks/chunk-GXCCTPDF.js +1 -0
- package/dist/esm/chunks/{chunk-6TFMLT4A.js → chunk-J7GYROV4.js} +1 -1
- package/dist/esm/chunks/{chunk-WT7RGGJU.js → chunk-KNJB72OO.js} +1 -1
- package/dist/esm/chunks/chunk-KVPLRK6Y.js +1 -0
- package/dist/esm/chunks/chunk-O4G2PAQC.js +1 -0
- package/dist/esm/chunks/chunk-WNFEYPHV.js +1 -0
- package/dist/esm/chunks/{chunk-4HD4J5JC.js → chunk-WXF4L42L.js} +1 -1
- package/dist/esm/chunks/{diagnose-XCEBQKBO.js → diagnose-XQQTDHLQ.js} +1 -1
- package/dist/esm/chunks/extras-6WLNUEGD.js +1 -0
- package/dist/esm/chunks/{markets-ui-M4IQ62CT.js → markets-ui-OAJW4PFU.js} +1 -1
- package/dist/esm/chunks/search-LUECIYJR.js +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -2
- package/dist/tether.diagnose.js +2 -2
- package/dist/tether.diagnose.min.js +2 -2
- package/dist/tether.extras.js +33 -22
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +210 -196
- package/dist/tether.markets.js +13 -2
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +3 -3
- package/dist/tether.min.js.map +4 -4
- package/dist/types/src/account/page-answers.d.ts +3 -1
- package/dist/types/src/analytics.d.ts +3 -1
- package/dist/types/src/cart/mutations.d.ts +2 -2
- package/dist/types/src/cart/store.d.ts +8 -2
- package/dist/types/src/cart.d.ts +1 -0
- package/dist/types/src/client.d.ts +21 -11
- package/dist/types/src/controls/navigation.d.ts +3 -1
- package/dist/types/src/dom.d.ts +3 -1
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/markets.d.ts +9 -2
- package/dist/types/src/markup.d.ts +7 -5
- package/dist/types/src/presets/barba.d.ts +3 -1
- package/dist/types/src/product-state.d.ts +3 -1
- package/dist/types/src/server.d.ts +4 -4
- package/dist/types/src/store-html.d.ts +4 -4
- package/dist/types/src/uri.d.ts +6 -0
- package/package.json +57 -5
- package/dist/esm/chunks/analytics-PG5FPRDN.js +0 -1
- package/dist/esm/chunks/chunk-E5YO6274.js +0 -1
- package/dist/esm/chunks/chunk-EW5SYO6L.js +0 -1
- package/dist/esm/chunks/chunk-HJY2JSNB.js +0 -1
- package/dist/esm/chunks/chunk-MQYB6BH4.js +0 -1
- package/dist/esm/chunks/chunk-RPMBCAGS.js +0 -1
- package/dist/esm/chunks/chunk-VFNHIGCS.js +0 -1
- package/dist/esm/chunks/chunk-YN6LEBEN.js +0 -1
- package/dist/esm/chunks/chunk-Z6HS3H7K.js +0 -1
- package/dist/esm/chunks/extras-4HU3VSBQ.js +0 -1
- package/dist/esm/chunks/search-A5DS2IOS.js +0 -1
|
@@ -138,7 +138,9 @@ export interface Profile {
|
|
|
138
138
|
firstName: string | null;
|
|
139
139
|
lastName: string | null;
|
|
140
140
|
}
|
|
141
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* What a subscription action changed: the contract (pause, resume, cancel) or its next billing cycle (skip, unskip).
|
|
143
|
+
*/
|
|
142
144
|
export type SubscriptionChange = {
|
|
143
145
|
contract: {
|
|
144
146
|
id: string | null;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Called by the core with the events it buffered while this part loaded; the queue then handles events as they come.
|
|
3
|
+
*/
|
|
2
4
|
export declare function startAnalytics(queue: Event[]): Promise<void>;
|
|
@@ -28,8 +28,8 @@ export interface CartLineInput {
|
|
|
28
28
|
export declare function isCartGone(error: unknown): boolean;
|
|
29
29
|
/**
|
|
30
30
|
* @returns True when a change failed without saying whether Shopify applied it: no answer or no whole body came (the
|
|
31
|
-
* network), a 2xx whose body isn't valid, or a server error (5xx
|
|
32
|
-
* Shopify's user errors and a 4xx are clear.
|
|
31
|
+
* network), a 2xx whose body isn't valid, or a server error (a 5xx, or a 2xx with `SERVER_ERROR`), which can come
|
|
32
|
+
* after the change was committed. Shopify's user errors and a 4xx are clear.
|
|
33
33
|
*/
|
|
34
34
|
export declare function isUnclearFailure(error: unknown): boolean;
|
|
35
35
|
/**
|
|
@@ -147,14 +147,20 @@ export declare function forgetSavedCart(): void;
|
|
|
147
147
|
export declare function keepQuietly(cart: ShopifyCart | null): void;
|
|
148
148
|
/** Renders the document with the store's cart. */
|
|
149
149
|
export declare function render(): void;
|
|
150
|
+
/**
|
|
151
|
+
* Why `tether:cart-updated` fired: `load` when the saved cart was loaded, failed to load or was forgotten; `pending`
|
|
152
|
+
* when quick clicks changed a quantity Shopify doesn't have yet, and `settled` once their last request is done; any
|
|
153
|
+
* other value names the change Shopify just answered. `docs/reference.md` lists them.
|
|
154
|
+
*/
|
|
155
|
+
export type CartUpdateReason = 'load' | 'add' | 'update' | 'remove' | 'note' | 'attributes' | 'discount' | 'buyer-identity' | 'pending' | 'settled';
|
|
150
156
|
/** @param reason The `reason` of `tether:cart-updated`. */
|
|
151
|
-
export declare function announce(reason:
|
|
157
|
+
export declare function announce(reason: CartUpdateReason): void;
|
|
152
158
|
/**
|
|
153
159
|
* Keeps a cart Shopify sent after a change, shows it, and tells this page and the visitor's other tabs.
|
|
154
160
|
*
|
|
155
161
|
* @returns `cart`.
|
|
156
162
|
*/
|
|
157
|
-
export declare function commit(cart: ShopifyCart | null, reason:
|
|
163
|
+
export declare function commit(cart: ShopifyCart | null, reason: CartUpdateReason): ShopifyCart | null;
|
|
158
164
|
/** The outcome of loading the saved cart: the cart, `null` when there is none, or the failure. */
|
|
159
165
|
export declare function settleLoad(outcome: {
|
|
160
166
|
kind: 'loaded';
|
package/dist/types/src/cart.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ export declare const Cart: {
|
|
|
68
68
|
/** The quantity to show: the one asked for while an update is on its way. */
|
|
69
69
|
quantityOf: (line: ShopifyCartLine) => number;
|
|
70
70
|
removeLine(lineIds: string | string[]): Promise<ShopifyCart | null>;
|
|
71
|
+
/** Removes the lines the cart has when the change runs, so one queued just before it is cleared too. */
|
|
71
72
|
clear(): Promise<ShopifyCart | null>;
|
|
72
73
|
setNote(note: string | null | undefined): Promise<ShopifyCart | null>;
|
|
73
74
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TetherConfig } from './config.js';
|
|
2
|
-
export type TetherErrorCode = 'NOT_FOUND' | 'NETWORK' | 'NOT_CONFIGURED' | 'NOT_LOGGED_IN' | 'INVALID' | 'INVALID_COUNTRY' | 'INVALID_DISCOUNT' | 'INVALID_RESPONSE' | 'ERROR' | `HTTP_${number}`;
|
|
2
|
+
export type TetherErrorCode = 'NOT_FOUND' | 'NETWORK' | 'NOT_CONFIGURED' | 'NOT_LOGGED_IN' | 'INVALID' | 'INVALID_COUNTRY' | 'INVALID_DISCOUNT' | 'INVALID_RESPONSE' | 'SERVER_ERROR' | 'ERROR' | `HTTP_${number}`;
|
|
3
3
|
export interface GraphQLError {
|
|
4
4
|
message: string;
|
|
5
5
|
extensions?: {
|
|
@@ -13,7 +13,7 @@ export interface UserError {
|
|
|
13
13
|
}
|
|
14
14
|
interface TetherErrorDetails {
|
|
15
15
|
/** Default `HTTP_<status>` with a status, else `ERROR`. */
|
|
16
|
-
code?: TetherErrorCode;
|
|
16
|
+
code?: TetherErrorCode | undefined;
|
|
17
17
|
/** The HTTP status of the response that failed. */
|
|
18
18
|
status?: number;
|
|
19
19
|
/** The GraphQL errors of that response. */
|
|
@@ -67,10 +67,10 @@ export declare const orNull: <T>(shape: ShapeOf<T>) => DataCheck<T | null>;
|
|
|
67
67
|
export declare const shaped: <T>(shape: ShapeOf<T>) => DataCheck<T>;
|
|
68
68
|
/**
|
|
69
69
|
* What an operation does to the store, which decides what is safe to retry. A query only reads, so a failure that may
|
|
70
|
-
* pass is retried: the network (no answer, or a body that stopped arriving), a 429, a 5xx
|
|
71
|
-
* have applied a mutation before a
|
|
72
|
-
* that it didn't run it (429 or `THROTTLED`): sending it again could add
|
|
73
|
-
* an answer that isn't valid, other GraphQL errors) are never retried.
|
|
70
|
+
* pass is retried: the network (no answer, or a body that stopped arriving), a 429, a 5xx, `THROTTLED` and
|
|
71
|
+
* `INTERNAL_SERVER_ERROR`. Shopify may have applied a mutation before a server error or a dropped connection, so a
|
|
72
|
+
* mutation is retried only when Shopify answers that it didn't run it (429 or `THROTTLED`): sending it again could add
|
|
73
|
+
* a line twice. Other failures (a 4xx, a 430, an answer that isn't valid, other GraphQL errors) are never retried.
|
|
74
74
|
*/
|
|
75
75
|
export type Operation = 'query' | 'mutation';
|
|
76
76
|
interface RequestOptions {
|
|
@@ -85,7 +85,7 @@ export interface StoreAccess {
|
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* A query's text, or a function that writes it for what the token may read: Tether's own queries, built from
|
|
88
|
-
* `fragments.ts`, leave out inventory for a token that can't read it.
|
|
88
|
+
* `fragments.ts`, leave out inventory for a token that can't read it. Documents Tether didn't write are strings.
|
|
89
89
|
*/
|
|
90
90
|
export type QueryText = string | ((access: StoreAccess) => string);
|
|
91
91
|
/** @returns The Storefront GraphQL endpoint of `conf`'s store. */
|
|
@@ -108,21 +108,31 @@ export declare function withContext(query: string, ctx?: {
|
|
|
108
108
|
* One Storefront API request, for any config: the browser's shared one (`gql`) or one the server helpers build.
|
|
109
109
|
* Queries carry a time bucket so Shopify's cache of an identical query text is at most `maxAge` seconds old. A query
|
|
110
110
|
* written for the store's access leaves out inventory once the token turns out not to read it (`INVENTORY_FIELD`);
|
|
111
|
-
* a fixed query text is the caller's own, and that refusal is its error
|
|
111
|
+
* a fixed query text is the caller's own, and that refusal is its error, as is a refusal of a text written without
|
|
112
|
+
* inventory, so the refusal costs at most one extra request. How often a failure is retried is
|
|
112
113
|
* `conf.retries`; which failures are retried is the operation's (`Operation`).
|
|
113
114
|
*
|
|
114
115
|
* @param isData Checks that `data` has what the caller then reads, so a malformed answer fails here.
|
|
115
116
|
* @throws {TetherError} `NOT_CONFIGURED` without a domain or token, `NETWORK` when the store can't be reached or
|
|
116
117
|
* the answer's body stops arriving, `INVALID_RESPONSE` for a 2xx whose body isn't valid (not JSON, not in the
|
|
117
|
-
* GraphQL shape, or `data` that `isData` refuses), `
|
|
118
|
+
* GraphQL shape, or `data` that `isData` refuses), `SERVER_ERROR` for a 2xx whose GraphQL errors leave open
|
|
119
|
+
* whether Shopify ran it (a top-level `INTERNAL_SERVER_ERROR`, or a mutation's errors without `data`),
|
|
120
|
+
* `HTTP_<status>` for any other HTTP or GraphQL failure.
|
|
118
121
|
*/
|
|
119
122
|
export declare function request<T>(conf: StorefrontConfig, query: QueryText, variables: Record<string, unknown>, isData: DataCheck<T>, { context, operation }?: RequestOptions): Promise<T>;
|
|
120
123
|
/** `request` with the browser's shared config. */
|
|
121
124
|
export declare function gql<T>(query: QueryText, variables: Record<string, unknown>, isData: DataCheck<T>, options?: RequestOptions): Promise<T>;
|
|
122
125
|
/** The check of `Tether.query()` and the server's `query()`, whose callers read `data` themselves. */
|
|
123
126
|
export declare const hasData: (data: unknown) => data is object;
|
|
124
|
-
/**
|
|
125
|
-
|
|
127
|
+
/**
|
|
128
|
+
* `Tether.query()` and the server's `query()`: a document Tether didn't write, sent with `conf`.
|
|
129
|
+
*
|
|
130
|
+
* @returns Shopify's `data`, checked only for being an object: the caller's own query decides its shape, so the caller
|
|
131
|
+
* checks the fields it reads.
|
|
132
|
+
*/
|
|
133
|
+
export declare function untypedQuery(conf: StorefrontConfig, text: string, variables?: Record<string, unknown>, options?: Omit<RequestOptions, 'operation'>): Promise<object>;
|
|
134
|
+
/** `Tether.query()`: `untypedQuery` with the browser's shared config. */
|
|
135
|
+
export declare function query(text: string, variables?: Record<string, unknown>, options?: Omit<RequestOptions, 'operation'>): Promise<object>;
|
|
126
136
|
/**
|
|
127
137
|
* @param payload A mutation's payload.
|
|
128
138
|
* @param name The mutation, for the error message.
|
|
@@ -5,7 +5,9 @@ interface PageHooks {
|
|
|
5
5
|
mount: (root: Document) => unknown;
|
|
6
6
|
unmount: () => void;
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Records a mount of the whole document, so the `astro:page-load` of the same page sends no second round of requests.
|
|
10
|
+
*/
|
|
9
11
|
export declare function rememberDocumentMount(): void;
|
|
10
12
|
/** Binds the document-wide listeners, once per page load of the script. */
|
|
11
13
|
export declare function bindNavigation(hooks: PageHooks): void;
|
package/dist/types/src/dom.d.ts
CHANGED
|
@@ -46,7 +46,9 @@ export declare const pageGlobal: (name: "TETHER_CONFIG" | "TETHER_INTEGRATION" |
|
|
|
46
46
|
* `onLayoutChange` (else refreshes ScrollTrigger) and emits `tether:layout-changed`, also when either of those throws.
|
|
47
47
|
*/
|
|
48
48
|
export declare function notifyLayoutChanged(reason: string): void;
|
|
49
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Notifies a layout change (`<reason>:images`) once every image in `root` that is still loading has loaded or failed.
|
|
51
|
+
*/
|
|
50
52
|
export declare function watchImages(root: ParentNode, reason: string): void;
|
|
51
53
|
/**
|
|
52
54
|
* Runs `task` with `aria-busy` on `el`; does nothing while `el` is already busy.
|
|
@@ -17,7 +17,7 @@ export type { MarketsConfig, CartWarning } from './config.js';
|
|
|
17
17
|
export type { Money } from './shopify-values.js';
|
|
18
18
|
export type { Image as ShopifyImage, Metafield as ShopifyMetafield, Product as ShopifyProduct, ProductVariant as ShopifyVariant, SellingPlan as ShopifySellingPlanNode, SellingPlanAdjustmentValue, SellingPlanAllocation as ShopifySellingPlanAllocation, SellingPlanGroup as ShopifySellingPlanGroup, } from './fragments.js';
|
|
19
19
|
export type { PlanInGroup as ShopifySellingPlan, PlanAdjustment, ProductWithPlans, VariantWithPlans, } from './selling-plans.js';
|
|
20
|
-
export type { CartStatus, CartVariant as ShopifyCartVariant, ShopifyCart, ShopifyCartLine } from './cart/store.js';
|
|
20
|
+
export type { CartStatus, CartUpdateReason, CartVariant as ShopifyCartVariant, ShopifyCart, ShopifyCartLine, } from './cart/store.js';
|
|
21
21
|
export type { Attributes, LineSpec as LineInput } from './cart/mutations.js';
|
|
22
22
|
export type { TetherError, TetherErrorCode, GraphQLError, UserError } from './client.js';
|
|
23
23
|
export type { ProductScope } from './product.js';
|
|
@@ -33,7 +33,7 @@ export type { AddressFields as CustomerAddressInput } from './account/operations
|
|
|
33
33
|
export type { CustomerAddress, Fulfillment, MailingAddress, OrderDetail, OrderDetailLine, SubscriptionContract, SubscriptionLine, } from './account/page-answers.js';
|
|
34
34
|
/** The helpers for selling plans, `Tether.plans`. */
|
|
35
35
|
export type SellingPlanHelpers = typeof plans;
|
|
36
|
-
export declare const VERSION = "0.
|
|
36
|
+
export declare const VERSION = "0.8.0";
|
|
37
37
|
/**
|
|
38
38
|
* Mounts every product scope and product list inside `root`. Safe to call repeatedly.
|
|
39
39
|
*
|
|
@@ -50,8 +50,15 @@ export interface Localization {
|
|
|
50
50
|
/** The localStorage key of the visitor's market: `<prefix>:market:<domain>`. */
|
|
51
51
|
export declare const storageKey: () => string;
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* A market as `rememberMarket` stores it, validated: storage is written by other tabs, older versions and other
|
|
54
|
+
* scripts too.
|
|
55
|
+
*
|
|
56
|
+
* @param text The value stored under `storageKey()`.
|
|
57
|
+
* @returns `null` when it isn't a valid market.
|
|
58
|
+
*/
|
|
59
|
+
export declare const parseSavedMarket: (text: string) => Market | null;
|
|
60
|
+
/**
|
|
61
|
+
* The visitor's saved market (`setCountry()`, `tether-country-select`).
|
|
55
62
|
*
|
|
56
63
|
* @param storage Default `localStorage`.
|
|
57
64
|
* @returns `null` when nothing valid is saved.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ShopifyCart } from './cart/store.js';
|
|
1
|
+
import type { CartUpdateReason, ShopifyCart } from './cart/store.js';
|
|
2
2
|
import type { CartLineInput } from './cart/mutations.js';
|
|
3
3
|
import type { CartWarning } from './config.js';
|
|
4
4
|
import type { Product, ProductVariant } from './fragments.js';
|
|
@@ -23,8 +23,8 @@ export declare function qsa(root: ParentNode | null | undefined, selector: strin
|
|
|
23
23
|
export declare const scoped: (root: Element | null | undefined, selector: string, scopeSelector: string) => HTMLElement[];
|
|
24
24
|
/**
|
|
25
25
|
* The events Tether dispatches, as `<prefix>:<name>` (`tether:cart-updated`), bubbling up to `document`, with the
|
|
26
|
-
* detail each carries. `emit` takes only these, and `Tether.on()` passes on only the events `emit` dispatched, so a
|
|
27
|
-
* detail its event really has.
|
|
26
|
+
* detail each carries. `emit` takes only these, and `Tether.on()` passes on only the events `emit` dispatched, so a
|
|
27
|
+
* listener gets the detail its event really has.
|
|
28
28
|
*/
|
|
29
29
|
export interface TetherEvents {
|
|
30
30
|
ready: {
|
|
@@ -68,7 +68,7 @@ export interface TetherEvents {
|
|
|
68
68
|
};
|
|
69
69
|
'cart-updated': {
|
|
70
70
|
cart: ShopifyCart | null;
|
|
71
|
-
reason:
|
|
71
|
+
reason: CartUpdateReason;
|
|
72
72
|
};
|
|
73
73
|
'cart-toggled': {
|
|
74
74
|
open: boolean;
|
|
@@ -125,7 +125,9 @@ export declare const ANALYTICS_EVENTS: readonly ["product-ready", "list-ready",
|
|
|
125
125
|
export type AnalyticsEventName = (typeof ANALYTICS_EVENTS)[number];
|
|
126
126
|
/** @returns The bubbling event `<prefix>:<name>`, known to `isOwnEvent`. */
|
|
127
127
|
export declare function ownEvent<Name extends keyof TetherEvents>(name: Name, detail: TetherEvents[Name]): CustomEvent<TetherEvents[Name]>;
|
|
128
|
-
/**
|
|
128
|
+
/**
|
|
129
|
+
* @returns True for an event `ownEvent` created as `name`, false for any other, such as one another script dispatched.
|
|
130
|
+
*/
|
|
129
131
|
export declare function isOwnEvent<Name extends keyof TetherEvents>(event: Event, name: Name): event is CustomEvent<TetherEvents[Name]>;
|
|
130
132
|
/** Dispatches the bubbling event `<prefix>:<name>`. */
|
|
131
133
|
export declare function emit<Name extends keyof TetherEvents>(name: Name, detail: TetherEvents[Name], target?: EventTarget): void;
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
* Tether.unmount();
|
|
22
22
|
*/
|
|
23
23
|
import type { TetherConfig } from '../config.js';
|
|
24
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* `gsap`, `lenis` and `scrollTrigger` are getters, read each time they are used, so an instance made later is found.
|
|
26
|
+
*/
|
|
25
27
|
interface BarbaPresetOptions {
|
|
26
28
|
/** Default `window.gsap`. */
|
|
27
29
|
gsap?: () => unknown;
|
|
@@ -98,7 +98,9 @@ export declare function initialChoice(product: Product, { variant, sellingPlan,
|
|
|
98
98
|
* @returns `null` for a product without variants.
|
|
99
99
|
*/
|
|
100
100
|
export declare function productView(product: Product, choice: ProductChoice, lowStock: number): ProductView | null;
|
|
101
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* The `tether-bind` values that follow the variant and purchase. Thunks, so only the binds on the page are computed.
|
|
103
|
+
*/
|
|
102
104
|
export declare function variantBindTexts(view: ProductView, format: Formatters): Map<string, () => BindText>;
|
|
103
105
|
/**
|
|
104
106
|
* The `tether-plan-bind` values of one plan in a plan list, for the variant.
|
|
@@ -42,8 +42,8 @@ interface HydrateOptions {
|
|
|
42
42
|
images?: number;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
|
-
* @returns `productPath` `/products` → `/products/<handle>`; templates with `{handle}` and `{id}` work too. `null`
|
|
46
|
-
* the path needs a handle or an id that is empty.
|
|
45
|
+
* @returns `productPath` `/products` → `/products/<handle>`; templates with `{handle}` and `{id}` work too. `null`
|
|
46
|
+
* when the path needs a handle or an id that is empty.
|
|
47
47
|
*/
|
|
48
48
|
export declare function productUrl(handle: string, { productPath, id }?: {
|
|
49
49
|
productPath?: string;
|
|
@@ -82,7 +82,7 @@ export declare function createStorefront(options?: StorefrontOptions): {
|
|
|
82
82
|
id: string;
|
|
83
83
|
} | null | undefined, intent?: "RELATED" | "COMPLEMENTARY") => Promise<Product[]>;
|
|
84
84
|
config: ServerConfig;
|
|
85
|
-
query:
|
|
85
|
+
query: (query: string, variables?: Record<string, unknown>, requestOptions?: {
|
|
86
86
|
context?: boolean;
|
|
87
|
-
}) => Promise<
|
|
87
|
+
}) => Promise<object>;
|
|
88
88
|
};
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
* action, an email gate). An origin a site adds is trusted the same way.
|
|
25
25
|
*
|
|
26
26
|
* Not prevented: content wider than the description (a table or embed on a narrow screen, or a box given a large
|
|
27
|
-
* width in pixels) overflows beside it, as in any HTML, and a capped shadow or outline still paints just past it.
|
|
28
|
-
* doesn't clip the element it fills (`contain: paint`, `overflow`), because that would cut off those wide
|
|
29
|
-
* embeds, stop margins collapsing through it and make it contain floats, changing how ordinary
|
|
30
|
-
* site that wants the clip sets it on that element in its own CSS.
|
|
27
|
+
* width in pixels) overflows beside it, as in any HTML, and a capped shadow or outline still paints just past it.
|
|
28
|
+
* Tether doesn't clip the element it fills (`contain: paint`, `overflow`), because that would cut off those wide
|
|
29
|
+
* tables and embeds, stop margins collapsing through it and make it contain floats, changing how ordinary
|
|
30
|
+
* descriptions look. A site that wants the clip sets it on that element in its own CSS.
|
|
31
31
|
*/
|
|
32
32
|
/**
|
|
33
33
|
* Store HTML as a fragment of content elements only.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decoding of percent-escaped text the page hands Tether (a path segment, a cookie value), which nothing guarantees
|
|
3
|
+
* is well formed.
|
|
4
|
+
*/
|
|
5
|
+
/** @returns `text` decoded, or as written when it has a malformed escape (`%E0%A4%A`). */
|
|
6
|
+
export declare function decodeOrKeep(text: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@occluze/tether",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Free, open-source alternative to Smootify and Storesynk (Shopyflow): Shopify products, cart and subscriptions in Webflow with HTML attributes. Optional Shopify to Webflow CMS sync.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/esm/index.js",
|
|
@@ -37,17 +37,17 @@
|
|
|
37
37
|
"lint": "eslint .",
|
|
38
38
|
"typecheck": "tsc -b",
|
|
39
39
|
"knip": "knip",
|
|
40
|
-
"deps": "depcruise src server/src server/bin server/scripts scripts",
|
|
40
|
+
"deps": "depcruise --config .config/dependency-cruiser.cjs src server/src server/bin server/scripts scripts",
|
|
41
41
|
"check": "npm run format:check && npm run lint && npm run typecheck && npm run knip && npm run deps && npm test",
|
|
42
42
|
"prepare": "lefthook install",
|
|
43
43
|
"test": "node --experimental-strip-types --test test/*.test.js server/test/*.test.js && npm run test:types",
|
|
44
|
-
"test:types": "tsc -p types/tsconfig.json",
|
|
44
|
+
"test:types": "tsc -p test/types/tsconfig.json",
|
|
45
45
|
"smoke": "node --experimental-strip-types scripts/smoke.ts",
|
|
46
46
|
"pretest": "node --experimental-strip-types scripts/build.ts --out .test-dist",
|
|
47
47
|
"presmoke": "node --experimental-strip-types scripts/build.ts",
|
|
48
48
|
"release": "node --experimental-strip-types scripts/release.ts",
|
|
49
|
-
"e2e:build": "npm run build && cd examples/astro && (test -f .env || cp .env.example .env) && npm install --no-audit --no-fund
|
|
50
|
-
"e2e": "npm run e2e:build && playwright test -c e2e/playwright.config.js"
|
|
49
|
+
"e2e:build": "npm run build && cd examples/astro && (test -f .env || cp .env.example .env) && npm install --no-save --no-audit --no-fund --ignore-scripts ../.. && npx astro build",
|
|
50
|
+
"e2e": "npm run e2e:build && playwright test -c test/e2e/playwright.config.js"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@eslint/js": "10.0.1",
|
|
@@ -118,5 +118,57 @@
|
|
|
118
118
|
},
|
|
119
119
|
"engines": {
|
|
120
120
|
"node": ">=22.18"
|
|
121
|
+
},
|
|
122
|
+
"prettier": {
|
|
123
|
+
"printWidth": 120,
|
|
124
|
+
"singleQuote": true,
|
|
125
|
+
"trailingComma": "all",
|
|
126
|
+
"overrides": [
|
|
127
|
+
{
|
|
128
|
+
"files": "*.md",
|
|
129
|
+
"options": {
|
|
130
|
+
"embeddedLanguageFormatting": "off"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"files": "CHANGELOG.md",
|
|
135
|
+
"options": {
|
|
136
|
+
"proseWrap": "always",
|
|
137
|
+
"printWidth": 100
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
"knip": {
|
|
143
|
+
"entry": [
|
|
144
|
+
"src/index.ts",
|
|
145
|
+
"src/server.ts",
|
|
146
|
+
"src/astro.ts",
|
|
147
|
+
"src/presets/barba.ts",
|
|
148
|
+
"src/parts/*.ts",
|
|
149
|
+
"src/lazy-iife.ts",
|
|
150
|
+
"server/src/entry.{js,ts}",
|
|
151
|
+
"server/src/index.ts",
|
|
152
|
+
"server/bin/tether-sync.{js,ts}",
|
|
153
|
+
"server/scripts/*.{mjs,ts}",
|
|
154
|
+
"scripts/*.ts",
|
|
155
|
+
"test/**/*.js",
|
|
156
|
+
"server/test/**/*.js",
|
|
157
|
+
"test/e2e/*.{js,mjs}",
|
|
158
|
+
"test/types/check.ts"
|
|
159
|
+
],
|
|
160
|
+
"project": [
|
|
161
|
+
"src/**/*.ts",
|
|
162
|
+
"server/src/**/*.{js,ts}",
|
|
163
|
+
"server/bin/*.{js,ts}",
|
|
164
|
+
"server/scripts/*.{mjs,ts}",
|
|
165
|
+
"scripts/*.ts"
|
|
166
|
+
],
|
|
167
|
+
"ignoreBinaries": [
|
|
168
|
+
"tsc"
|
|
169
|
+
]
|
|
170
|
+
},
|
|
171
|
+
"overrides": {
|
|
172
|
+
"minimatch": "11.0.5"
|
|
121
173
|
}
|
|
122
174
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as A}from"./chunk-YN6LEBEN.js";import"./chunk-BBVUVPMO.js";import"./chunk-VFNHIGCS.js";import{e as h}from"./chunk-HJY2JSNB.js";import"./chunk-6TFMLT4A.js";import{d as k,i as E,n as p,s as _,t as w}from"./chunk-MQYB6BH4.js";import{r as a,x as T,z as l}from"./chunk-E5YO6274.js";var F=500,S={"default-banner":"https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js",other:"https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.2/consent-tracking-api.js"},O="https://cdn.shopify.com/storefront/analytics/shopify.js",x=()=>window,m=()=>x().Shopify;function L(){let t=a.analytics?.shopify;return typeof t=="object"?t:{}}function I(){try{let t=m()?.customerPrivacy;return t?.consentStatus==="loaded"&&t.currentVisitorConsent?.()?.analytics!=="no"&&!!t.analyticsProcessingAllowed?.()}catch{return!1}}function j(t){let e=`hydrogen:${t}`;return{getTrackingValues:()=>{let n=I()?m()?.customerPrivacy?.__internal:void 0;return{uniqueToken:n?.uniqueToken?.({generateFallback:!0,tag:e})??"",visitToken:n?.visitToken?.({generateFallback:!0,tag:e})??""}}}}var $=t=>(e,n)=>{let i=t.subscribers.get(e)??new Set;return t.subscribers.set(e,i),i.add(n),()=>t.subscribers.get(e)?.delete(n)};function U(t){let e=[],n=[],i={shop:{shopId:t,channel:"headless"},consent:{mode:L().consent||"no-banner"}},o=()=>{if(I())for(let r of e)for(;r.next<n.length;r.next+=1){let s=n[r.next];s&&G(r,s)}},c={getConfig:()=>i,publish(r,s={}){if(n.push({event:r,payload:{shop:i.shop,url:window.location.href,...s}}),n.length>F){n.shift();for(let d of e)d.next=Math.max(0,d.next-1)}o()},addDestination(r){let s={name:r.name,next:0,subscribers:new Map,context:j(r.name)};return Promise.resolve(r.setup?.({subscribe:$(s),getConfig:c.getConfig})).then(()=>{e.push(s),o()}).catch(d=>{l(d,`analytics ${r.name}`)}),()=>{let d=e.indexOf(s);d>=0&&e.splice(d,1)}}};return document.addEventListener("consentTrackingApiLoaded",o),document.addEventListener("visitorConsentCollected",o),c}function G(t,{event:e,payload:n}){t.subscribers.get(e)?.forEach(i=>{try{i(n,t.context)}catch(o){l(o,`analytics ${t.name}`)}})}function P(t){let e=document.createElement("script");e.src=t,e.async=!0,document.head.appendChild(e)}async function R(t){let e=m();if(e?.analytics)return e.analytics;let n=await E("query TetherShopId { shop { id } }",{},k({shop:{id:"string"}}),{context:!1}),i=m()??{};x().Shopify=i,i.country=a.country??"US";let[o="en"]=(a.locale||"en").split("-");i.locale=o.toLowerCase(),i.shop=a.domain,i.routes={root:"/",match:()=>({pageTemplateName:t()?"product":"page"}),...i.routes};let{proxy:c,consent:r}=L();i.customerPrivacy={...i.customerPrivacy,config:c?{isHeadless:!0,asyncConsent:!0,asyncVisitorState:!0,consentDomain:window.location.host}:{isHeadless:!0,storefrontAccessToken:a.token,checkoutRootDomain:a.domain}};let s=U(n.shop.id);return i.analytics=s,P(r==="default-banner"?S["default-banner"]:S.other),P(O),T("shopify analytics ready",n.shop.id),s}var W="Default Title",V=100,H=200,Y=t=>t?parseFloat(t.amount):0,N=t=>(t??"").split("/").pop()??"";function C(t,e,n=1,i){let o={item_id:e?.sku||N(e?.id)||N(t.id),item_name:t.title,item_variant:e?.title===W?void 0:e?.title,item_brand:t.vendor||void 0,item_category:t.productType||void 0,price:Y(e?.price??t.priceRange?.minVariantPrice),quantity:n};return i!=null&&(o.index=i),o}var g=(t,e=t.quantity)=>C(t.merchandise.product,t.merchandise,e);function f(t){let e=t.reduce((n,i)=>n+i.price*(i.quantity||1),0);return Math.round(e*V)/V}var X=(t,e,n=1)=>({id:t.id,title:t.title,price:e.price,vendor:t.vendor||"",variantId:e.id,variantTitle:e.title,quantity:n,sku:e.sku||void 0,productType:t.productType||void 0}),D=t=>({id:t.id,quantity:t.quantity,merchandise:{id:t.merchandise.id,title:t.merchandise.title,price:t.merchandise.price,sku:t.merchandise.sku,product:{id:t.merchandise.product.id,title:t.merchandise.product.title,vendor:t.merchandise.product.vendor||"",handle:t.merchandise.product.handle}}});function Z(){let{dataLayer:t}=a.analytics??{},e=typeof t=="string"?t:"dataLayer",n=Reflect.get(window,e);if(Array.isArray(n))return n;let i=[];return Reflect.set(window,e,i),i}function z(t,e){let n=Z();if(!e){n.push({event:t});return}n.push({ecommerce:null}),n.push({event:t,ecommerce:e})}var y=null,v=null,q=null,b=new WeakSet;function u(t,e,n,i){a.analytics?.dataLayer&&z(t,e),y&&n&&y.publish(n,i);try{a.analytics?.onEvent?.(t,e)}catch(o){l(o,"analytics onEvent")}}function M(){let t=document.querySelector(p("product"));return!t||t.closest(`${p("collection")},${p("products")},${p("recommendations")}`)?null:A.get(t)??null}function J({product:t,scope:e}){if(b.has(e.root)||M()!==e)return;b.add(e.root);let n=e.variant??t.variants.nodes[0],i=[C(t,n)],o=n?[X(t,n)]:[];u("view_item",{currency:n?.price.currencyCode,value:f(i),items:i},"product_viewed",{products:o})}function K({products:t,collection:e}){let n=t.slice(0,H).map((o,c)=>C(o,o.variants.nodes[0],1,c)),i={item_list_id:e?.handle||"products",item_list_name:e?.title||"Products"};if(!e){u("view_item_list",{...i,items:n});return}u("view_item_list",{...i,items:n},"collection_viewed",{collection:{id:e.id,handle:e.handle}})}function Q(t,e,n){let i=t?.cost.totalAmount.currencyCode;e.forEach((o,c)=>{let r=n.get(c),s=o.quantity-(r?.quantity??0);if(s<=0)return;let d=[g(o,s)];u("add_to_cart",{currency:i,value:f(d),items:d},"product_added_to_cart",{cart:t,prevCart:q,currentLine:D(o),prevLine:r?D(r):void 0})}),n.forEach((o,c)=>{let r=o.quantity-(e.get(c)?.quantity??0);if(r<=0)return;let s=[g(o,r)];u("remove_from_cart",{currency:i,value:f(s),items:s})})}function tt({cart:t,reason:e}){let n=new Map((t?.lines.nodes??[]).map(i=>[i.merchandise.id,i]));v&&e!=="load"&&e!=="pending"&&Q(t,n,v),v=n,q=t}function et(){let t=h.lines.map(e=>g(e));u("view_cart",{currency:h.state?.cost.totalAmount.currencyCode,value:f(t),items:t})}function nt({cart:t}){if(!t)return;let e=t.lines.nodes.map(i=>g(i)),n=t.discountCodes.filter(i=>i.applicable).map(i=>i.code);u("begin_checkout",{currency:t.cost.totalAmount.currencyCode,value:f(e),coupon:n.join(",")||void 0,items:e})}var it={"product-ready":J,"list-ready":K,"cart-updated":tt,"cart-toggled":({open:t})=>{t&&et()},checkout:nt,search:({term:t})=>{t&&u("search",{search_term:t},"search_viewed",{searchTerm:t})}};function ot(t,e){it[e](t.detail)}function B(t){if(t.type==="astro:page-load"){b=new WeakSet,y?.publish("page_viewed",{});return}_.forEach(e=>{w(t,e)&&ot(t,e)})}async function ft(t){a.analytics?.shopify&&(y=await R(()=>M()!=null).catch(e=>(l(e,"shopify analytics"),null))),y?.publish("page_viewed",{}),t.splice(0).forEach(B),t.push=(...e)=>(e.forEach(B),t.length)}export{ft as startAnalytics};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var S=Object.defineProperty;var G=(n,e,t)=>e in n?S(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var Fn=(n,e)=>{for(var t in e)S(n,t,{get:e[t],enumerable:!0})};var $n=(n,e,t)=>G(n,typeof e!="symbol"?e+"":e,t);var j=/^(\d{4})-(01|04|07|10)$/;function C(n){let e=j.exec(typeof n=="string"?n:"");return e?{year:Number(e[1]),month:Number(e[2])}:null}var E=n=>C(n)!==null,z=(n,e)=>`${n}-${String(e).padStart(2,"0")}`;function x(n,e=1){let t=C(n);if(!t)throw new Error(`not a quarterly Shopify API version: ${n}`);let o=t.year*4+(t.month-1)/3+e;return z(Math.floor(o/4),o%4*3+1)}function Dn(n,e=new Date){if(n==="unstable")return{version:n,ok:!1,note:'"unstable" changes without notice: pin a dated version such as 2026-07'};let t=C(n);if(!t)return{version:n,ok:!1,note:"not a quarterly version (YYYY-01, -04, -07 or -10)"};let o=new Date(Date.UTC(t.year,t.month-1,1)),r=new Date(Date.UTC(t.year,t.month-1+12,1)),i=(r.getTime()-e.getTime())/2630016e3,f=o<=e,c=`supported until about ${r.toISOString().slice(0,7)}`;return f?i<=0?c="no longer supported: Shopify falls back to the oldest supported version. Upgrade (see README)":i<3&&(c=`${c}: plan the upgrade to ${x(n)} or later (see README)`):c="not released yet (release candidate at best)",{version:n,ok:f&&i>0,monthsLeft:Math.round(i),next:x(n),note:c}}function O(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function Q(n,e){return O(n)?n[e]:void 0}function Z(n){return Array.isArray(n)?n:[]}function B(n){return typeof n=="string"&&n!==""?n:null}var W=n=>typeof n=="number"&&Number.isFinite(n)?n:null,Kn=n=>W(n)??0,R=(n,e)=>Z(n).map(t=>e(t)),Yn=(n,e)=>({nodes:R(Q(n,"nodes"),e)}),vn=n=>R(n,B).filter(e=>e!==null);var J=/^[A-Z]{2}$/,X=new Set(["XX","T1"]),q=new Set(["PT_BR","PT_PT","ZH_CN","ZH_TW"]),nn=/^[A-Z]{2,3}$/;function T(n){let e=(typeof n=="string"?n:"").trim().toUpperCase();return!J.test(e)||X.has(e)?null:e}function w(n){let e=(typeof n=="string"?n:"").trim().replace("-","_").toUpperCase();if(q.has(e))return e;let t=e.split("_")[0]??"";return nn.test(t)?t:null}var _="2026-07";var en=/^[A-Za-z0-9_.-]+$/,tn=/^(\$app(:[A-Za-z0-9_-]+)?|[A-Za-z0-9_.-]+)$/,on=/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,rn=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,sn=/^[A-Za-z_$][\w$]*$/,N="https://site.invalid",an=new Set(["localhost","127.0.0.1","[::1]"]),M=["saved","server","webflow"],un=["no-banner","default-banner","custom-banner"],y=n=>typeof n=="string"&&n!=="",ln=n=>typeof n=="function";function L(n,e){if(typeof n!="string"||!n)return"";let t=n.replace(/^https?:\/\//,"").replace(/\/.*$/,"");return gn(t)?t:(e("domain",n),"")}function U(n){if(!y(n))return!1;try{let e=new URL(n,`${N}/`);return e.origin===N?!0:e.protocol==="https:"||e.protocol==="http:"&&an.has(e.hostname)}catch{return!1}}function I(n,e){return n==null||n===""?null:typeof n=="string"&&(U(n)||cn(n))?n:(e("partsUrl",n),null)}function cn(n){if(typeof location>"u")return!1;try{return new URL(n).origin===location.origin}catch{return!1}}function fn(n){if(typeof n!="string")return null;try{let e=new URL(n);return e.protocol==="https:"&&e.href===new URL(e.origin).href?e.origin:null}catch{return null}}function F(n,e){if(!Array.isArray(n))return e("embedOrigins",n),[];let t=[],o=n;for(let r of o){let i=fn(r);i?t.push(i):e("embedOrigin",r)}return t}function dn(n){let e,t;if(typeof n=="string"){let o=n.indexOf(".");e=o>0?n.slice(0,o):"",t=n.slice(o+1)}else typeof n=="object"&&n!==null&&(e=Reflect.get(n,"namespace"),t=Reflect.get(n,"key"));return typeof e!="string"||typeof t!="string"?null:tn.test(e)&&en.test(t)?{namespace:e,key:t}:null}function $(n,e){if(!Array.isArray(n))return e("metafields",n),[];let t=[],o=n;for(let r of o){let i=dn(r);i?t.push(typeof r=="string"?r:i):e("metafield",r)}return t}var d=n=>e=>n(e)?e:void 0,gn=n=>y(n)&&on.test(n),pn=n=>y(n)&&rn.test(n),yn=n=>typeof n=="boolean"||y(n)&&sn.test(n),p=d(U),k=d(y),P=d(n=>typeof n=="boolean"),V=d(ln);function m(n,e,t,o){if(e==null)return null;if(!O(e))return o(n,e),null;let r={},i=t;for(let[f,c]of Object.entries(i)){let h=e[f];if(h===void 0)continue;let A=c(h);A===void 0?o(`${n}.${f}`,h):r[f]=A}return r}var mn={server:p,orderUrl:p,subscriptionsUrl:p,paymentUrl:p,logoutUrl:p,locale:k,navigate:V},On="customer accounts need the Worker since 0.7.0: set account.server",kn={country:k,language:k,locale:k},hn={detect:n=>{if(typeof n=="boolean")return n;let e=Array.isArray(n)?n:[n];return typeof n=="string"||Array.isArray(n)?M.filter(t=>e.includes(t)):void 0},locales:n=>{if(!O(n))return;let e={};for(let[t,o]of Object.entries(n)){let r=m(`markets.locales.${t}`,o,kn,()=>{});r&&(e[t]=r)}return e},cookie:d(pn),remember:P,strict:P},Cn={consent:n=>un.find(e=>e===n),proxy:n=>n!==void 0&&!!n},Tn={dataLayer:d(yn),shopify:n=>typeof n=="boolean"?n:m("analytics.shopify",n,Cn,()=>{})??void 0,onEvent:V};function D(n,e,t){let o=m("account",n,mn,e);if(o===null)return null;let{server:r}=o;return r===void 0?(t(On),null):{...o,server:r}}var b=(n,e)=>m("markets",n,hn,e),H=(n,e)=>m("analytics",n,Tn,e);var u={domain:"",token:"",apiVersion:_,country:void 0,language:void 0,locale:void 0,markets:null,prefix:"tether",productPath:"/product",collectionPath:"/collection",metafields:[],embedOrigins:[],imagesFirst:25,variantsFirst:100,sellingPlanGroupsFirst:10,sellingPlansFirst:25,collectionFirst:24,retries:2,revalidate:!0,storageKey:"",cartDrawerOpenClass:"is-open",openCartOnAdd:!0,cartFocus:!0,checkoutTarget:"_self",defaultPurchase:"one-time",variantUrl:!1,maxAge:60,lowStock:5,searchDelay:150,autoMount:!0,observe:!1,astro:!0,partsUrl:null,analytics:null,account:null,warningText:null,formatMoney:null,onLayoutChange:null,onCartOpen:null,onCartClose:null,onLineEnter:null,onLineLeave:null,onValueChange:null,onError:null,debug:!1},s={...u};function v(n){let e=t=>(l(`Tether.config is read-only (${String(t)}): pass options to Tether.init() instead`),!1);return new Proxy(n,{get(t,o){let r=Reflect.get(t,o);return typeof r=="object"&&r!==null?v(r):r},set:(t,o)=>e(o),deleteProperty:(t,o)=>e(o),defineProperty:(t,o)=>e(o)})}var ee=v(s),wn=/^[a-z][a-z0-9-]*$/,bn=["revalidate","openCartOnAdd","cartFocus","variantUrl","autoMount","observe","astro","debug"],An=["token","productPath","collectionPath","cartDrawerOpenClass"],Sn=["imagesFirst","variantsFirst","sellingPlanGroupsFirst","sellingPlansFirst","collectionFirst","retries","maxAge","lowStock","searchDelay"],xn=["warningText","formatMoney","onLayoutChange","onCartOpen","onCartClose","onLineEnter","onLineLeave","onValueChange","onError"];function g(n,e,t){return e!==void 0&&l(`invalid ${n} ${JSON.stringify(e)}: using ${JSON.stringify(t)}`),t}function a(n,e){l(`invalid ${n} ${JSON.stringify(e)}: ignored`)}function En(n){for(let e of Object.keys(n))e in u||l(`unknown option ${JSON.stringify(e)}: ignored`)}function Rn(n){return typeof n=="function"?n:null}function _n(n){return Object.fromEntries(xn.map(t=>[t,Rn(n[t])]))}function Nn(n,e){return typeof e=="number"&&Number.isInteger(e)&&e>=0?e:g(n,e,u[n])}function Pn(n,e){return typeof e=="boolean"?e:g(n,e,u[n])}function Mn(n,e){return typeof e=="string"?e:g(n,e,u[n])}function Ln(n){if(!(n==null||n==="")){try{if(typeof n=="string"&&Intl.getCanonicalLocales(n).length)return n}catch{}a("locale",n)}}function K(n,e,t){return t.find(o=>o===e)??g(n,e,t[0])}function Un(n){return n==="unstable"?(l('apiVersion "unstable" changes without notice. Pin a dated version (e.g. 2026-07).'),n):E(n)?n:g("apiVersion",n,u.apiVersion)}function Y(n,e,t){if(e==null||e==="")return;let o=t(e);if(o!==null)return o;a(n,e)}function In(n){En(n);let e=L(n.domain,a),t=typeof n.prefix=="string"&&wn.test(n.prefix)?n.prefix:g("prefix",n.prefix,u.prefix),o={...u,..._n(n),domain:e,apiVersion:Un(n.apiVersion),country:Y("country",n.country,T),locale:Ln(n.locale),partsUrl:I(n.partsUrl,a),language:Y("language",n.language,w),markets:b(n.markets,a),analytics:H(n.analytics,a),account:D(n.account,a,l),prefix:t,storageKey:typeof n.storageKey=="string"&&n.storageKey?n.storageKey:`${t}:cart:${e}`,metafields:$(n.metafields??[],a),embedOrigins:F(n.embedOrigins??[],a),checkoutTarget:K("checkoutTarget",n.checkoutTarget,["_self","_blank"]),defaultPurchase:K("defaultPurchase",n.defaultPurchase,["one-time","subscription"])};for(let r of Sn)o[r]=Nn(r,n[r]);for(let r of bn)o[r]=Pn(r,n[r]);for(let r of An)o[r]=Mn(r,n[r]);return o}var te=n=>b(n,a);function oe(n={}){let e=In(n);for(let t of Object.keys(s))t in e||Reflect.deleteProperty(s,t);return Object.assign(s,e)}var re=()=>!!(s.domain&&s.token);function ie(...n){s.debug&&console.log(`[${s.prefix}]`,...n)}function l(...n){console.warn(`[${s.prefix}]`,...n)}function se(n,e){if(l(e,n instanceof Error&&n.message?n.message:n),!!s.onError)try{s.onError(n,e)}catch(t){l("onError threw",t)}}function le(n){return n instanceof Error?n.message:String(n)}var fe={domain:["PUBLIC_SHOPIFY_DOMAIN","PUBLIC_SHOPIFY_STORE_DOMAIN","SHOPIFY_DOMAIN"],token:["PUBLIC_SHOPIFY_STOREFRONT_TOKEN","PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN","SHOPIFY_STOREFRONT_TOKEN"]};function de(n){if(typeof n!="string")return!1;try{return new URL(n).protocol==="https:"}catch{return!1}}function ge(n){return/^shp[a-z]{2}_/.test(n.trim())}function pe(n,e){if(!n)return"";let t=parseFloat(n.amount);if(Number.isNaN(t))return"";try{return new Intl.NumberFormat(e||void 0,{style:"currency",currency:n.currencyCode}).format(t)}catch{return`${n.currencyCode} ${t.toFixed(2)}`}}function ye(n,e,t){if(!/\{(handle|id)\}/.test(n))return e?`${n.replace(/\/$/,"")}/${encodeURIComponent(e)}`:null;let o=t?t.split("/").at(-1)??"":"";return n.includes("{handle}")&&!e||n.includes("{id}")&&!o?null:n.replace(/\{handle\}/g,encodeURIComponent(e??"")).replace(/\{id\}/g,encodeURIComponent(o))}function me(n){let e=String(n??"").trim();return e?e.startsWith("gid://")?e:/^\d+$/.test(e)?`gid://shopify/Product/${e}`:/\/products\/([^/?#]+)/.exec(e)?.[1]??e:null}export{Fn as a,$n as b,Dn as c,O as d,Q as e,Z as f,B as g,W as h,Kn as i,R as j,Yn as k,vn as l,M as m,dn as n,T as o,w as p,u as q,s as r,ee as s,In as t,te as u,oe as v,re as w,ie as x,l as y,se as z,le as A,fe as B,de as C,ge as D,pe as E,ye as F,me as G};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a}from"./chunk-RPMBCAGS.js";import{a as o}from"./chunk-Z6HS3H7K.js";import{o as u,p as i,r as n,x as c,z as g}from"./chunk-E5YO6274.js";var f={country:void 0,language:void 0,locale:void 0},l=!1;function d(){let t=e=>document.querySelector(`meta[name="${n.prefix}-page-${e}"]`)?.getAttribute("content")||void 0,r=u(t("country"));return r?{country:r,language:i(t("language"))??void 0,locale:t("locale")}:null}async function m(){let t=n.markets??{};if(t.detect===!1)return null;if(!t.detect)return t.remember===!1?null:a();try{return(await o("markets")).detectMarket(t)}catch(r){return g(r,"markets"),null}}async function C(t){f={country:n.country,language:n.language,locale:n.locale};let r=d();if(l=r!==null,r){n.country=r.country,n.language=r.language,r.locale&&(n.locale=r.locale);return}let e=await m();e&&(e.country&&(n.country=e.country),e.language&&(n.language=e.language),e.locale&&!t.locale&&(n.locale=e.locale),c("market",e))}var s=(t,r)=>(t??"").toUpperCase()===(r??"").toUpperCase();function P(){let t=d(),r=t===null&&l;l=t!==null;let e=t??(r?a()??f:null);return!e?.country||s(e.country,n.country)&&s(e.language,n.language)?null:{country:e.country,language:e.language,locale:e.locale}}function S(t,r){return o("markets").then(e=>e.setCountry(t,r))}export{C as a,P as b,S as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as Y,d as Ct,g as q,h as bt,p as E,v as wt}from"./chunk-6TFMLT4A.js";import{A as gt,B as yt,D as x,G,H as S,I as N,L as ht,Q as M,a as g,c as $,d as R,i as F,l as dt,m as W,n as s,o as w,q as l,u as m,x as pt,z as mt}from"./chunk-MQYB6BH4.js";import{C as ft,r as a,x as lt,z as C}from"./chunk-E5YO6274.js";var Gt={id:"string",quantity:"number",attributes:["object"],cost:{totalAmount:E,subtotalAmount:E,amountPerQuantity:E},merchandise:{id:"string",selectedOptions:["object"],product:"object"}},X={id:"string",checkoutUrl:"string",totalQuantity:"number",attributes:["object"],discountCodes:["object"],cost:{totalAmount:E,subtotalAmount:E},lines:{nodes:[Gt]}};var Yt='a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])',Xt=60,z=!1,_=null,zt=t=>t!==null&&"focus"in t,St=t=>l(t,Yt).filter(n=>n.offsetParent!==null||n===document.activeElement),P=()=>l(document,s("cart-drawer")),J=t=>t.classList.contains(a.cartDrawerOpenClass);function y(){let t=P();return t.length?t.some(J):z}function K(t){l(document,s("cart-open")).forEach(n=>{n.setAttribute("aria-expanded",String(t))}),P().forEach(n=>{n.hasAttribute("role")||n.setAttribute("role","dialog"),!n.hasAttribute("aria-label")&&!n.hasAttribute("aria-labelledby")&&n.setAttribute("aria-label",w(n,"cart-label")||"Cart"),n.setAttribute("aria-modal",String(t)),!J(n)&&(n.setAttribute("aria-hidden","true"),a.cartFocus&&(n.inert=!0))})}function Jt(t){let n=St(t)[0]??t;n===t&&!t.hasAttribute("tabindex")&&(t.tabIndex=-1),n.focus({preventScroll:!0})}function V(){if(y())return;z=!0;let t=P().filter(e=>w(e,"cart-drawer")!=="manual");t.forEach(e=>{e.inert=!1,e.classList.add(a.cartDrawerOpenClass),e.setAttribute("aria-hidden","false")}),K(!0);let[n]=t;a.cartFocus&&n&&(_=zt(document.activeElement)?document.activeElement:null,setTimeout(()=>{Jt(n)},Xt)),a.onCartOpen?.(t),m("cart-toggled",{open:!0})}function Z(){if(!y())return;z=!1;let t=P(),n=t.some(e=>e.contains(document.activeElement));t.forEach(e=>{e.classList.remove(a.cartDrawerOpenClass),e.setAttribute("aria-hidden","true"),a.cartFocus&&(e.inert=!0)}),K(!1),n&&_?.isConnected&&_.focus({preventScroll:!0}),_=null,a.onCartClose?.(t),m("cart-toggled",{open:!1})}function vt(){y()?Z():V()}function Zt(t){if(t.key!=="Tab"||!a.cartFocus||!y())return;let n=P().find(J);if(!n)return;let e=St(n),r=e[0],i=e.at(-1);if(!r||!i)return;let o=document.activeElement,u=t.shiftKey?o===r:o===i;n.contains(o)&&!u||(t.preventDefault(),(t.shiftKey?i:r).focus())}var At="Default Title",tt=(t,n)=>n.get(t.id)?.quantity??t.quantity,kt=t=>t.split("/").pop()??t;function tn(t){let n=t.merchandise,e=yt(n.product.handle,n.product.id);if(!e)return null;let r=new URLSearchParams;r.set("variant",kt(n.id));let i=t.sellingPlanAllocation?.sellingPlan.id;return i&&r.set("selling_plan",kt(i)),`${e}${e.includes("?")?"&":"?"}${r.toString()}`}var Lt=t=>t.merchandise.product.title,Pt={title:Lt,"product-title":Lt,"variant-title":t=>t.merchandise.title===At?"":t.merchandise.title,options:t=>t.merchandise.selectedOptions.filter(n=>n.value!==At).map(n=>`${n.name}: ${n.value}`).join(", "),vendor:t=>t.merchandise.product.vendor,sku:t=>t.merchandise.sku??"",price:t=>x(t.cost.amountPerQuantity),"compare-at-price":t=>x(t.cost.compareAtAmountPerQuantity??t.merchandise.compareAtPrice),"line-total":t=>x(t.cost.totalAmount),"line-subtotal":t=>x(t.cost.subtotalAmount),quantity:(t,n)=>tt(t,n.pending),plan:t=>t.sellingPlanAllocation?.sellingPlan.name??"","plan-description":t=>t.sellingPlanAllocation?.sellingPlan.description??"",components:t=>(t.lineComponents??[]).map(n=>`${n.quantity} \xD7 ${n.merchandise.product.title}`).join(", ")},It="attribute:";function nn(t,n,e){if(Object.hasOwn(Pt,n))return Pt[n]?.(t,e);if(!n.startsWith(It))return;let r=n.slice(It.length);return t.attributes.find(i=>i.key===r)?.value??""}function en(t,n,e){let r=bt(e),i=!e.requiresSellingPlan&&w(t,"line-plan")!=="subscription-only",o={value:"",label:t.getAttribute(W("one-time-label"))||"One-time purchase"},u=[...i?[o]:[],...r.map(f=>({value:f.id,label:f.name}))],c=u.map(f=>f.value).join("|");t.dataset.tetherSig!==c&&(t.replaceChildren(...u.map(f=>{let b=document.createElement("option");return b.value=f.value,b.textContent=f.label,b})),t.dataset.tetherSig=c),t.value=n.sellingPlanAllocation?.sellingPlan.id??"",N(t,r.length>0)}function rn(t,n,e){let r=!!n.sellingPlanAllocation;t.classList.toggle("is-subscription",r);let i=e.warnings.find(c=>c.target===n.id);t.classList.toggle("is-warning",!!i);let o=e.pending.has(n.id);t.classList.toggle("is-busy",o),o?t.setAttribute("aria-busy","true"):t.removeAttribute("aria-busy"),l(t,s("line","warning")).forEach(c=>{S(c,i?.message??"")});let u=new Map([["subscription",r],["one-time",!r],["on-sale",Ct(n.cost.compareAtAmountPerQuantity?.amount,n.cost.amountPerQuantity.amount)],["has-components",(n.lineComponents??[]).length>0],["warning",!!i]]);l(t,s("line-show")).forEach(c=>{let f=w(c,"line-show"),b=f===null?void 0:u.get(f);b!==void 0&&N(c,b)})}function on(t,n,e){let r=n.merchandise;t.setAttribute(W("line-id"),n.id),l(t,s("line")).forEach(i=>{let o=w(i,"line")??"";if(o==="image"){pt(i,r.image?.url??r.product.featuredImage?.url,r.product.title);return}if(o==="url"){let c=tn(n);c&&i.setAttribute("href",c);return}let u=nn(n,o,e);u!==void 0&&S(i,u)}),rn(t,n,e),l(t,`select${s("line-plan")}`).forEach(i=>{wt(r.product.handle).then(o=>{en(i,n,o)}).catch(o=>{C(o,"line plan options")})})}function an(t,n){let e=t?.totalQuantity??0,r=(t?.lines.nodes??[]).some(o=>o.sellingPlanAllocation),i=new Map([["cart-empty",e===0],["cart-filled",e>0],["cart-has-subscription",r],["cart-no-subscription",!r],["cart-has-discount",(t?.discountCodes??[]).some(o=>o.applicable)],["cart-error",n.failed],["cart-warning",n.warnings.length>0]]);l(document,s("show")).forEach(o=>{let u=w(o,"show"),c=u===null?void 0:i.get(u);c===void 0||o.closest(s("product"))||N(o,c)}),l(document,s("checkout")).forEach(o=>{o.classList.toggle("is-disabled",!e),o.setAttribute("aria-disabled",String(!e))})}function sn(t){l(document,`textarea${s("cart-note")},input${s("cart-note")}`).forEach(n=>{document.activeElement!==n&&G(n,t?.note??"")}),l(document,s("cart-discounts")).forEach(n=>{mt(n,t?.discountCodes??[],(e,r)=>{e.setAttribute(W("discount-code"),r.code);let i=e.querySelector(s("discount","code"))??(e.firstElementChild?null:e);i&&G(i,r.code),e.classList.toggle("is-inapplicable",!r.applicable)})})}function xt(t){let{cart:n}=t,e=r=>n?x(n.cost[r]):"";K(y()),l(document,s("cart-count")).forEach(r=>{S(r,n?.totalQuantity??0)}),l(document,s("cart-subtotal")).forEach(r=>{S(r,e("subtotalAmount"))}),l(document,s("cart-total")).forEach(r=>{S(r,e("totalAmount"))}),l(document,s("cart-checkout-charge")).forEach(r=>{S(r,e("checkoutChargeAmount"))}),an(n,t),l(document,s("cart-warning")).forEach(r=>{S(r,[...new Set(t.warnings.map(i=>i.message))].join(" "))}),sn(n),l(document,s("cart-lines")).forEach(r=>{gt(r,n?.lines.nodes??[],i=>i.id,(i,o)=>{on(i,o,t)},{onEnter:a.onLineEnter,onLeave:a.onLineLeave})}),n&&ht("cart")}function Et(t){l(document,s("cart-count")).forEach(n=>{/^\s*0?\s*$/.test(n.textContent)&&(n.textContent=String(t))})}function nt(t,n="localStorage"){try{return window[n].getItem(t)}catch{return null}}function et(t,n,e="localStorage"){try{window[e].setItem(t,n)}catch{}}function Tt(t,n="localStorage"){try{window[n].removeItem(t)}catch{}}var $t=/^gid:\/\/shopify\/Cart\/[\w-]+(\?key=[\w-]+)?$/;var p={kind:"unknown"},T=[],I=new Map,j=()=>p;function d(){switch(p.kind){case"ready":case"error":return p.cart;case"unknown":case"empty":return null}}var qt=()=>T,rt=t=>t?{kind:"ready",cart:t}:{kind:"empty"},Ot=()=>`${a.storageKey}:seen`;function v(){let t=nt(a.storageKey);return t?$t.test(t)?t:(A(),null):null}function A(){Tt(a.storageKey)}function it(t){p=rt(t),t&&et(a.storageKey,t.id)}function O(){xt({cart:d(),warnings:T,pending:I,failed:p.kind==="error"})}function U(t){O(),m("cart-updated",{cart:d(),reason:t})}function h(t,n){return it(t),et(Ot(),`${Date.now()}|${t?.totalQuantity??0}`),U(n),t}function D(t){p=t.kind==="loaded"?rt(t.cart):{kind:"error",error:t.error,cart:null},U("load")}function un(){let t=nt(Ot())?.split("|")[1]??"",n=Number(t);return/^\d+$/.test(t)&&Number.isSafeInteger(n)?n:null}function Ut(){if(p.kind!=="unknown")return;let t=un();t!==null&&Et(t)}function Dt(t){T=t.filter((n,e)=>t.findIndex(r=>r.message===n.message)===e).map(n=>({...n,message:a.warningText?.(n)||n.message})),T.length&&m("cart-warning",{warnings:T})}var Mt=()=>{};function cn(){let t=Promise.resolve();return n=>{let e=t.then(n);return t=e.then(Mt,Mt),e}}var ln=cn();function Qt(t){return ln(t).then(n=>(p.kind==="error"&&(p=rt(p.cart),O()),n),n=>{throw p={kind:"error",error:n,cart:d()},O(),m("cart-error",{error:n}),n})}var ot=t=>tt(t,I),dn=()=>({open:y(),count:d()?.totalQuantity??0,loaded:p.kind!=="unknown",warnings:[...T]});function Rt(t){let n=["cart-updated","cart-toggled"].map(r=>`${a.prefix}:${r}`),e=()=>{t(d(),dn())};return n.forEach(r=>{document.addEventListener(r,e)}),e(),()=>{n.forEach(r=>{document.removeEventListener(r,e)})}}var fn=/does not exist|not found|invalid id/i,pn=t=>R({[t]:$({cart:$(X)})});function H(t){return t instanceof g?t.userErrors?.some(n=>n.field?.[0]==="cartId")?!0:(t.errors??[]).some(n=>fn.test(n.message)):!1}function Wt(t){return t instanceof g&&(t.code==="NETWORK"||t.code==="INVALID_RESPONSE"||(t.status??0)>=500)}function Nt(t,n=1,e={}){let r=typeof t=="object"&&t!==null?t:{...e,quantity:n,...t==null?{}:{variantId:t}},i=q.variant(r.merchandiseId||r.variantId||r.id);if(!i)throw new g("add(): variantId is required");let o=parseInt(String(r.quantity??1),10),u={merchandiseId:i,quantity:Math.max(1,o||1)},c=q.sellingPlan(r.sellingPlanId||r.sellingPlan);c&&(u.sellingPlanId=c);let f=M(r.attributes);return f.length&&(u.attributes=f),u}function mn(t,n,e){return r=>`mutation Tether_${t}(${n}){${t}(${e}){cart{...TetherCart}userErrors{field message}warnings{code message target}}}${Y(r)}`}async function _t(t,n,e,r){let i=await F(mn(t,n,e),r,pn(t),{operation:"mutation"}),o=dt(i[t],t);return Dt(o.warnings??[]),o.cart}function Ft(t){let n=a.country?{buyerIdentity:{countryCode:a.country},...t}:t;return _t("cartCreate","$input: CartInput!","input: $input",{input:n})}async function k({name:t,args:n,inner:e,variables:r,createInput:i}){let o=v();if(!o)return i?Ft(i):null;try{return await _t(t,`$cartId: ID!, ${n}`,`cartId: $cartId, ${e}`,{...r,cartId:o})}catch(u){if(!H(u)||(A(),!i))throw u;return lt("cart expired, creating a new one"),Ft(i)}}async function at(t){return(await F(e=>`query TetherCart($id:ID!){cart(id:$id){...TetherCart}}${Y(e)}`,{id:t},R({cart:$(X)}))).cart}async function Kt(t){return(await F("query TetherCheckout($id: ID!) { cart(id: $id) { checkoutUrl } }",{id:t},R({cart:$({checkoutUrl:"string"})}))).cart?.checkoutUrl??null}function Vt(t,n){let e=typeof n=="number"?{quantity:n}:n,r={id:t};e.quantity!==void 0&&(r.quantity=e.quantity),"sellingPlanId"in e&&(r.sellingPlanId=e.sellingPlanId?q.sellingPlan(e.sellingPlanId):null),e.attributes&&(r.attributes=M(e.attributes));let i=e.merchandiseId||e.variantId;return i&&(r.merchandiseId=q.variant(i)),r}var st=t=>k({name:"cartLinesUpdate",args:"$lines: [CartLineUpdateInput!]!",inner:"lines: $lines",variables:{lines:t},createInput:null}),ut=t=>k({name:"cartLinesRemove",args:"$lineIds: [ID!]!",inner:"lineIds: $lineIds",variables:{lineIds:t},createInput:null}),jt=(t,n)=>n>0?st([{id:t,quantity:n}]):ut([t]);var ct=null;function Ht(t){ct=t}var gn=t=>Kt(t).then(n=>({kind:"url",url:n}),n=>({kind:"failed",error:n}));async function yn(){if(!ct)return null;try{let t=await ct();return t&&`${t}${t.includes("?")?"&":"?"}logged_in=true`}catch(t){return C(t,"account checkout"),null}}async function hn(t){let n=gn(t),e=await yn();if(e)return e;let r=await n;if(r.kind==="failed")throw r.error;if(!r.url)throw new g("No checkoutUrl (cart empty or expired)");return r.url}function Cn(t){try{t.opener=null}catch{}}async function Bt(t=a.checkoutTarget){let n=v(),e=d();if(!n||e&&!e.totalQuantity)return null;let r=t==="_blank"?window.open("","_blank"):null;r&&Cn(r);try{let i=await hn(n);if(!ft(i))throw new g("The checkout URL is not https: not opened");return m("checkout",{url:i,cart:d()}),r&&!r.closed?r.location.href=i:window.location.href=i,i}catch(i){return r?.close(),C(i,"checkout failed"),null}}var B=()=>d()?.lines.nodes??[];async function bn(){let t=v();if(t)try{let n=await at(t);n||A(),h(n,"load")}catch(n){C(n,"cart reload after a failed change")}}function L(t){return Qt(()=>t().catch(async n=>{throw Wt(n)&&await bn(),n}))}function wn(t,n){let e=B().find(c=>c.id===t);if(!e)return Promise.resolve(d());let r=Math.max(0,ot(e)+n),i={quantity:r};I.set(t,i),U("pending");let o=()=>I.get(t)===i;return L(async()=>{if(!o())return d();if(B().find(b=>b.id===t)?.quantity===r)return d();let f=await jt(t,r);return o()?h(f,r>0?"update":"remove"):(it(f),f)}).finally(()=>{o()&&(I.delete(t),U("settled"))})}function Sn(t){let n=(d()?.discountCodes??[]).map(r=>r.code),e=typeof t=="function"?t(n):t;return(Array.isArray(e)?e:[e]).map(r=>r.trim()).filter(Boolean)}function vn(t){let n=new Map((d()?.attributes??[]).map(e=>[e.key,e.value]));return M(t).forEach(e=>n.set(e.key,e.value)),[...n].filter(([,e])=>e!=="").map(([e,r])=>({key:e,value:r}))}async function An(){let t=v();if(!t)return D({kind:"loaded",cart:null}),null;Ut();try{let n=await at(t);n||A(),D({kind:"loaded",cart:n})}catch(n){C(n,"cart load failed"),H(n)&&A(),D({kind:"failed",error:n})}return d()}var Q={init:An,id:v,get status(){return j()},get state(){return d()},get lines(){return[...B()]},get count(){return d()?.totalQuantity??0},get loaded(){return j().kind!=="unknown"},get lastError(){let t=j();return t.kind!=="error"?null:t.error instanceof Error?t.error:new Error(String(t.error))},get warnings(){return[...qt()]},get pendingQty(){return I},setCheckoutResolver:Ht,forgetSaved(){A(),D({kind:"loaded",cart:null})},render:O,subscribe:Rt,add(t,n=1,e={}){let r=(Array.isArray(t)?t:[t]).map(i=>Nt(i,n,e));return L(async()=>{let i=await k({name:"cartLinesAdd",args:"$lines: [CartLineInput!]!",inner:"lines: $lines",variables:{lines:r},createInput:{lines:r}});if(!i)throw new g("Shopify answered the add without a cart");return h(i,"add"),m("added",{cart:i,lines:r}),a.openCartOnAdd&&V(),i})},updateLine(t,n){let e=typeof n=="number"?n:n.quantity;if(e!==void 0&&e<=0)return Q.removeLine(t);let r=Vt(t,n);return L(async()=>h(await st([r]),"update"))},changeQuantity:wn,quantityOf:ot,removeLine(t){let n=Array.isArray(t)?t:[t];return L(async()=>h(await ut(n),"remove"))},clear(){let t=B().map(n=>n.id);return t.length?Q.removeLine(t):Promise.resolve(d())},setNote(t){let n={note:t??""};return L(async()=>h(await k({name:"cartNoteUpdate",args:"$note: String!",inner:"note: $note",variables:n,createInput:n}),"note"))},setAttributes(t){return L(async()=>{let n={attributes:vn(t)},e=await k({name:"cartAttributesUpdate",args:"$attributes: [AttributeInput!]!",inner:"attributes: $attributes",variables:n,createInput:n});return h(e,"attributes")})},setDiscountCodes(t){return L(async()=>{let n={discountCodes:Sn(t)},e=await k({name:"cartDiscountCodesUpdate",args:"$discountCodes: [String!]!",inner:"discountCodes: $discountCodes",variables:n,createInput:n});return h(e,"discount")})},async applyDiscount(t){let n=await Q.setDiscountCodes(i=>[...new Set([...i,t])]),e=t.toLowerCase();if((n?.discountCodes??[]).find(i=>i.code.toLowerCase()===e)?.applicable)return n;try{await Q.removeDiscount(t)}catch(i){C(i,"removing a discount code Shopify refused")}throw new g(`Discount code not valid: ${t}`,{code:"INVALID_DISCOUNT"})},removeDiscount(t){let n=t.toLowerCase();return Q.setDiscountCodes(e=>e.filter(r=>r.toLowerCase()!==n))},setBuyerIdentity(t,{create:n=!0}={}){return L(async()=>{let e=await k({name:"cartBuyerIdentityUpdate",args:"$buyerIdentity: CartBuyerIdentityInput!",inner:"buyerIdentity: $buyerIdentity",variables:{buyerIdentity:t},createInput:n?{buyerIdentity:t}:null}).catch(r=>{if(n||!H(r))throw r;return null});return h(e,"buyer-identity")})},checkout:Bt,drawers:P,isOpen:y,open:V,close:Z,toggle:vt};export{Zt as a,nt as b,et as c,Tt as d,Q as e};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as G,E as j,F as W,b as T,d as y,e as x,o as F,p as V,r as u,x as O,y as b,z as E}from"./chunk-E5YO6274.js";var p=class extends Error{constructor(r,{status:n,errors:i,userErrors:o,code:s}={}){super(r);T(this,"name","TetherError");T(this,"code");T(this,"status");T(this,"errors");T(this,"userErrors");this.code=s??(n?`HTTP_${n}`:"ERROR"),this.status=n,this.errors=i,this.userErrors=o}};function A(t,e){return typeof e=="function"?e(t):typeof e=="string"?e==="object"?y(t):typeof t===e:yt(e)?Array.isArray(t)&&t.every(r=>A(r,e[0])):y(t)&&Object.entries(e).every(([r,n])=>n===void 0||A(t[r],n))}var yt=t=>Array.isArray(t),Pe=t=>e=>e===null||A(e,t),Me=t=>e=>A(e,t);function Tt(t=u){return`https://${t.domain}/api/${t.apiVersion}/graphql.json`}var z=/"(?:\\.|[^"\\\n])*"|#[^\n]*/g,Et=/^\s*(?:query|mutation)(?:\s+\w+)?\s*(?:\([^)]*\))?/;function bt(t){return/\bmutation\b/.test(t.replace(z,""))?"mutation":"query"}function Y(t,{country:e,language:r}){let n=[];if(e&&n.push(`country: ${e}`),r&&n.push(`language: ${r}`),!n.length)return t;let i=`@inContext(${n.join(", ")})`,o=t.replace(z,f=>" ".repeat(f.length)),s=o.indexOf("{");if(o.slice(0,s).includes("@inContext"))return t;if(o.trimStart().startsWith("{"))return`query ${i} ${t.slice(s)}`;let c=Et.exec(o);if(!c)return t;let d=c[0].length;return`${t.slice(0,d).trimEnd()} ${i} ${t.slice(d).trimStart()}`}function _e(t,e=u){let r=F(e.country)??void 0,n=V(e.language)??void 0;return Y(t,{country:r,language:n})}var J=300,wt=500,q=430,St=1e3,N="quantityAvailable",Q=new Set,xt=t=>`${t.domain} ${t.apiVersion} ${t.token}`;function At(t,e,r,{context:n,operation:i}){let o=typeof e=="string"?e:e(r),s=n?Y(o,t):o;return t.maxAge<=0||i==="mutation"?s:`${s} #${Math.floor(Date.now()/(t.maxAge*St))}`}var vt=t=>new Promise(e=>setTimeout(e,t));function R(t,e){if(t===401||t===403){let r=e.token.startsWith("shpat_")?", not an Admin API token (shpat_\u2026)":"";return`Shopify rejected the Storefront token for ${e.domain} (${t}): use the public Storefront API token (Headless channel)${r}`}return t===404?`Store or API version not found (404): check domain ${e.domain} and apiVersion ${e.apiVersion}`:`HTTP ${t} from ${e.domain}`}function kt(t){let e=x(t,"message"),r=x(x(t,"extensions"),"code"),n=typeof e=="string"?e:"";return typeof r=="string"?{message:n,extensions:{code:r}}:{message:n}}function Lt(t){if(!y(t))return null;let{data:e,errors:r}=t;return r==null?{data:e}:Array.isArray(r)?{data:e,errors:r.map(kt)}:null}function C(t,e){return t.ok?new p(`Invalid response (${t.status})`,{code:"INVALID_RESPONSE",status:t.status}):new p(R(t.status,e),{status:t.status})}function B(t,e,r){let n=e.map(o=>o.message).filter(Boolean).join(" | "),i=n||"Storefront API error";return t.ok||(i=t.status===401||t.status===403||!n?R(t.status,r):n),new p(i,{status:t.status,errors:e})}function K(t,e){if(e==="any")return{kind:"retry",backoffMs:J};throw new p(`Network error: ${G(t)}`,{code:"NETWORK"})}async function Ot(t,e,r,n,i){let o;try{o=await(t.fetch??fetch)(Tt(t),{method:"POST",headers:{"Content-Type":"application/json","X-Shopify-Storefront-Access-Token":t.token},body:JSON.stringify({query:e,variables:r})})}catch(l){return K(l,i)}if(o.status===q)throw new p("Shopify security rejection (430)",{status:q});if(i!=="none"&&o.status===429||i==="any"&&o.status>=500)return{kind:"retry",backoffMs:J};let s;try{s=await o.json()}catch(l){if(l instanceof SyntaxError)throw C(o,t);return K(l,i)}let c=Lt(s);if(!c)throw C(o,t);let{data:d,errors:f=[]}=c;if(f.length){if(e.includes(N)&&f.some(l=>l.message.includes(N)))return{kind:"inventory-refused",error:B(o,f,t)};if(i!=="none"&&f.some(l=>l.extensions?.code==="THROTTLED"))return{kind:"retry",backoffMs:wt};throw B(o,f,t)}if(!o.ok)throw new p(R(o.status,t),{status:o.status});if(!n(d))throw C(o,t);return{kind:"data",data:d}}async function Ct(t,e,r,n,{context:i=!0,operation:o="query"}={}){if(!t.domain||!t.token)throw new p("Tether is not configured: domain and token are required",{code:"NOT_CONFIGURED"});let s=xt(t),c=o==="mutation"?"not-run":"any",d=0;for(;;){let f=At(t,e,{inventory:!Q.has(s)},{context:i,operation:o}),l=d<t.retries?c:"none",m=await Ot(t,f,r,n,l);switch(m.kind){case"data":return m.data;case"inventory-refused":if(typeof e=="string")throw m.error;O(`the token can't read inventory: ${N} is left out from now on`),Q.add(s);break;case"retry":d+=1,O("retry",d),await vt(m.backoffMs*2**d);break}}}function Nt(t,e,r,n){return Ct(u,t,e,r,n)}var Rt=t=>typeof t=="object"&&t!==null;function He(t,e={},r){let n=bt(typeof t=="string"?t:t({inventory:!0}));return Nt(t,e,Rt,{...r,operation:n})}function Ue(t,e){if(!t)throw new p(`${e}: empty response`);let r=t.userErrors??[];if(r.length)throw new p(r.map(n=>n.message).join(" | "),{userErrors:r});return t}var g=t=>`${u.prefix}-${t}`,It=(t,e)=>e===void 0?`[${g(t)}]`:`[${g(t)}="${e}"]`,I=(t,e)=>t.getAttribute(g(e)),Pt=(t,e)=>t.hasAttribute(g(e));function X(t,e){return t?[...t.querySelectorAll(e)]:[]}var Mt=(t,e,r)=>X(t,e).filter(n=>n.closest(r)===t),_t=["product-ready","list-ready","cart-updated","cart-toggled","checkout","search"],Z=new WeakMap;function tt(t,e){let r=new CustomEvent(`${u.prefix}:${t}`,{detail:e,bubbles:!0});return Z.set(r,t),r}function Ht(t,e){return Z.get(t)===e}function P(t,e,r=document){r.dispatchEvent(tt(t,e))}function rt(t,{width:e,height:r,crop:n}={}){if(!t)return t;let i;try{i=new URL(t)}catch(o){if(o instanceof TypeError)return t;throw o}return e&&i.searchParams.set("width",String(e)),r&&i.searchParams.set("height",String(r)),n&&i.searchParams.set("crop",n),i.toString()}function M(t,e){return t.getAttribute(e)??t.getAttribute(g(e))??t.getAttribute(`data-${e}`)}function nt(t,e){if(!t||!e)return t;let r=M(e,"max-width"),n=M(e,"max-height");return rt(t,{width:r,height:n,crop:r||n?M(e,"crop"):null})}var et=t=>t.replace(/\?.*$/,"");function ot(t,e){return!t||!e?!1:et(t)===et(e)}function Ut(t){return/^\s*[a-z][a-z0-9+.-]*:/i.test(t)&&!/^\s*(https?:|data:image\/)/i.test(t)?"none":`url("${t.replace(/["\\\n\r\f]/g,n=>`\\${n.charCodeAt(0).toString(16)} `)}")`}function $t(t,e,r){if(!e)return;let n=nt(e,t);if(t.tagName!=="IMG"){t.style.backgroundImage=Ut(n);return}if(ot(t.getAttribute("src"),n)){r!=null&&!t.getAttribute("alt")&&t.setAttribute("alt",r);return}t.removeAttribute("srcset"),t.removeAttribute("sizes"),t.setAttribute("src",n),r!=null&&t.setAttribute("alt",r),t.getAttribute("loading")||t.setAttribute("loading","lazy")}var _=new WeakMap,Dt=t=>!!_.get(t),H=t=>t.cloneNode(!0);function it(t){let e=_.get(t);if(e!==void 0)return e;let r=t.firstElementChild,n=r?H(r):null;return _.set(t,n),t.replaceChildren(),n}function Ft(t,e,r){let n=it(t);if(!n){e.length&&b("repeater without a template child",t);return}t.replaceChildren(),e.forEach((i,o)=>{let s=H(n);r(s,i,o),t.appendChild(s)})}function Vt(t,e){let r=()=>{t.remove()};if(!e){r();return}try{e(t,r)}catch(n){E(n,"repeater onLeave"),r()}}function Gt(t,e,r,n){e.forEach((i,o)=>{if(!r.has(i))return;let s=e[o-1];if(s?.parentNode===t?s.after(i):t.prepend(i),!!n)try{n(i)}catch(c){E(c,"repeater onEnter")}})}function jt(t,e,r,n,{onEnter:i,onLeave:o}={}){let s=it(t);if(!s){b("repeater without a template child",t);return}let c=`data-${u.prefix}-key`,d=`data-${u.prefix}-leaving`,f=()=>[...t.children].filter(a=>a.hasAttribute(c)&&!a.hasAttribute(d)),l=new Map(f().map(a=>[a.getAttribute(c),a])),m=[],w=new Set;e.forEach((a,S)=>{let L=String(r(a,S)),h=l.get(L);h?l.delete(L):(h=H(s),h.setAttribute(c,L),w.add(h)),n(h,a,S,w.has(h)),m.push(h)});let k=m.filter(a=>!w.has(a)),D=f().filter(a=>k.includes(a));if(!(D.length===k.length&&D.every((a,S)=>a===k[S]))){l.forEach(a=>{a.remove()}),m.forEach(a=>t.appendChild(a));return}Gt(t,m,w,i),l.forEach(a=>{a.setAttribute(d,""),a.removeAttribute(c),a.style.pointerEvents="none",a.inert=!0,Vt(a,o)})}var Wt="http://www.w3.org/1999/xhtml",qt=new Set(["h1","h2","h3","h4","h5","h6","p","span","div","br","hr","blockquote","code","pre","strong","em","b","i","u","s","small","sub","sup","ul","ol","li","dl","dt","dd","table","caption","colgroup","col","thead","tbody","tfoot","tr","th","td","a","img","picture","source","video","figure","figcaption","iframe"]),Qt=new Set(["script","style","template","noscript","textarea","select","title"]),Bt=new Set(["style","title","lang","dir","role","align","width","height"]),Kt=new Map([["a",new Set(["href","target","rel","hreflang"])],["img",new Set(["src","srcset","sizes","alt","loading","decoding"])],["source",new Set(["src","srcset","sizes","type","media"])],["video",new Set(["src","poster","controls","autoplay","muted","loop","playsinline","preload"])],["iframe",new Set(["src","allow","allowfullscreen","frameborder","loading"])],["blockquote",new Set(["cite"])],["ol",new Set(["start","type","reversed"])],["li",new Set(["value"])],["table",new Set(["border","cellpadding","cellspacing","summary"])],["col",new Set(["span"])],["colgroup",new Set(["span"])],["th",new Set(["colspan","rowspan","headers","scope","valign"])],["td",new Set(["colspan","rowspan","headers","valign"])]]),zt=new Set(["href","src","poster","cite"]),Yt=/^(javascript|vbscript|data):/i,Jt=/^data:image\/(png|gif|jpeg|webp|avif);/i,Xt=new Set(["position","top","right","bottom","left","z-index","-webkit-box-reflect"]),Zt=["inset","transform","translate","rotate","scale","offset"],te=/\d(?:[sld]?v|cq)(?:w|h|i|b|min|max)\b/i,ee=/^(?:outline|box-shadow|text-shadow|filter|text-decoration|text-underline-offset|text-stroke)|^(?:border-image|mask-border|mask-box-image)(?:-outset)?$/,st=40,re=new Map([["letter-spacing",{px:4,em:.25}],["word-spacing",{px:4,em:.25}],["text-indent",{px:st}]]),at=/(?<![\w#.-])[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?(%|[a-z]+)?/gi,ne=/(?<![\w-])(?!drop-shadow\(|blur\()[\w-]+\([^()]*\)/g,ut=/(?:var|calc|min|max|clamp|env|attr)\(/i,oe=/url\(|expression\(|@import/i,ie=/[\u0000- ]/g,se="allow-scripts allow-same-origin allow-popups allow-presentation",ae=new Set(["autoplay","encrypted-media","picture-in-picture","fullscreen","clipboard-write","accelerometer","gyroscope","web-share"]),ue="strict-origin-when-cross-origin",ce=["https://www.youtube.com","https://www.youtube-nocookie.com","https://player.vimeo.com","https://www.loom.com","https://fast.wistia.net"];function le(t,e){return Bt.has(e)||e.startsWith("aria-")||(Kt.get(t)?.has(e)??!1)}function de(t,e,r){let n=r.replace(ie,"");return Yt.test(n)?t==="img"&&e==="src"&&Jt.test(n):!0}function ct(t,e){try{return new URL(t,e)}catch{return null}}function fe(t,e,r){let n=t.baseURI,i=ct(n)?.origin??"null";return{origin:i==="null"?null:i,baseUrl:n,styleParser:e,embedOrigins:new Set([...ce,...r])}}function pe(t,e){let r=ct(t.trim(),e.baseUrl);return r!==null&&r.origin!==e.origin&&e.embedOrigins.has(r.origin)}function ge(t){let e=t.split(";").map(r=>r.trim().split(/\s+/)[0]?.toLowerCase()??"");return[...new Set(e.filter(r=>ae.has(r)))].join("; ")}function me(t,e){if(Xt.has(t)||Zt.some(n=>t.startsWith(n))||te.test(e))return!0;let r=re.get(t);return r?ut.test(e)||he(e,r):t.startsWith("margin")&&e.includes("-")}function he(t,e){return[...t.matchAll(at)].some(([r="",n=""])=>{let i=parseFloat(r);if(i>=0)return!1;let o=e[n.toLowerCase()];return o===void 0||-i>o})}function ye(t,e){return ee.test(t.replace(/^-webkit-/,""))?ut.test(e)?!0:[...e.replace(ne,"").matchAll(at)].some(([r="",n=""])=>{let i=Math.abs(parseFloat(r));return i!==0&&(n.toLowerCase()!=="px"||i>st)}):!1}function Te(t,e){let r=e.style;r.cssText=t;let n=Array.from({length:r.length},(o,s)=>r.item(s));for(let o of n){let s=r.getPropertyValue(o);(me(o,s)||ye(o,s)||oe.test(s))&&r.removeProperty(o)}let i=r.cssText;return e.removeAttribute("style"),i}function Ee(t,e){let r=t.localName;for(let o of[...t.attributes]){let s=o.name.toLowerCase(),c=zt.has(s);le(r,s)&&(!c||de(r,s,o.value))||t.removeAttribute(o.name)}let n=t.getAttribute("style");if(n===null)return;let i=Te(n,e.styleParser);i===""?t.removeAttribute("style"):t.setAttribute("style",i)}function be(t){if(t.localName==="iframe"){let r=ge(t.getAttribute("allow")??"");r===""?t.removeAttribute("allow"):t.setAttribute("allow",r),t.setAttribute("sandbox",se),t.setAttribute("referrerpolicy",ue);return}if(t.localName!=="a"||t.getAttribute("target")?.toLowerCase()!=="_blank")return;let e=new Set((t.getAttribute("rel")??"").split(/\s+/).filter(Boolean));e.add("noopener"),e.add("noreferrer"),t.setAttribute("rel",[...e].join(" "))}function we(t,e){let r=t.localName,n=t.namespaceURI===Wt;if(n&&Qt.has(r)){t.remove();return}if(!n||!qt.has(r)){t.replaceWith(...t.childNodes);return}if(r==="iframe"&&!pe(t.getAttribute("src")??"",e)){t.remove();return}Ee(t,e),be(t)}function lt(t,e=globalThis.document,r=[]){let n=e.createElement("template");n.innerHTML=t??"";let i=fe(e,n,r);for(let o of[...n.content.querySelectorAll("*")])we(o,i);return n.content}var dt="data-tether-seen",$="data-tether-shown",v="data-tether-prev-display",Se=120;function Xe(t,e){return W(u.productPath||"/product",t,e)}function mt(t,e){try{return t()}catch(r){if(r instanceof RangeError)return e;throw r}}function Ze(t,e=u.locale){return t?mt(()=>new Intl.NumberFormat(e||void 0,{style:"percent",maximumFractionDigits:0}).format(t/100),`${t}%`):""}function tr(t){return t?u.formatMoney?u.formatMoney(t,u.locale):j(t,u.locale):""}function er(t){return t?mt(()=>new Date(t).toLocaleDateString(u.locale||void 0),""):""}function rr(t,e){t.replaceChildren(lt(e,t.ownerDocument,u.embedOrigins))}var ht=t=>t.tagName==="INPUT"||t.tagName==="TEXTAREA",ft=t=>t.tagName==="INPUT";function xe(t,e){let r=e==null?"":String(e);ht(t)?t.value=r:t.textContent=r}var pt=t=>ht(t)?t.value:t.textContent;function nr(t,e){let r=pt(t);if(xe(t,e),r!==pt(t)&&t.hasAttribute(dt)&&u.onValueChange)try{u.onValueChange(t,r)}catch(n){E(n,"onValueChange")}t.setAttribute(dt,"1")}function Ae(t){if(t.hasAttribute($))return;t.setAttribute($,""),t.removeAttribute("hidden");let e=t.getAttribute(v);e!==null?(t.style.display=e,t.removeAttribute(v)):t.style.display==="none"&&(t.style.display=""),typeof getComputedStyle=="function"&&getComputedStyle(t).display==="none"&&(t.style.display=t.getAttribute(g("display"))||"block")}function or(t,e){if(e){Ae(t);return}t.removeAttribute($),!t.hasAttribute(v)&&t.style.display!=="none"&&t.setAttribute(v,t.style.display),t.style.display="none"}function ir(t,e){t.classList.toggle("is-selected",e),t.setAttribute("aria-pressed",e?"true":"false"),ft(t)&&(t.type==="radio"||t.type==="checkbox")&&(t.checked=e);let r=t.querySelector('input[type="radio"],input[type="checkbox"]');r&&ft(r)&&(r.checked=e)}var gt,ve=t=>Reflect.get(window,t);function ke(){let t=ve("ScrollTrigger");if(typeof t!="function")return;let e=Reflect.get(t,"refresh");typeof e=="function"&&Reflect.apply(e,t,[])}function Le(t){clearTimeout(gt),gt=setTimeout(()=>{try{u.onLayoutChange?u.onLayoutChange(t):ke()}catch(e){E(e,"layout-changed")}P("layout-changed",{reason:t})},Se)}function sr(t,e){let r=[...t.querySelectorAll("img")].filter(o=>!o.complete),n=r.length,i=()=>{n-=1,n===0&&Le(`${e}:images`)};r.forEach(o=>{o.addEventListener("load",i,{once:!0}),o.addEventListener("error",i,{once:!0})})}function ar(t,e){return t.getAttribute("aria-busy")==="true"?Promise.resolve(void 0):(t.setAttribute("aria-busy","true"),Promise.resolve().then(e).finally(()=>{t.removeAttribute("aria-busy")}))}function ur(t,e){let r=t?I(t,e):null;if(!r)return null;try{return JSON.parse(r)}catch{return b(`invalid JSON in ${g(e)}`,t),null}}function U(t){return t==null?"":typeof t=="string"?t:typeof t=="number"||typeof t=="boolean"?String(t):JSON.stringify(t)}function cr(t){return Array.isArray(t)?t.filter(y).map(r=>({key:U(r.key),value:U(r.value)})):y(t)?Object.entries(t).map(([e,r])=>({key:e,value:U(r)})):[]}function lr(t){return t?Array.isArray(t)?t.map(e=>({key:String(e.key),value:String(e.value??"")})):Object.entries(t).map(([e,r])=>({key:e,value:String(r??"")})):[]}export{p as a,A as b,Pe as c,Me as d,Tt as e,bt as f,_e as g,Ct as h,Nt as i,Rt as j,He as k,Ue as l,g as m,It as n,I as o,Pt as p,X as q,Mt as r,_t as s,Ht as t,P as u,rt as v,ot as w,$t as x,Dt as y,Ft as z,jt as A,Xe as B,Ze as C,tr as D,er as E,rr as F,xe as G,nr as H,or as I,ir as J,ve as K,Le as L,sr as M,ar as N,ur as O,cr as P,lr as Q};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as m,c as p}from"./chunk-HJY2JSNB.js";import{m as k,o as i,p as g,r as u,u as y}from"./chunk-E5YO6274.js";var w="tether_country",C=()=>`${u.prefix}:market:${u.domain}`,M={getItem:e=>m(e)};function S(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:M,global:e?window:{}}}function b(e){try{return JSON.parse(e)}catch(n){if(n instanceof SyntaxError)return null;throw n}}function E(e){if(typeof e!="object"||e===null)return null;let n=i(Reflect.get(e,"country"));if(!n)return null;let t=Reflect.get(e,"locale");return{country:n,language:g(Reflect.get(e,"language"))??void 0,locale:typeof t=="string"&&t?t:void 0}}function L(e=M){let n=e.getItem(C());return n?E(b(n)):null}function h(e,n){if(!e||!n)return null;let t=e.cookie.split(";").map(r=>r.trim()).find(r=>r.startsWith(`${n}=`));return t?decodeURIComponent(t.slice(n.length+1)):null}function s(e,n){if(!e||!n)return null;let t=n.toLowerCase(),r=Object.keys(e).find(o=>o.toLowerCase()===t);return r?e[r]??null:null}function x(e,n){let t=a=>n.document?.querySelector(`meta[name="${a}"]`)?.getAttribute("content"),r=Reflect.get(n.global,"TETHER_COUNTRY"),o=Reflect.get(n.global,"TETHER_LANGUAGE"),l=t("tether-country")||h(n.document,e.cookie||w);return{country:r||l,language:o||t("tether-language")}}function R(e,n){let t=(n.location?.pathname??"/").split("/").find(c=>c!==""),r=s(e.locales,t);if(r)return r;let o=n.document?.documentElement.getAttribute("lang");if(!o)return null;let l=s(e.locales,o)??s(e.locales,o.split("-")[0]);if(l)return{locale:o,...l};if(e.locales&&e.strict)return null;let a=o.split("-")[1];return{language:o,country:a?.length===2?a:null,locale:o}}function N(e,n,t){switch(e){case"saved":return n.remember===!1?null:L(t.storage);case"server":return x(n,t);case"webflow":return R(n,t)}}function v(e){return e?e===!0?k:e:["saved"]}function I(e=u.markets,n=S()){let t=(e===u.markets?e:y(e))??{};if(t.detect===!1)return{};let r={},o={sources:r};for(let l of v(t.detect)){let a=N(l,t,n);if(!a)continue;let c=i(a.country),d=g(a.language),f=typeof a.locale=="string"&&a.locale?a.locale:null;c&&!o.country&&(o.country=c,r.country=l),d&&!o.language&&(o.language=d,r.language=l),f&&!o.locale&&(o.locale=f,r.locale=l)}return o}function T(e){if(u.markets?.remember===!1)return;let n={country:e.country,language:e.language||void 0,locale:e.locale||void 0};p(C(),JSON.stringify(n))}export{L as a,I as b,T as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as p,m as c,n as i,o as d,r as u}from"./chunk-MQYB6BH4.js";var m="url:";function h(e){try{return decodeURIComponent(e)}catch(t){if(t instanceof URIError)return e;throw t}}function b(e,t=window.location,a="product"){let n=(d(e,a)??"").trim();if(!n.toLowerCase().startsWith(m))return{key:n||null,fromUrl:!1,raw:n};let r=n.slice(m.length).trim(),o;if(r.toLowerCase()==="path"){let s=t.pathname.split("/").filter(Boolean),f=s[s.length-1];o=f===void 0?null:h(f)}else o=new URLSearchParams(t.search).get(r||"handle");return{key:o?.trim()||null,fromUrl:!0,raw:n}}var w=["loading","ready","error","not-found"],y=e=>w.some(t=>t===e),S=e=>typeof e=="object"&&e!==null&&"code"in e?e.code:void 0,E=e=>S(e)==="NOT_FOUND",l=()=>["product","collection","products","recommendations"].map(e=>i(e)).join(","),U=(e,t)=>e===t||e.parentElement?.closest(l())===t;function g(e){let t=S(e);return typeof t=="string"&&t?t:"error"}function x(e,t,a){let n=t==="not-found",r=t==="error"||n;e.setAttribute(c("state"),n?"error":t),r?e.setAttribute(c("error"),n?"not-found":g(a)):e.removeAttribute(c("error")),u(e,i("show"),l()).forEach(o=>{let s=d(o,"show");y(s)&&p(o,s===t)}),r&&u(e,i("add-to-cart"),l()).forEach(o=>{o.classList.add("is-disabled"),o.setAttribute("aria-disabled","true"),"disabled"in o&&(o.disabled=!0)})}export{b as a,w as b,E as c,l as d,U as e,x as f};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as M,b as z,c as H,d as C,e as Z,f as tt,g as et,h as nt,i as it}from"./chunk-BBVUVPMO.js";import{b as $,e as rt}from"./chunk-VFNHIGCS.js";import{e as Y}from"./chunk-HJY2JSNB.js";import{g as J,h as N,i as S,n as K}from"./chunk-6TFMLT4A.js";import{B as D,C as B,D as L,E as U,F as G,G as d,I as x,J as I,L as V,M as j,N as Q,O as W,P as X,m as p,n as o,o as l,p as T,q as f,r as R,u as v,w as _,x as g,y as F,z as y}from"./chunk-MQYB6BH4.js";import{b as h,r as A,z as w}from"./chunk-E5YO6274.js";var ft=/^image:(\d+)$/,at="metafield:",gt=/^(rich_text|multi_line_text)_field$/,vt=["","true","all","*"],q=t=>t.tagName==="SELECT",b=(t,e)=>t.$(`select${e}`).filter(q);function bt(t,e){let n=e.images.nodes,i=[...t.children].map(a=>a.tagName==="IMG"?a:a.querySelector("img"));!F(t)&&i.length===n.length&&i.every((a,s)=>_(a?.getAttribute("src"),n[s]?.url))||y(t,n,(a,s)=>{let c=a.matches(`img,${o("bind","image")}`)?a:f(a,"img")[0]??a;g(c,s.url,s.altText||e.title)})}function Et(t,e,n){let i=n.indexOf("."),r=n.slice(0,i),a=n.slice(i+1),s=(e.metafields??[]).find(u=>u?.namespace===r&&u.key===a);if(!s){d(t,"");return}let c=s.reference?.image;if(c){g(t,c.url,c.altText);return}gt.test(s.type)&&(t.style.whiteSpace="pre-line"),d(t,s.value)}var Pt=new Map(Object.entries({title:t=>t.title,"description-text":t=>t.description,vendor:t=>t.vendor,type:t=>t.productType,handle:t=>t.handle,"published-at":t=>U(t.publishedAt),"min-price":t=>L(t.priceRange.minVariantPrice),"max-price":t=>L(t.priceRange.maxVariantPrice)}));function Tt(t,e){let n=(t.getAttribute("exclude")??"").split(",").map(r=>r.trim()).filter(Boolean),i=e.tags.filter(r=>!n.includes(r));y(t,i,(r,a)=>{d(r,a)})}function yt(t,e,n){let i=Pt.get(e);if(i){d(t,i(n));return}switch(e){case"description":G(t,n.descriptionHtml);break;case"featured-image":g(t,n.featuredImage?.url,n.featuredImage?.altText||n.title);break;case"url":case"link":{let r=D(n.handle,n.id);r&&t.setAttribute("href",r),e==="url"&&!t.firstElementChild&&!t.textContent.trim()&&d(t,n.title);break}case"images":bt(t,n);break;case"tags":Tt(t,n);break;default:Lt(t,e,n)}}function Lt(t,e,n){let i=ft.exec(e);if(i){let r=n.images.nodes[Number(i[1])-1]??n.featuredImage;g(t,r?.url,r?.altText||n.title)}else e.startsWith(at)&&Et(t,n,e.slice(at.length))}function xt(t){let{product:e}=t;t.$(o("option-list")).forEach(n=>{let i=t.optName(l(n,"option-list")),r=e.options.find(a=>a.name===i);if(!r||r.optionValues.length<=1&&T(n,"hide-single")){x(n,!1);return}y(n,r.optionValues,(a,s)=>{a.setAttribute(p("option-value"),s.name);let c=f(a,o("bind","option-value"))[0];c?d(c,s.name):a.firstElementChild||d(a,s.name);let u=f(a,o("bind","swatch"))[0],{swatch:m}=s;!u||!m||(m.color&&(u.style.backgroundColor=m.color),m.image?.previewImage&&g(u,m.image.previewImage.url,s.name))})})}function It(t){let{product:e}=t;b(t,o("option")).forEach(n=>{let i=e.options.find(r=>r.name===t.optName(l(n,"option")));if(!i){x(n,!1);return}n.replaceChildren(...i.optionValues.map(r=>new Option(r.name,r.name)))}),b(t,o("variant-select")).forEach(n=>{n.replaceChildren(...e.variants.nodes.map(i=>new Option(i.title,i.id)))}),b(t,o("plan")).forEach(n=>{let i=t.plans.map(s=>new Option(s.name,s.id)),r=!e.requiresSellingPlan&&l(n,"plan")!=="subscription-only",a=n.getAttribute(p("one-time-label"))||"One-time purchase";n.replaceChildren(...r?[new Option(a,"")]:[],...i)})}function St(t){t.$(o("plan-list")).forEach(e=>{let n=(l(e,"plan-list")??"").trim(),i=vt.includes(n.toLowerCase())?null:n,r=t.plans.filter(a=>!i||a.group.name===i);y(e,r,(a,s)=>{a.setAttribute(p("plan-value"),s.id),!a.firstElementChild&&!a.querySelector(o("plan-bind"))&&d(a,s.name)})})}function st(t){t.$(o("bind")).forEach(e=>{yt(e,l(e,"bind")??"",t.product)}),xt(t),It(t),St(t)}var ot={money:L,percent:B},Mt=t=>t.tagName==="INPUT";function O(t){let e=f(t,o("add-label"))[0]??t,n=e.dataset.tetherLabel??(Mt(e)?e.value:e.textContent);return e.dataset.tetherLabel=n,{label:e,original:n}}function kt(t,e){let{product:n}=t,i=r=>e.selected[t.optName(r)]??"";t.$(o("option-selected")).forEach(r=>{d(r,i(l(r,"option-selected")))}),t.$(o("option-list")).forEach(r=>{let a=t.optName(l(r,"option-list"));f(r,o("option-value")).forEach(s=>{let c=l(s,"option-value")??"";I(s,e.selected[a]===c);let u=!z(n,e.selected,a,c);s.classList.toggle("is-unavailable",u),s.setAttribute("data-unavailable",u?"true":"false")})}),b(t,o("option")).forEach(r=>{r.value=i(l(r,"option"))}),b(t,o("variant-select")).forEach(r=>{r.value=e.variant.id})}function At(t,e){let{variant:n,purchase:i,line:r}=e;t.$(o("purchase")).forEach(a=>{if(q(a)){a.value=i.kind;return}let s=l(a,"purchase");I(a,s===i.kind);let c=s==="subscription"?!e.subscriptionAvailable:t.product.requiresSellingPlan;a.classList.toggle("is-unavailable",c)}),t.$(o("plan-value")).forEach(a=>{let s=l(a,"plan-value")??"";I(a,r.kind==="subscription"&&s===r.planId),a.classList.toggle("is-unavailable",!S(n,s));let c=t.plans.find(m=>m.id===s),u=it(n,s,c,ot);f(a,o("plan-bind")).forEach(m=>{let E=u.get(l(m,"plan-bind")??"");E&&d(m,E())})}),b(t,o("plan")).forEach(a=>{a.value=r.kind==="subscription"?r.planId:""})}function wt(t,e){let n=new Map(Object.entries(e.show));$.forEach(i=>n.set(i,i==="ready")),t.$(o("show")).forEach(i=>{let r=l(i,"show")??"",a=n.get(r);a!==void 0&&($.some(s=>s===r)&&!rt(i,t.root)||x(i,a))})}function Vt(t,e){let n=!e.variant.availableForSale;t.$(o("add-to-cart")).forEach(i=>{i.classList.toggle("is-disabled",n),i.setAttribute("aria-disabled",String(n)),"disabled"in i&&(i.disabled=n);let r=l(i,"soldout-text"),a=l(i,"subscribe-text");if(!r&&!a)return;let{label:s,original:c}=O(i),u=c;e.line.kind==="subscription"&&a&&(u=a),n&&r&&(u=r),i.getAttribute("aria-busy")!=="true"&&d(s,u)})}function lt(t,e){let{variant:n}=e,{product:i}=t,r=nt(e,ot);t.$(o("bind")).forEach(a=>{let s=l(a,"bind")??"";if(s==="variant-image"){g(a,n.image?.url||i.featuredImage?.url,n.image?.altText||i.title);return}let c=r.get(s);c&&d(a,c())}),kt(t,e),At(t,e),wt(t,e),t.root.classList.toggle("is-subscription",e.line.kind==="subscription"),t.root.setAttribute(p("purchase-mode"),e.line.kind),Vt(t,e)}var ut=()=>o("product"),Nt=t=>t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA",ct=t=>t instanceof window.Element;function P(t,e,n){let i=e.closest(n);return i?.closest(ut())===t.root?i:null}function Ht(t,e){let{label:n,original:i}=O(e),r=l(e,"adding-text");Q(e,async()=>{r&&d(n,r);try{await t.addToCart()}catch(a){w(a,"add to cart failed"),v("error",{error:a,context:"add-to-cart"},t.root)}finally{r&&d(n,i)}}).then(()=>{t.renderVariant()}).catch(a=>{w(a,"add to cart render")})}function Ct(t,e,n){let i=P(t,n,o("option-value")),r=i?.closest(o("option-list"));if(i&&r){e.preventDefault(),t.select(t.optName(l(r,"option-list")),l(i,"option-value")??"");return}let a=P(t,n,o("plan-value"));if(a){e.preventDefault(),t.selectPlan(l(a,"plan-value"));return}let s=P(t,n,`${o("purchase")}:not(select)`);if(s){s.tagName!=="INPUT"&&e.preventDefault(),t.setPurchase(dt(l(s,"purchase")));return}let c=P(t,n,o("qty-plus")),u=c?null:P(t,n,o("qty-minus"));if(c||u){e.preventDefault(),t.setQuantity(t.quantity+(c?1:-1));return}let m=P(t,n,o("add-to-cart"));m&&(e.preventDefault(),Ht(t,m))}var dt=t=>t==="subscription"?"subscription":"one-time";function $t(t,e){let n=Nt(e)?e.value:"";e.matches(`select${o("option")}`)?t.select(t.optName(l(e,"option")),n):e.matches(`select${o("variant-select")}`)?t.selectVariant(n):e.matches(`select${o("plan")}`)?n?t.selectPlan(n):t.setPurchase("one-time"):e.matches(`select${o("purchase")}`)?t.setPurchase(dt(n)):e.matches(o("qty"))&&t.setQuantity(n)}function mt(t){t.root.addEventListener("click",e=>{ct(e.target)&&Ct(t,e,e.target)}),t.root.addEventListener("change",e=>{let{target:n}=e;ct(n)&&n.closest(ut())===t.root&&$t(t,n)})}var qt=new WeakMap,Ot=()=>o("product"),k=new Map;function Rt(t){t.forEach(e=>{k.has(e.handle)||k.set(e.handle,e.options.map(n=>n.name))})}var pt=t=>t.tagName==="INPUT",_t=t=>t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA";function Ft(t){return pt(t)&&t.type==="checkbox"?t.checked?t.value&&t.value!=="on"?t.value:"Yes":null:pt(t)&&t.type==="radio"?t.checked?t.value:null:_t(t)&&t.value||null}var ht=class{constructor(e,n){h(this,"root");h(this,"product");h(this,"plans");h(this,"selected");h(this,"purchase");h(this,"variant");h(this,"quantity");this.root=e,this.product=n,this.plans=N(n);let i=new URLSearchParams(window.location.search),r=tt(n,{variant:i.get("variant")||l(e,"variant"),sellingPlan:i.get("selling_plan"),defaultPlan:l(e,"default-plan"),defaultPurchase:l(e,"default-purchase")||A.defaultPurchase});this.selected=r.selected,this.purchase=r.purchase,this.variant=null,this.quantity=T(e,"quantity")?Math.max(0,parseInt(l(e,"quantity")??"",10)||0):1,qt.set(e,this),e.setAttribute(p("state"),"ready"),e.removeAttribute(p("error")),this.renderProduct(),mt(this),this.renderVariant(),j(e,"product"),V("product"),v("product-ready",{product:n,scope:this},e)}update(e){let n=this.variant?.id;this.product=e,this.plans=N(e);let i=e.variants.nodes.find(r=>r.id===n);i&&(this.selected=M(i)),this.root.setAttribute(p("state"),"ready"),this.root.removeAttribute(p("error")),this.renderProduct(),this.renderVariant(),V("product"),v("product-updated",{product:e,scope:this},this.root)}$(e){let n=R(this.root,e,Ot());return this.root.matches(e)?[this.root,...n]:n}optName(e){if(!e)return"";let{options:n}=this.product;if(n.some(r=>r.name===e))return e;let i=(k.get(this.product.handle)??[]).indexOf(e);return n[i]?.name??e}get plan(){let e=H(this.purchase);return this.plans.find(n=>n.id===e)??null}get subscriptionAvailable(){return this.plans.some(e=>S(this.variant,e.id))}get isSubscription(){return C(this.purchase,this.variant).kind==="subscription"}getLine(){if(!this.variant)return null;let e={merchandiseId:this.variant.id,quantity:this.quantity},n=C(this.purchase,this.variant);n.kind==="subscription"&&(e.sellingPlanId=n.planId);let i=this.collectAttributes();return i.length&&(e.attributes=i),e}collectAttributes(){let e=X(W(this.root,"line-attributes")),n=this.$(o("line-attribute")).flatMap(i=>{let r=Ft(i);return r===null?[]:[{key:l(i,"line-attribute")??"",value:r}]});return[...e,...n]}select(e,n){if(this.selected[e]===n)return;let i=this.product.variants.nodes.filter(s=>s.selectedOptions.some(c=>c.name===e&&c.value===n)),[r]=i;if(!r)return;let a={...this.selected,[e]:n};if(!i.some(s=>s.selectedOptions.every(c=>a[c.name]===c.value))){let s=u=>u.selectedOptions.filter(E=>E.name!==e&&this.selected[E.name]===E.value).length*2+(u.availableForSale?1:0),c=i.reduce((u,m)=>s(m)>s(u)?m:u,r);Object.assign(a,M(c))}this.selected=a,this.renderVariant()}selectVariant(e){let n=this.product.variants.nodes.find(i=>i.id===J.variant(e));n&&(this.selected=M(n),this.renderVariant())}setPurchase(e){let n=Z(this.product,this.variant,e,H(this.purchase));n.kind!==this.purchase.kind&&(this.purchase=n,this.renderVariant())}selectPlan(e){let n=K(this.product,e);n&&(this.purchase={kind:"subscription",planId:n.id},this.renderVariant())}setQuantity(e){let n=T(this.root,"quantity")?0:1;this.quantity=Math.max(n,parseInt(String(e),10)||0),this.$(o("qty")).forEach(i=>{d(i,this.quantity)}),this.renderVariant()}async addToCart(){if(!this.variant?.availableForSale)return null;let e=this.getLine();if(!e||e.quantity<1)return null;let n=await Y.add(e);return v("product-added",{product:this.product,variant:this.variant,line:e},this.root),n}renderProduct(){let{product:e}=this;k.has(e.handle)||this.$(`${o("option-list")},select${o("option")}`).map(i=>l(i,"option-list")||l(i,"option")).some(i=>e.options.some(r=>r.name===i))&&Rt([e]),st(this)}renderVariant(){let e=et(this.product,{selected:this.selected,purchase:this.purchase,quantity:this.quantity},A.lowStock);if(!e){this.variant=null;return}this.variant=e.variant,this.selected=e.selected,this.purchase=e.purchase,lt(this,e),v("variant-changed",{product:this.product,variant:e.variant,selected:{...e.selected},purchase:e.purchase.kind,sellingPlanId:e.line.kind==="subscription"?e.line.planId:null},this.root)}};export{qt as a,Rt as b,ht as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e={diagnose:()=>import("./diagnose-XCEBQKBO.js"),markets:()=>import("./markets-ui-M4IQ62CT.js"),search:()=>import("./search-A5DS2IOS.js"),extras:()=>import("./extras-4HU3VSBQ.js"),account:()=>import("./account-CXMA5RPZ.js"),"account-pages":()=>import("./account-pages-IZO7FEOZ.js"),analytics:()=>import("./analytics-PG5FPRDN.js")},a=t=>e[t](),r=void 0;export{a,r as b};
|