@asteby/storefront-react 0.3.0 → 0.5.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 +150 -0
- package/dist/chunk-2WZIWIBW.js +75 -0
- package/dist/chunk-2WZIWIBW.js.map +1 -0
- package/dist/chunk-672OTUM2.js +60 -0
- package/dist/chunk-672OTUM2.js.map +1 -0
- package/dist/{chunk-C6QZNKRE.js → chunk-6CVKW7F3.js} +6 -37
- package/dist/chunk-6CVKW7F3.js.map +1 -0
- package/dist/chunk-DQBL2DFJ.js +40 -0
- package/dist/chunk-DQBL2DFJ.js.map +1 -0
- package/dist/index.cjs +264 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +124 -6
- package/dist/index.d.ts +124 -6
- package/dist/index.js +263 -69
- package/dist/index.js.map +1 -1
- package/dist/mockups.cjs +47 -5
- package/dist/mockups.cjs.map +1 -1
- package/dist/mockups.d.cts +62 -3
- package/dist/mockups.d.ts +62 -3
- package/dist/mockups.js +47 -7
- package/dist/mockups.js.map +1 -1
- package/dist/payments.cjs +766 -0
- package/dist/payments.cjs.map +1 -0
- package/dist/payments.d.cts +364 -0
- package/dist/payments.d.ts +364 -0
- package/dist/payments.js +680 -0
- package/dist/payments.js.map +1 -0
- package/dist/promotions.cjs +573 -0
- package/dist/promotions.cjs.map +1 -0
- package/dist/promotions.d.cts +243 -0
- package/dist/promotions.d.ts +243 -0
- package/dist/promotions.js +480 -0
- package/dist/promotions.js.map +1 -0
- package/package.json +23 -2
- package/dist/chunk-C6QZNKRE.js.map +0 -1
package/dist/mockups.d.ts
CHANGED
|
@@ -29,8 +29,15 @@ type MockupTone = keyof typeof MOCKUP_TOKENS;
|
|
|
29
29
|
declare function tone(t: MockupTone, prop?: 'fill' | 'stroke'): CSSProperties;
|
|
30
30
|
/** Monospace stack for part numbers and sizes (`--mockup-font-mono`). */
|
|
31
31
|
declare const MOCKUP_MONO = "var(--mockup-font-mono, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace))";
|
|
32
|
-
/**
|
|
33
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Greedy word wrap by characters; the last allowed line ends in `…` when text
|
|
34
|
+
* is cut. Words longer than `wordMax` (default `maxChars`) are cut with `…`; a
|
|
35
|
+
* word between `maxChars` and `wordMax` keeps a line of its own, so the caller
|
|
36
|
+
* can shrink the font to fit it (`fitMockupFontSize`) instead of cutting it.
|
|
37
|
+
*/
|
|
38
|
+
declare function wrapMockupText(text: string | null | undefined, maxChars: number, maxLines: number, wordMax?: number): string[];
|
|
39
|
+
/** Longest word (in characters) that still fits `width` at font size `min` (glyph width `ratio` em). */
|
|
40
|
+
declare function mockupWordMax(width: number, min: number, ratio?: number): number;
|
|
34
41
|
/** Font size so the longest line fits `width` (approximate glyph width `ratio` em). */
|
|
35
42
|
declare function fitMockupFontSize(lines: readonly string[], width: number, max: number, min?: number, ratio?: number): number;
|
|
36
43
|
type MockupTextProps = Omit<SVGProps<SVGTextElement>, 'children'> & {
|
|
@@ -200,4 +207,56 @@ type ProductImageProps = Omit<ImageProps, 'data'> & {
|
|
|
200
207
|
*/
|
|
201
208
|
declare function ProductImage({ product, variant, image, kind: kindProp, resolveKind: resolveProp, registry: registryProp, labels: labelOverrides, alt, className, style, id, ...imageProps }: ProductImageProps): react.JSX.Element | null;
|
|
202
209
|
|
|
203
|
-
|
|
210
|
+
/**
|
|
211
|
+
* One store mockup, in one file: which products it claims, what it reads from
|
|
212
|
+
* them and how it draws. Every field but `kind` and `render` is optional.
|
|
213
|
+
*/
|
|
214
|
+
type MockupDefinition<D = any> = {
|
|
215
|
+
/** Kind name (`supplement`, `tire`, `casco-moto`). Reusing a base kind replaces it. */
|
|
216
|
+
kind: MockupKind;
|
|
217
|
+
/**
|
|
218
|
+
* Claims a product for this kind. Checked in list order, before the SDK's
|
|
219
|
+
* guess (`guess`: `mockup_kind` attribute, tire/part attributes, words in
|
|
220
|
+
* type/category/tags). Omit it to rely on the guess or on `mockup_kind`.
|
|
221
|
+
*/
|
|
222
|
+
match?: (product: MockupProduct, guess: MockupKind) => boolean;
|
|
223
|
+
/** Product (+ selected variant) → data for `render`. Default: the base extractor of the kind (generic data for new kinds). Never prices. */
|
|
224
|
+
data?: (product: MockupProduct, variant?: MockupVariant | null) => D;
|
|
225
|
+
/** Data → accessible name (prefix it with `labels.illustration`). Default: `describeMockup`. */
|
|
226
|
+
describe?: (data: D, labels: MockupLabels) => string;
|
|
227
|
+
/** The drawing: a component that returns a `<MockupFrame>` (or a base one: `SupplementMockup`…). */
|
|
228
|
+
render: MockupComponent<D>;
|
|
229
|
+
};
|
|
230
|
+
/** Typed, checked definition of a store mockup (throws on an invalid kind or a missing `render`). */
|
|
231
|
+
declare function defineMockup<D = any>(definition: MockupDefinition<D>): MockupDefinition<D>;
|
|
232
|
+
type CreateStoreMockupsOptions = {
|
|
233
|
+
/**
|
|
234
|
+
* Starting registry: `builtin` (default) keeps tire, part, supplement and
|
|
235
|
+
* generic for the kinds the store does not define; `none` starts empty (keep
|
|
236
|
+
* a `generic` among your definitions); or pass a registry to extend.
|
|
237
|
+
*/
|
|
238
|
+
base?: 'builtin' | 'none' | MockupRegistry;
|
|
239
|
+
/** Interface words (`illustration`, `servings`…) for every mockup. */
|
|
240
|
+
labels?: Partial<MockupLabels>;
|
|
241
|
+
};
|
|
242
|
+
/** What `<MockupProvider {...storeMockups}>` takes. */
|
|
243
|
+
type StoreMockups = {
|
|
244
|
+
registry: MockupRegistry;
|
|
245
|
+
resolveKind: ResolveMockupKind;
|
|
246
|
+
labels?: Partial<MockupLabels>;
|
|
247
|
+
/** Kinds defined by the store, in order. */
|
|
248
|
+
kinds: MockupKind[];
|
|
249
|
+
};
|
|
250
|
+
/**
|
|
251
|
+
* Builds the store's mockup setup from its definitions: a registry (base
|
|
252
|
+
* mockups + the store's, the store's win) and a `resolveKind` that asks each
|
|
253
|
+
* `match` in order and otherwise keeps the SDK's guess.
|
|
254
|
+
*
|
|
255
|
+
* ```tsx
|
|
256
|
+
* export const storeMockups = createStoreMockups([supplement, accessory])
|
|
257
|
+
* <MockupProvider {...storeMockups}>…</MockupProvider>
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
declare function createStoreMockups(definitions: readonly MockupDefinition[], options?: CreateStoreMockupsOptions): StoreMockups;
|
|
261
|
+
|
|
262
|
+
export { BUILTIN_MOCKUPS, type CreateStoreMockupsOptions, DEFAULT_MOCKUP_LABELS, GenericMockup, MOCKUP_MONO, MOCKUP_SIZE, MOCKUP_TOKENS, type MockupComponent, type MockupComponentProps, type MockupConfig, type MockupDefinition, MockupFrame, type MockupFrameProps, type MockupLabels, MockupProvider, type MockupProviderProps, type MockupRegistry, type MockupRenderer, type MockupRendererInput, MockupText, type MockupTextProps, type MockupTone, PartMockup, ProductImage, type ProductImageProduct, type ProductImageProps, ProductMockup, type ProductMockupProps, type ResolveMockupKind, type ResolvedMockupRenderer, type StoreMockups, SupplementMockup, TireMockup, createMockupRegistry, createStoreMockups, defaultMockupRegistry, defineMockup, describeMockup, fitMockupFontSize, mockupWordMax, registerMockup, tone, useMockupConfig, wrapMockupText };
|
package/dist/mockups.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Image } from './chunk-
|
|
1
|
+
import { Image } from './chunk-6CVKW7F3.js';
|
|
2
|
+
import './chunk-DQBL2DFJ.js';
|
|
2
3
|
import { mockupDataFromProduct, resolveMockupKind } from '@asteby/storefront/mockup';
|
|
3
4
|
export { BUILTIN_MOCKUP_KINDS, DEFAULT_MOCKUP_KIND_RULES, MOCKUP_KIND_ATTRIBUTES, MOCKUP_TEXT_LIMITS, cleanMockupText, genericMockupData, mockupDataFromProduct, mockupMonogram, partMockupData, resolveMockupKind, supplementMockupData, tireMockupData } from '@asteby/storefront/mockup';
|
|
4
5
|
import { createContext, useContext } from 'react';
|
|
@@ -25,17 +26,18 @@ function tone(t, prop = "fill") {
|
|
|
25
26
|
return { [prop]: `var(--mk-${t})` };
|
|
26
27
|
}
|
|
27
28
|
var MOCKUP_MONO = "var(--mockup-font-mono, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace))";
|
|
28
|
-
function wrapMockupText(text, maxChars, maxLines) {
|
|
29
|
+
function wrapMockupText(text, maxChars, maxLines, wordMax = maxChars) {
|
|
29
30
|
if (!text || maxLines < 1) return [];
|
|
31
|
+
const cap = Math.max(maxChars, wordMax);
|
|
30
32
|
const words = text.split(" ").filter(Boolean);
|
|
31
33
|
const lines = [];
|
|
32
34
|
let current = "";
|
|
33
35
|
let cut = false;
|
|
34
36
|
for (let i = 0; i < words.length; i++) {
|
|
35
37
|
let word = words[i];
|
|
36
|
-
if (Array.from(word).length >
|
|
38
|
+
if (Array.from(word).length > cap) word = Array.from(word).slice(0, cap - 1).join("") + "\u2026";
|
|
37
39
|
const next = current ? `${current} ${word}` : word;
|
|
38
|
-
if (Array.from(next).length <= maxChars) {
|
|
40
|
+
if (Array.from(next).length <= maxChars || !current) {
|
|
39
41
|
current = next;
|
|
40
42
|
continue;
|
|
41
43
|
}
|
|
@@ -51,11 +53,15 @@ function wrapMockupText(text, maxChars, maxLines) {
|
|
|
51
53
|
if (cut || lines.length > maxLines) {
|
|
52
54
|
const kept = lines.slice(0, maxLines);
|
|
53
55
|
const last = Array.from(kept[maxLines - 1] ?? "");
|
|
54
|
-
|
|
56
|
+
const limit = Math.max(maxChars, Math.min(cap, last.length));
|
|
57
|
+
kept[maxLines - 1] = (last.length >= limit ? last.slice(0, limit - 1).join("") : last.join("")).replace(/[\s.,;:…-]+$/, "") + "\u2026";
|
|
55
58
|
return kept;
|
|
56
59
|
}
|
|
57
60
|
return lines;
|
|
58
61
|
}
|
|
62
|
+
function mockupWordMax(width, min, ratio = 0.62) {
|
|
63
|
+
return Math.max(1, Math.floor(width / (min * ratio)));
|
|
64
|
+
}
|
|
59
65
|
function fitMockupFontSize(lines, width, max, min = 10, ratio = 0.62) {
|
|
60
66
|
const longest = Math.max(1, ...lines.map((l) => Array.from(l).length));
|
|
61
67
|
return Math.round(Math.max(min, Math.min(max, width / (longest * ratio))));
|
|
@@ -226,7 +232,7 @@ function SupplementMockup({ data, label, labels, ...rest }) {
|
|
|
226
232
|
const cx = box.x + box.w / 2;
|
|
227
233
|
const inner = box.w - 20;
|
|
228
234
|
const amount = data.presentation ?? (data.servings ? `${data.servings} ${labels.servings}` : null);
|
|
229
|
-
const nameLines = wrapMockupText(data.title, 12, 3);
|
|
235
|
+
const nameLines = wrapMockupText(data.title, 12, 3, mockupWordMax(inner, 12, 0.64));
|
|
230
236
|
const nameFont = fitMockupFontSize(nameLines, inner, 26, 12, 0.64);
|
|
231
237
|
const flavor = data.flavor ? wrapMockupText(data.flavor, 18, 1)[0] : null;
|
|
232
238
|
const flavorW = flavor ? Math.min(inner, Array.from(flavor).length * 6.6 + 20) : 0;
|
|
@@ -396,6 +402,40 @@ function ProductImage({
|
|
|
396
402
|
);
|
|
397
403
|
}
|
|
398
404
|
|
|
399
|
-
|
|
405
|
+
// src/mockups/define.tsx
|
|
406
|
+
var KIND_PATTERN2 = /^[a-z][a-z0-9_-]{0,31}$/;
|
|
407
|
+
function defineMockup(definition) {
|
|
408
|
+
if (!definition || typeof definition.kind !== "string" || !KIND_PATTERN2.test(definition.kind)) {
|
|
409
|
+
throw new TypeError(`defineMockup: invalid kind "${String(definition?.kind)}" (use a-z, 0-9, - and _)`);
|
|
410
|
+
}
|
|
411
|
+
if (typeof definition.render !== "function") throw new TypeError(`defineMockup("${definition.kind}"): render is required`);
|
|
412
|
+
if (definition.match !== void 0 && typeof definition.match !== "function") throw new TypeError(`defineMockup("${definition.kind}"): match must be a function`);
|
|
413
|
+
return Object.freeze({ ...definition });
|
|
414
|
+
}
|
|
415
|
+
function createStoreMockups(definitions, options = {}) {
|
|
416
|
+
const base = options.base ?? "builtin";
|
|
417
|
+
const registry = base === "builtin" ? createMockupRegistry(BUILTIN_MOCKUPS) : base === "none" ? createMockupRegistry() : base.extend();
|
|
418
|
+
const seen = /* @__PURE__ */ new Set();
|
|
419
|
+
for (const d of definitions) {
|
|
420
|
+
const def = defineMockup(d);
|
|
421
|
+
if (seen.has(def.kind)) throw new TypeError(`createStoreMockups: kind "${def.kind}" is defined twice`);
|
|
422
|
+
seen.add(def.kind);
|
|
423
|
+
registry.register(def.kind, {
|
|
424
|
+
component: def.render,
|
|
425
|
+
...def.data ? { fromProduct: def.data } : null,
|
|
426
|
+
...def.describe ? { describe: def.describe } : null
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
const matchers = definitions.filter((d) => typeof d.match === "function");
|
|
430
|
+
const resolveKind = (product, guess) => {
|
|
431
|
+
for (const d of matchers) if (d.match(product, guess)) return d.kind;
|
|
432
|
+
return guess;
|
|
433
|
+
};
|
|
434
|
+
const out = { registry, resolveKind, kinds: [...seen] };
|
|
435
|
+
if (options.labels) out.labels = options.labels;
|
|
436
|
+
return out;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export { BUILTIN_MOCKUPS, DEFAULT_MOCKUP_LABELS, GenericMockup, MOCKUP_MONO, MOCKUP_SIZE, MOCKUP_TOKENS, MockupFrame, MockupProvider, MockupText, PartMockup, ProductImage, ProductMockup, SupplementMockup, TireMockup, createMockupRegistry, createStoreMockups, defaultMockupRegistry, defineMockup, describeMockup, fitMockupFontSize, mockupWordMax, registerMockup, tone, useMockupConfig, wrapMockupText };
|
|
400
440
|
//# sourceMappingURL=mockups.js.map
|
|
401
441
|
//# sourceMappingURL=mockups.js.map
|
package/dist/mockups.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mockups/frame.tsx","../src/mockups/generic.tsx","../src/mockups/labels.ts","../src/mockups/part.tsx","../src/mockups/supplement.tsx","../src/mockups/tire.tsx","../src/mockups/registry.tsx","../src/mockups/product-image.tsx"],"names":["jsxs","jsx","Fragment"],"mappings":";;;;;;AAGO,IAAM,WAAA,GAAc;AAQpB,IAAM,aAAA,GAAgB;AAAA,EAC3B,EAAA,EAAI,oEAAA;AAAA,EACJ,OAAA,EAAS,qDAAA;AAAA,EACT,aAAA,EAAe,yDAAA;AAAA,EACf,KAAA,EAAO,4EAAA;AAAA,EACP,WAAA,EAAa,gFAAA;AAAA,EACb,GAAA,EAAK,0EAAA;AAAA,EACL,KAAA,EAAO,kFAAA;AAAA,EACP,MAAA,EAAQ,0EAAA;AAAA,EACR,YAAA,EAAc;AAChB;AAIA,IAAM,UAAA,GAAqC;AAAA,EACzC,GAAG,MAAA,CAAO,WAAA,CAAY,OAAO,OAAA,CAAQ,aAAa,EAAE,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA,KAAA,EAAQ,CAAC,CAAA,CAAA,EAAI,CAAC,CAAC,CAAC,CAAA;AAAA,EACrF,UAAA,EAAY,iGAAA;AAAA,EACZ,aAAA,EAAe;AACjB,CAAA;AAGO,SAAS,IAAA,CAAK,CAAA,EAAe,IAAA,GAA0B,MAAA,EAAuB;AACnF,EAAA,OAAO,EAAE,CAAC,IAAI,GAAG,CAAA,SAAA,EAAY,CAAC,CAAA,CAAA,CAAA,EAAI;AACpC;AAGO,IAAM,WAAA,GAAc;AAOpB,SAAS,cAAA,CAAe,IAAA,EAAiC,QAAA,EAAkB,QAAA,EAA4B;AAC5G,EAAA,IAAI,CAAC,IAAA,IAAQ,QAAA,GAAW,CAAA,SAAU,EAAC;AACnC,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AAC5C,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,OAAA,GAAU,EAAA;AACd,EAAA,IAAI,GAAA,GAAM,KAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,IAAI,IAAA,GAAO,MAAM,CAAC,CAAA;AAClB,IAAA,IAAI,MAAM,IAAA,CAAK,IAAI,EAAE,MAAA,GAAS,QAAA,SAAiB,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,CAAE,MAAM,CAAA,EAAG,QAAA,GAAW,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,GAAI,QAAA;AAClG,IAAA,MAAM,OAAO,OAAA,GAAU,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,IAAA;AAC9C,IAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,CAAE,UAAU,QAAA,EAAU;AACvC,MAAA,OAAA,GAAU,IAAA;AACV,MAAA;AAAA,IACF;AACA,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,IAAA,OAAA,GAAU,IAAA;AACV,IAAA,IAAI,KAAA,CAAM,WAAW,QAAA,EAAU;AAC7B,MAAA,GAAA,GAAM,IAAA;AACN,MAAA,OAAA,GAAU,EAAA;AACV,MAAA;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA;AAC/B,EAAA,IAAI,GAAA,IAAO,KAAA,CAAM,MAAA,GAAS,QAAA,EAAU;AAClC,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA;AACpC,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,KAAK,QAAA,GAAW,CAAC,KAAK,EAAE,CAAA;AAChD,IAAA,IAAA,CAAK,QAAA,GAAW,CAAC,CAAA,GAAA,CAAK,IAAA,CAAK,UAAU,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,QAAA,GAAW,CAAC,EAAE,IAAA,CAAK,EAAE,IAAI,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA,EAAG,OAAA,CAAQ,cAAA,EAAgB,EAAE,CAAA,GAAI,QAAA;AACpI,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,kBAAkB,KAAA,EAA0B,KAAA,EAAe,KAAa,GAAA,GAAM,EAAA,EAAI,QAAQ,IAAA,EAAc;AACtH,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAG,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,CAAE,MAAM,CAAC,CAAA;AACrE,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,KAAA,IAAS,OAAA,GAAU,KAAA,CAAM,CAAC,CAAC,CAAA;AAC3E;AAeO,SAAS,WAAW,EAAE,KAAA,EAAO,GAAG,CAAA,EAAG,IAAA,EAAM,aAAa,IAAA,EAAM,IAAA,EAAM,IAAI,KAAA,EAAO,MAAA,GAAS,KAAK,MAAA,GAAS,QAAA,EAAU,MAAM,KAAA,EAAO,GAAG,MAAK,EAAoB;AAC5J,EAAA,IAAI,CAAC,KAAA,CAAM,MAAA,EAAQ,OAAO,IAAA;AAC1B,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,CAAA;AAAA,MACA,CAAA;AAAA,MACA,QAAA,EAAU,IAAA;AAAA,MACV,UAAA,EAAY,MAAA;AAAA,MACZ,UAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,CAAC,CAAA,EAAG,GAAI,IAAA,GAAO,EAAE,UAAA,EAAY,WAAA,EAAY,GAAI,IAAA,EAAO,GAAG,KAAA,EAAM;AAAA,MAC7E,GAAG,IAAA;AAAA,MAEH,QAAA,EAAA,KAAA,CAAM,WAAW,CAAA,GACd,KAAA,CAAM,CAAC,CAAA,GACP,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,yBACd,OAAA,EAAA,EAAc,CAAA,EAAM,IAAI,CAAA,KAAM,CAAA,GAAI,IAAI,IAAA,GAAO,UAAA,EAC3C,QAAA,EAAA,IAAA,EAAA,EADS,CAEZ,CACD;AAAA;AAAA,GACP;AAEJ;AAqBO,SAAS,WAAA,CAAY,EAAE,KAAA,EAAO,UAAA,GAAa,OAAO,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,KAAA,GAAQ,WAAA,EAAa,MAAA,GAAS,WAAA,EAAa,GAAG,MAAK,EAAqB;AACtJ,EAAA,MAAM,IAAA,GAAO,UAAA,GAAa,EAAE,aAAA,EAAe,IAAA,KAAkB,EAAE,IAAA,EAAM,KAAA,EAAO,YAAA,EAAc,KAAA,EAAM;AAChG,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,4BAAA;AAAA,MACN,OAAA,EAAS,CAAA,IAAA,EAAO,WAAW,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA;AAAA,MAC1C,KAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA,EAAU,OAAA;AAAA,MACV,aAAA,EAAa,IAAA;AAAA,MACZ,GAAG,IAAA;AAAA,MACJ,KAAA,EAAO,EAAE,GAAG,UAAA,EAAY,GAAG,KAAA,EAAM;AAAA,MAChC,GAAG,IAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,UAAA,GAAa,IAAA,mBAAO,GAAA,CAAC,OAAA,EAAA,EAAO,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,wBACnC,GAAA,CAAC,UAAK,KAAA,EAAO,WAAA,EAAa,QAAQ,WAAA,EAAa,KAAA,EAAO,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA;AAAA,QACjE;AAAA;AAAA;AAAA,GACH;AAEJ;ACvJO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,KAAA,EAAO,QAAQ,OAAA,EAAS,GAAG,MAAK,EAA4C;AAChH,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,IAAA,CAAK,KAAA,EAAO,IAAI,CAAC,CAAA;AACnD,EAAA,MAAM,SAAA,GAAY,iBAAA,CAAkB,UAAA,EAAY,GAAA,EAAK,IAAI,EAAE,CAAA;AAC3D,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,MAAA,GAAS,CAAA,GAAI,GAAA,GAAM,GAAA;AAC7C,EAAA,MAAM,OAAA,GAAU,KAAK,QAAA,GAAW,cAAA,CAAe,KAAK,QAAA,EAAU,EAAA,EAAI,CAAC,CAAA,GAAI,EAAC;AACxE,EAAA,uBACEA,IAAAA,CAAC,WAAA,EAAA,EAAY,MAAK,SAAA,EAAU,KAAA,EAAe,GAAG,IAAA,EAC5C,QAAA,EAAA;AAAA,oBAAAC,IAAC,SAAA,EAAA,EAAQ,EAAA,EAAI,KAAK,EAAA,EAAI,GAAA,EAAK,IAAI,GAAA,EAAK,EAAA,EAAI,CAAA,EAAG,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,KAAK,CAAA,EAAG,OAAA,EAAS,MAAK,EAAG,CAAA;AAAA,oBACrFA,IAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6BAA4B,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA;AAAA,oBAC3DA,IAAC,MAAA,EAAA,EAAK,CAAA,EAAE,+BAA8B,KAAA,EAAO,IAAA,CAAK,SAAS,CAAA,EAAG,CAAA;AAAA,oBAC9DA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6BAAA,EAA8B,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAK,EAAG,CAAA;AAAA,oBAC9EA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,IAAI,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,KAAA,EAAO,IAAA,CAAK,SAAS,CAAA,EAAG,CAAA;AAAA,oBACrEA,GAAAA,CAAC,MAAA,EAAA,EAAK,GAAG,GAAA,EAAK,CAAA,EAAG,IAAI,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA,EAAI,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,QAAQ,CAAA,EAAG,OAAA,EAAS,KAAI,EAAG,CAAA;AAAA,oBACxFA,GAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAI,GAAA,EAAK,EAAA,EAAI,GAAA,EAAK,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,EAAG,CAAA;AAAA,IACtD,IAAA,CAAK,2BAAWA,GAAAA,CAAC,cAAW,KAAA,EAAO,CAAC,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA,EAAG,KAAK,CAAA,EAAG,GAAA,EAAK,MAAM,EAAA,EAAI,MAAA,EAAQ,KAAK,IAAA,EAAK,WAAA,EAAY,aAAA,EAAe,CAAA,EAAG,CAAA,GAAK,IAAA;AAAA,IACnI,IAAA,CAAK,KAAA,mBAAQA,GAAAA,CAAC,UAAA,EAAA,EAAW,OAAO,cAAA,CAAe,IAAA,CAAK,KAAA,EAAO,EAAA,EAAI,CAAC,CAAA,EAAG,GAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,KAAK,IAAA,EAAK,aAAA,EAAc,aAAA,EAAe,CAAA,EAAG,CAAA,GAAK,IAAA;AAAA,IACpJ,OAAA,CAAQ,SAAS,CAAA,IAAK,UAAA,CAAW,SAAS,CAAA,mBAAIA,GAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,OAAA,EAAS,GAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,KAAK,IAAA,EAAK,OAAA,EAAQ,aAAA,EAAe,CAAA,EAAG,CAAA,GAAK,IAAA;AAAA,oBACtJA,GAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,YAAY,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAW,UAAA,EAAY,GAAA,EAAK,QAAQ,GAAA,EAAK;AAAA,GAAA,EACnG,CAAA;AAEJ;;;ACRO,IAAM,qBAAA,GAAsC;AAAA,EACjD,YAAA,EAAc,8BAAA;AAAA,EACd,IAAA,EAAM,QAAA;AAAA,EACN,UAAA,EAAY,iBAAA;AAAA,EACZ,GAAA,EAAK,KAAA;AAAA,EACL,IAAA,EAAM,gBAAA;AAAA,EACN,MAAA,EAAQ,OAAA;AAAA,EACR,QAAA,EAAU,WAAA;AAAA,EACV,UAAA,EAAY,IAAA;AAAA,EACZ,OAAA,EAAS;AACX;AAEA,IAAM,GAAA,GAAM,CAAC,QAAA,EAAkB,MAAA,KAAmB,QAAA,CAAS,aAAY,CAAE,QAAA,CAAS,MAAA,CAAO,WAAA,EAAa,CAAA;AAG/F,SAAS,cAAA,CAAe,IAAA,EAA8D,MAAA,GAAuB,qBAAA,EAA+B;AACjJ,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,EAAA;AAC5B,EAAA,MAAM,KAAA,GAAuC,CAAC,KAAK,CAAA;AACnD,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,MAAA;AACH,MAAA,IAAI,KAAK,IAAA,IAAQ,CAAC,GAAA,CAAI,KAAA,EAAO,KAAK,IAAI,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,GAAG,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AACjF,MAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,GAAA,CAAI,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAO,CAAA;AACtE,MAAA;AAAA,IACF,KAAK,MAAA;AACH,MAAA,IAAI,KAAK,UAAA,IAAc,CAAC,GAAA,CAAI,KAAA,EAAO,KAAK,UAAU,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,GAAG,MAAA,CAAO,UAAU,CAAA,CAAA,EAAI,IAAA,CAAK,UAAU,CAAA,CAAE,CAAA;AACzG,MAAA;AAAA,IACF,KAAK,YAAA;AACH,MAAA,IAAI,KAAK,MAAA,IAAU,CAAC,GAAA,CAAI,KAAA,EAAO,KAAK,MAAM,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,GAAG,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,IAAA,CAAK,MAAM,CAAA,CAAE,CAAA;AACzF,MAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,CAAC,GAAA,CAAI,KAAA,EAAO,IAAA,CAAK,YAAY,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,YAAY,CAAA;AACrF,MAAA;AAAA;AAEJ,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAmB,CAAC,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC9D,EAAA,OAAO,SAAS,CAAA,EAAG,MAAA,CAAO,YAAY,CAAA,EAAA,EAAK,MAAM,KAAK,MAAA,CAAO,YAAA;AAC/D;AC9CA,IAAM,CAAA,GAAI,EAAA;AACV,IAAM,CAAA,GAAI,GAAA;AACV,IAAM,GAAA,GAAM,EAAA;AACZ,IAAM,KAAA,GAAQ,IAAI,GAAA,GAAM,CAAA;AACxB,IAAM,SAAA,GAAY,EAAE,OAAA,EAAS,IAAA,EAAK;AAG3B,SAAS,WAAW,EAAE,IAAA,EAAM,OAAO,MAAA,EAAQ,GAAG,MAAK,EAAyC;AACjG,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,SAAA;AACvC,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,UAAA,GAAa,MAAA,CAAO,aAAa,MAAA,CAAO,GAAA;AACnE,EAAA,MAAM,SAAA,GAAY,SAAS,CAAC,MAAM,IAAI,cAAA,CAAe,IAAA,CAAK,KAAA,EAAO,EAAA,EAAI,CAAC,CAAA;AACtE,EAAA,MAAM,QAAA,GAAW,MAAA,GAAS,iBAAA,CAAkB,SAAA,EAAW,KAAA,EAAO,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,GAAI,iBAAA,CAAkB,SAAA,EAAW,KAAA,EAAO,IAAI,EAAE,CAAA;AACxH,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,QAAA;AAClC,EAAA,MAAM,cAAc,IAAA,CAAK,KAAA,GAAS,KAAK,QAAA,IAAY,IAAA,CAAK,WAAY,IAAA,CAAK,QAAA;AAGzE,EAAA,MAAM,OAAiG,EAAC;AACxG,EAAA,IAAI,MAAA,EAAQ,IAAA,CAAK,IAAA,CAAK,EAAE,OAAO,cAAA,CAAe,IAAA,CAAK,KAAA,EAAO,EAAA,EAAI,CAAC,CAAA,EAAG,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,KAAK,CAAA;AACzF,EAAA,IAAI,IAAA,CAAK,SAAS,IAAA,CAAK,IAAA,CAAK,EAAE,KAAA,EAAO,cAAA,CAAe,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,EAAA,EAAK,KAAK,OAAO,CAAA,CAAA,EAAI,EAAA,EAAI,CAAC,CAAA,EAAG,IAAA,EAAM,IAAI,SAAA,EAAW,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,CAAA;AACvI,EAAA,IAAI,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,SAAA,EAAW,IAAA,CAAK,KAAK,EAAE,KAAA,EAAO,CAAC,CAAA,EAAG,MAAA,CAAO,GAAG,IAAI,IAAA,CAAK,SAAS,CAAA,CAAE,CAAA,EAAG,IAAA,EAAM,EAAA,EAAI,SAAA,EAAW,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,CAAA;AACnJ,EAAA,IAAI,CAAA,GAAI,GAAA;AACR,EAAA,MAAM,SAAoD,EAAC;AAC3D,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,MAAM,EAAA,GAAK,IAAI,CAAA,CAAE,IAAA;AACjB,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAA,CAAO,GAAA,GAAM,OAAO,CAAA,CAAE,IAAA,GAAO,IAAI,CAAA,GAAI,CAAA;AACvD,IAAA,IAAI,IAAA,GAAO,CAAA,IAAK,CAAC,CAAA,CAAE,MAAM,MAAA,EAAQ;AACjC,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,KAAA,CAAM,MAAA,GAAS,IAAA,GAAO,CAAC,GAAG,CAAA,CAAE,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,IAAA,GAAO,CAAC,CAAA,EAAG,CAAA,CAAE,KAAA,CAAM,IAAA,GAAO,CAAC,CAAA,CAAG,QAAQ,cAAA,EAAgB,QAAG,CAAC,CAAA,GAAI,CAAA,CAAE,KAAA;AAC3H,IAAA,MAAA,CAAO,KAAK,EAAE,GAAG,GAAG,KAAA,EAAO,CAAA,EAAG,IAAI,CAAA;AAClC,IAAA,CAAA,GAAI,MAAM,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,CAAA,CAAE,OAAO,GAAA,GAAM,EAAA;AAAA,EAC/C;AAEA,EAAA,uBACED,IAAAA,CAAC,WAAA,EAAA,EAAY,MAAK,MAAA,EAAO,KAAA,EAAe,GAAG,IAAA,EACzC,QAAA,EAAA;AAAA,oBAAAC,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,2BAAA,EAA4B,MAAK,MAAA,EAAO,WAAA,EAAa,CAAA,EAAG,aAAA,EAAc,OAAA,EAAQ,KAAA,EAAO,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA,EAAG,CAAA;AAAA,oBACtHA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,CAAA,EAAG,GAAG,EAAA,EAAI,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,KAAK,EAAA,EAAI,EAAA,EAAI,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,EAAG,CAAA;AAAA,oBACxEA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,CAAA,GAAI,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,KAAA,EAAO,CAAA,GAAI,GAAA,EAAK,MAAA,EAAQ,KAAA,EAAO,EAAA,EAAI,KAAA,EAAO,IAAA,EAAK,MAAA,EAAO,WAAA,EAAa,GAAA,EAAK,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA,EAAG,OAAA,EAAS,GAAA,EAAI,EAAG,CAAA;AAAA,oBAC1JA,GAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA;AAAA,oBACjDA,IAAC,QAAA,EAAA,EAAO,EAAA,EAAI,IAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,CAAA,EAAG,IAAA,EAAK,MAAA,EAAO,aAAa,GAAA,EAAK,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,SAAS,QAAQ,CAAA,EAAG,OAAA,EAAS,GAAA,EAAI,EAAG,CAAA;AAAA,IAChH,MAAA,mBAASA,GAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,cAAA,CAAe,MAAA,EAAQ,WAAA,GAAc,EAAA,GAAK,EAAA,EAAI,CAAC,CAAA,EAAG,CAAA,EAAG,KAAK,CAAA,EAAG,GAAA,EAAK,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,GAAA,EAAK,IAAA,EAAK,WAAA,EAAY,MAAA,EAAO,OAAA,EAAQ,aAAA,EAAe,GAAA,EAAK,CAAA,GAAK,IAAA;AAAA,IAC9K,WAAA,mBAAcA,GAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,cAAA,CAAe,WAAA,EAAa,MAAA,GAAS,EAAA,GAAK,EAAA,EAAI,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,GAAA,EAAK,IAAA,EAAK,WAAA,EAAY,MAAA,EAAO,KAAA,EAAM,KAAA,EAAO,SAAA,EAAW,CAAA,GAAK,IAAA;AAAA,oBACxLA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,GAAG,CAAA,EAAG,GAAA,EAAK,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA;AAAA,IAChE,MAAA,mBACCD,IAAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,CAAC,aAAa,GAAG,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,IAAA,EAAM,IAAI,MAAA,EAAQ,GAAA,EAAK,IAAA,EAAK,YAAA,EAAa,MAAA,EAAO,OAAA,EAAQ,aAAA,EAAe,CAAA,EAAG,KAAA,EAAO,EAAE,OAAA,EAAS,IAAA,EAAK,EAAG,CAAA;AAAA,sBAC5JA,GAAAA,CAAC,UAAA,EAAA,EAAW,OAAO,SAAA,EAAW,CAAA,EAAG,IAAI,GAAA,EAAK,CAAA,EAAG,KAAK,IAAA,EAAM,QAAA,EAAU,QAAQ,GAAA,EAAK,IAAA,EAAK,cAAa,MAAA,EAAO,OAAA,EAAQ,MAAI,IAAA,EAAC;AAAA,KAAA,EACvH,CAAA,mBAEAA,GAAAA,CAAC,UAAA,EAAA,EAAW,OAAO,SAAA,EAAW,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAG,SAAA,CAAU,SAAS,CAAA,GAAI,GAAA,GAAM,KAAK,IAAA,EAAM,QAAA,EAAU,QAAQ,GAAA,EAAK,IAAA,EAAK,YAAA,EAAa,MAAA,EAAO,OAAA,EAAQ,CAAA;AAAA,IAE9I,OAAO,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACdA,GAAAA,CAAC,UAAA,EAAA,EAAmB,KAAA,EAAO,CAAA,CAAE,OAAO,CAAA,EAAG,CAAA,GAAI,KAAK,CAAA,EAAG,CAAA,CAAE,GAAG,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,UAAA,EAAY,KAAK,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAQ,IAAA,EAAK,aAAY,MAAA,EAAO,OAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,MAAM,KAAA,EAAO,CAAA,CAAE,YAAY,SAAA,GAAY,MAAA,EAAA,EAAvK,CAAkL,CACpM;AAAA,GAAA,EACH,CAAA;AAEJ;AClDA,IAAM,MAAA,GAAyE;AAAA,EAC7E,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAI;AAAA,IACxC,IAAA,EAAM,sBACJD,IAAAA,CAAAE,UAAA,EACE,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,GAAA,EAAK,GAAG,EAAA,EAAI,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,IAAI,EAAA,EAAI,CAAA,EAAG,KAAA,EAAO,IAAA,CAAK,SAAS,CAAA,EAAG,CAAA;AAAA,sBAC5EA,GAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAI,GAAA,EAAK,IAAI,EAAA,EAAI,EAAA,EAAI,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,WAAA,EAAa,IAAI,eAAA,EAAgB,SAAA,EAAU,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,eAAe,QAAQ,CAAA,EAAG,OAAA,EAAS,IAAA,EAAK,EAAG,CAAA;AAAA,sBAC/IA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,GAAA,EAAK,GAAG,EAAA,EAAI,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,GAAG,EAAA,EAAI,CAAA,EAAG,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA;AAAA,sBAC1EA,IAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6DAA4D,KAAA,EAAO,IAAA,CAAK,SAAS,CAAA,EAAG;AAAA,KAAA,EAC9F;AAAA,GAEJ;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAI;AAAA,IACxC,IAAA,EAAM,sBACJD,IAAAA,CAAAE,UAAA,EACE,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,GAAA,EAAK,GAAG,EAAA,EAAI,KAAA,EAAO,EAAA,EAAI,MAAA,EAAQ,IAAI,EAAA,EAAI,CAAA,EAAG,KAAA,EAAO,IAAA,CAAK,SAAS,CAAA,EAAG,CAAA;AAAA,sBAC3EA,GAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAI,GAAA,EAAK,IAAI,EAAA,EAAI,EAAA,EAAI,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,WAAA,EAAa,IAAI,eAAA,EAAgB,SAAA,EAAU,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,eAAe,QAAQ,CAAA,EAAG,OAAA,EAAS,IAAA,EAAK,EAAG,CAAA;AAAA,sBAC/IA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,KAAK,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA;AAAA,sBACnEA,IAAC,MAAA,EAAA,EAAK,CAAA,EAAE,0FAAyF,KAAA,EAAO,IAAA,CAAK,SAAS,CAAA,EAAG;AAAA,KAAA,EAC3H;AAAA,GAEJ;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAI;AAAA,IACxC,IAAA,EAAM,sBACJD,IAAAA,CAAAE,UAAA,EACE,QAAA,EAAA;AAAA,sBAAAD,IAAC,MAAA,EAAA,EAAK,CAAA,EAAE,kDAAiD,KAAA,EAAO,IAAA,CAAK,SAAS,CAAA,EAAG,CAAA;AAAA,sBACjFA,IAAC,MAAA,EAAA,EAAK,CAAA,EAAE,+CAA8C,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA;AAAA,sBAC7EA,IAAC,MAAA,EAAA,EAAK,CAAA,EAAE,yBAAwB,IAAA,EAAK,MAAA,EAAO,aAAa,CAAA,EAAG,eAAA,EAAgB,OAAM,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,aAAA,EAAe,QAAQ,CAAA,EAAG,OAAA,EAAS,KAAI,EAAG;AAAA,KAAA,EAC/I;AAAA;AAGN,CAAA;AAGO,SAAS,iBAAiB,EAAE,IAAA,EAAM,OAAO,MAAA,EAAQ,GAAG,MAAK,EAA+C;AAC7G,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,KAAK,KAAK,MAAA,CAAO,GAAA;AAC3C,EAAA,MAAM,MAAM,KAAA,CAAM,KAAA;AAClB,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,CAAA,GAAI,GAAA,CAAI,CAAA,GAAI,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,IAAI,CAAA,GAAI,EAAA;AACtB,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,YAAA,KAAiB,IAAA,CAAK,QAAA,GAAW,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,MAAA,CAAO,QAAQ,CAAA,CAAA,GAAK,IAAA,CAAA;AAC7F,EAAA,MAAM,SAAA,GAAY,cAAA,CAAe,IAAA,CAAK,KAAA,EAAO,IAAI,CAAC,CAAA;AAClD,EAAA,MAAM,WAAW,iBAAA,CAAkB,SAAA,EAAW,KAAA,EAAO,EAAA,EAAI,IAAI,IAAI,CAAA;AACjE,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,GAAS,cAAA,CAAe,IAAA,CAAK,QAAQ,EAAA,EAAI,CAAC,CAAA,CAAE,CAAC,CAAA,GAAK,IAAA;AACtE,EAAA,MAAM,OAAA,GAAU,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,CAAE,MAAA,GAAS,GAAA,GAAM,EAAE,CAAA,GAAI,CAAA;AACjF,EAAA,MAAM,UAAA,GAAa,SAAS,cAAA,CAAe,MAAA,EAAQ,IAAI,CAAC,CAAA,CAAE,CAAC,CAAA,GAAK,IAAA;AAChE,EAAA,MAAM,OAAA,GAAU,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA,CAAE,MAAA,GAAS,GAAA,GAAM,EAAE,CAAA,GAAI,CAAA;AACzF,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,CAAA,IAAK,IAAA,CAAK,QAAQ,EAAA,GAAK,EAAA,CAAA;AACvC,EAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,GAAW,GAAA;AAC/B,EAAA,MAAM,UAAA,GAAa,KAAA,GAAA,CAAS,SAAA,CAAU,MAAA,GAAS,KAAK,QAAA,GAAW,IAAA;AAC/D,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,UAAA,GAAa,IAAI,GAAA,CAAI,CAAA,GAAI,GAAA,CAAI,CAAA,GAAI,EAAE,CAAA;AAC5D,EAAA,uBACED,IAAAA,CAAC,WAAA,EAAA,EAAY,MAAK,YAAA,EAAa,KAAA,EAAe,GAAG,IAAA,EAC/C,QAAA,EAAA;AAAA,oBAAAC,IAAC,SAAA,EAAA,EAAQ,EAAA,EAAI,KAAK,EAAA,EAAI,GAAA,EAAK,IAAI,GAAA,EAAK,EAAA,EAAI,CAAA,EAAG,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,KAAK,CAAA,EAAG,OAAA,EAAS,KAAI,EAAG,CAAA;AAAA,IACnF,MAAM,IAAA,EAAK;AAAA,oBACZA,IAAC,MAAA,EAAA,EAAK,CAAA,EAAG,IAAI,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA,EAAG,KAAA,EAAO,IAAI,CAAA,EAAG,MAAA,EAAQ,IAAI,CAAA,EAAG,EAAA,EAAI,GAAG,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,EAAG,CAAA;AAAA,oBACpFA,GAAAA,CAAC,MAAA,EAAA,EAAK,GAAG,GAAA,CAAI,CAAA,EAAG,GAAG,GAAA,CAAI,CAAA,EAAG,OAAO,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAA,EAAG,EAAA,EAAI,GAAG,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA;AAAA,IAChF,IAAA,CAAK,KAAA,mBAAQA,GAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,cAAA,CAAe,IAAA,CAAK,KAAA,EAAO,EAAA,EAAI,CAAC,CAAA,EAAG,GAAG,EAAA,EAAI,CAAA,EAAG,GAAA,CAAI,CAAA,GAAI,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,KAAK,IAAA,EAAK,WAAA,EAAY,aAAA,EAAe,GAAA,EAAK,KAAA,EAAO,EAAE,OAAA,EAAS,IAAA,IAAQ,CAAA,GAAK,IAAA;AAAA,oBACrLA,GAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,SAAA,EAAW,GAAG,EAAA,EAAI,CAAA,EAAG,KAAA,EAAO,IAAA,EAAM,UAAU,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,MAAK,WAAA,EAAY,CAAA;AAAA,IAC9G,MAAA,mBACCD,IAAAA,CAAAE,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAAD,IAAC,MAAA,EAAA,EAAK,CAAA,EAAG,EAAA,GAAK,OAAA,GAAU,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,QAAQ,EAAA,EAAI,EAAA,EAAI,IAAI,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA;AAAA,sBAClGA,GAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,CAAC,MAAM,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,UAAU,EAAA,EAAI,IAAA,EAAM,MAAM,MAAA,EAAQ,GAAA,EAAK,MAAK,YAAA,EAAa;AAAA,KAAA,EAClG,CAAA,GACE,IAAA;AAAA,IACH,UAAA,mBACCD,IAAAA,CAAAE,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,UAAK,CAAA,EAAG,EAAA,GAAK,UAAU,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA,GAAI,GAAA,CAAI,IAAI,EAAA,EAAI,KAAA,EAAO,SAAS,MAAA,EAAQ,EAAA,EAAI,IAAI,EAAA,EAAI,KAAA,EAAO,IAAA,CAAK,SAAS,CAAA,EAAG,CAAA;AAAA,sBAC9GA,IAAC,UAAA,EAAA,EAAW,KAAA,EAAO,CAAC,UAAU,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,GAAA,CAAI,IAAI,GAAA,CAAI,CAAA,GAAI,MAAM,IAAA,EAAM,IAAA,EAAM,QAAQ,GAAA,EAAK,IAAA,EAAK,aAAA,EAAc,aAAA,EAAe,CAAA,EAAG;AAAA,KAAA,EACjI,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AC9EA,IAAM,EAAA,GAAK,GAAA;AACX,IAAM,EAAA,GAAK,GAAA;AAGJ,SAAS,WAAW,EAAE,IAAA,EAAM,OAAO,MAAA,EAAQ,GAAG,MAAK,EAAyC;AACjG,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,UAAU,IAAA,CAAK,GAAA;AAChD,EAAA,MAAM,QAAA,GAAW,KAAA,GAAQ,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAM,CAAA,EAAA,EAAK,IAAA,CAAK,GAAG,CAAA,CAAA,GAAK,IAAA,CAAK,IAAA;AAC5E,EAAA,MAAM,QAAA,GAAW,QAAA,GAAW,iBAAA,CAAkB,CAAC,QAAQ,GAAG,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,GAAG,CAAA,GAAI,CAAA;AAC9E,EAAA,MAAM,UAAA,GAAa,QAAA,GAAW,EAAC,GAAI,cAAA,CAAe,KAAK,KAAA,IAAS,IAAA,CAAK,KAAA,EAAO,EAAA,EAAI,CAAC,CAAA;AACjF,EAAA,MAAM,SAAA,GAAY,iBAAA,CAAkB,UAAA,EAAY,GAAA,EAAK,IAAI,EAAE,CAAA;AAC3D,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,CAAK,UAAA,IAAc,CAAA,CAAE,QAAA,IAAY,EAAA,EAAI,WAAA,EAAY,CAAE,UAAA,CAAW,MAAA,CAAO,UAAA,CAAW,WAAA,EAAa,CAAA,GAAI,MAAA,CAAO,UAAA,GAAa,IAAA,EAAM,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,OAAA,GAAU,IAAI,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,QAAK,CAAA;AAC3M,EAAA,MAAM,MAAA,GAAS,CAAC,QAAA,GAAW,IAAA,CAAK,KAAA,GAAQ,IAAA,EAAM,MAAA,IAAU,IAAI,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,QAAK,CAAA;AACxF,EAAA,uBACED,IAAAA,CAAC,WAAA,EAAA,EAAY,MAAK,MAAA,EAAO,KAAA,EAAe,GAAG,IAAA,EACzC,QAAA,EAAA;AAAA,oBAAAC,IAAC,SAAA,EAAA,EAAQ,EAAA,EAAI,IAAI,EAAA,EAAI,EAAA,GAAK,KAAK,EAAA,EAAI,GAAA,EAAK,IAAI,CAAA,EAAG,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,KAAK,CAAA,EAAG,OAAA,EAAS,MAAK,EAAG,CAAA;AAAA,oBAEzFA,GAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAI,EAAA,EAAI,IAAI,EAAA,EAAI,CAAA,EAAG,GAAA,EAAK,IAAA,EAAK,QAAO,WAAA,EAAa,EAAA,EAAI,OAAO,IAAA,CAAK,SAAA,EAAW,QAAQ,CAAA,EAAG,CAAA;AAAA,oBAC/FA,GAAAA,CAAC,QAAA,EAAA,EAAO,IAAI,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EAAG,GAAA,EAAK,MAAK,MAAA,EAAO,WAAA,EAAa,GAAG,eAAA,EAAgB,KAAA,EAAM,OAAO,IAAA,CAAK,IAAA,EAAM,QAAQ,CAAA,EAAG,CAAA;AAAA,oBAC/GA,GAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAI,EAAA,EAAI,IAAI,EAAA,EAAI,CAAA,EAAG,GAAA,EAAK,IAAA,EAAK,MAAA,EAAO,WAAA,EAAa,KAAK,eAAA,EAAgB,KAAA,EAAM,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,eAAe,QAAQ,CAAA,EAAG,OAAA,EAAS,IAAA,EAAK,EAAG,CAAA;AAAA,oBAChJA,IAAC,QAAA,EAAA,EAAO,EAAA,EAAI,IAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,IAAA,EAAK,MAAA,EAAO,aAAa,GAAA,EAAK,KAAA,EAAO,EAAE,GAAG,IAAA,CAAK,eAAe,QAAQ,CAAA,EAAG,OAAA,EAAS,IAAA,EAAK,EAAG,CAAA;AAAA,oBAEzHA,GAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,EAAG,CAAA;AAAA,oBACrDA,GAAAA,CAAC,QAAA,EAAA,EAAO,IAAI,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EAAG,EAAA,EAAI,MAAK,MAAA,EAAO,WAAA,EAAa,IAAI,eAAA,EAAgB,SAAA,EAAU,OAAO,IAAA,CAAK,SAAA,EAAW,QAAQ,CAAA,EAAG,CAAA;AAAA,oBACxHA,GAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,EAAG,CAAA;AAAA,oBACrDA,GAAAA,CAAC,QAAA,EAAA,EAAO,IAAI,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EAAG,EAAA,EAAI,MAAK,MAAA,EAAO,WAAA,EAAa,GAAG,eAAA,EAAgB,UAAA,EAAW,OAAO,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA,EAAG,CAAA;AAAA,IACrH,IAAA,CAAK,wBACJA,GAAAA,CAAC,cAAW,KAAA,EAAO,CAAC,IAAA,CAAK,KAAK,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA,EAAG,GAAA,EAAK,MAAM,EAAA,EAAI,MAAA,EAAQ,KAAK,IAAA,EAAK,OAAA,EAAQ,aAAA,EAAe,CAAA,EAAG,CAAA,GACpG,IAAA;AAAA,IACH,QAAA,mBACCA,GAAAA,CAAC,MAAA,EAAA,EAAK,GAAG,EAAA,EAAI,CAAA,EAAG,GAAA,EAAK,QAAA,EAAU,QAAA,EAAU,UAAA,EAAY,KAAK,UAAA,EAAW,QAAA,EAAS,OAAO,IAAA,CAAK,KAAK,GAC5F,QAAA,EAAA,KAAA,mBACCD,IAAAA,CAAAE,QAAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAM,CAAA,CAAA,CAAA;AAAA,sBAC7BD,GAAAA,CAAC,OAAA,EAAA,EAAM,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAI,QAAA,EAAA,CAAA,CAAA,EAAI,IAAA,CAAK,GAAG,CAAA,CAAA,EAAG;AAAA,KAAA,EAChD,IAEA,QAAA,EAEJ,CAAA,mBAEAA,GAAAA,CAAC,UAAA,EAAA,EAAW,OAAO,UAAA,EAAY,CAAA,EAAG,IAAI,CAAA,EAAG,UAAA,CAAW,SAAS,CAAA,GAAI,GAAA,GAAM,KAAK,IAAA,EAAM,SAAA,EAAW,QAAQ,GAAA,EAAK,CAAA;AAAA,IAE3G,UAAU,IAAA,CAAK,OAAA,mBACdD,IAAAA,CAAC,MAAA,EAAA,EAAK,GAAG,EAAA,EAAI,CAAA,EAAG,KAAK,QAAA,EAAU,EAAA,EAAI,YAAY,GAAA,EAAK,UAAA,EAAW,UAAS,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,EACxF,QAAA,EAAA;AAAA,MAAA,IAAA,CAAK,OAAA,mBACJC,GAAAA,CAAC,OAAA,EAAA,EAAM,UAAA,EAAY,GAAA,EAAK,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EACzC,QAAA,EAAA,IAAA,CAAK,OAAA,EACR,CAAA,GACE,IAAA;AAAA,MACH,IAAA,CAAK,OAAA,IAAW,MAAA,GAAS,QAAA,GAAQ,IAAA;AAAA,MACjC,cAAA,CAAe,QAAQ,IAAA,CAAK,OAAA,GAAU,KAAK,EAAA,EAAI,CAAC,EAAE,CAAC;AAAA,KAAA,EACtD,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AClCA,IAAM,YAAA,GAAe,yBAAA;AAErB,SAAS,SAAA,CAAU,MAAkB,KAAA,EAAoD;AACvF,EAAA,MAAM,IAAoB,OAAO,KAAA,KAAU,aAAa,EAAE,SAAA,EAAW,OAAM,GAAI,KAAA;AAC/E,EAAA,IAAI,CAAC,CAAA,IAAK,OAAO,CAAA,CAAE,SAAA,KAAc,UAAA,EAAY,MAAM,IAAI,SAAA,CAAU,CAAA,QAAA,EAAW,IAAI,CAAA,wBAAA,CAA0B,CAAA;AAC1G,EAAA,OAAO;AAAA,IACL,WAAW,CAAA,CAAE,SAAA;AAAA,IACb,WAAA,EAAa,EAAE,WAAA,KAAgB,CAAC,SAAwB,OAAA,KAAmC,qBAAA,CAAsB,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA,CAAA;AAAA,IACvI,QAAA,EAAU,EAAE,QAAA,KAAa,CAAC,MAAW,MAAA,KAAyB,cAAA,CAAe,MAAM,MAAM,CAAA;AAAA,GAC3F;AACF;AAGO,SAAS,oBAAA,CAAqB,OAAA,GAA4D,EAAC,EAAmB;AACnH,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAoC;AACpD,EAAA,MAAM,QAAA,GAA2B;AAAA,IAC/B,QAAA,CAAS,MAAM,QAAA,EAAU;AACvB,MAAA,IAAI,CAAC,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,QAAS,IAAI,SAAA,CAAU,CAAA,qBAAA,EAAwB,IAAI,CAAA,yBAAA,CAA2B,CAAA;AACzG,MAAA,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,SAAA,CAAU,IAAA,EAAM,QAA+B,CAAC,CAAA;AAC9D,MAAA,OAAO,QAAA;AAAA,IACT,CAAA;AAAA,IACA,GAAA,EAAK,CAAC,IAAA,KAAS,GAAA,CAAI,IAAI,IAAI,CAAA;AAAA,IAC3B,GAAA,EAAK,CAAC,IAAA,KAAS,GAAA,CAAI,IAAI,IAAI,CAAA;AAAA,IAC3B,OAAO,MAAM,CAAC,GAAG,GAAA,CAAI,MAAM,CAAA;AAAA,IAC3B,MAAA,CAAO,SAAA,GAAY,EAAC,EAAG;AACrB,MAAA,MAAM,OAAO,oBAAA,EAAqB;AAClC,MAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,KAAK,IAAA,CAAK,QAAA,CAAS,GAAG,CAAC,CAAA;AAC5C,MAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG,IAAI,CAAA,EAAG,IAAA,CAAK,QAAA,CAAS,GAAG,CAAC,CAAA;AACzE,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,GACF;AACA,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG,IAAI,CAAA,EAAG,QAAA,CAAS,QAAA,CAAS,GAAG,CAAC,CAAA;AAC3E,EAAA,OAAO,QAAA;AACT;AAGO,IAAM,eAAA,GAAkB;AAAA,EAC7B,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,UAAA;AAAA,EACN,UAAA,EAAY,gBAAA;AAAA,EACZ,OAAA,EAAS;AACX;AAGO,IAAM,qBAAA,GAAwC,qBAAqB,eAAe;AAMlF,SAAS,cAAA,CAAkB,MAAkB,QAAA,EAAkD;AACpG,EAAA,OAAO,qBAAA,CAAsB,QAAA,CAAS,IAAA,EAAM,QAAQ,CAAA;AACtD;AAkBA,IAAM,aAAA,GAAgB,cAAmC,IAAI,CAAA;AAUtD,SAAS,eAAe,EAAE,QAAA,EAAU,WAAA,EAAa,MAAA,EAAQ,UAAS,EAAwB;AAC/F,EAAA,MAAM,MAAA,GAAS,WAAW,aAAa,CAAA;AACvC,EAAA,MAAM,KAAA,GAAsB;AAAA,IAC1B,QAAA,EAAU,QAAA,IAAY,MAAA,EAAQ,QAAA,IAAY,qBAAA;AAAA,IAC1C,WAAA,EAAa,eAAe,MAAA,EAAQ,WAAA;AAAA,IACpC,QAAQ,EAAE,GAAI,QAAQ,MAAA,IAAU,qBAAA,EAAwB,GAAG,MAAA;AAAO,GACpE;AACA,EAAA,uBAAOA,GAAAA,CAAC,aAAA,CAAc,QAAA,EAAd,EAAuB,OAAe,QAAA,EAAS,CAAA;AACzD;AAGO,SAAS,eAAA,GAAgC;AAC9C,EAAA,OAAO,WAAW,aAAa,CAAA,IAAK,EAAE,QAAA,EAAU,qBAAA,EAAuB,QAAQ,qBAAA,EAAsB;AACvG;AC9FO,SAAS,aAAA,CAAiB,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,cAAA,EAAgB,QAAA,EAAU,YAAA,EAAc,GAAG,GAAA,EAAI,EAA0B;AACrI,EAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,EAAA,MAAM,QAAA,GAAW,gBAAgB,MAAA,CAAO,QAAA;AACxC,EAAA,MAAM,WAAW,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,IAAK,QAAA,CAAS,IAAI,SAAS,CAAA;AAC7D,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,MAAM,MAAA,GAAS,iBAAiB,EAAE,GAAG,OAAO,MAAA,EAAQ,GAAG,cAAA,EAAe,GAAI,MAAA,CAAO,MAAA;AACjF,EAAA,MAAM,IAAA,GAAO,KAAA,GAAQ,CAAA,EAAG,MAAA,CAAO,YAAY,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,GAAK,QAAA,CAAS,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AACxF,EAAA,MAAM,YAAY,QAAA,CAAS,SAAA;AAC3B,EAAA,uBAAOA,IAAC,SAAA,EAAA,EAAU,IAAA,EAAY,OAAO,IAAA,EAAM,MAAA,EAAiB,GAAG,GAAA,EAAK,CAAA;AACtE;AA0BO,SAAS,YAAA,CAAa;AAAA,EAC3B,OAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA,EAAM,QAAA;AAAA,EACN,WAAA,EAAa,WAAA;AAAA,EACb,QAAA,EAAU,YAAA;AAAA,EACV,MAAA,EAAQ,cAAA;AAAA,EACR,GAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,EAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAsB;AACpB,EAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,EAAA,MAAM,GAAA,GAAM,KAAA,KAAU,MAAA,GAAY,KAAA,GAAS,OAAA,EAAS,KAAA,IAAS,OAAA,CAAQ,cAAA,IAAkB,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,IAAK,IAAA;AAC9G,EAAA,IAAI,KAAK,GAAA,EAAK;AACZ,IAAA,uBAAOA,GAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAM,KAAK,GAAA,EAAK,GAAA,IAAO,GAAA,CAAI,GAAA,IAAO,QAAQ,KAAA,EAAO,SAAA,EAAsB,KAAA,EAAc,EAAA,EAAS,GAAG,UAAA,EAAY,CAAA;AAAA,EAC7H;AAEA,EAAA,MAAM,QAAA,GAAW,gBAAgB,MAAA,CAAO,QAAA;AACxC,EAAA,IAAI,IAAA,GAAO,QAAA;AACX,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,KAAA,GAAQ,kBAAkB,OAAA,EAAS,EAAE,OAAO,QAAA,CAAS,KAAA,IAAS,CAAA;AACpE,IAAA,IAAA,GAAA,CAAQ,WAAA,IAAe,MAAA,CAAO,WAAA,IAAe,OAAA,EAAS,KAAK,CAAA,IAAK,KAAA;AAAA,EAClE;AACA,EAAA,MAAM,WAAW,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,IAAK,QAAA,CAAS,IAAI,SAAS,CAAA;AAC7D,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,MAAM,MAAA,GAAS,iBAAiB,EAAE,GAAG,OAAO,MAAA,EAAQ,GAAG,cAAA,EAAe,GAAI,MAAA,CAAO,MAAA;AACjF,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,WAAA,CAAY,OAAA,EAAS,OAAO,CAAA;AAClD,EAAA,MAAM,aAAa,GAAA,KAAQ,EAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,YAAY,CAAA,EAAA,EAAK,GAAG,CAAA,CAAA,GAAK,QAAA,CAAS,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AACrF,EAAA,MAAM,YAAY,QAAA,CAAS,SAAA;AAC3B,EAAA,uBACEA,GAAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,KAAA;AAAA,MACA,MAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA;AAAA,MACA,KAAA;AAAA,MACA,EAAA;AAAA,MACA,sBAAA,EAAqB;AAAA;AAAA,GACvB;AAEJ","file":"mockups.js","sourcesContent":["import type { CSSProperties, ReactNode, SVGProps } from 'react'\n\n/** Side of the square viewBox every mockup draws in. */\nexport const MOCKUP_SIZE = 400\n\n/**\n * Theme tokens. Each mockup reads `--mockup-*` (set them in the store CSS),\n * falls back to the store theme (`--color-muted`, `--color-primary`... as\n * emitted by `ThemeStyle`) and finally to neutral greys that follow\n * `color-scheme` through `light-dark()`. No brand colors live here.\n */\nexport const MOCKUP_TOKENS = {\n bg: 'var(--mockup-bg, var(--color-muted, light-dark(#f4f4f5, #27272a)))',\n surface: 'var(--mockup-surface, light-dark(#3f3f46, #0a0a0a))',\n 'surface-ink': 'var(--mockup-surface-ink, light-dark(#e4e4e7, #a1a1aa))',\n label: 'var(--mockup-label, var(--color-background, light-dark(#ffffff, #18181b)))',\n 'label-ink': 'var(--mockup-label-ink, var(--color-foreground, light-dark(#18181b, #fafafa)))',\n ink: 'var(--mockup-ink, var(--color-foreground, light-dark(#18181b, #fafafa)))',\n muted: 'var(--mockup-muted, var(--color-muted-foreground, light-dark(#71717a, #a1a1aa)))',\n accent: 'var(--mockup-accent, var(--color-primary, light-dark(#52525b, #d4d4d8)))',\n 'accent-ink': 'var(--mockup-accent-ink, var(--color-primary-foreground, light-dark(#ffffff, #18181b)))',\n} as const\n\nexport type MockupTone = keyof typeof MOCKUP_TOKENS\n\nconst ROOT_STYLE: Record<string, string> = {\n ...Object.fromEntries(Object.entries(MOCKUP_TOKENS).map(([k, v]) => [`--mk-${k}`, v])),\n fontFamily: 'var(--mockup-font, var(--font-heading, var(--font-sans, ui-sans-serif, system-ui, sans-serif)))',\n textTransform: 'var(--mockup-text-transform, none)',\n}\n\n/** `style` that paints an element with a token: `<rect style={tone('accent')} />`. */\nexport function tone(t: MockupTone, prop: 'fill' | 'stroke' = 'fill'): CSSProperties {\n return { [prop]: `var(--mk-${t})` }\n}\n\n/** Monospace stack for part numbers and sizes (`--mockup-font-mono`). */\nexport const MOCKUP_MONO = 'var(--mockup-font-mono, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace))'\n\n// ---------------------------------------------------------------------------\n// Text layout (no DOM measuring: works the same in SSR)\n// ---------------------------------------------------------------------------\n\n/** Greedy word wrap by characters; the last allowed line ends in `…` when text is cut. */\nexport function wrapMockupText(text: string | null | undefined, maxChars: number, maxLines: number): string[] {\n if (!text || maxLines < 1) return []\n const words = text.split(' ').filter(Boolean)\n const lines: string[] = []\n let current = ''\n let cut = false\n for (let i = 0; i < words.length; i++) {\n let word = words[i]!\n if (Array.from(word).length > maxChars) word = Array.from(word).slice(0, maxChars - 1).join('') + '…'\n const next = current ? `${current} ${word}` : word\n if (Array.from(next).length <= maxChars) {\n current = next\n continue\n }\n lines.push(current)\n current = word\n if (lines.length === maxLines) {\n cut = true\n current = ''\n break\n }\n }\n if (current) lines.push(current)\n if (cut || lines.length > maxLines) {\n const kept = lines.slice(0, maxLines)\n const last = Array.from(kept[maxLines - 1] ?? '')\n kept[maxLines - 1] = (last.length >= maxChars ? last.slice(0, maxChars - 1).join('') : last.join('')).replace(/[\\s.,;:…-]+$/, '') + '…'\n return kept\n }\n return lines\n}\n\n/** Font size so the longest line fits `width` (approximate glyph width `ratio` em). */\nexport function fitMockupFontSize(lines: readonly string[], width: number, max: number, min = 10, ratio = 0.62): number {\n const longest = Math.max(1, ...lines.map((l) => Array.from(l).length))\n return Math.round(Math.max(min, Math.min(max, width / (longest * ratio))))\n}\n\nexport type MockupTextProps = Omit<SVGProps<SVGTextElement>, 'children'> & {\n lines: readonly string[]\n x: number\n y: number\n size: number\n lineHeight?: number\n tone?: MockupTone\n weight?: number\n anchor?: 'start' | 'middle' | 'end'\n mono?: boolean\n}\n\n/** Multi-line `<text>`; `y` is the baseline of the first line. */\nexport function MockupText({ lines, x, y, size, lineHeight = 1.12, tone: t = 'ink', weight = 700, anchor = 'middle', mono, style, ...rest }: MockupTextProps) {\n if (!lines.length) return null\n return (\n <text\n x={x}\n y={y}\n fontSize={size}\n fontWeight={weight}\n textAnchor={anchor}\n style={{ ...tone(t), ...(mono ? { fontFamily: MOCKUP_MONO } : null), ...style }}\n {...rest}\n >\n {lines.length === 1\n ? lines[0]\n : lines.map((line, i) => (\n <tspan key={i} x={x} dy={i === 0 ? 0 : size * lineHeight}>\n {line}\n </tspan>\n ))}\n </text>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Frame\n// ---------------------------------------------------------------------------\n\nexport type MockupFrameProps = Omit<SVGProps<SVGSVGElement>, 'children' | 'role' | 'ref'> & {\n /** Accessible name (`aria-label` and `<title>`). */\n label: string\n /** Hide from assistive tech (the product name is already next to it). */\n decorative?: boolean\n /** Written to `data-mockup` for styling and tests. */\n kind?: string\n children?: ReactNode\n}\n\n/**\n * The `<svg>` shell shared by every mockup: square viewBox, token variables,\n * background, `role=\"img\"` with an accessible name that says it is an\n * illustration. Use it in custom renderers to get the same contract.\n */\nexport function MockupFrame({ label, decorative = false, kind, children, style, width = MOCKUP_SIZE, height = MOCKUP_SIZE, ...rest }: MockupFrameProps) {\n const a11y = decorative ? { 'aria-hidden': true as const } : { role: 'img', 'aria-label': label }\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={`0 0 ${MOCKUP_SIZE} ${MOCKUP_SIZE}`}\n width={width}\n height={height}\n focusable=\"false\"\n data-mockup={kind}\n {...a11y}\n style={{ ...ROOT_STYLE, ...style } as CSSProperties}\n {...rest}\n >\n {decorative ? null : <title>{label}</title>}\n <rect width={MOCKUP_SIZE} height={MOCKUP_SIZE} style={tone('bg')} />\n {children}\n </svg>\n )\n}\n","import type { GenericMockupData } from '@asteby/storefront/mockup'\nimport { MockupFrame, MockupText, fitMockupFontSize, tone, wrapMockupText } from './frame.js'\nimport type { MockupComponentProps } from './types.js'\n\n/** Closed box with the product monogram, the brand on the box and the name below. */\nexport function GenericMockup({ data, label, labels: _labels, ...rest }: MockupComponentProps<GenericMockupData>) {\n const titleLines = wrapMockupText(data.title, 28, 2)\n const titleFont = fitMockupFontSize(titleLines, 330, 22, 13)\n const titleY = titleLines.length > 1 ? 340 : 352\n const eyebrow = data.category ? wrapMockupText(data.category, 30, 1) : []\n return (\n <MockupFrame kind=\"generic\" label={label} {...rest}>\n <ellipse cx={200} cy={300} rx={130} ry={8} style={{ ...tone('ink'), opacity: 0.08 }} />\n <path d=\"M90 82L114 64H330L306 82Z\" style={tone('accent')} />\n <path d=\"M306 82L330 64V280L306 298Z\" style={tone('surface')} />\n <path d=\"M306 82L330 64V280L306 298Z\" style={{ fill: '#000', opacity: 0.22 }} />\n <rect x={90} y={82} width={216} height={216} style={tone('surface')} />\n <rect x={186} y={82} width={24} height={46} style={{ ...tone('accent'), opacity: 0.9 }} />\n <circle cx={198} cy={186} r={50} style={tone('label')} />\n {data.monogram ? <MockupText lines={[data.monogram]} x={198} y={202} size={44} weight={900} tone=\"label-ink\" letterSpacing={1} /> : null}\n {data.brand ? <MockupText lines={wrapMockupText(data.brand, 20, 1)} x={198} y={272} size={13} weight={700} tone=\"surface-ink\" letterSpacing={2} /> : null}\n {eyebrow.length > 0 && titleLines.length < 2 ? <MockupText lines={eyebrow} x={200} y={326} size={12} weight={600} tone=\"muted\" letterSpacing={1} /> : null}\n <MockupText lines={titleLines} x={200} y={titleY} size={titleFont} lineHeight={1.2} weight={700} />\n </MockupFrame>\n )\n}\n","import type { BuiltinMockupData } from '@asteby/storefront/mockup'\n\n/** Interface words used by the built-in mockups (generic UI text, not store copy). */\nexport type MockupLabels = {\n /** Prefix of every accessible name, so a mockup is never announced as a photo. */\n illustration: string\n size: string\n partNumber: string\n oem: string\n fits: string\n flavor: string\n /** Unit after a numeric `servings` attribute. */\n servings: string\n lightTruck: string\n runFlat: string\n}\n\nexport const DEFAULT_MOCKUP_LABELS: MockupLabels = {\n illustration: 'Ilustración de referencia',\n size: 'medida',\n partNumber: 'N.º de parte',\n oem: 'OEM',\n fits: 'Compatible con',\n flavor: 'sabor',\n servings: 'porciones',\n lightTruck: 'LT',\n runFlat: 'Run flat',\n}\n\nconst has = (haystack: string, needle: string) => haystack.toLowerCase().includes(needle.toLowerCase())\n\n/** Accessible name for built-in data: \"Ilustración de referencia: <title>, <key spec>\". */\nexport function describeMockup(data: Partial<BuiltinMockupData> & { title?: string | null }, labels: MockupLabels = DEFAULT_MOCKUP_LABELS): string {\n const title = data.title ?? ''\n const parts: (string | null | undefined)[] = [title]\n switch (data.kind) {\n case 'tire':\n if (data.size && !has(title, data.size)) parts.push(`${labels.size} ${data.size}`)\n if (data.service && !has(title, data.service)) parts.push(data.service)\n break\n case 'part':\n if (data.partNumber && !has(title, data.partNumber)) parts.push(`${labels.partNumber} ${data.partNumber}`)\n break\n case 'supplement':\n if (data.flavor && !has(title, data.flavor)) parts.push(`${labels.flavor} ${data.flavor}`)\n if (data.presentation && !has(title, data.presentation)) parts.push(data.presentation)\n break\n }\n const detail = parts.filter((p): p is string => !!p).join(', ')\n return detail ? `${labels.illustration}: ${detail}` : labels.illustration\n}\n","import type { PartMockupData } from '@asteby/storefront/mockup'\nimport { MockupFrame, MockupText, fitMockupFontSize, tone, wrapMockupText } from './frame.js'\nimport type { MockupComponentProps } from './types.js'\n\nconst X = 48\nconst W = 304\nconst PAD = 24\nconst INNER = W - PAD * 2\nconst SECONDARY = { opacity: 0.68 }\n\n/** Hang tag (\"ficha\") with the part number in a band, the name and the compatibility. */\nexport function PartMockup({ data, label, labels, ...rest }: MockupComponentProps<PartMockupData>) {\n const number = data.partNumber ?? data.oemNumber\n const numberCaption = data.partNumber ? labels.partNumber : labels.oem\n const bandLines = number ? [number] : wrapMockupText(data.title, 22, 2)\n const bandFont = number ? fitMockupFontSize(bandLines, INNER, 34, 14, 0.62) : fitMockupFontSize(bandLines, INNER, 24, 14)\n const header = data.brand ?? data.category\n const headerAside = data.brand ? (data.position ?? data.category) : data.position\n\n // Body lines below the band, laid out top-down until the tag ends.\n const body: { lines: string[]; size: number; secondary?: boolean; weight: number; mono?: boolean }[] = []\n if (number) body.push({ lines: wrapMockupText(data.title, 26, 2), size: 17, weight: 700 })\n if (data.fitment) body.push({ lines: wrapMockupText(`${labels.fits}: ${data.fitment}`, 34, 2), size: 13, secondary: true, weight: 500 })\n if (data.partNumber && data.oemNumber) body.push({ lines: [`${labels.oem} ${data.oemNumber}`], size: 13, secondary: true, weight: 600, mono: true })\n let y = 248\n const placed: ((typeof body)[number] & { y: number })[] = []\n for (const b of body) {\n const at = y + b.size\n const room = Math.floor((330 - at) / (b.size * 1.2)) + 1\n if (room < 1 || !b.lines.length) continue\n const lines = b.lines.length > room ? [...b.lines.slice(0, room - 1), b.lines[room - 1]!.replace(/[\\s.,;:…-]*$/, '…')] : b.lines\n placed.push({ ...b, lines, y: at })\n y = at + (lines.length - 1) * b.size * 1.2 + 10\n }\n\n return (\n <MockupFrame kind=\"part\" label={label} {...rest}>\n <path d=\"M78 98 C60 52 36 46 14 30\" fill=\"none\" strokeWidth={2} strokeLinecap=\"round\" style={tone('muted', 'stroke')} />\n <rect x={X} y={66} width={W} height={276} rx={18} style={tone('label')} />\n <rect x={X + 0.75} y={66.75} width={W - 1.5} height={274.5} rx={17.25} fill=\"none\" strokeWidth={1.5} style={{ ...tone('muted', 'stroke'), opacity: 0.3 }} />\n <circle cx={80} cy={98} r={9} style={tone('bg')} />\n <circle cx={80} cy={98} r={9} fill=\"none\" strokeWidth={1.5} style={{ ...tone('muted', 'stroke'), opacity: 0.5 }} />\n {header ? <MockupText lines={wrapMockupText(header, headerAside ? 14 : 22, 1)} x={104} y={104} size={16} weight={800} tone=\"label-ink\" anchor=\"start\" letterSpacing={0.5} /> : null}\n {headerAside ? <MockupText lines={wrapMockupText(headerAside, header ? 14 : 22, 1)} x={X + W - PAD} y={104} size={12} weight={600} tone=\"label-ink\" anchor=\"end\" style={SECONDARY} /> : null}\n <rect x={X} y={128} width={W} height={92} style={tone('accent')} />\n {number ? (\n <>\n <MockupText lines={[numberCaption]} x={X + PAD} y={154} size={12} weight={600} tone=\"accent-ink\" anchor=\"start\" letterSpacing={1} style={{ opacity: 0.85 }} />\n <MockupText lines={bandLines} x={X + PAD} y={198} size={bandFont} weight={800} tone=\"accent-ink\" anchor=\"start\" mono />\n </>\n ) : (\n <MockupText lines={bandLines} x={X + PAD} y={bandLines.length > 1 ? 168 : 182} size={bandFont} weight={800} tone=\"accent-ink\" anchor=\"start\" />\n )}\n {placed.map((b, i) => (\n <MockupText key={i} lines={b.lines} x={X + PAD} y={b.y} size={b.size} lineHeight={1.2} weight={b.weight} tone=\"label-ink\" anchor=\"start\" mono={b.mono} style={b.secondary ? SECONDARY : undefined} />\n ))}\n </MockupFrame>\n )\n}\n","import type { ReactNode } from 'react'\nimport type { SupplementMockupData, SupplementShape } from '@asteby/storefront/mockup'\nimport { MockupFrame, MockupText, fitMockupFontSize, tone, wrapMockupText } from './frame.js'\nimport type { MockupComponentProps } from './types.js'\n\ntype Box = { x: number; y: number; w: number; h: number }\n\n/** Container silhouettes (generic, unbranded) and where their label sits. */\nconst SHAPES: Record<SupplementShape, { label: Box; draw: () => ReactNode }> = {\n tub: {\n label: { x: 131, y: 128, w: 138, h: 200 },\n draw: () => (\n <>\n <rect x={120} y={44} width={160} height={54} rx={8} style={tone('surface')} />\n <line x1={128} y1={71} x2={272} y2={71} strokeWidth={42} strokeDasharray=\"1.5 7.5\" style={{ ...tone('surface-ink', 'stroke'), opacity: 0.18 }} />\n <rect x={117} y={95} width={166} height={9} rx={2} style={tone('accent')} />\n <path d=\"M122 104H278L283 344Q283 362 265 362H135Q117 362 117 344Z\" style={tone('surface')} />\n </>\n ),\n },\n bottle: {\n label: { x: 131, y: 148, w: 138, h: 184 },\n draw: () => (\n <>\n <rect x={158} y={46} width={84} height={40} rx={7} style={tone('surface')} />\n <line x1={164} y1={66} x2={236} y2={66} strokeWidth={30} strokeDasharray=\"1.5 6.5\" style={{ ...tone('surface-ink', 'stroke'), opacity: 0.18 }} />\n <rect x={168} y={84} width={64} height={12} style={tone('accent')} />\n <path d=\"M124 116Q124 96 148 96H252Q276 96 276 116L281 344Q281 362 263 362H137Q119 362 119 344Z\" style={tone('surface')} />\n </>\n ),\n },\n bag: {\n label: { x: 133, y: 118, w: 134, h: 196 },\n draw: () => (\n <>\n <path d=\"M118 64Q200 50 282 64L297 344Q200 360 103 344Z\" style={tone('surface')} />\n <path d=\"M118 64Q200 50 282 64L280 84Q200 70 120 84Z\" style={tone('accent')} />\n <path d=\"M124 92Q200 79 276 92\" fill=\"none\" strokeWidth={2} strokeDasharray=\"4 4\" style={{ ...tone('surface-ink', 'stroke'), opacity: 0.4 }} />\n </>\n ),\n },\n}\n\n/** Tub, bottle or bag with a label: brand, product name, flavor and presentation. */\nexport function SupplementMockup({ data, label, labels, ...rest }: MockupComponentProps<SupplementMockupData>) {\n const shape = SHAPES[data.shape] ?? SHAPES.tub\n const box = shape.label\n const cx = box.x + box.w / 2\n const inner = box.w - 20\n const amount = data.presentation ?? (data.servings ? `${data.servings} ${labels.servings}` : null)\n const nameLines = wrapMockupText(data.title, 12, 3)\n const nameFont = fitMockupFontSize(nameLines, inner, 26, 12, 0.64)\n const flavor = data.flavor ? wrapMockupText(data.flavor, 18, 1)[0]! : null\n const flavorW = flavor ? Math.min(inner, Array.from(flavor).length * 6.6 + 20) : 0\n const amountText = amount ? wrapMockupText(amount, 16, 1)[0]! : null\n const amountW = amountText ? Math.min(inner, Array.from(amountText).length * 7.4 + 24) : 0\n const top = box.y + (data.brand ? 46 : 30)\n const nameY = top + nameFont * 0.8\n const nameBottom = nameY + (nameLines.length - 1) * nameFont * 1.08\n const flavorY = Math.max(nameBottom + 14, box.y + box.h - 82)\n return (\n <MockupFrame kind=\"supplement\" label={label} {...rest}>\n <ellipse cx={200} cy={364} rx={110} ry={8} style={{ ...tone('ink'), opacity: 0.1 }} />\n {shape.draw()}\n <rect x={box.x} y={box.y} width={box.w} height={box.h} rx={6} style={tone('label')} />\n <rect x={box.x} y={box.y} width={box.w} height={6} rx={3} style={tone('accent')} />\n {data.brand ? <MockupText lines={wrapMockupText(data.brand, 16, 1)} x={cx} y={box.y + 28} size={12} weight={700} tone=\"label-ink\" letterSpacing={1.5} style={{ opacity: 0.68 }} /> : null}\n <MockupText lines={nameLines} x={cx} y={nameY} size={nameFont} lineHeight={1.08} weight={900} tone=\"label-ink\" />\n {flavor ? (\n <>\n <rect x={cx - flavorW / 2} y={flavorY} width={flavorW} height={22} rx={11} style={tone('accent')} />\n <MockupText lines={[flavor]} x={cx} y={flavorY + 15} size={11.5} weight={700} tone=\"accent-ink\" />\n </>\n ) : null}\n {amountText ? (\n <>\n <rect x={cx - amountW / 2} y={box.y + box.h - 40} width={amountW} height={26} rx={13} style={tone('surface')} />\n <MockupText lines={[amountText]} x={cx} y={box.y + box.h - 22.5} size={12.5} weight={700} tone=\"surface-ink\" letterSpacing={1} />\n </>\n ) : null}\n </MockupFrame>\n )\n}\n","import type { TireMockupData } from '@asteby/storefront/mockup'\nimport { MockupFrame, MockupText, fitMockupFontSize, tone, wrapMockupText } from './frame.js'\nimport type { MockupComponentProps } from './types.js'\n\nconst CX = 200\nconst CY = 146\n\n/** Tire seen from the side (tread blocks on the edge) with the size in big digits. Shows only what the data has. */\nexport function TireMockup({ data, label, labels, ...rest }: MockupComponentProps<TireMockupData>) {\n const split = data.width && data.aspect && data.rim\n const headline = split ? `${data.width}/${data.aspect} R${data.rim}` : data.size\n const sizeFont = headline ? fitMockupFontSize([headline], 330, 46, 22, 0.6) : 0\n const titleLines = headline ? [] : wrapMockupText(data.model ?? data.title, 24, 2)\n const titleFont = fitMockupFontSize(titleLines, 320, 26, 14)\n const extras = [data.lightTruck && !(headline ?? '').toUpperCase().startsWith(labels.lightTruck.toUpperCase()) ? labels.lightTruck : null, data.runFlat ? labels.runFlat : null].filter(Boolean).join(' · ')\n const footer = [headline ? data.model : null, extras || null].filter(Boolean).join(' · ')\n return (\n <MockupFrame kind=\"tire\" label={label} {...rest}>\n <ellipse cx={CX} cy={CY + 128} rx={120} ry={8} style={{ ...tone('ink'), opacity: 0.08 }} />\n {/* rubber, tread blocks, sidewall ring */}\n <circle cx={CX} cy={CY} r={102} fill=\"none\" strokeWidth={52} style={tone('surface', 'stroke')} />\n <circle cx={CX} cy={CY} r={124} fill=\"none\" strokeWidth={8} strokeDasharray=\"8 9\" style={tone('bg', 'stroke')} />\n <circle cx={CX} cy={CY} r={111} fill=\"none\" strokeWidth={1.5} strokeDasharray=\"3 5\" style={{ ...tone('surface-ink', 'stroke'), opacity: 0.35 }} />\n <circle cx={CX} cy={CY} r={86} fill=\"none\" strokeWidth={1.5} style={{ ...tone('surface-ink', 'stroke'), opacity: 0.25 }} />\n {/* rim with five windows and hub */}\n <circle cx={CX} cy={CY} r={74} style={tone('muted')} />\n <circle cx={CX} cy={CY} r={45} fill=\"none\" strokeWidth={36} strokeDasharray=\"36 20.5\" style={tone('surface', 'stroke')} />\n <circle cx={CX} cy={CY} r={20} style={tone('label')} />\n <circle cx={CX} cy={CY} r={11} fill=\"none\" strokeWidth={4} strokeDasharray=\"2.5 11.3\" style={tone('muted', 'stroke')} />\n {data.brand ? (\n <MockupText lines={[data.brand]} x={CX} y={302} size={15} weight={700} tone=\"muted\" letterSpacing={2} />\n ) : null}\n {headline ? (\n <text x={CX} y={346} fontSize={sizeFont} fontWeight={800} textAnchor=\"middle\" style={tone('ink')}>\n {split ? (\n <>\n {`${data.width}/${data.aspect} `}\n <tspan style={tone('accent')}>{`R${data.rim}`}</tspan>\n </>\n ) : (\n headline\n )}\n </text>\n ) : (\n <MockupText lines={titleLines} x={CX} y={titleLines.length > 1 ? 330 : 342} size={titleFont} weight={700} />\n )}\n {footer || data.service ? (\n <text x={CX} y={380} fontSize={15} fontWeight={600} textAnchor=\"middle\" style={tone('muted')}>\n {data.service ? (\n <tspan fontWeight={800} style={tone('accent')}>\n {data.service}\n </tspan>\n ) : null}\n {data.service && footer ? ' · ' : null}\n {wrapMockupText(footer, data.service ? 34 : 40, 1)[0]}\n </text>\n ) : null}\n </MockupFrame>\n )\n}\n","import { createContext, useContext, type ReactNode } from 'react'\nimport { mockupDataFromProduct, type MockupKind, type MockupProduct, type MockupVariant } from '@asteby/storefront/mockup'\nimport { GenericMockup } from './generic.js'\nimport { DEFAULT_MOCKUP_LABELS, describeMockup, type MockupLabels } from './labels.js'\nimport { PartMockup } from './part.js'\nimport { SupplementMockup } from './supplement.js'\nimport { TireMockup } from './tire.js'\nimport type { MockupComponent, MockupRenderer } from './types.js'\n\n/** A renderer, or just its component (data then comes from the built-in extractor). */\nexport type MockupRendererInput<D = any> = MockupRenderer<D> | MockupComponent<D>\n\n/** A resolved renderer: every hook filled in. */\nexport type ResolvedMockupRenderer<D = any> = Required<MockupRenderer<D>>\n\nexport type MockupRegistry = {\n /** Adds or replaces a kind. Returns the registry (chainable). */\n register<D>(kind: MockupKind, renderer: MockupRendererInput<D>): MockupRegistry\n get(kind: MockupKind): ResolvedMockupRenderer | undefined\n has(kind: MockupKind): boolean\n kinds(): MockupKind[]\n /** New registry with these entries plus the overrides (the original is untouched). */\n extend(overrides?: Partial<Record<MockupKind, MockupRendererInput>>): MockupRegistry\n}\n\nconst KIND_PATTERN = /^[a-z][a-z0-9_-]{0,31}$/\n\nfunction normalize(kind: MockupKind, input: MockupRendererInput): ResolvedMockupRenderer {\n const r: MockupRenderer = typeof input === 'function' ? { component: input } : input\n if (!r || typeof r.component !== 'function') throw new TypeError(`Mockup \"${kind}\": component is required`)\n return {\n component: r.component,\n fromProduct: r.fromProduct ?? ((product: MockupProduct, variant?: MockupVariant | null) => mockupDataFromProduct(kind, product, variant)),\n describe: r.describe ?? ((data: any, labels: MockupLabels) => describeMockup(data, labels)),\n }\n}\n\n/** A registry of mockup kinds. Pass `BUILTIN_MOCKUPS` (or a subset) to start from the base ones. */\nexport function createMockupRegistry(initial: Partial<Record<MockupKind, MockupRendererInput>> = {}): MockupRegistry {\n const map = new Map<string, ResolvedMockupRenderer>()\n const registry: MockupRegistry = {\n register(kind, renderer) {\n if (!KIND_PATTERN.test(kind)) throw new TypeError(`Invalid mockup kind \"${kind}\" (use a-z, 0-9, - and _)`)\n map.set(kind, normalize(kind, renderer as MockupRendererInput))\n return registry\n },\n get: (kind) => map.get(kind),\n has: (kind) => map.has(kind),\n kinds: () => [...map.keys()],\n extend(overrides = {}) {\n const next = createMockupRegistry()\n for (const [k, r] of map) next.register(k, r)\n for (const [k, r] of Object.entries(overrides)) if (r) next.register(k, r)\n return next\n },\n }\n for (const [k, r] of Object.entries(initial)) if (r) registry.register(k, r)\n return registry\n}\n\n/** The four base mockups. */\nexport const BUILTIN_MOCKUPS = {\n tire: TireMockup,\n part: PartMockup,\n supplement: SupplementMockup,\n generic: GenericMockup,\n} satisfies Record<string, MockupRendererInput>\n\n/** Registry used when no `MockupProvider`/`registry` prop is given. */\nexport const defaultMockupRegistry: MockupRegistry = createMockupRegistry(BUILTIN_MOCKUPS)\n\n/**\n * Registers a kind in the default registry (call it once at module scope, e.g.\n * in `app/root.tsx`). For an isolated registry use `createMockupRegistry` + `MockupProvider`.\n */\nexport function registerMockup<D>(kind: MockupKind, renderer: MockupRendererInput<D>): MockupRegistry {\n return defaultMockupRegistry.register(kind, renderer)\n}\n\n// ---------------------------------------------------------------------------\n// Provider\n// ---------------------------------------------------------------------------\n\n/**\n * Store-level kind resolver. Receives the default guess; return a kind to\n * override it, or `null`/`undefined` to keep the default.\n */\nexport type ResolveMockupKind = (product: MockupProduct, defaultKind: MockupKind) => MockupKind | null | undefined\n\nexport type MockupConfig = {\n registry: MockupRegistry\n resolveKind?: ResolveMockupKind | undefined\n labels: MockupLabels\n}\n\nconst MockupContext = createContext<MockupConfig | null>(null)\n\nexport type MockupProviderProps = {\n registry?: MockupRegistry\n resolveKind?: ResolveMockupKind\n labels?: Partial<MockupLabels>\n children?: ReactNode\n}\n\n/** Per-store mockup configuration (registry, kind resolver, labels) for every `ProductImage` below. */\nexport function MockupProvider({ registry, resolveKind, labels, children }: MockupProviderProps) {\n const parent = useContext(MockupContext)\n const value: MockupConfig = {\n registry: registry ?? parent?.registry ?? defaultMockupRegistry,\n resolveKind: resolveKind ?? parent?.resolveKind,\n labels: { ...(parent?.labels ?? DEFAULT_MOCKUP_LABELS), ...labels },\n }\n return <MockupContext.Provider value={value}>{children}</MockupContext.Provider>\n}\n\n/** Current mockup configuration (defaults when there is no provider). */\nexport function useMockupConfig(): MockupConfig {\n return useContext(MockupContext) ?? { registry: defaultMockupRegistry, labels: DEFAULT_MOCKUP_LABELS }\n}\n","import type { CSSProperties } from 'react'\nimport type { Image as ImageData, Product, ProductVariant } from '@asteby/storefront'\nimport { resolveMockupKind, type MockupKind, type MockupProduct, type MockupVariant } from '@asteby/storefront/mockup'\nimport { Image, type ImageProps } from '../components.js'\nimport type { MockupFrameProps } from './frame.js'\nimport type { MockupLabels } from './labels.js'\nimport { useMockupConfig, type MockupRegistry, type ResolveMockupKind } from './registry.js'\n\ntype SvgPassThrough = Omit<MockupFrameProps, 'label' | 'kind' | 'children'>\n\nexport type ProductMockupProps<D = unknown> = SvgPassThrough & {\n kind: MockupKind\n data: D\n /** Accessible name override (still prefixed with `labels.illustration`). */\n label?: string\n labels?: Partial<MockupLabels>\n registry?: MockupRegistry\n}\n\n/**\n * Draws the mockup registered for `kind` with already extracted `data`\n * (e.g. from `mockupDataFromProduct`). Unknown kinds fall back to `generic`;\n * returns `null` when the registry has neither.\n */\nexport function ProductMockup<D>({ kind, data, label, labels: labelOverrides, registry: registryProp, ...svg }: ProductMockupProps<D>) {\n const config = useMockupConfig()\n const registry = registryProp ?? config.registry\n const renderer = registry.get(kind) ?? registry.get('generic')\n if (!renderer) return null\n const labels = labelOverrides ? { ...config.labels, ...labelOverrides } : config.labels\n const name = label ? `${labels.illustration}: ${label}` : renderer.describe(data, labels)\n const Component = renderer.component\n return <Component data={data} label={name} labels={labels} {...svg} />\n}\n\n/** Product fields `ProductImage` reads: the mockup fields plus the images. */\nexport type ProductImageProduct = MockupProduct & Partial<Pick<Product, 'featured_image' | 'images'>>\n\nexport type ProductImageProps = Omit<ImageProps, 'data'> & {\n product: ProductImageProduct\n /** Selected variant: its image wins; its options (flavor, presentation) feed the mockup. */\n variant?: (MockupVariant & Partial<Pick<ProductVariant, 'image'>>) | null\n /** Explicit image (e.g. a gallery slide). `null` forces the mockup. */\n image?: ImageData | null\n /** Forces a mockup kind (skips resolution). */\n kind?: MockupKind\n resolveKind?: ResolveMockupKind\n registry?: MockupRegistry\n labels?: Partial<MockupLabels>\n}\n\n/**\n * The product's image from OPS (responsive `Image`: `alt`, intrinsic size,\n * `priority` for LCP) or, when it has none, the mockup for its kind. Kind:\n * `kind` prop → `resolveKind` (prop, then `MockupProvider`) → `resolveMockupKind`.\n *\n * The mockup's accessible name always says it is an illustration; `alt=\"\"`\n * makes it decorative (`aria-hidden`), like an empty `alt` on an image.\n */\nexport function ProductImage({\n product,\n variant,\n image,\n kind: kindProp,\n resolveKind: resolveProp,\n registry: registryProp,\n labels: labelOverrides,\n alt,\n className,\n style,\n id,\n ...imageProps\n}: ProductImageProps) {\n const config = useMockupConfig()\n const img = image !== undefined ? image : (variant?.image ?? product.featured_image ?? product.images?.[0] ?? null)\n if (img?.url) {\n return <Image data={img} alt={alt ?? img.alt ?? product.title} className={className} style={style} id={id} {...imageProps} />\n }\n\n const registry = registryProp ?? config.registry\n let kind = kindProp\n if (!kind) {\n const guess = resolveMockupKind(product, { kinds: registry.kinds() })\n kind = (resolveProp ?? config.resolveKind)?.(product, guess) ?? guess\n }\n const renderer = registry.get(kind) ?? registry.get('generic')\n if (!renderer) return null\n const labels = labelOverrides ? { ...config.labels, ...labelOverrides } : config.labels\n const data = renderer.fromProduct(product, variant)\n const decorative = alt === ''\n const label = alt ? `${labels.illustration}: ${alt}` : renderer.describe(data, labels)\n const Component = renderer.component\n return (\n <Component\n data={data}\n label={label}\n labels={labels}\n decorative={decorative}\n className={className}\n style={style as CSSProperties | undefined}\n id={id}\n data-mockup-fallback=\"\"\n />\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/mockups/frame.tsx","../src/mockups/generic.tsx","../src/mockups/labels.ts","../src/mockups/part.tsx","../src/mockups/supplement.tsx","../src/mockups/tire.tsx","../src/mockups/registry.tsx","../src/mockups/product-image.tsx","../src/mockups/define.tsx"],"names":["jsxs","jsx","Fragment","KIND_PATTERN"],"mappings":"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","file":"mockups.js","sourcesContent":["import type { CSSProperties, ReactNode, SVGProps } from 'react'\n\n/** Side of the square viewBox every mockup draws in. */\nexport const MOCKUP_SIZE = 400\n\n/**\n * Theme tokens. Each mockup reads `--mockup-*` (set them in the store CSS),\n * falls back to the store theme (`--color-muted`, `--color-primary`... as\n * emitted by `ThemeStyle`) and finally to neutral greys that follow\n * `color-scheme` through `light-dark()`. No brand colors live here.\n */\nexport const MOCKUP_TOKENS = {\n bg: 'var(--mockup-bg, var(--color-muted, light-dark(#f4f4f5, #27272a)))',\n surface: 'var(--mockup-surface, light-dark(#3f3f46, #0a0a0a))',\n 'surface-ink': 'var(--mockup-surface-ink, light-dark(#e4e4e7, #a1a1aa))',\n label: 'var(--mockup-label, var(--color-background, light-dark(#ffffff, #18181b)))',\n 'label-ink': 'var(--mockup-label-ink, var(--color-foreground, light-dark(#18181b, #fafafa)))',\n ink: 'var(--mockup-ink, var(--color-foreground, light-dark(#18181b, #fafafa)))',\n muted: 'var(--mockup-muted, var(--color-muted-foreground, light-dark(#71717a, #a1a1aa)))',\n accent: 'var(--mockup-accent, var(--color-primary, light-dark(#52525b, #d4d4d8)))',\n 'accent-ink': 'var(--mockup-accent-ink, var(--color-primary-foreground, light-dark(#ffffff, #18181b)))',\n} as const\n\nexport type MockupTone = keyof typeof MOCKUP_TOKENS\n\nconst ROOT_STYLE: Record<string, string> = {\n ...Object.fromEntries(Object.entries(MOCKUP_TOKENS).map(([k, v]) => [`--mk-${k}`, v])),\n fontFamily: 'var(--mockup-font, var(--font-heading, var(--font-sans, ui-sans-serif, system-ui, sans-serif)))',\n textTransform: 'var(--mockup-text-transform, none)',\n}\n\n/** `style` that paints an element with a token: `<rect style={tone('accent')} />`. */\nexport function tone(t: MockupTone, prop: 'fill' | 'stroke' = 'fill'): CSSProperties {\n return { [prop]: `var(--mk-${t})` }\n}\n\n/** Monospace stack for part numbers and sizes (`--mockup-font-mono`). */\nexport const MOCKUP_MONO = 'var(--mockup-font-mono, var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace))'\n\n// ---------------------------------------------------------------------------\n// Text layout (no DOM measuring: works the same in SSR)\n// ---------------------------------------------------------------------------\n\n/**\n * Greedy word wrap by characters; the last allowed line ends in `…` when text\n * is cut. Words longer than `wordMax` (default `maxChars`) are cut with `…`; a\n * word between `maxChars` and `wordMax` keeps a line of its own, so the caller\n * can shrink the font to fit it (`fitMockupFontSize`) instead of cutting it.\n */\nexport function wrapMockupText(text: string | null | undefined, maxChars: number, maxLines: number, wordMax: number = maxChars): string[] {\n if (!text || maxLines < 1) return []\n const cap = Math.max(maxChars, wordMax)\n const words = text.split(' ').filter(Boolean)\n const lines: string[] = []\n let current = ''\n let cut = false\n for (let i = 0; i < words.length; i++) {\n let word = words[i]!\n if (Array.from(word).length > cap) word = Array.from(word).slice(0, cap - 1).join('') + '…'\n const next = current ? `${current} ${word}` : word\n if (Array.from(next).length <= maxChars || !current) {\n current = next\n continue\n }\n lines.push(current)\n current = word\n if (lines.length === maxLines) {\n cut = true\n current = ''\n break\n }\n }\n if (current) lines.push(current)\n if (cut || lines.length > maxLines) {\n const kept = lines.slice(0, maxLines)\n const last = Array.from(kept[maxLines - 1] ?? '')\n const limit = Math.max(maxChars, Math.min(cap, last.length))\n kept[maxLines - 1] = (last.length >= limit ? last.slice(0, limit - 1).join('') : last.join('')).replace(/[\\s.,;:…-]+$/, '') + '…'\n return kept\n }\n return lines\n}\n\n/** Longest word (in characters) that still fits `width` at font size `min` (glyph width `ratio` em). */\nexport function mockupWordMax(width: number, min: number, ratio = 0.62): number {\n return Math.max(1, Math.floor(width / (min * ratio)))\n}\n\n/** Font size so the longest line fits `width` (approximate glyph width `ratio` em). */\nexport function fitMockupFontSize(lines: readonly string[], width: number, max: number, min = 10, ratio = 0.62): number {\n const longest = Math.max(1, ...lines.map((l) => Array.from(l).length))\n return Math.round(Math.max(min, Math.min(max, width / (longest * ratio))))\n}\n\nexport type MockupTextProps = Omit<SVGProps<SVGTextElement>, 'children'> & {\n lines: readonly string[]\n x: number\n y: number\n size: number\n lineHeight?: number\n tone?: MockupTone\n weight?: number\n anchor?: 'start' | 'middle' | 'end'\n mono?: boolean\n}\n\n/** Multi-line `<text>`; `y` is the baseline of the first line. */\nexport function MockupText({ lines, x, y, size, lineHeight = 1.12, tone: t = 'ink', weight = 700, anchor = 'middle', mono, style, ...rest }: MockupTextProps) {\n if (!lines.length) return null\n return (\n <text\n x={x}\n y={y}\n fontSize={size}\n fontWeight={weight}\n textAnchor={anchor}\n style={{ ...tone(t), ...(mono ? { fontFamily: MOCKUP_MONO } : null), ...style }}\n {...rest}\n >\n {lines.length === 1\n ? lines[0]\n : lines.map((line, i) => (\n <tspan key={i} x={x} dy={i === 0 ? 0 : size * lineHeight}>\n {line}\n </tspan>\n ))}\n </text>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Frame\n// ---------------------------------------------------------------------------\n\nexport type MockupFrameProps = Omit<SVGProps<SVGSVGElement>, 'children' | 'role' | 'ref'> & {\n /** Accessible name (`aria-label` and `<title>`). */\n label: string\n /** Hide from assistive tech (the product name is already next to it). */\n decorative?: boolean\n /** Written to `data-mockup` for styling and tests. */\n kind?: string\n children?: ReactNode\n}\n\n/**\n * The `<svg>` shell shared by every mockup: square viewBox, token variables,\n * background, `role=\"img\"` with an accessible name that says it is an\n * illustration. Use it in custom renderers to get the same contract.\n */\nexport function MockupFrame({ label, decorative = false, kind, children, style, width = MOCKUP_SIZE, height = MOCKUP_SIZE, ...rest }: MockupFrameProps) {\n const a11y = decorative ? { 'aria-hidden': true as const } : { role: 'img', 'aria-label': label }\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={`0 0 ${MOCKUP_SIZE} ${MOCKUP_SIZE}`}\n width={width}\n height={height}\n focusable=\"false\"\n data-mockup={kind}\n {...a11y}\n style={{ ...ROOT_STYLE, ...style } as CSSProperties}\n {...rest}\n >\n {decorative ? null : <title>{label}</title>}\n <rect width={MOCKUP_SIZE} height={MOCKUP_SIZE} style={tone('bg')} />\n {children}\n </svg>\n )\n}\n","import type { GenericMockupData } from '@asteby/storefront/mockup'\nimport { MockupFrame, MockupText, fitMockupFontSize, tone, wrapMockupText } from './frame.js'\nimport type { MockupComponentProps } from './types.js'\n\n/** Closed box with the product monogram, the brand on the box and the name below. */\nexport function GenericMockup({ data, label, labels: _labels, ...rest }: MockupComponentProps<GenericMockupData>) {\n const titleLines = wrapMockupText(data.title, 28, 2)\n const titleFont = fitMockupFontSize(titleLines, 330, 22, 13)\n const titleY = titleLines.length > 1 ? 340 : 352\n const eyebrow = data.category ? wrapMockupText(data.category, 30, 1) : []\n return (\n <MockupFrame kind=\"generic\" label={label} {...rest}>\n <ellipse cx={200} cy={300} rx={130} ry={8} style={{ ...tone('ink'), opacity: 0.08 }} />\n <path d=\"M90 82L114 64H330L306 82Z\" style={tone('accent')} />\n <path d=\"M306 82L330 64V280L306 298Z\" style={tone('surface')} />\n <path d=\"M306 82L330 64V280L306 298Z\" style={{ fill: '#000', opacity: 0.22 }} />\n <rect x={90} y={82} width={216} height={216} style={tone('surface')} />\n <rect x={186} y={82} width={24} height={46} style={{ ...tone('accent'), opacity: 0.9 }} />\n <circle cx={198} cy={186} r={50} style={tone('label')} />\n {data.monogram ? <MockupText lines={[data.monogram]} x={198} y={202} size={44} weight={900} tone=\"label-ink\" letterSpacing={1} /> : null}\n {data.brand ? <MockupText lines={wrapMockupText(data.brand, 20, 1)} x={198} y={272} size={13} weight={700} tone=\"surface-ink\" letterSpacing={2} /> : null}\n {eyebrow.length > 0 && titleLines.length < 2 ? <MockupText lines={eyebrow} x={200} y={326} size={12} weight={600} tone=\"muted\" letterSpacing={1} /> : null}\n <MockupText lines={titleLines} x={200} y={titleY} size={titleFont} lineHeight={1.2} weight={700} />\n </MockupFrame>\n )\n}\n","import type { BuiltinMockupData } from '@asteby/storefront/mockup'\n\n/** Interface words used by the built-in mockups (generic UI text, not store copy). */\nexport type MockupLabels = {\n /** Prefix of every accessible name, so a mockup is never announced as a photo. */\n illustration: string\n size: string\n partNumber: string\n oem: string\n fits: string\n flavor: string\n /** Unit after a numeric `servings` attribute. */\n servings: string\n lightTruck: string\n runFlat: string\n}\n\nexport const DEFAULT_MOCKUP_LABELS: MockupLabels = {\n illustration: 'Ilustración de referencia',\n size: 'medida',\n partNumber: 'N.º de parte',\n oem: 'OEM',\n fits: 'Compatible con',\n flavor: 'sabor',\n servings: 'porciones',\n lightTruck: 'LT',\n runFlat: 'Run flat',\n}\n\nconst has = (haystack: string, needle: string) => haystack.toLowerCase().includes(needle.toLowerCase())\n\n/** Accessible name for built-in data: \"Ilustración de referencia: <title>, <key spec>\". */\nexport function describeMockup(data: Partial<BuiltinMockupData> & { title?: string | null }, labels: MockupLabels = DEFAULT_MOCKUP_LABELS): string {\n const title = data.title ?? ''\n const parts: (string | null | undefined)[] = [title]\n switch (data.kind) {\n case 'tire':\n if (data.size && !has(title, data.size)) parts.push(`${labels.size} ${data.size}`)\n if (data.service && !has(title, data.service)) parts.push(data.service)\n break\n case 'part':\n if (data.partNumber && !has(title, data.partNumber)) parts.push(`${labels.partNumber} ${data.partNumber}`)\n break\n case 'supplement':\n if (data.flavor && !has(title, data.flavor)) parts.push(`${labels.flavor} ${data.flavor}`)\n if (data.presentation && !has(title, data.presentation)) parts.push(data.presentation)\n break\n }\n const detail = parts.filter((p): p is string => !!p).join(', ')\n return detail ? `${labels.illustration}: ${detail}` : labels.illustration\n}\n","import type { PartMockupData } from '@asteby/storefront/mockup'\nimport { MockupFrame, MockupText, fitMockupFontSize, tone, wrapMockupText } from './frame.js'\nimport type { MockupComponentProps } from './types.js'\n\nconst X = 48\nconst W = 304\nconst PAD = 24\nconst INNER = W - PAD * 2\nconst SECONDARY = { opacity: 0.68 }\n\n/** Hang tag (\"ficha\") with the part number in a band, the name and the compatibility. */\nexport function PartMockup({ data, label, labels, ...rest }: MockupComponentProps<PartMockupData>) {\n const number = data.partNumber ?? data.oemNumber\n const numberCaption = data.partNumber ? labels.partNumber : labels.oem\n const bandLines = number ? [number] : wrapMockupText(data.title, 22, 2)\n const bandFont = number ? fitMockupFontSize(bandLines, INNER, 34, 14, 0.62) : fitMockupFontSize(bandLines, INNER, 24, 14)\n const header = data.brand ?? data.category\n const headerAside = data.brand ? (data.position ?? data.category) : data.position\n\n // Body lines below the band, laid out top-down until the tag ends.\n const body: { lines: string[]; size: number; secondary?: boolean; weight: number; mono?: boolean }[] = []\n if (number) body.push({ lines: wrapMockupText(data.title, 26, 2), size: 17, weight: 700 })\n if (data.fitment) body.push({ lines: wrapMockupText(`${labels.fits}: ${data.fitment}`, 34, 2), size: 13, secondary: true, weight: 500 })\n if (data.partNumber && data.oemNumber) body.push({ lines: [`${labels.oem} ${data.oemNumber}`], size: 13, secondary: true, weight: 600, mono: true })\n let y = 248\n const placed: ((typeof body)[number] & { y: number })[] = []\n for (const b of body) {\n const at = y + b.size\n const room = Math.floor((330 - at) / (b.size * 1.2)) + 1\n if (room < 1 || !b.lines.length) continue\n const lines = b.lines.length > room ? [...b.lines.slice(0, room - 1), b.lines[room - 1]!.replace(/[\\s.,;:…-]*$/, '…')] : b.lines\n placed.push({ ...b, lines, y: at })\n y = at + (lines.length - 1) * b.size * 1.2 + 10\n }\n\n return (\n <MockupFrame kind=\"part\" label={label} {...rest}>\n <path d=\"M78 98 C60 52 36 46 14 30\" fill=\"none\" strokeWidth={2} strokeLinecap=\"round\" style={tone('muted', 'stroke')} />\n <rect x={X} y={66} width={W} height={276} rx={18} style={tone('label')} />\n <rect x={X + 0.75} y={66.75} width={W - 1.5} height={274.5} rx={17.25} fill=\"none\" strokeWidth={1.5} style={{ ...tone('muted', 'stroke'), opacity: 0.3 }} />\n <circle cx={80} cy={98} r={9} style={tone('bg')} />\n <circle cx={80} cy={98} r={9} fill=\"none\" strokeWidth={1.5} style={{ ...tone('muted', 'stroke'), opacity: 0.5 }} />\n {header ? <MockupText lines={wrapMockupText(header, headerAside ? 14 : 22, 1)} x={104} y={104} size={16} weight={800} tone=\"label-ink\" anchor=\"start\" letterSpacing={0.5} /> : null}\n {headerAside ? <MockupText lines={wrapMockupText(headerAside, header ? 14 : 22, 1)} x={X + W - PAD} y={104} size={12} weight={600} tone=\"label-ink\" anchor=\"end\" style={SECONDARY} /> : null}\n <rect x={X} y={128} width={W} height={92} style={tone('accent')} />\n {number ? (\n <>\n <MockupText lines={[numberCaption]} x={X + PAD} y={154} size={12} weight={600} tone=\"accent-ink\" anchor=\"start\" letterSpacing={1} style={{ opacity: 0.85 }} />\n <MockupText lines={bandLines} x={X + PAD} y={198} size={bandFont} weight={800} tone=\"accent-ink\" anchor=\"start\" mono />\n </>\n ) : (\n <MockupText lines={bandLines} x={X + PAD} y={bandLines.length > 1 ? 168 : 182} size={bandFont} weight={800} tone=\"accent-ink\" anchor=\"start\" />\n )}\n {placed.map((b, i) => (\n <MockupText key={i} lines={b.lines} x={X + PAD} y={b.y} size={b.size} lineHeight={1.2} weight={b.weight} tone=\"label-ink\" anchor=\"start\" mono={b.mono} style={b.secondary ? SECONDARY : undefined} />\n ))}\n </MockupFrame>\n )\n}\n","import type { ReactNode } from 'react'\nimport type { SupplementMockupData, SupplementShape } from '@asteby/storefront/mockup'\nimport { MockupFrame, MockupText, fitMockupFontSize, mockupWordMax, tone, wrapMockupText } from './frame.js'\nimport type { MockupComponentProps } from './types.js'\n\ntype Box = { x: number; y: number; w: number; h: number }\n\n/** Container silhouettes (generic, unbranded) and where their label sits. */\nconst SHAPES: Record<SupplementShape, { label: Box; draw: () => ReactNode }> = {\n tub: {\n label: { x: 131, y: 128, w: 138, h: 200 },\n draw: () => (\n <>\n <rect x={120} y={44} width={160} height={54} rx={8} style={tone('surface')} />\n <line x1={128} y1={71} x2={272} y2={71} strokeWidth={42} strokeDasharray=\"1.5 7.5\" style={{ ...tone('surface-ink', 'stroke'), opacity: 0.18 }} />\n <rect x={117} y={95} width={166} height={9} rx={2} style={tone('accent')} />\n <path d=\"M122 104H278L283 344Q283 362 265 362H135Q117 362 117 344Z\" style={tone('surface')} />\n </>\n ),\n },\n bottle: {\n label: { x: 131, y: 148, w: 138, h: 184 },\n draw: () => (\n <>\n <rect x={158} y={46} width={84} height={40} rx={7} style={tone('surface')} />\n <line x1={164} y1={66} x2={236} y2={66} strokeWidth={30} strokeDasharray=\"1.5 6.5\" style={{ ...tone('surface-ink', 'stroke'), opacity: 0.18 }} />\n <rect x={168} y={84} width={64} height={12} style={tone('accent')} />\n <path d=\"M124 116Q124 96 148 96H252Q276 96 276 116L281 344Q281 362 263 362H137Q119 362 119 344Z\" style={tone('surface')} />\n </>\n ),\n },\n bag: {\n label: { x: 133, y: 118, w: 134, h: 196 },\n draw: () => (\n <>\n <path d=\"M118 64Q200 50 282 64L297 344Q200 360 103 344Z\" style={tone('surface')} />\n <path d=\"M118 64Q200 50 282 64L280 84Q200 70 120 84Z\" style={tone('accent')} />\n <path d=\"M124 92Q200 79 276 92\" fill=\"none\" strokeWidth={2} strokeDasharray=\"4 4\" style={{ ...tone('surface-ink', 'stroke'), opacity: 0.4 }} />\n </>\n ),\n },\n}\n\n/** Tub, bottle or bag with a label: brand, product name, flavor and presentation. */\nexport function SupplementMockup({ data, label, labels, ...rest }: MockupComponentProps<SupplementMockupData>) {\n const shape = SHAPES[data.shape] ?? SHAPES.tub\n const box = shape.label\n const cx = box.x + box.w / 2\n const inner = box.w - 20\n const amount = data.presentation ?? (data.servings ? `${data.servings} ${labels.servings}` : null)\n // Long words (CREATINA MONOHIDRATADA) keep a line of their own and the font shrinks to the longest one;\n // only words that would not fit even at the minimum size are cut.\n const nameLines = wrapMockupText(data.title, 12, 3, mockupWordMax(inner, 12, 0.64))\n const nameFont = fitMockupFontSize(nameLines, inner, 26, 12, 0.64)\n const flavor = data.flavor ? wrapMockupText(data.flavor, 18, 1)[0]! : null\n const flavorW = flavor ? Math.min(inner, Array.from(flavor).length * 6.6 + 20) : 0\n const amountText = amount ? wrapMockupText(amount, 16, 1)[0]! : null\n const amountW = amountText ? Math.min(inner, Array.from(amountText).length * 7.4 + 24) : 0\n const top = box.y + (data.brand ? 46 : 30)\n const nameY = top + nameFont * 0.8\n const nameBottom = nameY + (nameLines.length - 1) * nameFont * 1.08\n const flavorY = Math.max(nameBottom + 14, box.y + box.h - 82)\n return (\n <MockupFrame kind=\"supplement\" label={label} {...rest}>\n <ellipse cx={200} cy={364} rx={110} ry={8} style={{ ...tone('ink'), opacity: 0.1 }} />\n {shape.draw()}\n <rect x={box.x} y={box.y} width={box.w} height={box.h} rx={6} style={tone('label')} />\n <rect x={box.x} y={box.y} width={box.w} height={6} rx={3} style={tone('accent')} />\n {data.brand ? <MockupText lines={wrapMockupText(data.brand, 16, 1)} x={cx} y={box.y + 28} size={12} weight={700} tone=\"label-ink\" letterSpacing={1.5} style={{ opacity: 0.68 }} /> : null}\n <MockupText lines={nameLines} x={cx} y={nameY} size={nameFont} lineHeight={1.08} weight={900} tone=\"label-ink\" />\n {flavor ? (\n <>\n <rect x={cx - flavorW / 2} y={flavorY} width={flavorW} height={22} rx={11} style={tone('accent')} />\n <MockupText lines={[flavor]} x={cx} y={flavorY + 15} size={11.5} weight={700} tone=\"accent-ink\" />\n </>\n ) : null}\n {amountText ? (\n <>\n <rect x={cx - amountW / 2} y={box.y + box.h - 40} width={amountW} height={26} rx={13} style={tone('surface')} />\n <MockupText lines={[amountText]} x={cx} y={box.y + box.h - 22.5} size={12.5} weight={700} tone=\"surface-ink\" letterSpacing={1} />\n </>\n ) : null}\n </MockupFrame>\n )\n}\n","import type { TireMockupData } from '@asteby/storefront/mockup'\nimport { MockupFrame, MockupText, fitMockupFontSize, tone, wrapMockupText } from './frame.js'\nimport type { MockupComponentProps } from './types.js'\n\nconst CX = 200\nconst CY = 146\n\n/** Tire seen from the side (tread blocks on the edge) with the size in big digits. Shows only what the data has. */\nexport function TireMockup({ data, label, labels, ...rest }: MockupComponentProps<TireMockupData>) {\n const split = data.width && data.aspect && data.rim\n const headline = split ? `${data.width}/${data.aspect} R${data.rim}` : data.size\n const sizeFont = headline ? fitMockupFontSize([headline], 330, 46, 22, 0.6) : 0\n const titleLines = headline ? [] : wrapMockupText(data.model ?? data.title, 24, 2)\n const titleFont = fitMockupFontSize(titleLines, 320, 26, 14)\n const extras = [data.lightTruck && !(headline ?? '').toUpperCase().startsWith(labels.lightTruck.toUpperCase()) ? labels.lightTruck : null, data.runFlat ? labels.runFlat : null].filter(Boolean).join(' · ')\n const footer = [headline ? data.model : null, extras || null].filter(Boolean).join(' · ')\n return (\n <MockupFrame kind=\"tire\" label={label} {...rest}>\n <ellipse cx={CX} cy={CY + 128} rx={120} ry={8} style={{ ...tone('ink'), opacity: 0.08 }} />\n {/* rubber, tread blocks, sidewall ring */}\n <circle cx={CX} cy={CY} r={102} fill=\"none\" strokeWidth={52} style={tone('surface', 'stroke')} />\n <circle cx={CX} cy={CY} r={124} fill=\"none\" strokeWidth={8} strokeDasharray=\"8 9\" style={tone('bg', 'stroke')} />\n <circle cx={CX} cy={CY} r={111} fill=\"none\" strokeWidth={1.5} strokeDasharray=\"3 5\" style={{ ...tone('surface-ink', 'stroke'), opacity: 0.35 }} />\n <circle cx={CX} cy={CY} r={86} fill=\"none\" strokeWidth={1.5} style={{ ...tone('surface-ink', 'stroke'), opacity: 0.25 }} />\n {/* rim with five windows and hub */}\n <circle cx={CX} cy={CY} r={74} style={tone('muted')} />\n <circle cx={CX} cy={CY} r={45} fill=\"none\" strokeWidth={36} strokeDasharray=\"36 20.5\" style={tone('surface', 'stroke')} />\n <circle cx={CX} cy={CY} r={20} style={tone('label')} />\n <circle cx={CX} cy={CY} r={11} fill=\"none\" strokeWidth={4} strokeDasharray=\"2.5 11.3\" style={tone('muted', 'stroke')} />\n {data.brand ? (\n <MockupText lines={[data.brand]} x={CX} y={302} size={15} weight={700} tone=\"muted\" letterSpacing={2} />\n ) : null}\n {headline ? (\n <text x={CX} y={346} fontSize={sizeFont} fontWeight={800} textAnchor=\"middle\" style={tone('ink')}>\n {split ? (\n <>\n {`${data.width}/${data.aspect} `}\n <tspan style={tone('accent')}>{`R${data.rim}`}</tspan>\n </>\n ) : (\n headline\n )}\n </text>\n ) : (\n <MockupText lines={titleLines} x={CX} y={titleLines.length > 1 ? 330 : 342} size={titleFont} weight={700} />\n )}\n {footer || data.service ? (\n <text x={CX} y={380} fontSize={15} fontWeight={600} textAnchor=\"middle\" style={tone('muted')}>\n {data.service ? (\n <tspan fontWeight={800} style={tone('accent')}>\n {data.service}\n </tspan>\n ) : null}\n {data.service && footer ? ' · ' : null}\n {wrapMockupText(footer, data.service ? 34 : 40, 1)[0]}\n </text>\n ) : null}\n </MockupFrame>\n )\n}\n","import { createContext, useContext, type ReactNode } from 'react'\nimport { mockupDataFromProduct, type MockupKind, type MockupProduct, type MockupVariant } from '@asteby/storefront/mockup'\nimport { GenericMockup } from './generic.js'\nimport { DEFAULT_MOCKUP_LABELS, describeMockup, type MockupLabels } from './labels.js'\nimport { PartMockup } from './part.js'\nimport { SupplementMockup } from './supplement.js'\nimport { TireMockup } from './tire.js'\nimport type { MockupComponent, MockupRenderer } from './types.js'\n\n/** A renderer, or just its component (data then comes from the built-in extractor). */\nexport type MockupRendererInput<D = any> = MockupRenderer<D> | MockupComponent<D>\n\n/** A resolved renderer: every hook filled in. */\nexport type ResolvedMockupRenderer<D = any> = Required<MockupRenderer<D>>\n\nexport type MockupRegistry = {\n /** Adds or replaces a kind. Returns the registry (chainable). */\n register<D>(kind: MockupKind, renderer: MockupRendererInput<D>): MockupRegistry\n get(kind: MockupKind): ResolvedMockupRenderer | undefined\n has(kind: MockupKind): boolean\n kinds(): MockupKind[]\n /** New registry with these entries plus the overrides (the original is untouched). */\n extend(overrides?: Partial<Record<MockupKind, MockupRendererInput>>): MockupRegistry\n}\n\nconst KIND_PATTERN = /^[a-z][a-z0-9_-]{0,31}$/\n\nfunction normalize(kind: MockupKind, input: MockupRendererInput): ResolvedMockupRenderer {\n const r: MockupRenderer = typeof input === 'function' ? { component: input } : input\n if (!r || typeof r.component !== 'function') throw new TypeError(`Mockup \"${kind}\": component is required`)\n return {\n component: r.component,\n fromProduct: r.fromProduct ?? ((product: MockupProduct, variant?: MockupVariant | null) => mockupDataFromProduct(kind, product, variant)),\n describe: r.describe ?? ((data: any, labels: MockupLabels) => describeMockup(data, labels)),\n }\n}\n\n/** A registry of mockup kinds. Pass `BUILTIN_MOCKUPS` (or a subset) to start from the base ones. */\nexport function createMockupRegistry(initial: Partial<Record<MockupKind, MockupRendererInput>> = {}): MockupRegistry {\n const map = new Map<string, ResolvedMockupRenderer>()\n const registry: MockupRegistry = {\n register(kind, renderer) {\n if (!KIND_PATTERN.test(kind)) throw new TypeError(`Invalid mockup kind \"${kind}\" (use a-z, 0-9, - and _)`)\n map.set(kind, normalize(kind, renderer as MockupRendererInput))\n return registry\n },\n get: (kind) => map.get(kind),\n has: (kind) => map.has(kind),\n kinds: () => [...map.keys()],\n extend(overrides = {}) {\n const next = createMockupRegistry()\n for (const [k, r] of map) next.register(k, r)\n for (const [k, r] of Object.entries(overrides)) if (r) next.register(k, r)\n return next\n },\n }\n for (const [k, r] of Object.entries(initial)) if (r) registry.register(k, r)\n return registry\n}\n\n/** The four base mockups. */\nexport const BUILTIN_MOCKUPS = {\n tire: TireMockup,\n part: PartMockup,\n supplement: SupplementMockup,\n generic: GenericMockup,\n} satisfies Record<string, MockupRendererInput>\n\n/** Registry used when no `MockupProvider`/`registry` prop is given. */\nexport const defaultMockupRegistry: MockupRegistry = createMockupRegistry(BUILTIN_MOCKUPS)\n\n/**\n * Registers a kind in the default registry (call it once at module scope, e.g.\n * in `app/root.tsx`). For an isolated registry use `createMockupRegistry` + `MockupProvider`.\n */\nexport function registerMockup<D>(kind: MockupKind, renderer: MockupRendererInput<D>): MockupRegistry {\n return defaultMockupRegistry.register(kind, renderer)\n}\n\n// ---------------------------------------------------------------------------\n// Provider\n// ---------------------------------------------------------------------------\n\n/**\n * Store-level kind resolver. Receives the default guess; return a kind to\n * override it, or `null`/`undefined` to keep the default.\n */\nexport type ResolveMockupKind = (product: MockupProduct, defaultKind: MockupKind) => MockupKind | null | undefined\n\nexport type MockupConfig = {\n registry: MockupRegistry\n resolveKind?: ResolveMockupKind | undefined\n labels: MockupLabels\n}\n\nconst MockupContext = createContext<MockupConfig | null>(null)\n\nexport type MockupProviderProps = {\n registry?: MockupRegistry\n resolveKind?: ResolveMockupKind\n labels?: Partial<MockupLabels>\n children?: ReactNode\n}\n\n/** Per-store mockup configuration (registry, kind resolver, labels) for every `ProductImage` below. */\nexport function MockupProvider({ registry, resolveKind, labels, children }: MockupProviderProps) {\n const parent = useContext(MockupContext)\n const value: MockupConfig = {\n registry: registry ?? parent?.registry ?? defaultMockupRegistry,\n resolveKind: resolveKind ?? parent?.resolveKind,\n labels: { ...(parent?.labels ?? DEFAULT_MOCKUP_LABELS), ...labels },\n }\n return <MockupContext.Provider value={value}>{children}</MockupContext.Provider>\n}\n\n/** Current mockup configuration (defaults when there is no provider). */\nexport function useMockupConfig(): MockupConfig {\n return useContext(MockupContext) ?? { registry: defaultMockupRegistry, labels: DEFAULT_MOCKUP_LABELS }\n}\n","import type { CSSProperties } from 'react'\nimport type { Image as ImageData, Product, ProductVariant } from '@asteby/storefront'\nimport { resolveMockupKind, type MockupKind, type MockupProduct, type MockupVariant } from '@asteby/storefront/mockup'\nimport { Image, type ImageProps } from '../components.js'\nimport type { MockupFrameProps } from './frame.js'\nimport type { MockupLabels } from './labels.js'\nimport { useMockupConfig, type MockupRegistry, type ResolveMockupKind } from './registry.js'\n\ntype SvgPassThrough = Omit<MockupFrameProps, 'label' | 'kind' | 'children'>\n\nexport type ProductMockupProps<D = unknown> = SvgPassThrough & {\n kind: MockupKind\n data: D\n /** Accessible name override (still prefixed with `labels.illustration`). */\n label?: string\n labels?: Partial<MockupLabels>\n registry?: MockupRegistry\n}\n\n/**\n * Draws the mockup registered for `kind` with already extracted `data`\n * (e.g. from `mockupDataFromProduct`). Unknown kinds fall back to `generic`;\n * returns `null` when the registry has neither.\n */\nexport function ProductMockup<D>({ kind, data, label, labels: labelOverrides, registry: registryProp, ...svg }: ProductMockupProps<D>) {\n const config = useMockupConfig()\n const registry = registryProp ?? config.registry\n const renderer = registry.get(kind) ?? registry.get('generic')\n if (!renderer) return null\n const labels = labelOverrides ? { ...config.labels, ...labelOverrides } : config.labels\n const name = label ? `${labels.illustration}: ${label}` : renderer.describe(data, labels)\n const Component = renderer.component\n return <Component data={data} label={name} labels={labels} {...svg} />\n}\n\n/** Product fields `ProductImage` reads: the mockup fields plus the images. */\nexport type ProductImageProduct = MockupProduct & Partial<Pick<Product, 'featured_image' | 'images'>>\n\nexport type ProductImageProps = Omit<ImageProps, 'data'> & {\n product: ProductImageProduct\n /** Selected variant: its image wins; its options (flavor, presentation) feed the mockup. */\n variant?: (MockupVariant & Partial<Pick<ProductVariant, 'image'>>) | null\n /** Explicit image (e.g. a gallery slide). `null` forces the mockup. */\n image?: ImageData | null\n /** Forces a mockup kind (skips resolution). */\n kind?: MockupKind\n resolveKind?: ResolveMockupKind\n registry?: MockupRegistry\n labels?: Partial<MockupLabels>\n}\n\n/**\n * The product's image from OPS (responsive `Image`: `alt`, intrinsic size,\n * `priority` for LCP) or, when it has none, the mockup for its kind. Kind:\n * `kind` prop → `resolveKind` (prop, then `MockupProvider`) → `resolveMockupKind`.\n *\n * The mockup's accessible name always says it is an illustration; `alt=\"\"`\n * makes it decorative (`aria-hidden`), like an empty `alt` on an image.\n */\nexport function ProductImage({\n product,\n variant,\n image,\n kind: kindProp,\n resolveKind: resolveProp,\n registry: registryProp,\n labels: labelOverrides,\n alt,\n className,\n style,\n id,\n ...imageProps\n}: ProductImageProps) {\n const config = useMockupConfig()\n const img = image !== undefined ? image : (variant?.image ?? product.featured_image ?? product.images?.[0] ?? null)\n if (img?.url) {\n return <Image data={img} alt={alt ?? img.alt ?? product.title} className={className} style={style} id={id} {...imageProps} />\n }\n\n const registry = registryProp ?? config.registry\n let kind = kindProp\n if (!kind) {\n const guess = resolveMockupKind(product, { kinds: registry.kinds() })\n kind = (resolveProp ?? config.resolveKind)?.(product, guess) ?? guess\n }\n const renderer = registry.get(kind) ?? registry.get('generic')\n if (!renderer) return null\n const labels = labelOverrides ? { ...config.labels, ...labelOverrides } : config.labels\n const data = renderer.fromProduct(product, variant)\n const decorative = alt === ''\n const label = alt ? `${labels.illustration}: ${alt}` : renderer.describe(data, labels)\n const Component = renderer.component\n return (\n <Component\n data={data}\n label={label}\n labels={labels}\n decorative={decorative}\n className={className}\n style={style as CSSProperties | undefined}\n id={id}\n data-mockup-fallback=\"\"\n />\n )\n}\n","import type { MockupKind, MockupProduct, MockupVariant } from '@asteby/storefront/mockup'\nimport type { MockupLabels } from './labels.js'\nimport { BUILTIN_MOCKUPS, createMockupRegistry, type MockupRegistry, type ResolveMockupKind } from './registry.js'\nimport type { MockupComponent } from './types.js'\n\nconst KIND_PATTERN = /^[a-z][a-z0-9_-]{0,31}$/\n\n/**\n * One store mockup, in one file: which products it claims, what it reads from\n * them and how it draws. Every field but `kind` and `render` is optional.\n */\nexport type MockupDefinition<D = any> = {\n /** Kind name (`supplement`, `tire`, `casco-moto`). Reusing a base kind replaces it. */\n kind: MockupKind\n /**\n * Claims a product for this kind. Checked in list order, before the SDK's\n * guess (`guess`: `mockup_kind` attribute, tire/part attributes, words in\n * type/category/tags). Omit it to rely on the guess or on `mockup_kind`.\n */\n match?: (product: MockupProduct, guess: MockupKind) => boolean\n /** Product (+ selected variant) → data for `render`. Default: the base extractor of the kind (generic data for new kinds). Never prices. */\n data?: (product: MockupProduct, variant?: MockupVariant | null) => D\n /** Data → accessible name (prefix it with `labels.illustration`). Default: `describeMockup`. */\n describe?: (data: D, labels: MockupLabels) => string\n /** The drawing: a component that returns a `<MockupFrame>` (or a base one: `SupplementMockup`…). */\n render: MockupComponent<D>\n}\n\n/** Typed, checked definition of a store mockup (throws on an invalid kind or a missing `render`). */\nexport function defineMockup<D = any>(definition: MockupDefinition<D>): MockupDefinition<D> {\n if (!definition || typeof definition.kind !== 'string' || !KIND_PATTERN.test(definition.kind)) {\n throw new TypeError(`defineMockup: invalid kind \"${String(definition?.kind)}\" (use a-z, 0-9, - and _)`)\n }\n if (typeof definition.render !== 'function') throw new TypeError(`defineMockup(\"${definition.kind}\"): render is required`)\n if (definition.match !== undefined && typeof definition.match !== 'function') throw new TypeError(`defineMockup(\"${definition.kind}\"): match must be a function`)\n return Object.freeze({ ...definition })\n}\n\nexport type CreateStoreMockupsOptions = {\n /**\n * Starting registry: `builtin` (default) keeps tire, part, supplement and\n * generic for the kinds the store does not define; `none` starts empty (keep\n * a `generic` among your definitions); or pass a registry to extend.\n */\n base?: 'builtin' | 'none' | MockupRegistry\n /** Interface words (`illustration`, `servings`…) for every mockup. */\n labels?: Partial<MockupLabels>\n}\n\n/** What `<MockupProvider {...storeMockups}>` takes. */\nexport type StoreMockups = {\n registry: MockupRegistry\n resolveKind: ResolveMockupKind\n labels?: Partial<MockupLabels>\n /** Kinds defined by the store, in order. */\n kinds: MockupKind[]\n}\n\n/**\n * Builds the store's mockup setup from its definitions: a registry (base\n * mockups + the store's, the store's win) and a `resolveKind` that asks each\n * `match` in order and otherwise keeps the SDK's guess.\n *\n * ```tsx\n * export const storeMockups = createStoreMockups([supplement, accessory])\n * <MockupProvider {...storeMockups}>…</MockupProvider>\n * ```\n */\nexport function createStoreMockups(definitions: readonly MockupDefinition[], options: CreateStoreMockupsOptions = {}): StoreMockups {\n const base = options.base ?? 'builtin'\n const registry = base === 'builtin' ? createMockupRegistry(BUILTIN_MOCKUPS) : base === 'none' ? createMockupRegistry() : base.extend()\n const seen = new Set<string>()\n for (const d of definitions) {\n const def = defineMockup(d)\n if (seen.has(def.kind)) throw new TypeError(`createStoreMockups: kind \"${def.kind}\" is defined twice`)\n seen.add(def.kind)\n registry.register(def.kind, {\n component: def.render,\n ...(def.data ? { fromProduct: def.data } : null),\n ...(def.describe ? { describe: def.describe } : null),\n })\n }\n const matchers = definitions.filter((d) => typeof d.match === 'function')\n const resolveKind: ResolveMockupKind = (product, guess) => {\n for (const d of matchers) if (d.match!(product, guess)) return d.kind\n return guess\n }\n const out: StoreMockups = { registry, resolveKind, kinds: [...seen] }\n if (options.labels) out.labels = options.labels\n return out\n}\n"]}
|