@shopbb/helium 0.3.0-alpha.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/components/AddToCartButton.d.ts.map +1 -1
  2. package/dist/components/AddToCartButton.js +17 -5
  3. package/dist/components/AddToCartButton.js.map +1 -1
  4. package/dist/components/AnalyticsProvider.d.ts +106 -0
  5. package/dist/components/AnalyticsProvider.d.ts.map +1 -0
  6. package/dist/components/AnalyticsProvider.js +135 -0
  7. package/dist/components/AnalyticsProvider.js.map +1 -0
  8. package/dist/components/CartProvider.d.ts +111 -0
  9. package/dist/components/CartProvider.d.ts.map +1 -0
  10. package/dist/components/CartProvider.js +263 -0
  11. package/dist/components/CartProvider.js.map +1 -0
  12. package/dist/components/Money.d.ts.map +1 -1
  13. package/dist/components/Money.js +6 -1
  14. package/dist/components/Money.js.map +1 -1
  15. package/dist/components/ProductOptionsProvider.d.ts +70 -0
  16. package/dist/components/ProductOptionsProvider.d.ts.map +1 -0
  17. package/dist/components/ProductOptionsProvider.js +93 -0
  18. package/dist/components/ProductOptionsProvider.js.map +1 -0
  19. package/dist/components/ShopProvider.d.ts +49 -0
  20. package/dist/components/ShopProvider.d.ts.map +1 -0
  21. package/dist/components/ShopProvider.js +62 -0
  22. package/dist/components/ShopProvider.js.map +1 -0
  23. package/dist/components/index.d.ts +18 -1
  24. package/dist/components/index.d.ts.map +1 -1
  25. package/dist/components/index.js +16 -1
  26. package/dist/components/index.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/components/AddToCartButton.tsx +16 -5
  29. package/src/components/AnalyticsProvider.tsx +175 -0
  30. package/src/components/CartProvider.tsx +378 -0
  31. package/src/components/Money.tsx +7 -1
  32. package/src/components/ProductOptionsProvider.tsx +149 -0
  33. package/src/components/ShopProvider.tsx +86 -0
  34. package/src/components/index.ts +39 -1
