@cossistant/react 0.0.26 → 0.0.28
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/api.d.ts +1 -1
- package/api.d.ts.map +1 -1
- package/checks.d.ts +1 -1
- package/checks.d.ts.map +1 -1
- package/clsx.d.ts +1 -1
- package/clsx.d.ts.map +1 -1
- package/coerce.d.ts +1 -1
- package/coerce.d.ts.map +1 -1
- package/conversation.d.ts +3 -0
- package/conversation.d.ts.map +1 -1
- package/core.d.ts +1 -1
- package/core.d.ts.map +1 -1
- package/errors.d.ts +1 -1
- package/errors.d.ts.map +1 -1
- package/errors2.d.ts +1 -1
- package/errors2.d.ts.map +1 -1
- package/hooks/index.d.ts +2 -1
- package/hooks/index.js +6 -5
- package/hooks/private/store/use-website-store.js +2 -1
- package/hooks/private/store/use-website-store.js.map +1 -1
- package/hooks/private/use-client-query.d.ts +6 -0
- package/hooks/private/use-client-query.d.ts.map +1 -1
- package/hooks/private/use-client-query.js +26 -3
- package/hooks/private/use-client-query.js.map +1 -1
- package/hooks/private/use-multimodal-input.d.ts.map +1 -1
- package/hooks/private/use-multimodal-input.js +7 -5
- package/hooks/private/use-multimodal-input.js.map +1 -1
- package/hooks/private/use-visitor-typing-reporter.d.ts +18 -1
- package/hooks/private/use-visitor-typing-reporter.d.ts.map +1 -1
- package/hooks/private/use-visitor-typing-reporter.js +34 -4
- package/hooks/private/use-visitor-typing-reporter.js.map +1 -1
- package/hooks/use-conversation-page.d.ts +1 -0
- package/hooks/use-conversation-page.d.ts.map +1 -1
- package/hooks/use-conversation-page.js +6 -1
- package/hooks/use-conversation-page.js.map +1 -1
- package/hooks/use-conversation-preview.d.ts +2 -1
- package/hooks/use-conversation-preview.d.ts.map +1 -1
- package/hooks/use-conversation-preview.js +1 -1
- package/hooks/use-conversation-preview.js.map +1 -1
- package/hooks/use-conversation-timeline-items.js +2 -1
- package/hooks/use-conversation-timeline-items.js.map +1 -1
- package/hooks/use-conversation.js +2 -1
- package/hooks/use-conversation.js.map +1 -1
- package/hooks/use-conversations.js +1 -0
- package/hooks/use-conversations.js.map +1 -1
- package/hooks/use-create-conversation.d.ts.map +1 -1
- package/hooks/use-file-upload.d.ts +55 -0
- package/hooks/use-file-upload.d.ts.map +1 -0
- package/hooks/use-file-upload.js +100 -0
- package/hooks/use-file-upload.js.map +1 -0
- package/hooks/use-message-composer.d.ts +11 -0
- package/hooks/use-message-composer.d.ts.map +1 -1
- package/hooks/use-message-composer.js +7 -3
- package/hooks/use-message-composer.js.map +1 -1
- package/hooks/use-send-message.d.ts +1 -0
- package/hooks/use-send-message.d.ts.map +1 -1
- package/hooks/use-send-message.js +63 -11
- package/hooks/use-send-message.js.map +1 -1
- package/index.d.ts +6 -3
- package/index.js +13 -10
- package/openapi30.d.ts +1 -1
- package/openapi30.d.ts.map +1 -1
- package/openapi31.d.ts +1 -1
- package/openapi31.d.ts.map +1 -1
- package/package.json +4 -3
- package/parse.d.ts +1 -1
- package/parse.d.ts.map +1 -1
- package/primitives/avatar/image.d.ts +1 -1
- package/primitives/conversation-timeline.d.ts.map +1 -1
- package/primitives/conversation-timeline.js +10 -5
- package/primitives/conversation-timeline.js.map +1 -1
- package/primitives/index.d.ts +4 -3
- package/primitives/index.js +12 -5
- package/primitives/index.parts.d.ts +3 -2
- package/primitives/index.parts.js +4 -3
- package/primitives/multimodal-input.d.ts +2 -2
- package/primitives/multimodal-input.d.ts.map +1 -1
- package/primitives/timeline-item-attachments.d.ts +100 -0
- package/primitives/timeline-item-attachments.d.ts.map +1 -0
- package/primitives/timeline-item-attachments.js +151 -0
- package/primitives/timeline-item-attachments.js.map +1 -0
- package/primitives/trigger.d.ts +91 -0
- package/primitives/trigger.d.ts.map +1 -0
- package/primitives/trigger.js +74 -0
- package/primitives/trigger.js.map +1 -0
- package/primitives/window.d.ts +22 -1
- package/primitives/window.d.ts.map +1 -1
- package/primitives/window.js +91 -5
- package/primitives/window.js.map +1 -1
- package/provider.d.ts.map +1 -1
- package/provider.js +8 -3
- package/provider.js.map +1 -1
- package/realtime/index.js +1 -1
- package/realtime/provider.js +1 -1
- package/realtime/support-provider.js +1 -1
- package/realtime/support-provider.js.map +1 -1
- package/realtime-events.d.ts +40 -1
- package/realtime-events.d.ts.map +1 -1
- package/registries.d.ts +1 -1
- package/registries.d.ts.map +1 -1
- package/schemas.d.ts +1 -1
- package/schemas.d.ts.map +1 -1
- package/schemas2.d.ts +1 -1
- package/schemas2.d.ts.map +1 -1
- package/schemas3.d.ts +1 -0
- package/schemas3.d.ts.map +1 -1
- package/specification-extension.d.ts +1 -1
- package/specification-extension.d.ts.map +1 -1
- package/standard-schema.d.ts +1 -1
- package/standard-schema.d.ts.map +1 -1
- package/support/components/content.d.ts +30 -0
- package/support/components/content.d.ts.map +1 -0
- package/support/components/content.js +282 -0
- package/support/components/content.js.map +1 -0
- package/support/components/conversation-button-link.js +1 -1
- package/support/components/conversation-timeline.js +3 -3
- package/support/components/conversation-timeline.js.map +1 -1
- package/support/components/header.js +1 -1
- package/support/components/image-lightbox.d.ts +49 -0
- package/support/components/image-lightbox.d.ts.map +1 -0
- package/support/components/image-lightbox.js +142 -0
- package/support/components/image-lightbox.js.map +1 -0
- package/support/components/index.d.ts +5 -4
- package/support/components/index.js +4 -4
- package/support/components/multimodal-input.d.ts +4 -1
- package/support/components/multimodal-input.d.ts.map +1 -1
- package/support/components/multimodal-input.js +71 -45
- package/support/components/multimodal-input.js.map +1 -1
- package/support/components/navigation-tab.js +1 -1
- package/support/components/root.d.ts +23 -0
- package/support/components/root.d.ts.map +1 -0
- package/support/components/root.js +36 -0
- package/support/components/root.js.map +1 -0
- package/support/components/timeline-message-item.d.ts.map +1 -1
- package/support/components/timeline-message-item.js +82 -18
- package/support/components/timeline-message-item.js.map +1 -1
- package/support/components/trigger.d.ts +14 -0
- package/support/components/trigger.d.ts.map +1 -0
- package/support/components/{bubble.js → trigger.js} +16 -12
- package/support/components/trigger.js.map +1 -0
- package/support/components/typing-indicator.d.ts.map +1 -1
- package/support/components/typing-indicator.js +1 -0
- package/support/components/typing-indicator.js.map +1 -1
- package/support/context/controlled-state.d.ts +46 -0
- package/support/context/controlled-state.d.ts.map +1 -0
- package/support/context/controlled-state.js +34 -0
- package/support/context/controlled-state.js.map +1 -0
- package/support/context/events.d.ts +103 -0
- package/support/context/events.d.ts.map +1 -0
- package/support/context/events.js +139 -0
- package/support/context/events.js.map +1 -0
- package/support/context/handle.d.ts +90 -0
- package/support/context/handle.d.ts.map +1 -0
- package/support/context/handle.js +79 -0
- package/support/context/handle.js.map +1 -0
- package/support/context/positioning.d.ts +17 -0
- package/support/context/positioning.d.ts.map +1 -0
- package/support/context/positioning.js +26 -0
- package/support/context/positioning.js.map +1 -0
- package/support/context/slots.d.ts +85 -0
- package/support/context/slots.d.ts.map +1 -0
- package/support/context/slots.js +115 -0
- package/support/context/slots.js.map +1 -0
- package/support/context/websocket.d.ts +8 -1
- package/support/context/websocket.d.ts.map +1 -1
- package/support/context/websocket.js +8 -1
- package/support/context/websocket.js.map +1 -1
- package/support/index.d.ts +239 -54
- package/support/index.d.ts.map +1 -1
- package/support/index.js +254 -33
- package/support/index.js.map +1 -1
- package/support/pages/articles.d.ts.map +1 -1
- package/support/pages/articles.js +3 -4
- package/support/pages/articles.js.map +1 -1
- package/support/pages/conversation-history.js +2 -2
- package/support/pages/conversation.js +6 -5
- package/support/pages/conversation.js.map +1 -1
- package/support/pages/home.js +2 -2
- package/support/router.d.ts +52 -12
- package/support/router.d.ts.map +1 -1
- package/support/router.js +78 -30
- package/support/router.js.map +1 -1
- package/support/store/index.d.ts +2 -2
- package/support/store/support-store.d.ts +26 -20
- package/support/store/support-store.d.ts.map +1 -1
- package/support/store/support-store.js +47 -6
- package/support/store/support-store.js.map +1 -1
- package/support/{support-D2EgfIts.css → support-C7Xaw-N6.css} +1 -2
- package/support/support-C7Xaw-N6.css.map +1 -0
- package/support/text/index.js.map +1 -1
- package/support/types.d.ts +75 -12
- package/support/types.d.ts.map +1 -1
- package/support.css +2 -2
- package/tailwind.css +0 -1
- package/timeline-item.d.ts +68 -2
- package/timeline-item.d.ts.map +1 -1
- package/util.d.ts +1 -1
- package/util.d.ts.map +1 -1
- package/utils/index.d.ts +2 -1
- package/utils/index.js +2 -1
- package/utils/merge-refs.d.ts +30 -0
- package/utils/merge-refs.d.ts.map +1 -0
- package/utils/merge-refs.js +46 -0
- package/utils/merge-refs.js.map +1 -0
- package/utils/use-render-element.d.ts.map +1 -1
- package/utils/use-render-element.js +20 -7
- package/utils/use-render-element.js.map +1 -1
- package/versions.d.ts +1 -1
- package/versions.d.ts.map +1 -1
- package/zod-extensions.d.ts +1 -1
- package/zod-extensions.d.ts.map +1 -1
- package/primitives/bubble.d.ts +0 -38
- package/primitives/bubble.d.ts.map +0 -1
- package/primitives/bubble.js +0 -57
- package/primitives/bubble.js.map +0 -1
- package/support/components/bubble.d.ts +0 -10
- package/support/components/bubble.d.ts.map +0 -1
- package/support/components/bubble.js.map +0 -1
- package/support/components/container.d.ts +0 -13
- package/support/components/container.d.ts.map +0 -1
- package/support/components/container.js +0 -109
- package/support/components/container.js.map +0 -1
- package/support/components/support-content.d.ts +0 -22
- package/support/components/support-content.d.ts.map +0 -1
- package/support/components/support-content.js +0 -48
- package/support/components/support-content.js.map +0 -1
- package/support/support-D2EgfIts.css.map +0 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/support/context/slots.d.ts
|
|
4
|
+
type SlotContextValue = {
|
|
5
|
+
/**
|
|
6
|
+
* Custom header slot content
|
|
7
|
+
*/
|
|
8
|
+
header: React$1.ReactNode | null;
|
|
9
|
+
/**
|
|
10
|
+
* Custom footer slot content
|
|
11
|
+
*/
|
|
12
|
+
footer: React$1.ReactNode | null;
|
|
13
|
+
/**
|
|
14
|
+
* Whether to use the custom header
|
|
15
|
+
*/
|
|
16
|
+
hasCustomHeader: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to use the custom footer
|
|
19
|
+
*/
|
|
20
|
+
hasCustomFooter: boolean;
|
|
21
|
+
};
|
|
22
|
+
type SlotProviderProps = {
|
|
23
|
+
children: React$1.ReactNode;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Provider for slot-based customization.
|
|
27
|
+
* Allows children to register custom header/footer content.
|
|
28
|
+
*/
|
|
29
|
+
declare const SlotProvider: React$1.FC<SlotProviderProps>;
|
|
30
|
+
/**
|
|
31
|
+
* Access slot values (for content component)
|
|
32
|
+
*/
|
|
33
|
+
declare function useSlots(): SlotContextValue;
|
|
34
|
+
type SlotProps = {
|
|
35
|
+
/**
|
|
36
|
+
* Content to render in the slot.
|
|
37
|
+
*/
|
|
38
|
+
children: React$1.ReactNode;
|
|
39
|
+
/**
|
|
40
|
+
* When true, renders children directly without a wrapper.
|
|
41
|
+
* Useful when you want your component to receive all props.
|
|
42
|
+
*/
|
|
43
|
+
asChild?: boolean;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Header slot component.
|
|
47
|
+
* Use inside Support.Content to replace the default header.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* <Support.Content>
|
|
51
|
+
* <Support.Header>
|
|
52
|
+
* <MyCustomHeader />
|
|
53
|
+
* </Support.Header>
|
|
54
|
+
* <Support.Router />
|
|
55
|
+
* </Support.Content>
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* // With asChild pattern
|
|
59
|
+
* <Support.Header asChild>
|
|
60
|
+
* <MyCustomHeader showBackButton />
|
|
61
|
+
* </Support.Header>
|
|
62
|
+
*/
|
|
63
|
+
declare const HeaderSlot: React$1.FC<SlotProps>;
|
|
64
|
+
/**
|
|
65
|
+
* Footer slot component.
|
|
66
|
+
* Use inside Support.Content to replace the default footer.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* <Support.Content>
|
|
70
|
+
* <Support.Router />
|
|
71
|
+
* <Support.Footer>
|
|
72
|
+
* <MyCustomFooter />
|
|
73
|
+
* </Support.Footer>
|
|
74
|
+
* </Support.Content>
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* // With asChild pattern
|
|
78
|
+
* <Support.Footer asChild>
|
|
79
|
+
* <MyCustomFooter showBranding={false} />
|
|
80
|
+
* </Support.Footer>
|
|
81
|
+
*/
|
|
82
|
+
declare const FooterSlot: React$1.FC<SlotProps>;
|
|
83
|
+
//#endregion
|
|
84
|
+
export { FooterSlot, HeaderSlot, SlotContextValue, SlotProps, SlotProvider, SlotProviderProps, useSlots };
|
|
85
|
+
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.d.ts","names":[],"sources":["../../../src/support/context/slots.tsx"],"sourcesContent":[],"mappings":";;;KAQY,gBAAA;;AAAZ;AAyCA;EAQa,MAAA,EA7CJ,OAAA,CAAM,SA0Ed,GAAA,IA7BmC;EAsCpB;AAehB;AA8BA;EAoCa,MAAA,EAhKJ,OAAA,CAAM,SA6Kd,GAbiC,IAAA;;;;;;;;;;KA/HtB,iBAAA;YACD,OAAA,CAAM;;;;;;cAOJ,cAAc,OAAA,CAAM,GAAG;;;;iBAsCpB,QAAA,CAAA,GAAY;KAehB,SAAA;;;;YAID,OAAA,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;cA0BJ,YAAY,OAAA,CAAM,GAAG;;;;;;;;;;;;;;;;;;;cAoCrB,YAAY,OAAA,CAAM,GAAG"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import * as React$1 from "react";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/support/context/slots.tsx
|
|
8
|
+
const SlotContext = React$1.createContext({
|
|
9
|
+
header: null,
|
|
10
|
+
footer: null,
|
|
11
|
+
hasCustomHeader: false,
|
|
12
|
+
hasCustomFooter: false
|
|
13
|
+
});
|
|
14
|
+
const SlotRegistrationContext = React$1.createContext(null);
|
|
15
|
+
/**
|
|
16
|
+
* Provider for slot-based customization.
|
|
17
|
+
* Allows children to register custom header/footer content.
|
|
18
|
+
*/
|
|
19
|
+
const SlotProvider = ({ children }) => {
|
|
20
|
+
const [header, setHeader] = React$1.useState(null);
|
|
21
|
+
const [footer, setFooter] = React$1.useState(null);
|
|
22
|
+
const registration = React$1.useMemo(() => ({
|
|
23
|
+
registerHeader: (content) => setHeader(content),
|
|
24
|
+
registerFooter: (content) => setFooter(content),
|
|
25
|
+
unregisterHeader: () => setHeader(null),
|
|
26
|
+
unregisterFooter: () => setFooter(null)
|
|
27
|
+
}), []);
|
|
28
|
+
const value = React$1.useMemo(() => ({
|
|
29
|
+
header,
|
|
30
|
+
footer,
|
|
31
|
+
hasCustomHeader: header !== null,
|
|
32
|
+
hasCustomFooter: footer !== null
|
|
33
|
+
}), [header, footer]);
|
|
34
|
+
return /* @__PURE__ */ jsx(SlotRegistrationContext.Provider, {
|
|
35
|
+
value: registration,
|
|
36
|
+
children: /* @__PURE__ */ jsx(SlotContext.Provider, {
|
|
37
|
+
value,
|
|
38
|
+
children
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Access slot values (for content component)
|
|
44
|
+
*/
|
|
45
|
+
function useSlots() {
|
|
46
|
+
return React$1.useContext(SlotContext);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Access slot registration (for slot components)
|
|
50
|
+
*/
|
|
51
|
+
function useSlotRegistration() {
|
|
52
|
+
return React$1.useContext(SlotRegistrationContext);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Header slot component.
|
|
56
|
+
* Use inside Support.Content to replace the default header.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* <Support.Content>
|
|
60
|
+
* <Support.Header>
|
|
61
|
+
* <MyCustomHeader />
|
|
62
|
+
* </Support.Header>
|
|
63
|
+
* <Support.Router />
|
|
64
|
+
* </Support.Content>
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* // With asChild pattern
|
|
68
|
+
* <Support.Header asChild>
|
|
69
|
+
* <MyCustomHeader showBackButton />
|
|
70
|
+
* </Support.Header>
|
|
71
|
+
*/
|
|
72
|
+
const HeaderSlot = ({ children, asChild }) => {
|
|
73
|
+
const registration = useSlotRegistration();
|
|
74
|
+
React$1.useEffect(() => {
|
|
75
|
+
if (registration) {
|
|
76
|
+
registration.registerHeader(children);
|
|
77
|
+
return () => registration.unregisterHeader();
|
|
78
|
+
}
|
|
79
|
+
}, [registration, children]);
|
|
80
|
+
return null;
|
|
81
|
+
};
|
|
82
|
+
HeaderSlot.displayName = "Support.Header";
|
|
83
|
+
/**
|
|
84
|
+
* Footer slot component.
|
|
85
|
+
* Use inside Support.Content to replace the default footer.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* <Support.Content>
|
|
89
|
+
* <Support.Router />
|
|
90
|
+
* <Support.Footer>
|
|
91
|
+
* <MyCustomFooter />
|
|
92
|
+
* </Support.Footer>
|
|
93
|
+
* </Support.Content>
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* // With asChild pattern
|
|
97
|
+
* <Support.Footer asChild>
|
|
98
|
+
* <MyCustomFooter showBranding={false} />
|
|
99
|
+
* </Support.Footer>
|
|
100
|
+
*/
|
|
101
|
+
const FooterSlot = ({ children, asChild }) => {
|
|
102
|
+
const registration = useSlotRegistration();
|
|
103
|
+
React$1.useEffect(() => {
|
|
104
|
+
if (registration) {
|
|
105
|
+
registration.registerFooter(children);
|
|
106
|
+
return () => registration.unregisterFooter();
|
|
107
|
+
}
|
|
108
|
+
}, [registration, children]);
|
|
109
|
+
return null;
|
|
110
|
+
};
|
|
111
|
+
FooterSlot.displayName = "Support.Footer";
|
|
112
|
+
|
|
113
|
+
//#endregion
|
|
114
|
+
export { FooterSlot, HeaderSlot, SlotProvider, useSlots };
|
|
115
|
+
//# sourceMappingURL=slots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.js","names":["React","SlotProvider: React.FC<SlotProviderProps>","HeaderSlot: React.FC<SlotProps>","FooterSlot: React.FC<SlotProps>"],"sources":["../../../src/support/context/slots.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\n// =============================================================================\n// Slot Types\n// =============================================================================\n\nexport type SlotContextValue = {\n\t/**\n\t * Custom header slot content\n\t */\n\theader: React.ReactNode | null;\n\t/**\n\t * Custom footer slot content\n\t */\n\tfooter: React.ReactNode | null;\n\t/**\n\t * Whether to use the custom header\n\t */\n\thasCustomHeader: boolean;\n\t/**\n\t * Whether to use the custom footer\n\t */\n\thasCustomFooter: boolean;\n};\n\ntype SlotRegistration = {\n\tregisterHeader: (content: React.ReactNode) => void;\n\tregisterFooter: (content: React.ReactNode) => void;\n\tunregisterHeader: () => void;\n\tunregisterFooter: () => void;\n};\n\nconst SlotContext = React.createContext<SlotContextValue>({\n\theader: null,\n\tfooter: null,\n\thasCustomHeader: false,\n\thasCustomFooter: false,\n});\n\nconst SlotRegistrationContext = React.createContext<SlotRegistration | null>(\n\tnull\n);\n\n// =============================================================================\n// Provider\n// =============================================================================\n\nexport type SlotProviderProps = {\n\tchildren: React.ReactNode;\n};\n\n/**\n * Provider for slot-based customization.\n * Allows children to register custom header/footer content.\n */\nexport const SlotProvider: React.FC<SlotProviderProps> = ({ children }) => {\n\tconst [header, setHeader] = React.useState<React.ReactNode | null>(null);\n\tconst [footer, setFooter] = React.useState<React.ReactNode | null>(null);\n\n\tconst registration = React.useMemo<SlotRegistration>(\n\t\t() => ({\n\t\t\tregisterHeader: (content) => setHeader(content),\n\t\t\tregisterFooter: (content) => setFooter(content),\n\t\t\tunregisterHeader: () => setHeader(null),\n\t\t\tunregisterFooter: () => setFooter(null),\n\t\t}),\n\t\t[]\n\t);\n\n\tconst value = React.useMemo<SlotContextValue>(\n\t\t() => ({\n\t\t\theader,\n\t\t\tfooter,\n\t\t\thasCustomHeader: header !== null,\n\t\t\thasCustomFooter: footer !== null,\n\t\t}),\n\t\t[header, footer]\n\t);\n\n\treturn (\n\t\t<SlotRegistrationContext.Provider value={registration}>\n\t\t\t<SlotContext.Provider value={value}>{children}</SlotContext.Provider>\n\t\t</SlotRegistrationContext.Provider>\n\t);\n};\n\n// =============================================================================\n// Hooks\n// =============================================================================\n\n/**\n * Access slot values (for content component)\n */\nexport function useSlots(): SlotContextValue {\n\treturn React.useContext(SlotContext);\n}\n\n/**\n * Access slot registration (for slot components)\n */\nfunction useSlotRegistration(): SlotRegistration | null {\n\treturn React.useContext(SlotRegistrationContext);\n}\n\n// =============================================================================\n// Slot Components\n// =============================================================================\n\nexport type SlotProps = {\n\t/**\n\t * Content to render in the slot.\n\t */\n\tchildren: React.ReactNode;\n\t/**\n\t * When true, renders children directly without a wrapper.\n\t * Useful when you want your component to receive all props.\n\t */\n\tasChild?: boolean;\n};\n\n/**\n * Header slot component.\n * Use inside Support.Content to replace the default header.\n *\n * @example\n * <Support.Content>\n * <Support.Header>\n * <MyCustomHeader />\n * </Support.Header>\n * <Support.Router />\n * </Support.Content>\n *\n * @example\n * // With asChild pattern\n * <Support.Header asChild>\n * <MyCustomHeader showBackButton />\n * </Support.Header>\n */\nexport const HeaderSlot: React.FC<SlotProps> = ({ children, asChild }) => {\n\tconst registration = useSlotRegistration();\n\n\tReact.useEffect(() => {\n\t\tif (registration) {\n\t\t\tregistration.registerHeader(children);\n\t\t\treturn () => registration.unregisterHeader();\n\t\t}\n\t}, [registration, children]);\n\n\t// This component doesn't render anything directly\n\t// It registers its children as the header slot\n\treturn null;\n};\n\n(HeaderSlot as React.FC & { displayName?: string }).displayName =\n\t\"Support.Header\";\n\n/**\n * Footer slot component.\n * Use inside Support.Content to replace the default footer.\n *\n * @example\n * <Support.Content>\n * <Support.Router />\n * <Support.Footer>\n * <MyCustomFooter />\n * </Support.Footer>\n * </Support.Content>\n *\n * @example\n * // With asChild pattern\n * <Support.Footer asChild>\n * <MyCustomFooter showBranding={false} />\n * </Support.Footer>\n */\nexport const FooterSlot: React.FC<SlotProps> = ({ children, asChild }) => {\n\tconst registration = useSlotRegistration();\n\n\tReact.useEffect(() => {\n\t\tif (registration) {\n\t\t\tregistration.registerFooter(children);\n\t\t\treturn () => registration.unregisterFooter();\n\t\t}\n\t}, [registration, children]);\n\n\t// This component doesn't render anything directly\n\t// It registers its children as the footer slot\n\treturn null;\n};\n\n(FooterSlot as React.FC & { displayName?: string }).displayName =\n\t\"Support.Footer\";\n"],"mappings":";;;;;;;AAkCA,MAAM,cAAcA,QAAM,cAAgC;CACzD,QAAQ;CACR,QAAQ;CACR,iBAAiB;CACjB,iBAAiB;CACjB,CAAC;AAEF,MAAM,0BAA0BA,QAAM,cACrC,KACA;;;;;AAcD,MAAaC,gBAA6C,EAAE,eAAe;CAC1E,MAAM,CAAC,QAAQ,aAAaD,QAAM,SAAiC,KAAK;CACxE,MAAM,CAAC,QAAQ,aAAaA,QAAM,SAAiC,KAAK;CAExE,MAAM,eAAeA,QAAM,eACnB;EACN,iBAAiB,YAAY,UAAU,QAAQ;EAC/C,iBAAiB,YAAY,UAAU,QAAQ;EAC/C,wBAAwB,UAAU,KAAK;EACvC,wBAAwB,UAAU,KAAK;EACvC,GACD,EAAE,CACF;CAED,MAAM,QAAQA,QAAM,eACZ;EACN;EACA;EACA,iBAAiB,WAAW;EAC5B,iBAAiB,WAAW;EAC5B,GACD,CAAC,QAAQ,OAAO,CAChB;AAED,QACC,oBAAC,wBAAwB;EAAS,OAAO;YACxC,oBAAC,YAAY;GAAgB;GAAQ;IAAgC;GACnC;;;;;AAWrC,SAAgB,WAA6B;AAC5C,QAAOA,QAAM,WAAW,YAAY;;;;;AAMrC,SAAS,sBAA+C;AACvD,QAAOA,QAAM,WAAW,wBAAwB;;;;;;;;;;;;;;;;;;;;AAqCjD,MAAaE,cAAmC,EAAE,UAAU,cAAc;CACzE,MAAM,eAAe,qBAAqB;AAE1C,SAAM,gBAAgB;AACrB,MAAI,cAAc;AACjB,gBAAa,eAAe,SAAS;AACrC,gBAAa,aAAa,kBAAkB;;IAE3C,CAAC,cAAc,SAAS,CAAC;AAI5B,QAAO;;AAGR,AAAC,WAAmD,cACnD;;;;;;;;;;;;;;;;;;;AAoBD,MAAaC,cAAmC,EAAE,UAAU,cAAc;CACzE,MAAM,eAAe,qBAAqB;AAE1C,SAAM,gBAAgB;AACrB,MAAI,cAAc;AACjB,gBAAa,eAAe,SAAS;AACrC,gBAAa,aAAa,kBAAkB;;IAE3C,CAAC,cAAc,SAAS,CAAC;AAI5B,QAAO;;AAGR,AAAC,WAAmD,cACnD"}
|
|
@@ -23,8 +23,15 @@ type WebSocketProviderProps = {
|
|
|
23
23
|
declare const WebSocketProvider: React.FC<WebSocketProviderProps>;
|
|
24
24
|
/**
|
|
25
25
|
* Accessor for the support websocket context.
|
|
26
|
+
* Throws if used outside WebSocketProvider.
|
|
26
27
|
*/
|
|
27
28
|
declare const useWebSocket: () => WebSocketContextValue;
|
|
29
|
+
/**
|
|
30
|
+
* Safe accessor for the support websocket context.
|
|
31
|
+
* Returns null if used outside WebSocketProvider instead of throwing.
|
|
32
|
+
* Useful for optional WebSocket usage in hooks that may or may not have the provider.
|
|
33
|
+
*/
|
|
34
|
+
declare const useWebSocketSafe: () => WebSocketContextValue | null;
|
|
28
35
|
//#endregion
|
|
29
|
-
export { type RealtimeEvent, type WebSocketContextValue, WebSocketProvider, type WebSocketProviderProps, useWebSocket };
|
|
36
|
+
export { type RealtimeEvent, type WebSocketContextValue, WebSocketProvider, type WebSocketProviderProps, useWebSocket, useWebSocketSafe };
|
|
30
37
|
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":[],"mappings":";;;;;;KAYK,qBAAA,GAAwB;KAExB,sBAAA;YACM,KAAA,CAAM;;EAHZ,SAAA,CAAA,EAAA,MAAA;EAEA,SAAA,CAAA,EAAA,MAAA;EAsJQ,KAAA,CAAA,EAAA,MAAA;
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":[],"mappings":";;;;;;KAYK,qBAAA,GAAwB;KAExB,sBAAA;YACM,KAAA,CAAM;;EAHZ,SAAA,CAAA,EAAA,MAAA;EAEA,SAAA,CAAA,EAAA,MAAA;EAsJQ,KAAA,CAAA,EAAA,MAAA;EA+BA,WAAA,CAAA,EAAA,OAMZ;EAOY,SAAA,CAAA,EAAA,GAAA,GAAA,IACgB;;oBA1LV;;;;;;cA6IN,mBAAmB,KAAA,CAAM,GAAG;;;;;cA+B5B,oBAAmB;;;;;;cAanB,wBAAuB"}
|
|
@@ -107,13 +107,20 @@ const WebSocketProvider = ({ children, publicKey, websiteId, visitorId, wsUrl, a
|
|
|
107
107
|
};
|
|
108
108
|
/**
|
|
109
109
|
* Accessor for the support websocket context.
|
|
110
|
+
* Throws if used outside WebSocketProvider.
|
|
110
111
|
*/
|
|
111
112
|
const useWebSocket = () => {
|
|
112
113
|
const context = useContext(WebSocketContext);
|
|
113
114
|
if (!context) throw new Error("useWebSocket must be used within WebSocketProvider");
|
|
114
115
|
return context;
|
|
115
116
|
};
|
|
117
|
+
/**
|
|
118
|
+
* Safe accessor for the support websocket context.
|
|
119
|
+
* Returns null if used outside WebSocketProvider instead of throwing.
|
|
120
|
+
* Useful for optional WebSocket usage in hooks that may or may not have the provider.
|
|
121
|
+
*/
|
|
122
|
+
const useWebSocketSafe = () => useContext(WebSocketContext);
|
|
116
123
|
|
|
117
124
|
//#endregion
|
|
118
|
-
export { WebSocketProvider, useWebSocket };
|
|
125
|
+
export { WebSocketProvider, useWebSocket, useWebSocketSafe };
|
|
119
126
|
//# sourceMappingURL=websocket.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\n/**\n * Support-specific realtime provider that authenticates visitors and keeps the\n * connection alive with presence pings.\n */\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\n/**\n * Accessor for the support websocket context.\n */\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;;;;;AAQ9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;AAGL,QACC,oBAAC;EACA,MAJW,wBAAwB;GAAE;GAAW;GAAW;GAAW,CAAC;EAK1D;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C
|
|
1
|
+
{"version":3,"file":"websocket.js","names":["WebSocketBridge: React.FC<WebSocketBridgeProps>","intervalId: number | null","WebSocketProvider: React.FC<WebSocketProviderProps>"],"sources":["../../../src/support/context/websocket.tsx"],"sourcesContent":["\"use client\";\n\nimport { PRESENCE_PING_INTERVAL_MS } from \"@cossistant/types\";\nimport type React from \"react\";\nimport { createContext, useContext, useEffect, useMemo } from \"react\";\nimport {\n\ttype RealtimeAuthConfig,\n\ttype RealtimeContextValue,\n\tRealtimeProvider,\n\tuseRealtimeConnection,\n} from \"../../realtime\";\n\ntype WebSocketContextValue = RealtimeContextValue;\n\ntype WebSocketProviderProps = {\n\tchildren: React.ReactNode;\n\tpublicKey?: string;\n\twebsiteId?: string;\n\tvisitorId?: string;\n\twsUrl?: string;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketContext = createContext<WebSocketContextValue | null>(null);\n\nfunction createVisitorAuthConfig({\n\tvisitorId,\n\twebsiteId,\n\tpublicKey,\n}: Pick<\n\tWebSocketProviderProps,\n\t\"visitorId\" | \"websiteId\" | \"publicKey\"\n>): RealtimeAuthConfig | null {\n\tconst normalizedVisitorId = visitorId?.trim();\n\tif (!normalizedVisitorId) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tkind: \"visitor\",\n\t\tvisitorId: normalizedVisitorId,\n\t\twebsiteId: websiteId?.trim() || null,\n\t\tpublicKey: publicKey?.trim() || null,\n\t} satisfies RealtimeAuthConfig;\n}\n\ntype WebSocketBridgeProps = {\n\tchildren: React.ReactNode;\n\tonError?: (error: Error) => void;\n};\n\nconst WebSocketBridge: React.FC<WebSocketBridgeProps> = ({\n\tchildren,\n\tonError,\n}) => {\n\tconst connection = useRealtimeConnection();\n\tconst { visitorId, sendRaw, isConnected } = connection;\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\" || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(visitorId && sendRaw)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pingMessage = \"presence:ping\";\n\n\t\tconst sendPresencePing = () => {\n\t\t\tif (!isConnected) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tsendRaw(pingMessage);\n\t\t\t} catch (error) {\n\t\t\t\tif (!onError) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalizedError =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\n\t\t\t\t\t\t\t\ttypeof error === \"string\"\n\t\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t\t: \"Unknown presence ping error\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (!normalizedError.message.includes(\"Failed to send presence ping\")) {\n\t\t\t\t\tnormalizedError.message = `Failed to send presence ping: ${normalizedError.message}`;\n\t\t\t\t}\n\n\t\t\t\tonError(normalizedError);\n\t\t\t}\n\t\t};\n\n\t\tlet intervalId: number | null = null;\n\n\t\tconst clearPresenceInterval = () => {\n\t\t\tif (intervalId !== null) {\n\t\t\t\twindow.clearInterval(intervalId);\n\t\t\t\tintervalId = null;\n\t\t\t}\n\t\t};\n\n\t\tconst startPresenceInterval = () => {\n\t\t\tclearPresenceInterval();\n\n\t\t\tif (!isConnected || document.visibilityState === \"hidden\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tintervalId = window.setInterval(\n\t\t\t\tsendPresencePing,\n\t\t\t\tPRESENCE_PING_INTERVAL_MS\n\t\t\t);\n\t\t};\n\n\t\tconst handleFocus = () => {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\tclearPresenceInterval();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t};\n\n\t\twindow.addEventListener(\"focus\", handleFocus);\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\tif (isConnected && document.visibilityState !== \"hidden\") {\n\t\t\tsendPresencePing();\n\t\t\tstartPresenceInterval();\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"focus\", handleFocus);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t\tclearPresenceInterval();\n\t\t};\n\t}, [isConnected, onError, sendRaw, visitorId]);\n\tconst value = useMemo(() => connection, [connection]);\n\treturn (\n\t\t<WebSocketContext.Provider value={value}>\n\t\t\t{children}\n\t\t</WebSocketContext.Provider>\n\t);\n};\n\n/**\n * Support-specific realtime provider that authenticates visitors and keeps the\n * connection alive with presence pings.\n */\nexport const WebSocketProvider: React.FC<WebSocketProviderProps> = ({\n\tchildren,\n\tpublicKey,\n\twebsiteId,\n\tvisitorId,\n\twsUrl,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}) => {\n\tconst auth = createVisitorAuthConfig({ publicKey, websiteId, visitorId });\n\n\treturn (\n\t\t<RealtimeProvider\n\t\t\tauth={auth}\n\t\t\tautoConnect={autoConnect}\n\t\t\tonConnect={onConnect}\n\t\t\tonDisconnect={onDisconnect}\n\t\t\tonError={onError}\n\t\t\twsUrl={wsUrl}\n\t\t>\n\t\t\t<WebSocketBridge onError={onError}>{children}</WebSocketBridge>\n\t\t</RealtimeProvider>\n\t);\n};\n\n/**\n * Accessor for the support websocket context.\n * Throws if used outside WebSocketProvider.\n */\nexport const useWebSocket = (): WebSocketContextValue => {\n\tconst context = useContext(WebSocketContext);\n\tif (!context) {\n\t\tthrow new Error(\"useWebSocket must be used within WebSocketProvider\");\n\t}\n\treturn context;\n};\n\n/**\n * Safe accessor for the support websocket context.\n * Returns null if used outside WebSocketProvider instead of throwing.\n * Useful for optional WebSocket usage in hooks that may or may not have the provider.\n */\nexport const useWebSocketSafe = (): WebSocketContextValue | null =>\n\tuseContext(WebSocketContext);\n\nexport type { WebSocketContextValue, WebSocketProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AA0BA,MAAM,mBAAmB,cAA4C,KAAK;AAE1E,SAAS,wBAAwB,EAChC,WACA,WACA,aAI6B;CAC7B,MAAM,sBAAsB,WAAW,MAAM;AAC7C,KAAI,CAAC,oBACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,WAAW,MAAM,IAAI;EAChC,WAAW,WAAW,MAAM,IAAI;EAChC;;AAQF,MAAMA,mBAAmD,EACxD,UACA,cACK;CACL,MAAM,aAAa,uBAAuB;CAC1C,MAAM,EAAE,WAAW,SAAS,gBAAgB;AAE5C,iBAAgB;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACxD;AAGD,MAAI,EAAE,aAAa,SAClB;EAGD,MAAM,cAAc;EAEpB,MAAM,yBAAyB;AAC9B,OAAI,CAAC,YACJ;AAGD,OAAI;AACH,YAAQ,YAAY;YACZ,OAAO;AACf,QAAI,CAAC,QACJ;IAGD,MAAM,kBACL,iBAAiB,QACd,QACA,IAAI,MACJ,OAAO,UAAU,WACd,QACA,8BACH;AAEJ,QAAI,CAAC,gBAAgB,QAAQ,SAAS,+BAA+B,CACpE,iBAAgB,UAAU,iCAAiC,gBAAgB;AAG5E,YAAQ,gBAAgB;;;EAI1B,IAAIC,aAA4B;EAEhC,MAAM,8BAA8B;AACnC,OAAI,eAAe,MAAM;AACxB,WAAO,cAAc,WAAW;AAChC,iBAAa;;;EAIf,MAAM,8BAA8B;AACnC,0BAAuB;AAEvB,OAAI,CAAC,eAAe,SAAS,oBAAoB,SAChD;AAGD,gBAAa,OAAO,YACnB,kBACA,0BACA;;EAGF,MAAM,oBAAoB;AACzB,qBAAkB;AAClB,0BAAuB;;EAGxB,MAAM,+BAA+B;AACpC,OAAI,SAAS,oBAAoB,UAAU;AAC1C,2BAAuB;AACvB;;AAGD,qBAAkB;AAClB,0BAAuB;;AAGxB,SAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAS,iBAAiB,oBAAoB,uBAAuB;AAErE,MAAI,eAAe,SAAS,oBAAoB,UAAU;AACzD,qBAAkB;AAClB,0BAAuB;;AAGxB,eAAa;AACZ,UAAO,oBAAoB,SAAS,YAAY;AAChD,YAAS,oBAAoB,oBAAoB,uBAAuB;AACxE,0BAAuB;;IAEtB;EAAC;EAAa;EAAS;EAAS;EAAU,CAAC;CAC9C,MAAM,QAAQ,cAAc,YAAY,CAAC,WAAW,CAAC;AACrD,QACC,oBAAC,iBAAiB;EAAgB;EAChC;GAC0B;;;;;;AAQ9B,MAAaC,qBAAuD,EACnE,UACA,WACA,WACA,WACA,OACA,cAAc,MACd,WACA,cACA,cACK;AAGL,QACC,oBAAC;EACA,MAJW,wBAAwB;GAAE;GAAW;GAAW;GAAW,CAAC;EAK1D;EACF;EACG;EACL;EACF;YAEP,oBAAC;GAAyB;GAAU;IAA2B;GAC7C;;;;;;AAQrB,MAAa,qBAA4C;CACxD,MAAM,UAAU,WAAW,iBAAiB;AAC5C,KAAI,CAAC,QACJ,OAAM,IAAI,MAAM,qDAAqD;AAEtE,QAAO;;;;;;;AAQR,MAAa,yBACZ,WAAW,iBAAiB"}
|
package/support/index.d.ts
CHANGED
|
@@ -1,74 +1,259 @@
|
|
|
1
1
|
import { SupportLocale, SupportTextContentOverrides } from "./text/locales/keys.js";
|
|
2
|
-
import { CustomPage } from "./router.js";
|
|
2
|
+
import { CustomPage, PageProps } from "./router.js";
|
|
3
|
+
import { SlotProps } from "./context/slots.js";
|
|
4
|
+
import { ConversationEndEvent, ConversationStartEvent, ErrorEvent, MessageReceivedEvent, MessageSentEvent, SupportEvent, SupportEventCallbacks, SupportEventType, useSupportEventEmitter, useSupportEvents } from "./context/events.js";
|
|
5
|
+
import { SupportHandle, useSupportHandle } from "./context/handle.js";
|
|
3
6
|
import { Text, useSupportText } from "./text/index.js";
|
|
4
|
-
import {
|
|
7
|
+
import { Align, CollisionPadding, ContentProps, RootProps, Side, TriggerRenderProps } from "./types.js";
|
|
5
8
|
import { CoButton } from "./components/button.js";
|
|
6
9
|
import { Header } from "./components/header.js";
|
|
7
10
|
import { WebSocketContextValue, WebSocketProvider, useWebSocket } from "./context/websocket.js";
|
|
8
11
|
import { useSupportConfig, useSupportNavigation, useSupportStore } from "./store/support-store.js";
|
|
9
12
|
import "./store/index.js";
|
|
10
|
-
import
|
|
11
|
-
import
|
|
13
|
+
import * as React$1 from "react";
|
|
14
|
+
import * as _cossistant_core0 from "@cossistant/core";
|
|
15
|
+
import { DefaultRoutes, NavigationState, RouteRegistry, SupportPage as SupportPageType } from "@cossistant/core";
|
|
12
16
|
import { DefaultMessage } from "@cossistant/types";
|
|
13
17
|
|
|
14
18
|
//#region src/support/index.d.ts
|
|
15
19
|
type SupportProps<Locale extends string = SupportLocale> = {
|
|
20
|
+
/**
|
|
21
|
+
* Additional CSS classes for the root wrapper.
|
|
22
|
+
*/
|
|
16
23
|
className?: string;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Which side of the trigger to place the content.
|
|
26
|
+
* @default "top"
|
|
27
|
+
*/
|
|
28
|
+
side?: Side;
|
|
29
|
+
/**
|
|
30
|
+
* Alignment along the side axis.
|
|
31
|
+
* @default "end"
|
|
32
|
+
*/
|
|
33
|
+
align?: Align;
|
|
34
|
+
/**
|
|
35
|
+
* Distance (in pixels) between the trigger and the content.
|
|
36
|
+
* @default 16
|
|
37
|
+
*/
|
|
38
|
+
sideOffset?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Enable automatic collision avoidance.
|
|
41
|
+
* When true, the content repositions to stay within the viewport.
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
avoidCollisions?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Padding from viewport edges when avoiding collisions.
|
|
47
|
+
* @default 8
|
|
48
|
+
*/
|
|
49
|
+
collisionPadding?: CollisionPadding;
|
|
50
|
+
/**
|
|
51
|
+
* Granular className overrides for specific parts.
|
|
52
|
+
*/
|
|
53
|
+
classNames?: {
|
|
54
|
+
trigger?: string;
|
|
55
|
+
content?: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Force a specific theme. Omit for automatic detection.
|
|
59
|
+
*/
|
|
60
|
+
theme?: "light" | "dark";
|
|
61
|
+
/**
|
|
62
|
+
* Controlled open state.
|
|
63
|
+
* When provided, the widget operates in controlled mode.
|
|
64
|
+
* Use with `onOpenChange` to manage state externally.
|
|
65
|
+
*/
|
|
66
|
+
open?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Callback fired when the open state should change.
|
|
69
|
+
* Use with `open` prop for controlled mode.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
73
|
+
* <Support open={isOpen} onOpenChange={setIsOpen} />
|
|
74
|
+
*/
|
|
75
|
+
onOpenChange?: (open: boolean) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Whether the widget should open automatically on mount (uncontrolled mode).
|
|
78
|
+
* Ignored when `open` prop is provided (controlled mode).
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
defaultOpen?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Quick reply options displayed to users.
|
|
84
|
+
*/
|
|
20
85
|
quickOptions?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Custom welcome messages shown before a conversation starts.
|
|
88
|
+
*/
|
|
21
89
|
defaultMessages?: DefaultMessage[];
|
|
22
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Locale string for widget translations.
|
|
92
|
+
*/
|
|
23
93
|
locale?: Locale;
|
|
94
|
+
/**
|
|
95
|
+
* Custom text content overrides for internationalization.
|
|
96
|
+
*/
|
|
24
97
|
content?: SupportTextContentOverrides<Locale>;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
container?: React.ComponentType<ContainerSlotProps>;
|
|
29
|
-
router?: React.ComponentType<RouterSlotProps>;
|
|
30
|
-
};
|
|
31
|
-
classNames?: {
|
|
32
|
-
root?: string;
|
|
33
|
-
bubble?: string;
|
|
34
|
-
container?: string;
|
|
35
|
-
};
|
|
98
|
+
/**
|
|
99
|
+
* Custom pages to add to the router.
|
|
100
|
+
*/
|
|
36
101
|
customPages?: CustomPage[];
|
|
37
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Called when a new conversation is started.
|
|
104
|
+
*/
|
|
105
|
+
onConversationStart?: (event: ConversationStartEvent) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Called when a conversation ends (resolved, closed, etc.).
|
|
108
|
+
*/
|
|
109
|
+
onConversationEnd?: (event: ConversationEndEvent) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Called when the visitor sends a message.
|
|
112
|
+
*/
|
|
113
|
+
onMessageSent?: (event: MessageSentEvent) => void;
|
|
114
|
+
/**
|
|
115
|
+
* Called when a message is received from an agent (human or AI).
|
|
116
|
+
*/
|
|
117
|
+
onMessageReceived?: (event: MessageReceivedEvent) => void;
|
|
118
|
+
/**
|
|
119
|
+
* Called when an error occurs within the widget.
|
|
120
|
+
*/
|
|
121
|
+
onError?: (event: ErrorEvent) => void;
|
|
122
|
+
/**
|
|
123
|
+
* Children for composition. Can include:
|
|
124
|
+
* - <Support.Trigger> for custom trigger
|
|
125
|
+
* - <Support.Content> for custom content positioning
|
|
126
|
+
* - <Support.Page> components for custom routes
|
|
127
|
+
*/
|
|
128
|
+
children?: React$1.ReactNode;
|
|
129
|
+
};
|
|
130
|
+
type SupportTriggerProps = Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
|
|
131
|
+
/**
|
|
132
|
+
* Content to render inside the trigger.
|
|
133
|
+
* Can be static content or a function receiving render props.
|
|
134
|
+
*/
|
|
135
|
+
children?: React$1.ReactNode | ((props: TriggerRenderProps) => React$1.ReactNode);
|
|
136
|
+
/**
|
|
137
|
+
* When true, renders children directly with all props passed through.
|
|
138
|
+
*/
|
|
139
|
+
asChild?: boolean;
|
|
140
|
+
className?: string;
|
|
141
|
+
};
|
|
142
|
+
type SupportContentProps = {
|
|
143
|
+
className?: string;
|
|
144
|
+
/**
|
|
145
|
+
* Which side of the trigger to place the content.
|
|
146
|
+
* @default "top"
|
|
147
|
+
*/
|
|
148
|
+
side?: Side;
|
|
149
|
+
/**
|
|
150
|
+
* Alignment along the side axis.
|
|
151
|
+
* @default "end"
|
|
152
|
+
*/
|
|
153
|
+
align?: Align;
|
|
154
|
+
/**
|
|
155
|
+
* Distance (in pixels) between the trigger and the content.
|
|
156
|
+
* @default 16
|
|
157
|
+
*/
|
|
158
|
+
sideOffset?: number;
|
|
159
|
+
/**
|
|
160
|
+
* Enable automatic collision avoidance.
|
|
161
|
+
* When true, the content repositions to stay within the viewport.
|
|
162
|
+
* @default true
|
|
163
|
+
*/
|
|
164
|
+
avoidCollisions?: boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Padding from viewport edges when avoiding collisions.
|
|
167
|
+
* @default 8
|
|
168
|
+
*/
|
|
169
|
+
collisionPadding?: CollisionPadding;
|
|
170
|
+
children?: React$1.ReactNode;
|
|
171
|
+
};
|
|
172
|
+
type SupportRouterProps = {
|
|
173
|
+
/**
|
|
174
|
+
* Custom pages to add alongside built-in pages.
|
|
175
|
+
*/
|
|
176
|
+
customPages?: CustomPage[];
|
|
177
|
+
/**
|
|
178
|
+
* Page components to register.
|
|
179
|
+
*/
|
|
180
|
+
children?: React$1.ReactNode;
|
|
181
|
+
};
|
|
182
|
+
type SupportPageProps<K extends keyof _cossistant_core0.RouteRegistry = keyof _cossistant_core0.RouteRegistry> = {
|
|
183
|
+
name: K;
|
|
184
|
+
component: React$1.ComponentType<{
|
|
185
|
+
params?: _cossistant_core0.RouteRegistry[K];
|
|
186
|
+
}>;
|
|
187
|
+
};
|
|
188
|
+
type SupportRootProps = {
|
|
189
|
+
/**
|
|
190
|
+
* Controlled open state.
|
|
191
|
+
* When provided, the widget operates in controlled mode.
|
|
192
|
+
*/
|
|
193
|
+
open?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Callback fired when the open state should change.
|
|
196
|
+
* Use with `open` prop for controlled mode.
|
|
197
|
+
*/
|
|
198
|
+
onOpenChange?: (open: boolean) => void;
|
|
199
|
+
/**
|
|
200
|
+
* Whether the widget should open automatically (uncontrolled mode).
|
|
201
|
+
* Ignored when `open` prop is provided.
|
|
202
|
+
* @default false
|
|
203
|
+
*/
|
|
204
|
+
defaultOpen?: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Force a specific theme.
|
|
207
|
+
*/
|
|
208
|
+
theme?: "light" | "dark";
|
|
209
|
+
/**
|
|
210
|
+
* Additional CSS classes.
|
|
211
|
+
*/
|
|
212
|
+
className?: string;
|
|
213
|
+
/**
|
|
214
|
+
* Called when a new conversation is started.
|
|
215
|
+
*/
|
|
216
|
+
onConversationStart?: (event: ConversationStartEvent) => void;
|
|
217
|
+
/**
|
|
218
|
+
* Called when a conversation ends.
|
|
219
|
+
*/
|
|
220
|
+
onConversationEnd?: (event: ConversationEndEvent) => void;
|
|
221
|
+
/**
|
|
222
|
+
* Called when the visitor sends a message.
|
|
223
|
+
*/
|
|
224
|
+
onMessageSent?: (event: MessageSentEvent) => void;
|
|
225
|
+
/**
|
|
226
|
+
* Called when a message is received from an agent.
|
|
227
|
+
*/
|
|
228
|
+
onMessageReceived?: (event: MessageReceivedEvent) => void;
|
|
229
|
+
/**
|
|
230
|
+
* Called when an error occurs.
|
|
231
|
+
*/
|
|
232
|
+
onError?: (event: ErrorEvent) => void;
|
|
233
|
+
children: React$1.ReactNode;
|
|
234
|
+
};
|
|
235
|
+
declare const Support: (<Locale extends string = SupportLocale>(props: SupportProps<Locale> & {
|
|
236
|
+
ref?: React$1.Ref<SupportHandle>;
|
|
237
|
+
}) => React$1.ReactElement | null) & {
|
|
238
|
+
Root: React$1.ForwardRefExoticComponent<SupportRootProps & React$1.RefAttributes<SupportHandle>>;
|
|
239
|
+
Trigger: React$1.ForwardRefExoticComponent<Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
|
|
240
|
+
/**
|
|
241
|
+
* Content to render inside the trigger.
|
|
242
|
+
* Can be static content or a function receiving render props.
|
|
243
|
+
*/
|
|
244
|
+
children?: React$1.ReactNode | ((props: TriggerRenderProps) => React$1.ReactNode);
|
|
245
|
+
/**
|
|
246
|
+
* When true, renders children directly with all props passed through.
|
|
247
|
+
*/
|
|
248
|
+
asChild?: boolean;
|
|
249
|
+
className?: string;
|
|
250
|
+
} & React$1.RefAttributes<HTMLButtonElement>>;
|
|
251
|
+
Content: React$1.FC<SupportContentProps>;
|
|
252
|
+
Router: React$1.FC<SupportRouterProps>;
|
|
253
|
+
Page: <K extends keyof _cossistant_core0.RouteRegistry>(_props: PageProps<K>) => null;
|
|
254
|
+
Header: React$1.FC<SlotProps>;
|
|
255
|
+
Footer: React$1.FC<SlotProps>;
|
|
38
256
|
};
|
|
39
|
-
/**
|
|
40
|
-
* Complete support widget with chat, routing, and real-time features.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* // Zero config
|
|
44
|
-
* <Support />
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* // With customization and custom pages
|
|
48
|
-
* <Support
|
|
49
|
-
* theme="dark"
|
|
50
|
-
* classNames={{ bubble: "bg-purple-600" }}
|
|
51
|
-
* customPages={[
|
|
52
|
-
* { name: "FAQ", component: FAQPage }
|
|
53
|
-
* ]}
|
|
54
|
-
* />
|
|
55
|
-
*/
|
|
56
|
-
declare function Support<Locale extends string = SupportLocale>({
|
|
57
|
-
className,
|
|
58
|
-
position,
|
|
59
|
-
align,
|
|
60
|
-
positioning,
|
|
61
|
-
quickOptions,
|
|
62
|
-
defaultMessages,
|
|
63
|
-
defaultOpen,
|
|
64
|
-
locale,
|
|
65
|
-
content,
|
|
66
|
-
theme,
|
|
67
|
-
slots,
|
|
68
|
-
classNames,
|
|
69
|
-
customPages,
|
|
70
|
-
children
|
|
71
|
-
}: SupportProps<Locale>): ReactElement | null;
|
|
72
257
|
//#endregion
|
|
73
|
-
export { type
|
|
258
|
+
export { type Align, CoButton as Button, type CollisionPadding, type ContentProps, type ConversationEndEvent, type ConversationStartEvent, type CustomPage, type DefaultRoutes, type ErrorEvent, Header, type MessageReceivedEvent, type MessageSentEvent, type NavigationState, type RootProps, type RouteRegistry, type Side, Support, Support as default, SupportContentProps, type SupportEvent, type SupportEventCallbacks, type SupportEventType, type SupportHandle, type SupportLocale, SupportPageProps, type SupportPageType, SupportProps, SupportRootProps, SupportRouterProps, type SupportTextContentOverrides, SupportTriggerProps, Text, type TriggerRenderProps, type WebSocketContextValue, WebSocketProvider, useSupportConfig, useSupportEventEmitter, useSupportEvents, useSupportHandle, useSupportNavigation, useSupportStore, useSupportText, useWebSocket };
|
|
74
259
|
//# sourceMappingURL=index.d.ts.map
|
package/support/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/support/index.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;KAsCY,qCAAqC;;;;;;;;;SAUzC;EAVI;;;;EAmCQ,KAAA,CAAA,EAnBX,KAmBW;EA+CD;;;;EAeJ,UAAA,CAAA,EAAA,MAAA;EASgB;;;;;EA4BnB,eAAM,CAAA,EAAA,OAAA;EAAS;AA6M3B;;;EAAkC,gBAAA,CAAA,EAhTd,gBAgTc;EAQtB;;;EAAiE,UAAA,CAAA,EAAA;IAsCjE,OAAA,CAAA,EAAA,MAAA;IAMJ,OAAA,CAAA,EAAA,MAAA;EAKC,CAAA;EAgBW;;;EA4CR,KAAA,CAAA,EAAA,OAAA,GAAA,MAAkB;EAsClB;;;;;EAMwC,IAAA,CAAA,EAAA,OAAA;EADxC;;AAuBZ;;;;;;EA6CW,YAAM,CAAA,EAAA,CAAA,IAAA,EAAA,OAAA,EAAA,GAAA,IAAA;EAAS;AA2F1B;;;;EAtUiD,WAAA,CAAA,EAAA,OAAA;EAAV;;;;;;;oBA1PpB;;;;EAyQ2C,MAAM,CAAA,EApQ1D,MAoQ0D;;;;YA/PzD,4BAA4B;;;;gBAKxB;;;;gCASgB;;;;8BAKF;;;;0BAKJ;;;;8BAKI;;;;oBAKV;;;;;;;aAQP,OAAA,CAAM;;KA6MN,mBAAA,GAAsB,KACjC,OAAA,CAAM,qBAAqB;;;;;aAOhB,OAAA,CAAM,qBAAqB,uBAAuB,OAAA,CAAM;;;;;;;KAsCxD,mBAAA;;;;;;SAMJ;;;;;UAKC;;;;;;;;;;;;;;;;qBAgBW;aACR,OAAA,CAAM;;KA2CN,kBAAA;;;;gBAIG;;;;aAIH,OAAA,CAAM;;KA8BN,iCAAgB,iBAAA,CAEO,sBAAa,iBAAA,CAAoC;QAE7E;aACK,OAAA,CAAM;aADV,iBAAA,CAE8B,aAAA,CAAc;;;KAsBxC,gBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA4BmB;;;;8BAIF;;;;0BAIJ;;;;8BAII;;;;oBAIV;YACR,OAAA,CAAM;;cA2FJ,mCAxUS,sBAEd,aAAa;QAAkB,OAAA,CAAM,IAAI;MAC5C,OAAA,CAAM;;;;;;;eAcC,OAAA,CAAM,qBAAqB,uBAAuB,OAAA,CAAM"}
|