@crafter/rn-ai-elements 0.0.1
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/lib/commonjs/chatbot/AIImage.js +126 -0
- package/lib/commonjs/chatbot/AIImage.js.map +1 -0
- package/lib/commonjs/chatbot/Attachments.js +317 -0
- package/lib/commonjs/chatbot/Attachments.js.map +1 -0
- package/lib/commonjs/chatbot/ChatErrorBoundary.js +201 -0
- package/lib/commonjs/chatbot/ChatErrorBoundary.js.map +1 -0
- package/lib/commonjs/chatbot/ChatMessageItem.js +169 -0
- package/lib/commonjs/chatbot/ChatMessageItem.js.map +1 -0
- package/lib/commonjs/chatbot/Conversation.js +415 -0
- package/lib/commonjs/chatbot/Conversation.js.map +1 -0
- package/lib/commonjs/chatbot/ConversationScrollButton.js +131 -0
- package/lib/commonjs/chatbot/ConversationScrollButton.js.map +1 -0
- package/lib/commonjs/chatbot/Message.js +203 -0
- package/lib/commonjs/chatbot/Message.js.map +1 -0
- package/lib/commonjs/chatbot/PromptInput.js +352 -0
- package/lib/commonjs/chatbot/PromptInput.js.map +1 -0
- package/lib/commonjs/chatbot/Reasoning.js +184 -0
- package/lib/commonjs/chatbot/Reasoning.js.map +1 -0
- package/lib/commonjs/chatbot/Shimmer.js +116 -0
- package/lib/commonjs/chatbot/Shimmer.js.map +1 -0
- package/lib/commonjs/chatbot/Sources.js +212 -0
- package/lib/commonjs/chatbot/Sources.js.map +1 -0
- package/lib/commonjs/chatbot/Suggestion.js +99 -0
- package/lib/commonjs/chatbot/Suggestion.js.map +1 -0
- package/lib/commonjs/chatbot/Tool.js +307 -0
- package/lib/commonjs/chatbot/Tool.js.map +1 -0
- package/lib/commonjs/chatbot/adapters/uiMessageAdapter.js +141 -0
- package/lib/commonjs/chatbot/adapters/uiMessageAdapter.js.map +1 -0
- package/lib/commonjs/chatbot/index.js +140 -0
- package/lib/commonjs/chatbot/index.js.map +1 -0
- package/lib/commonjs/chatbot/types.js +6 -0
- package/lib/commonjs/chatbot/types.js.map +1 -0
- package/lib/commonjs/hooks/index.js +34 -0
- package/lib/commonjs/hooks/index.js.map +1 -0
- package/lib/commonjs/hooks/useAutoScroll.js +39 -0
- package/lib/commonjs/hooks/useAutoScroll.js.map +1 -0
- package/lib/commonjs/hooks/useClipboard.js +44 -0
- package/lib/commonjs/hooks/useClipboard.js.map +1 -0
- package/lib/commonjs/hooks/useCollapsible.js +35 -0
- package/lib/commonjs/hooks/useCollapsible.js.map +1 -0
- package/lib/commonjs/hooks/useStickToBottom.js +68 -0
- package/lib/commonjs/hooks/useStickToBottom.js.map +1 -0
- package/lib/commonjs/index.js +257 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/primitives/Badge.js +119 -0
- package/lib/commonjs/primitives/Badge.js.map +1 -0
- package/lib/commonjs/primitives/Button.js +185 -0
- package/lib/commonjs/primitives/Button.js.map +1 -0
- package/lib/commonjs/primitives/Card.js +166 -0
- package/lib/commonjs/primitives/Card.js.map +1 -0
- package/lib/commonjs/primitives/Collapsible.js +137 -0
- package/lib/commonjs/primitives/Collapsible.js.map +1 -0
- package/lib/commonjs/primitives/ScrollArea.js +40 -0
- package/lib/commonjs/primitives/ScrollArea.js.map +1 -0
- package/lib/commonjs/primitives/index.js +83 -0
- package/lib/commonjs/primitives/index.js.map +1 -0
- package/lib/commonjs/streaming/StreamingMarkdown.js +252 -0
- package/lib/commonjs/streaming/StreamingMarkdown.js.map +1 -0
- package/lib/commonjs/streaming/index.js +13 -0
- package/lib/commonjs/streaming/index.js.map +1 -0
- package/lib/commonjs/streaming/parser.js +482 -0
- package/lib/commonjs/streaming/parser.js.map +1 -0
- package/lib/commonjs/streaming/renderers/BlockquoteRenderer.js +35 -0
- package/lib/commonjs/streaming/renderers/BlockquoteRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/CodeRenderer.js +128 -0
- package/lib/commonjs/streaming/renderers/CodeRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/HeadingRenderer.js +61 -0
- package/lib/commonjs/streaming/renderers/HeadingRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/ImageRenderer.js +53 -0
- package/lib/commonjs/streaming/renderers/ImageRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/LinkRenderer.js +49 -0
- package/lib/commonjs/streaming/renderers/LinkRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/ListRenderer.js +63 -0
- package/lib/commonjs/streaming/renderers/ListRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/TableRenderer.js +77 -0
- package/lib/commonjs/streaming/renderers/TableRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/TextRenderer.js +41 -0
- package/lib/commonjs/streaming/renderers/TextRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/index.js +76 -0
- package/lib/commonjs/streaming/renderers/index.js.map +1 -0
- package/lib/commonjs/streaming/renderers/renderInlineChildren.js +112 -0
- package/lib/commonjs/streaming/renderers/renderInlineChildren.js.map +1 -0
- package/lib/commonjs/streaming/renderers/renderNode.js +81 -0
- package/lib/commonjs/streaming/renderers/renderNode.js.map +1 -0
- package/lib/commonjs/theme/ThemeProvider.js +68 -0
- package/lib/commonjs/theme/ThemeProvider.js.map +1 -0
- package/lib/commonjs/theme/defaultTheme.js +96 -0
- package/lib/commonjs/theme/defaultTheme.js.map +1 -0
- package/lib/commonjs/theme/index.js +32 -0
- package/lib/commonjs/theme/index.js.map +1 -0
- package/lib/commonjs/theme/tokens.js +2 -0
- package/lib/commonjs/theme/tokens.js.map +1 -0
- package/lib/commonjs/types.d.js +2 -0
- package/lib/commonjs/types.d.js.map +1 -0
- package/lib/commonjs/voice/index.js +13 -0
- package/lib/commonjs/voice/index.js.map +1 -0
- package/lib/commonjs/voice/useSpeechRecognition.js +172 -0
- package/lib/commonjs/voice/useSpeechRecognition.js.map +1 -0
- package/lib/module/chatbot/AIImage.js +121 -0
- package/lib/module/chatbot/AIImage.js.map +1 -0
- package/lib/module/chatbot/Attachments.js +312 -0
- package/lib/module/chatbot/Attachments.js.map +1 -0
- package/lib/module/chatbot/ChatErrorBoundary.js +196 -0
- package/lib/module/chatbot/ChatErrorBoundary.js.map +1 -0
- package/lib/module/chatbot/ChatMessageItem.js +164 -0
- package/lib/module/chatbot/ChatMessageItem.js.map +1 -0
- package/lib/module/chatbot/Conversation.js +412 -0
- package/lib/module/chatbot/Conversation.js.map +1 -0
- package/lib/module/chatbot/ConversationScrollButton.js +126 -0
- package/lib/module/chatbot/ConversationScrollButton.js.map +1 -0
- package/lib/module/chatbot/Message.js +198 -0
- package/lib/module/chatbot/Message.js.map +1 -0
- package/lib/module/chatbot/PromptInput.js +347 -0
- package/lib/module/chatbot/PromptInput.js.map +1 -0
- package/lib/module/chatbot/Reasoning.js +179 -0
- package/lib/module/chatbot/Reasoning.js.map +1 -0
- package/lib/module/chatbot/Shimmer.js +111 -0
- package/lib/module/chatbot/Shimmer.js.map +1 -0
- package/lib/module/chatbot/Sources.js +207 -0
- package/lib/module/chatbot/Sources.js.map +1 -0
- package/lib/module/chatbot/Suggestion.js +94 -0
- package/lib/module/chatbot/Suggestion.js.map +1 -0
- package/lib/module/chatbot/Tool.js +303 -0
- package/lib/module/chatbot/Tool.js.map +1 -0
- package/lib/module/chatbot/adapters/uiMessageAdapter.js +137 -0
- package/lib/module/chatbot/adapters/uiMessageAdapter.js.map +1 -0
- package/lib/module/chatbot/index.js +39 -0
- package/lib/module/chatbot/index.js.map +1 -0
- package/lib/module/chatbot/types.js +4 -0
- package/lib/module/chatbot/types.js.map +1 -0
- package/lib/module/hooks/index.js +7 -0
- package/lib/module/hooks/index.js.map +1 -0
- package/lib/module/hooks/useAutoScroll.js +35 -0
- package/lib/module/hooks/useAutoScroll.js.map +1 -0
- package/lib/module/hooks/useClipboard.js +40 -0
- package/lib/module/hooks/useClipboard.js.map +1 -0
- package/lib/module/hooks/useCollapsible.js +31 -0
- package/lib/module/hooks/useCollapsible.js.map +1 -0
- package/lib/module/hooks/useStickToBottom.js +64 -0
- package/lib/module/hooks/useStickToBottom.js.map +1 -0
- package/lib/module/index.js +19 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/primitives/Badge.js +114 -0
- package/lib/module/primitives/Badge.js.map +1 -0
- package/lib/module/primitives/Button.js +180 -0
- package/lib/module/primitives/Button.js.map +1 -0
- package/lib/module/primitives/Card.js +156 -0
- package/lib/module/primitives/Card.js.map +1 -0
- package/lib/module/primitives/Collapsible.js +130 -0
- package/lib/module/primitives/Collapsible.js.map +1 -0
- package/lib/module/primitives/ScrollArea.js +35 -0
- package/lib/module/primitives/ScrollArea.js.map +1 -0
- package/lib/module/primitives/index.js +8 -0
- package/lib/module/primitives/index.js.map +1 -0
- package/lib/module/streaming/StreamingMarkdown.js +246 -0
- package/lib/module/streaming/StreamingMarkdown.js.map +1 -0
- package/lib/module/streaming/index.js +4 -0
- package/lib/module/streaming/index.js.map +1 -0
- package/lib/module/streaming/parser.js +477 -0
- package/lib/module/streaming/parser.js.map +1 -0
- package/lib/module/streaming/renderers/BlockquoteRenderer.js +30 -0
- package/lib/module/streaming/renderers/BlockquoteRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/CodeRenderer.js +123 -0
- package/lib/module/streaming/renderers/CodeRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/HeadingRenderer.js +56 -0
- package/lib/module/streaming/renderers/HeadingRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/ImageRenderer.js +48 -0
- package/lib/module/streaming/renderers/ImageRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/LinkRenderer.js +44 -0
- package/lib/module/streaming/renderers/LinkRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/ListRenderer.js +58 -0
- package/lib/module/streaming/renderers/ListRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/TableRenderer.js +72 -0
- package/lib/module/streaming/renderers/TableRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/TextRenderer.js +36 -0
- package/lib/module/streaming/renderers/TextRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/index.js +13 -0
- package/lib/module/streaming/renderers/index.js.map +1 -0
- package/lib/module/streaming/renderers/renderInlineChildren.js +107 -0
- package/lib/module/streaming/renderers/renderInlineChildren.js.map +1 -0
- package/lib/module/streaming/renderers/renderNode.js +78 -0
- package/lib/module/streaming/renderers/renderNode.js.map +1 -0
- package/lib/module/theme/ThemeProvider.js +62 -0
- package/lib/module/theme/ThemeProvider.js.map +1 -0
- package/lib/module/theme/defaultTheme.js +92 -0
- package/lib/module/theme/defaultTheme.js.map +1 -0
- package/lib/module/theme/index.js +5 -0
- package/lib/module/theme/index.js.map +1 -0
- package/lib/module/theme/tokens.js +2 -0
- package/lib/module/theme/tokens.js.map +1 -0
- package/lib/module/types.d.js +2 -0
- package/lib/module/types.d.js.map +1 -0
- package/lib/module/voice/index.js +14 -0
- package/lib/module/voice/index.js.map +1 -0
- package/lib/module/voice/useSpeechRecognition.js +169 -0
- package/lib/module/voice/useSpeechRecognition.js.map +1 -0
- package/lib/typescript/src/chatbot/AIImage.d.ts +24 -0
- package/lib/typescript/src/chatbot/AIImage.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Attachments.d.ts +20 -0
- package/lib/typescript/src/chatbot/Attachments.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/ChatErrorBoundary.d.ts +57 -0
- package/lib/typescript/src/chatbot/ChatErrorBoundary.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/ChatMessageItem.d.ts +45 -0
- package/lib/typescript/src/chatbot/ChatMessageItem.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Conversation.d.ts +94 -0
- package/lib/typescript/src/chatbot/Conversation.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/ConversationScrollButton.d.ts +62 -0
- package/lib/typescript/src/chatbot/ConversationScrollButton.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Message.d.ts +39 -0
- package/lib/typescript/src/chatbot/Message.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/PromptInput.d.ts +93 -0
- package/lib/typescript/src/chatbot/PromptInput.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Reasoning.d.ts +14 -0
- package/lib/typescript/src/chatbot/Reasoning.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Shimmer.d.ts +13 -0
- package/lib/typescript/src/chatbot/Shimmer.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Sources.d.ts +17 -0
- package/lib/typescript/src/chatbot/Sources.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Suggestion.d.ts +15 -0
- package/lib/typescript/src/chatbot/Suggestion.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Tool.d.ts +30 -0
- package/lib/typescript/src/chatbot/Tool.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/adapters/uiMessageAdapter.d.ts +24 -0
- package/lib/typescript/src/chatbot/adapters/uiMessageAdapter.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/index.d.ts +29 -0
- package/lib/typescript/src/chatbot/index.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/types.d.ts +49 -0
- package/lib/typescript/src/chatbot/types.d.ts.map +1 -0
- package/lib/typescript/src/hooks/index.d.ts +9 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useAutoScroll.d.ts +23 -0
- package/lib/typescript/src/hooks/useAutoScroll.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useClipboard.d.ts +22 -0
- package/lib/typescript/src/hooks/useClipboard.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useCollapsible.d.ts +28 -0
- package/lib/typescript/src/hooks/useCollapsible.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useStickToBottom.d.ts +39 -0
- package/lib/typescript/src/hooks/useStickToBottom.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +11 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Badge.d.ts +10 -0
- package/lib/typescript/src/primitives/Badge.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Button.d.ts +16 -0
- package/lib/typescript/src/primitives/Button.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Card.d.ts +33 -0
- package/lib/typescript/src/primitives/Card.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Collapsible.d.ts +20 -0
- package/lib/typescript/src/primitives/Collapsible.d.ts.map +1 -0
- package/lib/typescript/src/primitives/ScrollArea.d.ts +10 -0
- package/lib/typescript/src/primitives/ScrollArea.d.ts.map +1 -0
- package/lib/typescript/src/primitives/index.d.ts +11 -0
- package/lib/typescript/src/primitives/index.d.ts.map +1 -0
- package/lib/typescript/src/streaming/StreamingMarkdown.d.ts +47 -0
- package/lib/typescript/src/streaming/StreamingMarkdown.d.ts.map +1 -0
- package/lib/typescript/src/streaming/index.d.ts +3 -0
- package/lib/typescript/src/streaming/index.d.ts.map +1 -0
- package/lib/typescript/src/streaming/parser.d.ts +41 -0
- package/lib/typescript/src/streaming/parser.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/BlockquoteRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/BlockquoteRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/CodeRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/CodeRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/HeadingRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/HeadingRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/ImageRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/ImageRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/LinkRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/LinkRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/ListRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/ListRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/TableRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/TableRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/TextRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/TextRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/index.d.ts +19 -0
- package/lib/typescript/src/streaming/renderers/index.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/renderInlineChildren.d.ts +12 -0
- package/lib/typescript/src/streaming/renderers/renderInlineChildren.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/renderNode.d.ts +8 -0
- package/lib/typescript/src/streaming/renderers/renderNode.d.ts.map +1 -0
- package/lib/typescript/src/theme/ThemeProvider.d.ts +14 -0
- package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/src/theme/defaultTheme.d.ts +4 -0
- package/lib/typescript/src/theme/defaultTheme.d.ts.map +1 -0
- package/lib/typescript/src/theme/index.d.ts +5 -0
- package/lib/typescript/src/theme/index.d.ts.map +1 -0
- package/lib/typescript/src/theme/tokens.d.ts +66 -0
- package/lib/typescript/src/theme/tokens.d.ts.map +1 -0
- package/lib/typescript/src/voice/index.d.ts +3 -0
- package/lib/typescript/src/voice/index.d.ts.map +1 -0
- package/lib/typescript/src/voice/useSpeechRecognition.d.ts +77 -0
- package/lib/typescript/src/voice/useSpeechRecognition.d.ts.map +1 -0
- package/package.json +132 -0
- package/src/chatbot/AIImage.tsx +166 -0
- package/src/chatbot/Attachments.tsx +382 -0
- package/src/chatbot/ChatErrorBoundary.tsx +230 -0
- package/src/chatbot/ChatMessageItem.tsx +195 -0
- package/src/chatbot/Conversation.tsx +537 -0
- package/src/chatbot/ConversationScrollButton.tsx +149 -0
- package/src/chatbot/Message.tsx +266 -0
- package/src/chatbot/PromptInput.tsx +532 -0
- package/src/chatbot/Reasoning.tsx +198 -0
- package/src/chatbot/Shimmer.tsx +146 -0
- package/src/chatbot/Sources.tsx +263 -0
- package/src/chatbot/Suggestion.tsx +123 -0
- package/src/chatbot/Tool.tsx +340 -0
- package/src/chatbot/adapters/uiMessageAdapter.ts +177 -0
- package/src/chatbot/index.ts +97 -0
- package/src/chatbot/types.ts +66 -0
- package/src/hooks/index.ts +17 -0
- package/src/hooks/useAutoScroll.ts +43 -0
- package/src/hooks/useClipboard.ts +46 -0
- package/src/hooks/useCollapsible.ts +42 -0
- package/src/hooks/useStickToBottom.ts +82 -0
- package/src/index.ts +139 -0
- package/src/primitives/Badge.tsx +119 -0
- package/src/primitives/Button.tsx +213 -0
- package/src/primitives/Card.tsx +221 -0
- package/src/primitives/Collapsible.tsx +168 -0
- package/src/primitives/ScrollArea.tsx +53 -0
- package/src/primitives/index.ts +36 -0
- package/src/streaming/StreamingMarkdown.tsx +282 -0
- package/src/streaming/index.ts +2 -0
- package/src/streaming/parser.ts +506 -0
- package/src/streaming/renderers/BlockquoteRenderer.tsx +42 -0
- package/src/streaming/renderers/CodeRenderer.tsx +158 -0
- package/src/streaming/renderers/HeadingRenderer.tsx +64 -0
- package/src/streaming/renderers/ImageRenderer.tsx +62 -0
- package/src/streaming/renderers/LinkRenderer.tsx +53 -0
- package/src/streaming/renderers/ListRenderer.tsx +65 -0
- package/src/streaming/renderers/TableRenderer.tsx +103 -0
- package/src/streaming/renderers/TextRenderer.tsx +39 -0
- package/src/streaming/renderers/index.ts +26 -0
- package/src/streaming/renderers/renderInlineChildren.tsx +115 -0
- package/src/streaming/renderers/renderNode.tsx +72 -0
- package/src/theme/ThemeProvider.tsx +77 -0
- package/src/theme/defaultTheme.ts +93 -0
- package/src/theme/index.ts +4 -0
- package/src/theme/tokens.ts +69 -0
- package/src/types.d.ts +71 -0
- package/src/voice/index.ts +15 -0
- package/src/voice/useSpeechRecognition.ts +230 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { AIElementsTheme } from './tokens';
|
|
2
|
+
|
|
3
|
+
const sharedTokens: Pick<AIElementsTheme, 'spacing' | 'radius' | 'typography'> = {
|
|
4
|
+
spacing: {
|
|
5
|
+
xs: 4,
|
|
6
|
+
sm: 8,
|
|
7
|
+
md: 12,
|
|
8
|
+
lg: 16,
|
|
9
|
+
xl: 24,
|
|
10
|
+
'2xl': 32,
|
|
11
|
+
},
|
|
12
|
+
radius: {
|
|
13
|
+
sm: 6,
|
|
14
|
+
md: 10,
|
|
15
|
+
lg: 16,
|
|
16
|
+
full: 9999,
|
|
17
|
+
},
|
|
18
|
+
typography: {
|
|
19
|
+
fontFamily: 'System',
|
|
20
|
+
monoFontFamily: 'monospace',
|
|
21
|
+
fontSize: {
|
|
22
|
+
xs: 11,
|
|
23
|
+
sm: 13,
|
|
24
|
+
md: 15,
|
|
25
|
+
lg: 17,
|
|
26
|
+
xl: 20,
|
|
27
|
+
'2xl': 24,
|
|
28
|
+
},
|
|
29
|
+
lineHeight: {
|
|
30
|
+
tight: 1.25,
|
|
31
|
+
normal: 1.5,
|
|
32
|
+
relaxed: 1.75,
|
|
33
|
+
},
|
|
34
|
+
fontWeight: {
|
|
35
|
+
normal: '400',
|
|
36
|
+
medium: '500',
|
|
37
|
+
semibold: '600',
|
|
38
|
+
bold: '700',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const lightTheme: AIElementsTheme = {
|
|
44
|
+
...sharedTokens,
|
|
45
|
+
dark: false,
|
|
46
|
+
colors: {
|
|
47
|
+
primary: '#18181B',
|
|
48
|
+
primaryForeground: '#FAFAFA',
|
|
49
|
+
secondary: '#F4F4F5',
|
|
50
|
+
secondaryForeground: '#18181B',
|
|
51
|
+
background: '#FFFFFF',
|
|
52
|
+
foreground: '#09090B',
|
|
53
|
+
muted: '#F4F4F5',
|
|
54
|
+
mutedForeground: '#71717A',
|
|
55
|
+
card: '#FFFFFF',
|
|
56
|
+
cardForeground: '#09090B',
|
|
57
|
+
border: '#E4E4E7',
|
|
58
|
+
destructive: '#EF4444',
|
|
59
|
+
destructiveForeground: '#FAFAFA',
|
|
60
|
+
success: '#22C55E',
|
|
61
|
+
successForeground: '#FAFAFA',
|
|
62
|
+
warning: '#F59E0B',
|
|
63
|
+
warningForeground: '#18181B',
|
|
64
|
+
accent: '#F4F4F5',
|
|
65
|
+
accentForeground: '#18181B',
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const darkTheme: AIElementsTheme = {
|
|
70
|
+
...sharedTokens,
|
|
71
|
+
dark: true,
|
|
72
|
+
colors: {
|
|
73
|
+
primary: '#FAFAFA',
|
|
74
|
+
primaryForeground: '#18181B',
|
|
75
|
+
secondary: '#27272A',
|
|
76
|
+
secondaryForeground: '#FAFAFA',
|
|
77
|
+
background: '#09090B',
|
|
78
|
+
foreground: '#FAFAFA',
|
|
79
|
+
muted: '#27272A',
|
|
80
|
+
mutedForeground: '#A1A1AA',
|
|
81
|
+
card: '#09090B',
|
|
82
|
+
cardForeground: '#FAFAFA',
|
|
83
|
+
border: '#27272A',
|
|
84
|
+
destructive: '#DC2626',
|
|
85
|
+
destructiveForeground: '#FAFAFA',
|
|
86
|
+
success: '#16A34A',
|
|
87
|
+
successForeground: '#FAFAFA',
|
|
88
|
+
warning: '#D97706',
|
|
89
|
+
warningForeground: '#FAFAFA',
|
|
90
|
+
accent: '#27272A',
|
|
91
|
+
accentForeground: '#FAFAFA',
|
|
92
|
+
},
|
|
93
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { AIElementsProvider, useAIElementsTheme } from './ThemeProvider';
|
|
2
|
+
export type { AIElementsProviderProps, ColorSchemeMode } from './ThemeProvider';
|
|
3
|
+
export type { AIElementsTheme, ColorTokens, SpacingTokens, RadiusTokens, TypographyTokens } from './tokens';
|
|
4
|
+
export { lightTheme, darkTheme } from './defaultTheme';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface ColorTokens {
|
|
2
|
+
primary: string;
|
|
3
|
+
primaryForeground: string;
|
|
4
|
+
secondary: string;
|
|
5
|
+
secondaryForeground: string;
|
|
6
|
+
background: string;
|
|
7
|
+
foreground: string;
|
|
8
|
+
muted: string;
|
|
9
|
+
mutedForeground: string;
|
|
10
|
+
card: string;
|
|
11
|
+
cardForeground: string;
|
|
12
|
+
border: string;
|
|
13
|
+
destructive: string;
|
|
14
|
+
destructiveForeground: string;
|
|
15
|
+
success: string;
|
|
16
|
+
successForeground: string;
|
|
17
|
+
warning: string;
|
|
18
|
+
warningForeground: string;
|
|
19
|
+
accent: string;
|
|
20
|
+
accentForeground: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SpacingTokens {
|
|
24
|
+
xs: number;
|
|
25
|
+
sm: number;
|
|
26
|
+
md: number;
|
|
27
|
+
lg: number;
|
|
28
|
+
xl: number;
|
|
29
|
+
'2xl': number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface RadiusTokens {
|
|
33
|
+
sm: number;
|
|
34
|
+
md: number;
|
|
35
|
+
lg: number;
|
|
36
|
+
full: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface TypographyTokens {
|
|
40
|
+
fontFamily: string;
|
|
41
|
+
monoFontFamily: string;
|
|
42
|
+
fontSize: {
|
|
43
|
+
xs: number;
|
|
44
|
+
sm: number;
|
|
45
|
+
md: number;
|
|
46
|
+
lg: number;
|
|
47
|
+
xl: number;
|
|
48
|
+
'2xl': number;
|
|
49
|
+
};
|
|
50
|
+
lineHeight: {
|
|
51
|
+
tight: number;
|
|
52
|
+
normal: number;
|
|
53
|
+
relaxed: number;
|
|
54
|
+
};
|
|
55
|
+
fontWeight: {
|
|
56
|
+
normal: string;
|
|
57
|
+
medium: string;
|
|
58
|
+
semibold: string;
|
|
59
|
+
bold: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface AIElementsTheme {
|
|
64
|
+
colors: ColorTokens;
|
|
65
|
+
spacing: SpacingTokens;
|
|
66
|
+
radius: RadiusTokens;
|
|
67
|
+
typography: TypographyTokens;
|
|
68
|
+
dark: boolean;
|
|
69
|
+
}
|
package/src/types.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Ambient module declarations for untyped peer dependencies.
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// NOTE: the previous version of this file ALSO shadowed `lucide-react-native`
|
|
6
|
+
// with a manual enumeration of a subset of icons. That was written before
|
|
7
|
+
// lucide shipped proper types, and it silently broke any icon we hadn't
|
|
8
|
+
// listed (the listed icons took precedence via TypeScript's module
|
|
9
|
+
// augmentation rules, and unlisted ones failed to resolve entirely).
|
|
10
|
+
// Deleting the lucide block lets the real package types flow through. If
|
|
11
|
+
// you see "Module has no exported member 'X'" from lucide, add the icon
|
|
12
|
+
// to the actual lucide-react-native package, not here.
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
declare module 'react-native-markdown-display' {
|
|
16
|
+
import { ComponentType } from 'react';
|
|
17
|
+
import { TextStyle, ViewStyle, ImageStyle } from 'react-native';
|
|
18
|
+
|
|
19
|
+
type MarkdownStyle = {
|
|
20
|
+
body?: TextStyle;
|
|
21
|
+
heading1?: TextStyle;
|
|
22
|
+
heading2?: TextStyle;
|
|
23
|
+
heading3?: TextStyle;
|
|
24
|
+
heading4?: TextStyle;
|
|
25
|
+
heading5?: TextStyle;
|
|
26
|
+
heading6?: TextStyle;
|
|
27
|
+
hr?: ViewStyle;
|
|
28
|
+
strong?: TextStyle;
|
|
29
|
+
em?: TextStyle;
|
|
30
|
+
s?: TextStyle;
|
|
31
|
+
blockquote?: ViewStyle;
|
|
32
|
+
bullet_list?: ViewStyle;
|
|
33
|
+
ordered_list?: ViewStyle;
|
|
34
|
+
list_item?: ViewStyle;
|
|
35
|
+
bullet_list_icon?: TextStyle;
|
|
36
|
+
ordered_list_icon?: TextStyle;
|
|
37
|
+
code_inline?: TextStyle;
|
|
38
|
+
code_block?: TextStyle;
|
|
39
|
+
fence?: TextStyle;
|
|
40
|
+
table?: ViewStyle;
|
|
41
|
+
thead?: ViewStyle;
|
|
42
|
+
tbody?: ViewStyle;
|
|
43
|
+
th?: ViewStyle;
|
|
44
|
+
tr?: ViewStyle;
|
|
45
|
+
td?: ViewStyle;
|
|
46
|
+
link?: TextStyle;
|
|
47
|
+
blocklink?: ViewStyle;
|
|
48
|
+
image?: ImageStyle;
|
|
49
|
+
text?: TextStyle;
|
|
50
|
+
textgroup?: ViewStyle;
|
|
51
|
+
paragraph?: ViewStyle;
|
|
52
|
+
hardbreak?: ViewStyle;
|
|
53
|
+
softbreak?: ViewStyle;
|
|
54
|
+
pre?: ViewStyle;
|
|
55
|
+
inline?: ViewStyle;
|
|
56
|
+
span?: ViewStyle;
|
|
57
|
+
[key: string]: any;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
interface MarkdownProps {
|
|
61
|
+
children: string;
|
|
62
|
+
style?: MarkdownStyle;
|
|
63
|
+
mergeStyle?: boolean;
|
|
64
|
+
rules?: Record<string, any>;
|
|
65
|
+
onLinkPress?: (url: string) => boolean;
|
|
66
|
+
debugPrintTree?: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const Markdown: ComponentType<MarkdownProps>;
|
|
70
|
+
export default Markdown;
|
|
71
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @crafter/rn-ai-elements/voice — speech-recognition hook
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// This subpath export exists so consumers who want voice input install
|
|
6
|
+
// `expo-speech-recognition` themselves (it's an optional peer dep) and
|
|
7
|
+
// import from `@crafter/rn-ai-elements/voice`. Consumers who don't want
|
|
8
|
+
// voice input never trigger the import and don't need the peer dep.
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
export { useSpeechRecognition } from './useSpeechRecognition';
|
|
12
|
+
export type {
|
|
13
|
+
UseSpeechRecognitionOptions,
|
|
14
|
+
UseSpeechRecognitionReturn,
|
|
15
|
+
} from './useSpeechRecognition';
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { useCallback, useRef, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ExpoSpeechRecognitionModule,
|
|
4
|
+
useSpeechRecognitionEvent,
|
|
5
|
+
type ExpoSpeechRecognitionErrorCode,
|
|
6
|
+
type ExpoSpeechRecognitionOptions,
|
|
7
|
+
} from 'expo-speech-recognition';
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// useSpeechRecognition — React wrapper around ExpoSpeechRecognitionModule
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
//
|
|
13
|
+
// Wraps the imperative `ExpoSpeechRecognitionModule.start / stop / abort`
|
|
14
|
+
// API with React state so a component can just read `isListening` +
|
|
15
|
+
// `transcript` and call `start()` / `stop()` / `toggle()`. Handles:
|
|
16
|
+
//
|
|
17
|
+
// - Permission request + gating (asks once, then uses the cached result)
|
|
18
|
+
// - Transcript accumulation across interim and final results
|
|
19
|
+
// - Automatic cleanup if the component unmounts mid-recognition
|
|
20
|
+
// - Error surfacing as a discriminated `error` state
|
|
21
|
+
//
|
|
22
|
+
// **Peer dependency:** this hook imports from `expo-speech-recognition`,
|
|
23
|
+
// which is declared as an **optional** peer dependency of
|
|
24
|
+
// `@crafter/rn-ai-elements`. Consumers who don't want voice input don't
|
|
25
|
+
// have to install it — they just don't import from
|
|
26
|
+
// `@crafter/rn-ai-elements/voice`. Consumers who do want voice input
|
|
27
|
+
// install `expo-speech-recognition` themselves, add its config plugin to
|
|
28
|
+
// `app.json`, and rebuild the native app.
|
|
29
|
+
//
|
|
30
|
+
// Intentionally minimal: no language picker, no contextual biasing, no
|
|
31
|
+
// audio persistence. Covers the common case of "tap mic, speak, text
|
|
32
|
+
// appears in the input field" and nothing more — add config props later
|
|
33
|
+
// if a consumer needs them.
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
export interface UseSpeechRecognitionOptions {
|
|
37
|
+
/** BCP-47 locale tag for recognition. Default `'en-US'`. */
|
|
38
|
+
lang?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Emit interim (partial) results as the user speaks. Default `true` —
|
|
41
|
+
* gives a ChatGPT-style live transcription feel.
|
|
42
|
+
*/
|
|
43
|
+
interimResults?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Keep recognizing after a pause instead of auto-stopping on silence.
|
|
46
|
+
* Default `false` — the user typically taps-to-stop anyway, and
|
|
47
|
+
* continuous mode has caveats on Android 12-.
|
|
48
|
+
*/
|
|
49
|
+
continuous?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Insert punctuation into the transcript automatically. Default `true`
|
|
52
|
+
* — matches the feel of iOS's built-in dictation.
|
|
53
|
+
*/
|
|
54
|
+
addsPunctuation?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Called when a final transcript is available. Useful for auto-submit
|
|
57
|
+
* flows; the transcript is also available via the `transcript` state.
|
|
58
|
+
*/
|
|
59
|
+
onFinalResult?: (transcript: string) => void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface UseSpeechRecognitionReturn {
|
|
63
|
+
/** True while the recognizer is actively listening. */
|
|
64
|
+
isListening: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* The current transcript — updates live with interim results while
|
|
67
|
+
* `isListening`, then settles on the final transcript when recognition
|
|
68
|
+
* stops. Cleared by `reset()` or by calling `start()` again.
|
|
69
|
+
*/
|
|
70
|
+
transcript: string;
|
|
71
|
+
/** Last error from the recognizer, or `null` if nothing has gone wrong. */
|
|
72
|
+
error: { code: ExpoSpeechRecognitionErrorCode; message: string } | null;
|
|
73
|
+
/** Request permissions (if needed) and start recognition. */
|
|
74
|
+
start: () => Promise<void>;
|
|
75
|
+
/** Stop recognition — final result will be delivered before isListening flips. */
|
|
76
|
+
stop: () => void;
|
|
77
|
+
/** Shortcut: start if idle, stop if listening. Most common press handler. */
|
|
78
|
+
toggle: () => Promise<void>;
|
|
79
|
+
/** Clear the transcript and reset the error state. */
|
|
80
|
+
reset: () => void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const DEFAULT_LANG = 'en-US';
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* React hook wrapping `expo-speech-recognition` for chat-style voice input.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```tsx
|
|
90
|
+
* import { useSpeechRecognition } from '@crafter/rn-ai-elements/voice';
|
|
91
|
+
*
|
|
92
|
+
* const { isListening, transcript, toggle } = useSpeechRecognition({
|
|
93
|
+
* onFinalResult: (text) => console.log('final:', text),
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
96
|
+
* // Pipe transcript into your input state
|
|
97
|
+
* useEffect(() => {
|
|
98
|
+
* if (transcript) setInput(transcript);
|
|
99
|
+
* }, [transcript]);
|
|
100
|
+
*
|
|
101
|
+
* // Wire the mic button
|
|
102
|
+
* <PromptInput
|
|
103
|
+
* value={input}
|
|
104
|
+
* onChangeText={setInput}
|
|
105
|
+
* isListening={isListening}
|
|
106
|
+
* onMicPress={toggle}
|
|
107
|
+
* ...
|
|
108
|
+
* />
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export function useSpeechRecognition(
|
|
112
|
+
options: UseSpeechRecognitionOptions = {},
|
|
113
|
+
): UseSpeechRecognitionReturn {
|
|
114
|
+
const {
|
|
115
|
+
lang = DEFAULT_LANG,
|
|
116
|
+
interimResults = true,
|
|
117
|
+
continuous = false,
|
|
118
|
+
addsPunctuation = true,
|
|
119
|
+
onFinalResult,
|
|
120
|
+
} = options;
|
|
121
|
+
|
|
122
|
+
const [isListening, setIsListening] = useState(false);
|
|
123
|
+
const [transcript, setTranscript] = useState('');
|
|
124
|
+
const [error, setError] = useState<UseSpeechRecognitionReturn['error']>(null);
|
|
125
|
+
|
|
126
|
+
// Keep the latest onFinalResult in a ref so consumers don't have to
|
|
127
|
+
// memoize it to avoid re-registering listeners.
|
|
128
|
+
const onFinalResultRef = useRef(onFinalResult);
|
|
129
|
+
onFinalResultRef.current = onFinalResult;
|
|
130
|
+
|
|
131
|
+
// --- Native event listeners (auto-cleanup on unmount) -------------------
|
|
132
|
+
|
|
133
|
+
useSpeechRecognitionEvent('start', () => {
|
|
134
|
+
setIsListening(true);
|
|
135
|
+
setError(null);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
useSpeechRecognitionEvent('end', () => {
|
|
139
|
+
setIsListening(false);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
useSpeechRecognitionEvent('result', (event) => {
|
|
143
|
+
// `event.results` is an array of alternatives; the first entry is the
|
|
144
|
+
// best transcript per the platform's ranking. We only render that one.
|
|
145
|
+
const best = event.results[0]?.transcript ?? '';
|
|
146
|
+
setTranscript(best);
|
|
147
|
+
|
|
148
|
+
if (event.isFinal) {
|
|
149
|
+
onFinalResultRef.current?.(best);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
useSpeechRecognitionEvent('error', (event) => {
|
|
154
|
+
// `no-speech` is a soft "nothing was said" signal, not a hard error —
|
|
155
|
+
// it still fires `end` afterwards, so just surface it quietly.
|
|
156
|
+
setError({ code: event.error, message: event.message });
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// --- Control methods -----------------------------------------------------
|
|
160
|
+
|
|
161
|
+
const start = useCallback(async () => {
|
|
162
|
+
// Check current permissions first, only prompt if they're missing —
|
|
163
|
+
// requesting every time is jarring and will hit the dialog dismissal
|
|
164
|
+
// cap on iOS.
|
|
165
|
+
const current = await ExpoSpeechRecognitionModule.getPermissionsAsync();
|
|
166
|
+
if (!current.granted) {
|
|
167
|
+
const requested =
|
|
168
|
+
await ExpoSpeechRecognitionModule.requestPermissionsAsync();
|
|
169
|
+
if (!requested.granted) {
|
|
170
|
+
setError({
|
|
171
|
+
code: 'not-allowed',
|
|
172
|
+
message:
|
|
173
|
+
'Speech recognition permission was denied. Enable it in Settings to use voice input.',
|
|
174
|
+
});
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Fresh run → clear any stale transcript/error from the previous turn.
|
|
180
|
+
setTranscript('');
|
|
181
|
+
setError(null);
|
|
182
|
+
|
|
183
|
+
const recognitionOptions: ExpoSpeechRecognitionOptions = {
|
|
184
|
+
lang,
|
|
185
|
+
interimResults,
|
|
186
|
+
continuous,
|
|
187
|
+
addsPunctuation,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
ExpoSpeechRecognitionModule.start(recognitionOptions);
|
|
192
|
+
} catch (err) {
|
|
193
|
+
setError({
|
|
194
|
+
code: 'client',
|
|
195
|
+
message: err instanceof Error ? err.message : String(err),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}, [lang, interimResults, continuous, addsPunctuation]);
|
|
199
|
+
|
|
200
|
+
const stop = useCallback(() => {
|
|
201
|
+
try {
|
|
202
|
+
ExpoSpeechRecognitionModule.stop();
|
|
203
|
+
} catch {
|
|
204
|
+
// If stop is called while not listening it's a no-op — swallow.
|
|
205
|
+
}
|
|
206
|
+
}, []);
|
|
207
|
+
|
|
208
|
+
const toggle = useCallback(async () => {
|
|
209
|
+
if (isListening) {
|
|
210
|
+
stop();
|
|
211
|
+
} else {
|
|
212
|
+
await start();
|
|
213
|
+
}
|
|
214
|
+
}, [isListening, start, stop]);
|
|
215
|
+
|
|
216
|
+
const reset = useCallback(() => {
|
|
217
|
+
setTranscript('');
|
|
218
|
+
setError(null);
|
|
219
|
+
}, []);
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
isListening,
|
|
223
|
+
transcript,
|
|
224
|
+
error,
|
|
225
|
+
start,
|
|
226
|
+
stop,
|
|
227
|
+
toggle,
|
|
228
|
+
reset,
|
|
229
|
+
};
|
|
230
|
+
}
|