@@ -0,0 +1,263 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * <CartProvider> + useCart()
4
+ *
5
+ * 接管 cart 全生命周期:
6
+ * - 自动从 cookie 读取 cart_id 并 fetch
7
+ * - 不存在则懒创建
8
+ * - linesAdd / linesUpdate / linesRemove 全部带 optimistic update + 失败回滚
9
+ * - subscribe(callback) 给外部(如 Analytics)订阅 cart 变化
10
+ *
11
+ * 用法:
12
+ * <ShopProvider {...}>
13
+ * <CartProvider>
14
+ * <App />
15
+ * </CartProvider>
16
+ * </ShopProvider>
17
+ *
18
+ * const { cart, status, linesAdd, linesUpdate, linesRemove } = useCart();
19
+ *
20
+ * 注意:必须套在 <ShopProvider> 内(依赖它的 storefrontAccessToken + apiUrl)。
21
+ */
22
+ import * as React from 'react';
23
+ import { useShop } from './ShopProvider';
24
+ const CartContext = React.createContext(null);
25
+ // ============================================================
26
+ // GraphQL
27
+ // ============================================================
28
+ const CART_FRAGMENT = /* GraphQL */ `
29
+ fragment CartParts on Cart {
30
+ id totalQuantity checkoutUrl
31
+ lines(first: 100) {
32
+ nodes {
33
+ id quantity
34
+ merchandise {
35
+ ... on ProductVariant {
36
+ id title
37
+ image { url altText width height }
38
+ price { amount currencyCode }
39
+ product { title handle }
40
+ }
41
+ }
42
+ cost { totalAmount { amount currencyCode } }
43
+ }
44
+ }
45
+ cost {
46
+ subtotalAmount { amount currencyCode }
47
+ totalAmount { amount currencyCode }
48
+ }
49
+ }
50
+ `;
51
+ const Q_GET_CART = CART_FRAGMENT + `
52
+ query GetCart($id: ID!) { cart(id: $id) { ...CartParts } }
53
+ `;
54
+ const M_CART_CREATE = CART_FRAGMENT + `
55
+ mutation Create($input: CartInput) {
56
+ cartCreate(input: $input) { cart { ...CartParts } userErrors { field message code } }
57
+ }
58
+ `;
59
+ const M_LINES_ADD = CART_FRAGMENT + `
60
+ mutation Add($cartId: ID!, $lines: [CartLineInput!]!) {
61
+ cartLinesAdd(cartId: $cartId, lines: $lines) { cart { ...CartParts } userErrors { field message code } }
62
+ }
63
+ `;
64
+ const M_LINES_UPDATE = CART_FRAGMENT + `
65
+ mutation Update($cartId: ID!, $lines: [CartLineUpdateInput!]!) {
66
+ cartLinesUpdate(cartId: $cartId, lines: $lines) { cart { ...CartParts } userErrors { field message code } }
67
+ }
68
+ `;
69
+ const M_LINES_REMOVE = CART_FRAGMENT + `
70
+ mutation Remove($cartId: ID!, $lineIds: [ID!]!) {
71
+ cartLinesRemove(cartId: $cartId, lineIds: $lineIds) { cart { ...CartParts } userErrors { field message code } }
72
+ }
73
+ `;
74
+ // ============================================================
75
+ // cookie cart id
76
+ // ============================================================
77
+ const COOKIE_NAME = 'cart';
78
+ function readCartIdFromCookie() {
79
+ if (typeof document === 'undefined')
80
+ return null;
81
+ const m = document.cookie.match(new RegExp('(?:^|; )' + COOKIE_NAME + '=([^;]+)'));
82
+ if (!m)
83
+ return null;
84
+ return `gid://shopbb/Cart/${decodeURIComponent(m[1])}`;
85
+ }
86
+ function saveCartIdToCookie(cartGid) {
87
+ if (typeof document === 'undefined')
88
+ return;
89
+ const id = cartGid.replace(/^gid:\/\/shopbb\/Cart\//, '');
90
+ const oneYear = 365 * 24 * 60 * 60;
91
+ document.cookie = `${COOKIE_NAME}=${encodeURIComponent(id)}; path=/; max-age=${oneYear}; SameSite=Lax`;
92
+ }
93
+ export function CartProvider({ children, fetchOnMount = true }) {
94
+ const shop = useShop();
95
+ const [cart, setCart] = React.useState(null);
96
+ const [status, setStatus] = React.useState('uninitialized');
97
+ const [error, setError] = React.useState(null);
98
+ const listenersRef = React.useRef(new Set());
99
+ const gql = React.useCallback(async (query, variables) => {
100
+ const res = await fetch(shop.apiUrl, {
101
+ method: 'POST',
102
+ headers: {
103
+ 'Content-Type': 'application/json',
104
+ 'X-Storefront-Access-Token': shop.storefrontAccessToken,
105
+ },
106
+ body: JSON.stringify({ query, variables }),
107
+ credentials: 'include',
108
+ });
109
+ const json = await res.json();
110
+ if (json.errors)
111
+ throw new Error(json.errors[0]?.message || 'GraphQL error');
112
+ return json.data;
113
+ }, [shop.apiUrl, shop.storefrontAccessToken]);
114
+ const notifyListeners = React.useCallback((c) => {
115
+ for (const fn of listenersRef.current)
116
+ fn(c);
117
+ }, []);
118
+ // 应用新 cart 数据(state + 订阅者)
119
+ const applyCart = React.useCallback((next) => {
120
+ setCart(next);
121
+ notifyListeners(next);
122
+ }, [notifyListeners]);
123
+ // 保证有 cart_id,没有就创建
124
+ const ensureCartId = React.useCallback(async () => {
125
+ const cookieCartId = readCartIdFromCookie();
126
+ if (cookieCartId)
127
+ return cookieCartId;
128
+ const data = await gql(M_CART_CREATE, { input: { lines: [] } });
129
+ if (data.cartCreate.userErrors.length > 0) {
130
+ throw new Error(data.cartCreate.userErrors[0].message);
131
+ }
132
+ const newCart = data.cartCreate.cart;
133
+ saveCartIdToCookie(newCart.id);
134
+ applyCart(newCart);
135
+ return newCart.id;
136
+ }, [gql, applyCart]);
137
+ // 初始拉取
138
+ const refetch = React.useCallback(async () => {
139
+ setStatus('loading');
140
+ try {
141
+ const cookieCartId = readCartIdFromCookie();
142
+ if (!cookieCartId) {
143
+ applyCart(null);
144
+ setStatus('idle');
145
+ return;
146
+ }
147
+ const data = await gql(Q_GET_CART, { id: cookieCartId });
148
+ applyCart(data.cart);
149
+ setStatus('idle');
150
+ }
151
+ catch (err) {
152
+ setError(err?.message ?? String(err));
153
+ setStatus('error');
154
+ }
155
+ }, [gql, applyCart]);
156
+ React.useEffect(() => {
157
+ if (fetchOnMount && status === 'uninitialized') {
158
+ void refetch();
159
+ }
160
+ }, [fetchOnMount, status, refetch]);
161
+ // optimistic 包装
162
+ const runMutation = React.useCallback(async (optimisticCart, mutator) => {
163
+ const prev = cart;
164
+ if (optimisticCart)
165
+ applyCart(optimisticCart);
166
+ setStatus('updating');
167
+ try {
168
+ const result = await mutator();
169
+ if (result.userErrors && result.userErrors.length > 0) {
170
+ throw new Error(result.userErrors[0].message);
171
+ }
172
+ applyCart(result.cart);
173
+ setStatus('idle');
174
+ setError(null);
175
+ }
176
+ catch (err) {
177
+ applyCart(prev); // 回滚
178
+ setError(err?.message ?? String(err));
179
+ setStatus('error');
180
+ throw err;
181
+ }
182
+ }, [cart, applyCart]);
183
+ const linesAdd = React.useCallback(async (lines) => {
184
+ const cartId = await ensureCartId();
185
+ await runMutation(null, async () => {
186
+ const data = await gql(M_LINES_ADD, {
187
+ cartId,
188
+ lines: lines.map((l) => ({ merchandiseId: l.merchandiseId, quantity: l.quantity ?? 1 })),
189
+ });
190
+ return data.cartLinesAdd;
191
+ });
192
+ }, [ensureCartId, runMutation, gql]);
193
+ const linesUpdate = React.useCallback(async (lines) => {
194
+ // remove 走 remove
195
+ const toRemove = lines.filter((l) => l.quantity <= 0).map((l) => l.id);
196
+ const toUpdate = lines.filter((l) => l.quantity > 0);
197
+ // optimistic: 改 quantity
198
+ const optimistic = cart != null
199
+ ? {
200
+ ...cart,
201
+ lines: {
202
+ ...cart.lines,
203
+ nodes: cart.lines.nodes
204
+ .map((ln) => {
205
+ const upd = toUpdate.find((l) => l.id === ln.id);
206
+ return upd ? { ...ln, quantity: upd.quantity } : ln;
207
+ })
208
+ .filter((ln) => !toRemove.includes(ln.id)),
209
+ },
210
+ }
211
+ : null;
212
+ const cartId = await ensureCartId();
213
+ await runMutation(optimistic, async () => {
214
+ if (toRemove.length > 0) {
215
+ await gql(M_LINES_REMOVE, { cartId, lineIds: toRemove });
216
+ }
217
+ if (toUpdate.length === 0) {
218
+ const data = await gql(Q_GET_CART, { id: cartId });
219
+ return { cart: data.cart, userErrors: [] };
220
+ }
221
+ const data = await gql(M_LINES_UPDATE, { cartId, lines: toUpdate });
222
+ return data.cartLinesUpdate;
223
+ });
224
+ }, [cart, ensureCartId, runMutation, gql]);
225
+ const linesRemove = React.useCallback(async (lineIds) => {
226
+ const optimistic = cart != null
227
+ ? {
228
+ ...cart,
229
+ lines: { ...cart.lines, nodes: cart.lines.nodes.filter((l) => !lineIds.includes(l.id)) },
230
+ }
231
+ : null;
232
+ const cartId = await ensureCartId();
233
+ await runMutation(optimistic, async () => {
234
+ const data = await gql(M_LINES_REMOVE, { cartId, lineIds });
235
+ return data.cartLinesRemove;
236
+ });
237
+ }, [cart, ensureCartId, runMutation, gql]);
238
+ const subscribe = React.useCallback((listener) => {
239
+ listenersRef.current.add(listener);
240
+ return () => {
241
+ listenersRef.current.delete(listener);
242
+ };
243
+ }, []);
244
+ const value = React.useMemo(() => ({ cart, status, error, linesAdd, linesUpdate, linesRemove, refetch, subscribe }), [cart, status, error, linesAdd, linesUpdate, linesRemove, refetch, subscribe]);
245
+ return _jsx(CartContext.Provider, { value: value, children: children });
246
+ }
247
+ /**
248
+ * 拿 cart context。Provider 外 throw。
249
+ */
250
+ export function useCart() {
251
+ const v = React.useContext(CartContext);
252
+ if (!v)
253
+ throw new Error('useCart must be used inside <CartProvider>');
254
+ return v;
255
+ }
256
+ /**
257
+ * 非 throw 版本:Provider 外返回 null。
258
+ * 给可选 fallback 用,比如 <AddToCartButton> 在没 Provider 时退化到 props.onAdd。
259
+ */
260
+ export function useCartOptional() {
261
+ return React.useContext(CartContext);
262
+ }
263
+ //# sourceMappingURL=CartProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CartProvider.js","sourceRoot":"","sources":["../../src/components/CartProvider.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Money.d.ts","sourceRoot":"","sources":["../../src/components/Money.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACnE,cAAc;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,oBAAoB;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB;IACjB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;IACjC,gCAAgC;IAChC,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAYD,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,2CAmDtC"}
1
+ {"version":3,"file":"Money.d.ts","sourceRoot":"","sources":["../../src/components/Money.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACnE,cAAc;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,oBAAoB;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB;IACjB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;IACjC,gCAAgC;IAChC,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAYD,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,2CAwDtC"}
@@ -1,4 +1,5 @@
1
1
  import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useShopOptional } from './ShopProvider';
2
3
  // currencyCode → 默认 locale 推断
3
4
  const DEFAULT_LOCALE_BY_CURRENCY = {
4
5
  CNY: 'zh-CN',
@@ -11,7 +12,11 @@ const DEFAULT_LOCALE_BY_CURRENCY = {
11
12
  export function Money(props) {
12
13
  const { data, withoutCurrency, withoutTrailingZeros, locale: localeProp, as, measurement, ...rest } = props;
13
14
  const Tag = as || 'span';
14
- const locale = localeProp || DEFAULT_LOCALE_BY_CURRENCY[data.currencyCode] || 'en-US';
15
+ const shop = useShopOptional();
16
+ const locale = localeProp ||
17
+ shop?.locale ||
18
+ DEFAULT_LOCALE_BY_CURRENCY[data.currencyCode] ||
19
+ 'en-US';
15
20
  const amount = Number(data.amount);
16
21
  let formatted;
17
22
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"Money.js","sourceRoot":"","sources":["../../src/components/Money.tsx"],"names":[],"mappings":";AA4CA,8BAA8B;AAC9B,MAAM,0BAA0B,GAA2B;IACzD,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;CACb,CAAC;AAEF,MAAM,UAAU,KAAK,CAAC,KAAiB;IACrC,MAAM,EACJ,IAAI,EACJ,eAAe,EACf,oBAAoB,EACpB,MAAM,EAAE,UAAU,EAClB,EAAE,EACF,WAAW,EACX,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,MAAM,GAAG,GAAQ,EAAE,IAAI,MAAM,CAAC;IAC9B,MAAM,MAAM,GAAG,UAAU,IAAI,0BAA0B,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC;IACtF,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEnC,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,IAAI,GAA6B,eAAe;YACpD,CAAC,CAAC;gBACE,qBAAqB,EAAE,oBAAoB,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/E,qBAAqB,EAAE,CAAC;aACzB;YACH,CAAC,CAAC;gBACE,KAAK,EAAE,UAAU;gBACjB,QAAQ,EAAE,IAAI,CAAC,YAAY;gBAC3B,qBAAqB,EAAE,oBAAoB,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/E,qBAAqB,EAAE,CAAC;aACzB,CAAC;QACN,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;QAClC,SAAS,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAChG,CAAC;IAED,iCAAiC;IACjC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,WAAW,CAAC,aAAa,EAAE,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,OAAO,CACL,MAAC,GAAG,OAAK,IAAI,gBAAc,IAAI,CAAC,MAAM,yBAAuB,IAAI,CAAC,YAAY,aAC3E,SAAS,EACT,MAAM,IACH,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"Money.js","sourceRoot":"","sources":["../../src/components/Money.tsx"],"names":[],"mappings":";AAgBA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA6BjD,8BAA8B;AAC9B,MAAM,0BAA0B,GAA2B;IACzD,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;CACb,CAAC;AAEF,MAAM,UAAU,KAAK,CAAC,KAAiB;IACrC,MAAM,EACJ,IAAI,EACJ,eAAe,EACf,oBAAoB,EACpB,MAAM,EAAE,UAAU,EAClB,EAAE,EACF,WAAW,EACX,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,MAAM,GAAG,GAAQ,EAAE,IAAI,MAAM,CAAC;IAC9B,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,MAAM,MAAM,GACV,UAAU;QACV,IAAI,EAAE,MAAM;QACZ,0BAA0B,CAAC,IAAI,CAAC,YAAY,CAAC;QAC7C,OAAO,CAAC;IACV,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEnC,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,IAAI,GAA6B,eAAe;YACpD,CAAC,CAAC;gBACE,qBAAqB,EAAE,oBAAoB,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/E,qBAAqB,EAAE,CAAC;aACzB;YACH,CAAC,CAAC;gBACE,KAAK,EAAE,UAAU;gBACjB,QAAQ,EAAE,IAAI,CAAC,YAAY;gBAC3B,qBAAqB,EAAE,oBAAoB,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/E,qBAAqB,EAAE,CAAC;aACzB,CAAC;QACN,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;QAClC,SAAS,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAChG,CAAC;IAED,iCAAiC;IACjC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,WAAW,CAAC,aAAa,EAAE,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,OAAO,CACL,MAAC,GAAG,OAAK,IAAI,gBAAc,IAAI,CAAC,MAAM,yBAAuB,IAAI,CAAC,YAAY,aAC3E,SAAS,EACT,MAAM,IACH,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * <ProductOptionsProvider> + useProductOptions()
3
+ *
4
+ * 给商品详情页用。包住 product 后,自动管理 selectedVariantId 状态 +
5
+ * 暴露当前 variant、available options、setOption 等。
6
+ *
7
+ * 用法:
8
+ * <ProductOptionsProvider product={product}>
9
+ * <ProductDetailBody />
10
+ * </ProductOptionsProvider>
11
+ *
12
+ * function ProductDetailBody() {
13
+ * const { selectedVariant, options, setOptionValue } = useProductOptions();
14
+ * return ...;
15
+ * }
16
+ */
17
+ import * as React from 'react';
18
+ interface SelectedOption {
19
+ name: string;
20
+ value: string;
21
+ }
22
+ interface ProductVariantLike {
23
+ id: string;
24
+ availableForSale: boolean;
25
+ selectedOptions?: SelectedOption[];
26
+ price?: {
27
+ amount: string;
28
+ currencyCode: string;
29
+ };
30
+ compareAtPrice?: {
31
+ amount: string;
32
+ currencyCode: string;
33
+ } | null;
34
+ }
35
+ interface ProductLike {
36
+ id: string;
37
+ options?: Array<{
38
+ name: string;
39
+ values: string[];
40
+ }>;
41
+ variants: {
42
+ nodes: ProductVariantLike[];
43
+ };
44
+ }
45
+ export interface ProductOptionItem {
46
+ name: string;
47
+ values: Array<{
48
+ value: string;
49
+ available: boolean;
50
+ isSelected: boolean;
51
+ }>;
52
+ }
53
+ export interface ProductOptionsContextValue {
54
+ product: ProductLike;
55
+ selectedVariant: ProductVariantLike | null;
56
+ selectedOptions: Record<string, string>;
57
+ options: ProductOptionItem[];
58
+ setOptionValue: (name: string, value: string) => void;
59
+ setVariantById: (variantId: string) => void;
60
+ }
61
+ export interface ProductOptionsProviderProps {
62
+ product: ProductLike;
63
+ /** 初始 selectedVariantId;默认第一个可购 variant */
64
+ initialVariantId?: string;
65
+ children: React.ReactNode;
66
+ }
67
+ export declare function ProductOptionsProvider(props: ProductOptionsProviderProps): import("react/jsx-runtime").JSX.Element;
68
+ export declare function useProductOptions(): ProductOptionsContextValue;
69
+ export {};
70
+ //# sourceMappingURL=ProductOptionsProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductOptionsProvider.d.ts","sourceRoot":"","sources":["../../src/components/ProductOptionsProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,UAAU,cAAc;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;CAAE;AAEzD,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,cAAc,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAClE;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACpD,QAAQ,EAAE;QAAE,KAAK,EAAE,kBAAkB,EAAE,CAAA;KAAE,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC3E;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,WAAW,CAAC;IACrB,eAAe,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC3C,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAID,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,WAAW,CAAC;IACrB,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,2CAoFxE;AAED,wBAAgB,iBAAiB,IAAI,0BAA0B,CAI9D"}
@@ -0,0 +1,93 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * <ProductOptionsProvider> + useProductOptions()
4
+ *
5
+ * 给商品详情页用。包住 product 后,自动管理 selectedVariantId 状态 +
6
+ * 暴露当前 variant、available options、setOption 等。
7
+ *
8
+ * 用法:
9
+ * <ProductOptionsProvider product={product}>
10
+ * <ProductDetailBody />
11
+ * </ProductOptionsProvider>
12
+ *
13
+ * function ProductDetailBody() {
14
+ * const { selectedVariant, options, setOptionValue } = useProductOptions();
15
+ * return ...;
16
+ * }
17
+ */
18
+ import * as React from 'react';
19
+ const Ctx = React.createContext(null);
20
+ export function ProductOptionsProvider(props) {
21
+ const { product, initialVariantId, children } = props;
22
+ const variants = product.variants.nodes;
23
+ const findDefault = React.useCallback(() => {
24
+ if (initialVariantId) {
25
+ const found = variants.find((v) => v.id === initialVariantId);
26
+ if (found)
27
+ return found;
28
+ }
29
+ return variants.find((v) => v.availableForSale) ?? variants[0] ?? null;
30
+ }, [initialVariantId, variants]);
31
+ const [selectedVariantId, setSelectedVariantId] = React.useState(findDefault()?.id ?? null);
32
+ React.useEffect(() => {
33
+ setSelectedVariantId(findDefault()?.id ?? null);
34
+ }, [findDefault]);
35
+ const selectedVariant = variants.find((v) => v.id === selectedVariantId) ?? null;
36
+ const selectedOptions = React.useMemo(() => {
37
+ const m = {};
38
+ for (const so of selectedVariant?.selectedOptions ?? [])
39
+ m[so.name] = so.value;
40
+ return m;
41
+ }, [selectedVariant]);
42
+ const options = React.useMemo(() => {
43
+ const dimMap = new Map();
44
+ // 收集所有 option 维度
45
+ if (product.options?.length) {
46
+ for (const opt of product.options) {
47
+ dimMap.set(opt.name, new Set(opt.values));
48
+ }
49
+ }
50
+ else {
51
+ for (const v of variants) {
52
+ for (const so of v.selectedOptions ?? []) {
53
+ if (!dimMap.has(so.name))
54
+ dimMap.set(so.name, new Set());
55
+ dimMap.get(so.name).add(so.value);
56
+ }
57
+ }
58
+ }
59
+ return Array.from(dimMap.entries()).map(([name, vals]) => ({
60
+ name,
61
+ values: Array.from(vals).map((v) => ({
62
+ value: v,
63
+ available: variants.some((variant) => variant.availableForSale &&
64
+ variant.selectedOptions?.some((so) => so.name === name && so.value === v)),
65
+ isSelected: selectedOptions[name] === v,
66
+ })),
67
+ }));
68
+ }, [product, variants, selectedOptions]);
69
+ const setOptionValue = React.useCallback((name, value) => {
70
+ const next = { ...selectedOptions, [name]: value };
71
+ // 找匹配 variant
72
+ const target = variants.find((v) => Object.entries(next).every(([n, val]) => v.selectedOptions?.some((so) => so.name === n && so.value === val)));
73
+ if (target)
74
+ setSelectedVariantId(target.id);
75
+ }, [selectedOptions, variants]);
76
+ const setVariantById = React.useCallback((id) => setSelectedVariantId(id), []);
77
+ const value = {
78
+ product,
79
+ selectedVariant,
80
+ selectedOptions,
81
+ options,
82
+ setOptionValue,
83
+ setVariantById,
84
+ };
85
+ return _jsx(Ctx.Provider, { value: value, children: children });
86
+ }
87
+ export function useProductOptions() {
88
+ const v = React.useContext(Ctx);
89
+ if (!v)
90
+ throw new Error('useProductOptions must be used inside <ProductOptionsProvider>');
91
+ return v;
92
+ }
93
+ //# sourceMappingURL=ProductOptionsProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductOptionsProvider.js","sourceRoot":"","sources":["../../src/components/ProductOptionsProvider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * <ShopProvider> + useShop()
3
+ *
4
+ * 全局店铺上下文 — 注入 storefront token / apiUrl / 货币 / locale / shop 元信息。
5
+ * 子组件用 useShop() 直接拿,不用 prop-drill。
6
+ *
7
+ * 用法:
8
+ * <ShopProvider
9
+ * storeId="store_xxx"
10
+ * storefrontAccessToken="shpat_pub_..."
11
+ * apiUrl="https://api.example.com/api/2026-04/graphql.json"
12
+ * shopName="Shopflare"
13
+ * currencyCode="CNY"
14
+ * locale="zh-CN"
15
+ * >
16
+ * <App />
17
+ * </ShopProvider>
18
+ *
19
+ * // 任意子组件:
20
+ * const { storeId, storefrontAccessToken } = useShop();
21
+ */
22
+ import * as React from 'react';
23
+ export interface ShopContextValue {
24
+ storeId: string;
25
+ storefrontAccessToken: string;
26
+ apiUrl: string;
27
+ shopName: string;
28
+ currencyCode: string;
29
+ locale: string;
30
+ /** 额外自定义字段,用户可塞任意业务 meta */
31
+ meta?: Record<string, any>;
32
+ }
33
+ export interface ShopProviderProps extends Partial<ShopContextValue> {
34
+ storeId: string;
35
+ storefrontAccessToken: string;
36
+ apiUrl: string;
37
+ children: React.ReactNode;
38
+ }
39
+ export declare function ShopProvider(props: ShopProviderProps): import("react/jsx-runtime").JSX.Element;
40
+ /**
41
+ * 拿当前 shop context。Provider 外调用会 throw。
42
+ */
43
+ export declare function useShop(): ShopContextValue;
44
+ /**
45
+ * 非 throw 版本:Provider 外返回 null。
46
+ * 给组件做"可选 fallback"用,比如 <Money> 在没 ShopProvider 时也要能跑。
47
+ */
48
+ export declare function useShopOptional(): ShopContextValue | null;
49
+ //# sourceMappingURL=ShopProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShopProvider.d.ts","sourceRoot":"","sources":["../../src/components/ShopProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAID,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,gBAAgB,CAAC;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CAsBpD;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,gBAAgB,CAM1C;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,gBAAgB,GAAG,IAAI,CAEzD"}
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * <ShopProvider> + useShop()
4
+ *
5
+ * 全局店铺上下文 — 注入 storefront token / apiUrl / 货币 / locale / shop 元信息。
6
+ * 子组件用 useShop() 直接拿,不用 prop-drill。
7
+ *
8
+ * 用法:
9
+ * <ShopProvider
10
+ * storeId="store_xxx"
11
+ * storefrontAccessToken="shpat_pub_..."
12
+ * apiUrl="https://api.example.com/api/2026-04/graphql.json"
13
+ * shopName="Shopflare"
14
+ * currencyCode="CNY"
15
+ * locale="zh-CN"
16
+ * >
17
+ * <App />
18
+ * </ShopProvider>
19
+ *
20
+ * // 任意子组件:
21
+ * const { storeId, storefrontAccessToken } = useShop();
22
+ */
23
+ import * as React from 'react';
24
+ const ShopContext = React.createContext(null);
25
+ export function ShopProvider(props) {
26
+ const value = React.useMemo(() => ({
27
+ storeId: props.storeId,
28
+ storefrontAccessToken: props.storefrontAccessToken,
29
+ apiUrl: props.apiUrl,
30
+ shopName: props.shopName ?? '',
31
+ currencyCode: props.currencyCode ?? 'USD',
32
+ locale: props.locale ?? 'en-US',
33
+ meta: props.meta,
34
+ }), [
35
+ props.storeId,
36
+ props.storefrontAccessToken,
37
+ props.apiUrl,
38
+ props.shopName,
39
+ props.currencyCode,
40
+ props.locale,
41
+ props.meta,
42
+ ]);
43
+ return _jsx(ShopContext.Provider, { value: value, children: props.children });
44
+ }
45
+ /**
46
+ * 拿当前 shop context。Provider 外调用会 throw。
47
+ */
48
+ export function useShop() {
49
+ const v = React.useContext(ShopContext);
50
+ if (!v) {
51
+ throw new Error('useShop must be used inside <ShopProvider>');
52
+ }
53
+ return v;
54
+ }
55
+ /**
56
+ * 非 throw 版本:Provider 外返回 null。
57
+ * 给组件做"可选 fallback"用,比如 <Money> 在没 ShopProvider 时也要能跑。
58
+ */
59
+ export function useShopOptional() {
60
+ return React.useContext(ShopContext);
61
+ }
62
+ //# sourceMappingURL=ShopProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShopProvider.js","sourceRoot":"","sources":["../../src/components/ShopProvider.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAa/B,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAA0B,IAAI,CAAC,CAAC;AASvE,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CACzB,GAAG,EAAE,CAAC,CAAC;QACL,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;QAClD,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,KAAK;QACzC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,OAAO;QAC/B,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,EACF;QACE,KAAK,CAAC,OAAO;QACb,KAAK,CAAC,qBAAqB;QAC3B,KAAK,CAAC,MAAM;QACZ,KAAK,CAAC,QAAQ;QACd,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,MAAM;QACZ,KAAK,CAAC,IAAI;KACX,CACF,CAAC;IACF,OAAO,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,KAAK,CAAC,QAAQ,GAAwB,CAAC;AACrF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO;IACrB,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC"}
@@ -2,13 +2,30 @@
2
2
  * @shopbb/helium/components — 商家用 React 组件
3
3
  *
4
4
  * 用法:
5
- * import { Money, Image, ProductPrice, AddToCartButton } from '@shopbb/helium/components';
5
+ * import {
6
+ * ShopProvider, CartProvider, AnalyticsProvider,
7
+ * useShop, useCart, useAnalytics,
8
+ * Money, Image, ProductPrice,
9
+ * AddToCartButton, CartLineQuantityAdjustButton,
10
+ * VariantSelector, ProductOptionsProvider, useProductOptions,
11
+ * Analytics,
12
+ * } from '@shopbb/helium/components';
6
13
  *
7
14
  * 设计原则:
8
15
  * - 无样式:组件只管行为 + 语义化 DOM,样式商家自己写
9
16
  * - data-* 钩子:方便选择器
10
17
  * - 对齐 Shopify Hydrogen 同名组件的 API,迁移成本低
18
+ * - Provider 链:<ShopProvider> > <CartProvider> > <AnalyticsProvider> > App
19
+ * 组件优先从 Provider 拿;Provider 缺省时回退到 props 或 noop
11
20
  */
21
+ export { ShopProvider, useShop, useShopOptional } from './ShopProvider';
22
+ export type { ShopContextValue, ShopProviderProps } from './ShopProvider';
23
+ export { CartProvider, useCart, useCartOptional } from './CartProvider';
24
+ export type { Cart, CartLine, CartLineMerchandise, CartStatus, CartUserError, CartContextValue, CartProviderProps, } from './CartProvider';
25
+ export { ProductOptionsProvider, useProductOptions, } from './ProductOptionsProvider';
26
+ export type { ProductOptionsContextValue, ProductOptionsProviderProps, ProductOptionItem, } from './ProductOptionsProvider';
27
+ export { AnalyticsProvider, useAnalytics, Analytics } from './AnalyticsProvider';
28
+ export type { AnalyticsEvent, AnalyticsContextValue, AnalyticsProviderProps } from './AnalyticsProvider';
12
29
  export { Money } from './Money';
13
30
  export type { MoneyProps, MoneyData, MoneyMeasurement } from './Money';
14
31
  export { Image } from './Image';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,YAAY,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,aAAa,GACd,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,YAAY,EACV,IAAI,EACJ,QAAQ,EACR,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACjF,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGzG,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,YAAY,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,aAAa,GACd,MAAM,mBAAmB,CAAC"}