@opensite/ui 0.7.9 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/carousel-feature-badge.cjs +114 -214
- package/dist/carousel-feature-badge.js +114 -214
- package/dist/carousel-horizontal-cards.cjs +283 -211
- package/dist/carousel-horizontal-cards.d.cts +5 -1
- package/dist/carousel-horizontal-cards.d.ts +5 -1
- package/dist/carousel-horizontal-cards.js +283 -211
- package/dist/carousel-pagination.cjs +601 -0
- package/dist/carousel-pagination.d.cts +75 -0
- package/dist/carousel-pagination.d.ts +75 -0
- package/dist/carousel-pagination.js +579 -0
- package/dist/components.cjs +45 -0
- package/dist/components.d.cts +1 -0
- package/dist/components.d.ts +1 -0
- package/dist/components.js +45 -1
- package/dist/index.cjs +45 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +45 -1
- package/dist/registry.cjs +424 -309
- package/dist/registry.js +424 -309
- package/package.json +6 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var React6 = require('react');
|
|
4
5
|
var clsx = require('clsx');
|
|
5
6
|
var tailwindMerge = require('tailwind-merge');
|
|
6
7
|
var reactSlot = require('@radix-ui/react-slot');
|
|
7
8
|
var classVarianceAuthority = require('class-variance-authority');
|
|
8
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
-
var React4 = require('react');
|
|
10
|
-
var useEmblaCarousel = require('embla-carousel-react');
|
|
11
10
|
var img = require('@page-speed/img');
|
|
11
|
+
var useEmblaCarousel = require('embla-carousel-react');
|
|
12
12
|
|
|
13
13
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
14
|
|
|
@@ -30,10 +30,10 @@ function _interopNamespace(e) {
|
|
|
30
30
|
return Object.freeze(n);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
var
|
|
33
|
+
var React6__namespace = /*#__PURE__*/_interopNamespace(React6);
|
|
34
34
|
var useEmblaCarousel__default = /*#__PURE__*/_interopDefault(useEmblaCarousel);
|
|
35
35
|
|
|
36
|
-
//
|
|
36
|
+
// components/blocks/carousel/carousel-feature-badge.tsx
|
|
37
37
|
function cn(...inputs) {
|
|
38
38
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
39
39
|
}
|
|
@@ -144,7 +144,7 @@ function useNavigation({
|
|
|
144
144
|
href,
|
|
145
145
|
onClick
|
|
146
146
|
} = {}) {
|
|
147
|
-
const linkType =
|
|
147
|
+
const linkType = React6__namespace.useMemo(() => {
|
|
148
148
|
if (!href || href.trim() === "") {
|
|
149
149
|
return onClick ? "none" : "none";
|
|
150
150
|
}
|
|
@@ -165,7 +165,7 @@ function useNavigation({
|
|
|
165
165
|
return "internal";
|
|
166
166
|
}
|
|
167
167
|
}, [href, onClick]);
|
|
168
|
-
const normalizedHref =
|
|
168
|
+
const normalizedHref = React6__namespace.useMemo(() => {
|
|
169
169
|
if (!href || href.trim() === "") {
|
|
170
170
|
return void 0;
|
|
171
171
|
}
|
|
@@ -183,7 +183,7 @@ function useNavigation({
|
|
|
183
183
|
return trimmed;
|
|
184
184
|
}
|
|
185
185
|
}, [href, linkType]);
|
|
186
|
-
const target =
|
|
186
|
+
const target = React6__namespace.useMemo(() => {
|
|
187
187
|
switch (linkType) {
|
|
188
188
|
case "external":
|
|
189
189
|
return "_blank";
|
|
@@ -196,7 +196,7 @@ function useNavigation({
|
|
|
196
196
|
return void 0;
|
|
197
197
|
}
|
|
198
198
|
}, [linkType]);
|
|
199
|
-
const rel =
|
|
199
|
+
const rel = React6__namespace.useMemo(() => {
|
|
200
200
|
if (linkType === "external") {
|
|
201
201
|
return "noopener noreferrer";
|
|
202
202
|
}
|
|
@@ -205,7 +205,7 @@ function useNavigation({
|
|
|
205
205
|
const isExternal = linkType === "external";
|
|
206
206
|
const isInternal = linkType === "internal";
|
|
207
207
|
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
208
|
-
const handleClick =
|
|
208
|
+
const handleClick = React6__namespace.useCallback(
|
|
209
209
|
(event) => {
|
|
210
210
|
if (onClick) {
|
|
211
211
|
try {
|
|
@@ -389,7 +389,7 @@ var buttonVariants = classVarianceAuthority.cva(baseStyles, {
|
|
|
389
389
|
size: "default"
|
|
390
390
|
}
|
|
391
391
|
});
|
|
392
|
-
var Pressable =
|
|
392
|
+
var Pressable = React6__namespace.forwardRef(
|
|
393
393
|
({
|
|
394
394
|
children,
|
|
395
395
|
className,
|
|
@@ -495,10 +495,10 @@ function DynamicIcon({
|
|
|
495
495
|
className,
|
|
496
496
|
alt
|
|
497
497
|
}) {
|
|
498
|
-
const [svgContent, setSvgContent] =
|
|
499
|
-
const [isLoading, setIsLoading] =
|
|
500
|
-
const [error, setError] =
|
|
501
|
-
const { url, iconName } =
|
|
498
|
+
const [svgContent, setSvgContent] = React6__namespace.useState(null);
|
|
499
|
+
const [isLoading, setIsLoading] = React6__namespace.useState(true);
|
|
500
|
+
const [error, setError] = React6__namespace.useState(null);
|
|
501
|
+
const { url, iconName } = React6__namespace.useMemo(() => {
|
|
502
502
|
const separator = name.includes("/") ? "/" : ":";
|
|
503
503
|
const [prefix, iconName2] = name.split(separator);
|
|
504
504
|
const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
|
|
@@ -507,7 +507,7 @@ function DynamicIcon({
|
|
|
507
507
|
iconName: iconName2
|
|
508
508
|
};
|
|
509
509
|
}, [name, size]);
|
|
510
|
-
|
|
510
|
+
React6__namespace.useEffect(() => {
|
|
511
511
|
let isMounted = true;
|
|
512
512
|
const fetchSvg = async () => {
|
|
513
513
|
const cached = svgCache.get(url);
|
|
@@ -592,192 +592,49 @@ function processSvgForCurrentColor(svg) {
|
|
|
592
592
|
);
|
|
593
593
|
return processed;
|
|
594
594
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
return context;
|
|
602
|
-
}
|
|
603
|
-
function Carousel({
|
|
604
|
-
orientation = "horizontal",
|
|
605
|
-
opts,
|
|
606
|
-
setApi,
|
|
607
|
-
plugins,
|
|
595
|
+
function CarouselPagination({
|
|
596
|
+
onPrevious,
|
|
597
|
+
onNext,
|
|
598
|
+
canScrollPrevious = true,
|
|
599
|
+
canScrollNext = true,
|
|
600
|
+
iconSize = 24,
|
|
608
601
|
className,
|
|
609
|
-
|
|
610
|
-
|
|
602
|
+
buttonClassName,
|
|
603
|
+
previousIcon = "lucide/arrow-left",
|
|
604
|
+
nextIcon = "lucide/arrow-right",
|
|
605
|
+
previousAriaLabel = "Previous",
|
|
606
|
+
nextAriaLabel = "Next"
|
|
611
607
|
}) {
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
}, []);
|
|
626
|
-
const scrollPrev = React4__namespace.useCallback(() => {
|
|
627
|
-
api?.scrollPrev();
|
|
628
|
-
}, [api]);
|
|
629
|
-
const scrollNext = React4__namespace.useCallback(() => {
|
|
630
|
-
api?.scrollNext();
|
|
631
|
-
}, [api]);
|
|
632
|
-
const handleKeyDown = React4__namespace.useCallback(
|
|
633
|
-
(event) => {
|
|
634
|
-
if (event.key === "ArrowLeft") {
|
|
635
|
-
event.preventDefault();
|
|
636
|
-
scrollPrev();
|
|
637
|
-
} else if (event.key === "ArrowRight") {
|
|
638
|
-
event.preventDefault();
|
|
639
|
-
scrollNext();
|
|
608
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex justify-end gap-2", className), children: [
|
|
609
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
610
|
+
Pressable,
|
|
611
|
+
{
|
|
612
|
+
onClick: onPrevious,
|
|
613
|
+
disabled: !canScrollPrevious,
|
|
614
|
+
"aria-label": previousAriaLabel,
|
|
615
|
+
asButton: true,
|
|
616
|
+
className: cn(
|
|
617
|
+
"relative z-40 flex h-10 w-10 items-center justify-center rounded-full disabled:opacity-50",
|
|
618
|
+
buttonClassName
|
|
619
|
+
),
|
|
620
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: previousIcon, size: iconSize })
|
|
640
621
|
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
}
|
|
657
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
658
|
-
CarouselContext.Provider,
|
|
659
|
-
{
|
|
660
|
-
value: {
|
|
661
|
-
carouselRef,
|
|
662
|
-
api,
|
|
663
|
-
opts,
|
|
664
|
-
orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
|
|
665
|
-
scrollPrev,
|
|
666
|
-
scrollNext,
|
|
667
|
-
canScrollPrev,
|
|
668
|
-
canScrollNext
|
|
669
|
-
},
|
|
670
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
671
|
-
"div",
|
|
672
|
-
{
|
|
673
|
-
onKeyDownCapture: handleKeyDown,
|
|
674
|
-
className: cn("relative", className),
|
|
675
|
-
role: "region",
|
|
676
|
-
"aria-roledescription": "carousel",
|
|
677
|
-
"data-slot": "carousel",
|
|
678
|
-
...props,
|
|
679
|
-
children
|
|
680
|
-
}
|
|
681
|
-
)
|
|
682
|
-
}
|
|
683
|
-
);
|
|
684
|
-
}
|
|
685
|
-
function CarouselContent({ className, ...props }) {
|
|
686
|
-
const { carouselRef, orientation } = useCarousel();
|
|
687
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
688
|
-
"div",
|
|
689
|
-
{
|
|
690
|
-
ref: carouselRef,
|
|
691
|
-
className: "overflow-hidden",
|
|
692
|
-
"data-slot": "carousel-content",
|
|
693
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
694
|
-
"div",
|
|
695
|
-
{
|
|
696
|
-
className: cn(
|
|
697
|
-
"flex",
|
|
698
|
-
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
|
|
699
|
-
className
|
|
700
|
-
),
|
|
701
|
-
...props
|
|
702
|
-
}
|
|
703
|
-
)
|
|
704
|
-
}
|
|
705
|
-
);
|
|
706
|
-
}
|
|
707
|
-
function CarouselItem({ className, ...props }) {
|
|
708
|
-
const { orientation } = useCarousel();
|
|
709
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
710
|
-
"div",
|
|
711
|
-
{
|
|
712
|
-
role: "group",
|
|
713
|
-
"aria-roledescription": "slide",
|
|
714
|
-
"data-slot": "carousel-item",
|
|
715
|
-
className: cn(
|
|
716
|
-
"min-w-0 shrink-0 grow-0 basis-full",
|
|
717
|
-
orientation === "horizontal" ? "pl-4" : "pt-4",
|
|
718
|
-
className
|
|
719
|
-
),
|
|
720
|
-
...props
|
|
721
|
-
}
|
|
722
|
-
);
|
|
723
|
-
}
|
|
724
|
-
function CarouselPrevious({
|
|
725
|
-
className,
|
|
726
|
-
variant = "outline",
|
|
727
|
-
size = "icon",
|
|
728
|
-
...props
|
|
729
|
-
}) {
|
|
730
|
-
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
|
731
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
732
|
-
Pressable,
|
|
733
|
-
{
|
|
734
|
-
"data-slot": "carousel-previous",
|
|
735
|
-
variant,
|
|
736
|
-
size,
|
|
737
|
-
className: cn(
|
|
738
|
-
"absolute size-8 rounded-full",
|
|
739
|
-
orientation === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
740
|
-
className
|
|
741
|
-
),
|
|
742
|
-
disabled: !canScrollPrev,
|
|
743
|
-
onClick: scrollPrev,
|
|
744
|
-
asButton: true,
|
|
745
|
-
...props,
|
|
746
|
-
children: [
|
|
747
|
-
/* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/arrow-left" }),
|
|
748
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Previous slide" })
|
|
749
|
-
]
|
|
750
|
-
}
|
|
751
|
-
);
|
|
752
|
-
}
|
|
753
|
-
function CarouselNext({
|
|
754
|
-
className,
|
|
755
|
-
variant = "outline",
|
|
756
|
-
size = "icon",
|
|
757
|
-
...props
|
|
758
|
-
}) {
|
|
759
|
-
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
|
760
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
761
|
-
Pressable,
|
|
762
|
-
{
|
|
763
|
-
"data-slot": "carousel-next",
|
|
764
|
-
variant,
|
|
765
|
-
size,
|
|
766
|
-
className: cn(
|
|
767
|
-
"absolute size-8 rounded-full",
|
|
768
|
-
orientation === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
769
|
-
className
|
|
770
|
-
),
|
|
771
|
-
disabled: !canScrollNext,
|
|
772
|
-
onClick: scrollNext,
|
|
773
|
-
asButton: true,
|
|
774
|
-
...props,
|
|
775
|
-
children: [
|
|
776
|
-
/* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/arrow-right" }),
|
|
777
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Next slide" })
|
|
778
|
-
]
|
|
779
|
-
}
|
|
780
|
-
);
|
|
622
|
+
),
|
|
623
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
624
|
+
Pressable,
|
|
625
|
+
{
|
|
626
|
+
onClick: onNext,
|
|
627
|
+
disabled: !canScrollNext,
|
|
628
|
+
"aria-label": nextAriaLabel,
|
|
629
|
+
asButton: true,
|
|
630
|
+
className: cn(
|
|
631
|
+
"relative z-40 flex h-10 w-10 items-center justify-center rounded-full disabled:opacity-50",
|
|
632
|
+
buttonClassName
|
|
633
|
+
),
|
|
634
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: nextIcon, size: iconSize })
|
|
635
|
+
}
|
|
636
|
+
)
|
|
637
|
+
] });
|
|
781
638
|
}
|
|
782
639
|
var maxWidthStyles = {
|
|
783
640
|
sm: "max-w-screen-sm",
|
|
@@ -788,7 +645,7 @@ var maxWidthStyles = {
|
|
|
788
645
|
"4xl": "max-w-[1536px]",
|
|
789
646
|
full: "max-w-full"
|
|
790
647
|
};
|
|
791
|
-
var Container =
|
|
648
|
+
var Container = React6__namespace.default.forwardRef(
|
|
792
649
|
({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
|
|
793
650
|
const Component = as;
|
|
794
651
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1093,7 +950,7 @@ var spacingStyles = {
|
|
|
1093
950
|
};
|
|
1094
951
|
var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
|
|
1095
952
|
var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
|
|
1096
|
-
var Section =
|
|
953
|
+
var Section = React6__namespace.default.forwardRef(
|
|
1097
954
|
({
|
|
1098
955
|
id,
|
|
1099
956
|
title,
|
|
@@ -1181,27 +1038,62 @@ function CarouselFeatureBadge({
|
|
|
1181
1038
|
slideLayoutVariant = "square",
|
|
1182
1039
|
containerMaxWidth = "2xl"
|
|
1183
1040
|
}) {
|
|
1041
|
+
const [emblaRef, emblaApi] = useEmblaCarousel__default.default();
|
|
1042
|
+
const [canScrollPrev, setCanScrollPrev] = React6__namespace.useState(false);
|
|
1043
|
+
const [canScrollNext, setCanScrollNext] = React6__namespace.useState(false);
|
|
1044
|
+
const scrollPrev = React6__namespace.useCallback(() => {
|
|
1045
|
+
emblaApi?.scrollPrev();
|
|
1046
|
+
}, [emblaApi]);
|
|
1047
|
+
const scrollNext = React6__namespace.useCallback(() => {
|
|
1048
|
+
emblaApi?.scrollNext();
|
|
1049
|
+
}, [emblaApi]);
|
|
1050
|
+
const onSelect = React6__namespace.useCallback(() => {
|
|
1051
|
+
if (!emblaApi) return;
|
|
1052
|
+
setCanScrollPrev(emblaApi.canScrollPrev());
|
|
1053
|
+
setCanScrollNext(emblaApi.canScrollNext());
|
|
1054
|
+
}, [emblaApi]);
|
|
1055
|
+
React6__namespace.useEffect(() => {
|
|
1056
|
+
if (!emblaApi) return;
|
|
1057
|
+
onSelect();
|
|
1058
|
+
emblaApi.on("reInit", onSelect);
|
|
1059
|
+
emblaApi.on("select", onSelect);
|
|
1060
|
+
return () => {
|
|
1061
|
+
emblaApi?.off("select", onSelect);
|
|
1062
|
+
};
|
|
1063
|
+
}, [emblaApi, onSelect]);
|
|
1184
1064
|
const renderCarouselItems = () => {
|
|
1185
1065
|
if (itemsSlot) return itemsSlot;
|
|
1186
1066
|
if (!items || items.length === 0) return null;
|
|
1187
|
-
return items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1067
|
+
return items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1188
1068
|
"div",
|
|
1189
1069
|
{
|
|
1070
|
+
role: "group",
|
|
1071
|
+
"aria-roledescription": "slide",
|
|
1190
1072
|
className: cn(
|
|
1191
|
-
"
|
|
1192
|
-
|
|
1073
|
+
"min-w-0 shrink-0 grow-0 basis-full pl-4",
|
|
1074
|
+
carouselItemClassName
|
|
1193
1075
|
),
|
|
1194
1076
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1195
|
-
|
|
1077
|
+
"div",
|
|
1196
1078
|
{
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1079
|
+
className: cn(
|
|
1080
|
+
"flex items-center justify-center overflow-hidden rounded-2xl",
|
|
1081
|
+
SLIDE_LAYOUT_ASPECT_MAP[slideLayoutVariant]
|
|
1082
|
+
),
|
|
1083
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1084
|
+
img.Img,
|
|
1085
|
+
{
|
|
1086
|
+
src: item.src,
|
|
1087
|
+
alt: item.alt,
|
|
1088
|
+
className: cn("h-full w-full object-cover", item.className),
|
|
1089
|
+
optixFlowConfig
|
|
1090
|
+
}
|
|
1091
|
+
)
|
|
1201
1092
|
}
|
|
1202
1093
|
)
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1094
|
+
},
|
|
1095
|
+
index
|
|
1096
|
+
));
|
|
1205
1097
|
};
|
|
1206
1098
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1207
1099
|
Section,
|
|
@@ -1244,10 +1136,18 @@ function CarouselFeatureBadge({
|
|
|
1244
1136
|
]
|
|
1245
1137
|
}
|
|
1246
1138
|
),
|
|
1247
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full max-w-full
|
|
1248
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1249
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1250
|
-
|
|
1139
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full max-w-full", carouselClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1140
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: emblaRef, className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex -ml-4", children: renderCarouselItems() }) }),
|
|
1141
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1142
|
+
CarouselPagination,
|
|
1143
|
+
{
|
|
1144
|
+
onPrevious: scrollPrev,
|
|
1145
|
+
onNext: scrollNext,
|
|
1146
|
+
canScrollPrevious: canScrollPrev,
|
|
1147
|
+
canScrollNext,
|
|
1148
|
+
className: "mt-4"
|
|
1149
|
+
}
|
|
1150
|
+
)
|
|
1251
1151
|
] }) })
|
|
1252
1152
|
] }) })
|
|
1253
1153
|
}
|