@apia/ai 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/components/chat/AutoscrollContainer.js +58 -0
  2. package/dist/components/chat/AutoscrollContainer.js.map +1 -0
  3. package/dist/components/chat/ChatController.d.ts +38 -0
  4. package/dist/components/chat/ChatController.d.ts.map +1 -0
  5. package/dist/components/chat/ChatController.js +124 -0
  6. package/dist/components/chat/ChatController.js.map +1 -0
  7. package/dist/components/chat/Textarea.js +218 -0
  8. package/dist/components/chat/Textarea.js.map +1 -0
  9. package/dist/components/chat/files/useHandleFileUpload.js +61 -0
  10. package/dist/components/chat/files/useHandleFileUpload.js.map +1 -0
  11. package/dist/components/chat/messages/ChatMessage.d.ts +14 -0
  12. package/dist/components/chat/messages/ChatMessage.d.ts.map +1 -0
  13. package/dist/components/chat/messages/ChatMessage.js +52 -0
  14. package/dist/components/chat/messages/ChatMessage.js.map +1 -0
  15. package/dist/components/chat/messages/MultipleChoiceMessage.d.ts +21 -0
  16. package/dist/components/chat/messages/MultipleChoiceMessage.d.ts.map +1 -0
  17. package/dist/components/chat/messages/MultipleChoiceMessage.js +38 -0
  18. package/dist/components/chat/messages/MultipleChoiceMessage.js.map +1 -0
  19. package/dist/files/ocr/getImageOcrMaker.js +34 -0
  20. package/dist/files/ocr/getImageOcrMaker.js.map +1 -0
  21. package/dist/files/pdf/getPdfReader.js +45 -0
  22. package/dist/files/pdf/getPdfReader.js.map +1 -0
  23. package/dist/index.d.ts +4 -61
  24. package/dist/index.js +4 -614
  25. package/dist/index.js.map +1 -1
  26. package/package.json +23 -34
  27. package/LICENSE.md +0 -21
  28. package/README.md +0 -28
  29. package/cleanDist.json +0 -3
@@ -0,0 +1,58 @@
1
+ import { jsx } from '@apia/theme/jsx-runtime';
2
+ import { Box, getVariant } from '@apia/theme';
3
+ import { useRef, useCallback } from 'react';
4
+
5
+ const AutoscrollContainer = ({ children }) => {
6
+ const observer = useRef(null);
7
+ const unsuscribe = useRef(null);
8
+ const isFullScrolled = useRef(false);
9
+ const hasInited = useRef(false);
10
+ const ref = useCallback((el) => {
11
+ if (!el)
12
+ return;
13
+ if (!hasInited.current) {
14
+ hasInited.current = true;
15
+ el.scrollTo({
16
+ top: el.getBoundingClientRect().height,
17
+ behavior: "auto"
18
+ });
19
+ isFullScrolled.current = true;
20
+ }
21
+ observer.current?.disconnect();
22
+ unsuscribe.current?.();
23
+ observer.current = new MutationObserver(([mutation]) => {
24
+ if (mutation && mutation.target instanceof HTMLElement && mutation.target === el) {
25
+ if (isFullScrolled.current && mutation.target.scrollTop !== mutation.target.scrollHeight - mutation.target.offsetHeight) {
26
+ mutation.target.scrollTo({
27
+ top: mutation.target.scrollHeight,
28
+ behavior: "smooth"
29
+ });
30
+ }
31
+ }
32
+ });
33
+ observer.current.observe(el, { childList: true, subtree: true });
34
+ const handleScroll = (ev) => {
35
+ if (ev.target === el && el instanceof HTMLElement) {
36
+ setTimeout(() => {
37
+ isFullScrolled.current = Math.abs(el.scrollTop - (el.scrollHeight - el.offsetHeight)) < 150;
38
+ }, 100);
39
+ }
40
+ };
41
+ el.addEventListener("scroll", handleScroll);
42
+ unsuscribe.current = () => {
43
+ el.removeEventListener("scroll", handleScroll);
44
+ };
45
+ }, []);
46
+ return /* @__PURE__ */ jsx(
47
+ Box,
48
+ {
49
+ ...getVariant("layout.common.components.autoscrollContainer"),
50
+ className: "autoscrollContainer",
51
+ ref,
52
+ children
53
+ }
54
+ );
55
+ };
56
+
57
+ export { AutoscrollContainer };
58
+ //# sourceMappingURL=AutoscrollContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoscrollContainer.js","sources":["../../../src/components/chat/AutoscrollContainer.tsx"],"sourcesContent":["import { getVariant } from '@apia/theme';\nimport { ReactNode, useCallback, useRef } from 'react';\nimport { Box } from '@apia/theme';\n\nexport const AutoscrollContainer = ({ children }: { children: ReactNode }) => {\n const observer = useRef<MutationObserver | null>(null);\n const unsuscribe = useRef<(() => void) | null>(null);\n const isFullScrolled = useRef(false);\n const hasInited = useRef(false);\n\n const ref = useCallback((el: HTMLElement) => {\n if (!el) return;\n\n if (!hasInited.current) {\n hasInited.current = true;\n el.scrollTo({\n top: el.getBoundingClientRect().height,\n behavior: 'auto',\n });\n isFullScrolled.current = true;\n }\n\n observer.current?.disconnect();\n unsuscribe.current?.();\n\n observer.current = new MutationObserver(([mutation]) => {\n if (\n mutation &&\n mutation.target instanceof HTMLElement &&\n mutation.target === el\n ) {\n if (\n isFullScrolled.current &&\n mutation.target.scrollTop !==\n mutation.target.scrollHeight - mutation.target.offsetHeight\n ) {\n // eslint-disable-next-line no-param-reassign\n mutation.target.scrollTo({\n top: mutation.target.scrollHeight,\n behavior: 'smooth',\n });\n }\n }\n });\n observer.current.observe(el, { childList: true, subtree: true });\n\n const handleScroll = (ev: Event) => {\n if (ev.target === el && el instanceof HTMLElement) {\n setTimeout(() => {\n isFullScrolled.current =\n Math.abs(el.scrollTop - (el.scrollHeight - el.offsetHeight)) < 150;\n }, 100);\n }\n };\n el.addEventListener('scroll', handleScroll);\n unsuscribe.current = () => {\n el.removeEventListener('scroll', handleScroll);\n };\n }, []);\n\n return (\n <Box\n {...getVariant('layout.common.components.autoscrollContainer')}\n className=\"autoscrollContainer\"\n ref={ref}\n >\n {children}\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;AAIO,MAAM,mBAAsB,GAAA,CAAC,EAAE,QAAA,EAAwC,KAAA;AAC5E,EAAM,MAAA,QAAA,GAAW,OAAgC,IAAI,CAAA,CAAA;AACrD,EAAM,MAAA,UAAA,GAAa,OAA4B,IAAI,CAAA,CAAA;AACnD,EAAM,MAAA,cAAA,GAAiB,OAAO,KAAK,CAAA,CAAA;AACnC,EAAM,MAAA,SAAA,GAAY,OAAO,KAAK,CAAA,CAAA;AAE9B,EAAM,MAAA,GAAA,GAAM,WAAY,CAAA,CAAC,EAAoB,KAAA;AAC3C,IAAA,IAAI,CAAC,EAAA;AAAI,MAAA,OAAA;AAET,IAAI,IAAA,CAAC,UAAU,OAAS,EAAA;AACtB,MAAA,SAAA,CAAU,OAAU,GAAA,IAAA,CAAA;AACpB,MAAA,EAAA,CAAG,QAAS,CAAA;AAAA,QACV,GAAA,EAAK,EAAG,CAAA,qBAAA,EAAwB,CAAA,MAAA;AAAA,QAChC,QAAU,EAAA,MAAA;AAAA,OACX,CAAA,CAAA;AACD,MAAA,cAAA,CAAe,OAAU,GAAA,IAAA,CAAA;AAAA,KAC3B;AAEA,IAAA,QAAA,CAAS,SAAS,UAAW,EAAA,CAAA;AAC7B,IAAA,UAAA,CAAW,OAAU,IAAA,CAAA;AAErB,IAAA,QAAA,CAAS,UAAU,IAAI,gBAAA,CAAiB,CAAC,CAAC,QAAQ,CAAM,KAAA;AACtD,MAAA,IACE,YACA,QAAS,CAAA,MAAA,YAAkB,WAC3B,IAAA,QAAA,CAAS,WAAW,EACpB,EAAA;AACA,QACE,IAAA,cAAA,CAAe,OACf,IAAA,QAAA,CAAS,MAAO,CAAA,SAAA,KACd,SAAS,MAAO,CAAA,YAAA,GAAe,QAAS,CAAA,MAAA,CAAO,YACjD,EAAA;AAEA,UAAA,QAAA,CAAS,OAAO,QAAS,CAAA;AAAA,YACvB,GAAA,EAAK,SAAS,MAAO,CAAA,YAAA;AAAA,YACrB,QAAU,EAAA,QAAA;AAAA,WACX,CAAA,CAAA;AAAA,SACH;AAAA,OACF;AAAA,KACD,CAAA,CAAA;AACD,IAAS,QAAA,CAAA,OAAA,CAAQ,QAAQ,EAAI,EAAA,EAAE,WAAW,IAAM,EAAA,OAAA,EAAS,MAAM,CAAA,CAAA;AAE/D,IAAM,MAAA,YAAA,GAAe,CAAC,EAAc,KAAA;AAClC,MAAA,IAAI,EAAG,CAAA,MAAA,KAAW,EAAM,IAAA,EAAA,YAAc,WAAa,EAAA;AACjD,QAAA,UAAA,CAAW,MAAM;AACf,UAAe,cAAA,CAAA,OAAA,GACb,KAAK,GAAI,CAAA,EAAA,CAAG,aAAa,EAAG,CAAA,YAAA,GAAe,EAAG,CAAA,YAAA,CAAa,CAAI,GAAA,GAAA,CAAA;AAAA,WAChE,GAAG,CAAA,CAAA;AAAA,OACR;AAAA,KACF,CAAA;AACA,IAAG,EAAA,CAAA,gBAAA,CAAiB,UAAU,YAAY,CAAA,CAAA;AAC1C,IAAA,UAAA,CAAW,UAAU,MAAM;AACzB,MAAG,EAAA,CAAA,mBAAA,CAAoB,UAAU,YAAY,CAAA,CAAA;AAAA,KAC/C,CAAA;AAAA,GACF,EAAG,EAAE,CAAA,CAAA;AAEL,EACE,uBAAA,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,WAAW,8CAA8C,CAAA;AAAA,MAC7D,SAAU,EAAA,qBAAA;AAAA,MACV,GAAA;AAAA,MAEC,QAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ;;;;"}
@@ -0,0 +1,38 @@
1
+ import * as react from 'react';
2
+ import { EventEmitter } from '@apia/util';
3
+ import { ChatMessage } from './messages/ChatMessage.js';
4
+
5
+ type TMessageType = 'user' | 'system' | 'warning' | 'error' | 'information' | 'response' | 'multipleChoice';
6
+ declare class ChatController extends EventEmitter<{
7
+ listChange: ChatMessage[];
8
+ messageSubmited?: string;
9
+ }> {
10
+ #private;
11
+ id: string;
12
+ constructor(id: string, welcomeMessage?: string);
13
+ components: {
14
+ MessageHistory: () => react.JSX.Element;
15
+ Textarea: {
16
+ ({ hideDeleteButton, isLoading: outIsLoading, onSubmit, preventAppendUserMessages, }: {
17
+ hideDeleteButton?: boolean | undefined;
18
+ isLoading?: boolean | undefined;
19
+ onSubmit: (text: string) => Promise<void>;
20
+ preventAppendUserMessages?: boolean | undefined;
21
+ }): react.JSX.Element;
22
+ displayName: string;
23
+ };
24
+ };
25
+ history: {
26
+ add: (prompt: string) => void;
27
+ next: () => string;
28
+ previous: () => string | undefined;
29
+ useList: () => ChatMessage[];
30
+ };
31
+ messages: {
32
+ add: (message: ChatMessage) => void;
33
+ clear: () => void;
34
+ };
35
+ }
36
+
37
+ export { ChatController, type TMessageType };
38
+ //# sourceMappingURL=ChatController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatController.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,124 @@
1
+ import { jsx } from '@apia/theme/jsx-runtime';
2
+ import { Box, getVariant } from '@apia/theme';
3
+ import { EventEmitter } from '@apia/util';
4
+ import { useState, useEffect } from 'react';
5
+ import { AutoscrollContainer } from './AutoscrollContainer.js';
6
+ import { makeTextarea } from './Textarea.js';
7
+ import { ChatMessage } from './messages/ChatMessage.js';
8
+
9
+ var __defProp = Object.defineProperty;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __publicField = (obj, key, value) => {
12
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
13
+ return value;
14
+ };
15
+ var __accessCheck = (obj, member, msg) => {
16
+ if (!member.has(obj))
17
+ throw TypeError("Cannot " + msg);
18
+ };
19
+ var __privateGet = (obj, member, getter) => {
20
+ __accessCheck(obj, member, "read from private field");
21
+ return getter ? getter.call(obj) : member.get(obj);
22
+ };
23
+ var __privateAdd = (obj, member, value) => {
24
+ if (member.has(obj))
25
+ throw TypeError("Cannot add the same private member more than once");
26
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
27
+ };
28
+ var __privateSet = (obj, member, value, setter) => {
29
+ __accessCheck(obj, member, "write to private field");
30
+ setter ? setter.call(obj, value) : member.set(obj, value);
31
+ return value;
32
+ };
33
+ var __privateWrapper = (obj, member, setter, getter) => ({
34
+ set _(value) {
35
+ __privateSet(obj, member, value, setter);
36
+ },
37
+ get _() {
38
+ return __privateGet(obj, member, getter);
39
+ }
40
+ });
41
+ var _messages, _promptsHistory, _currentHistoryIndex;
42
+ class ChatController extends EventEmitter {
43
+ constructor(id, welcomeMessage) {
44
+ super();
45
+ this.id = id;
46
+ __privateAdd(this, _messages, []);
47
+ __publicField(this, "components", {
48
+ MessageHistory: () => {
49
+ const messages = this.history.useList();
50
+ return /* @__PURE__ */ jsx(
51
+ Box,
52
+ {
53
+ ...getVariant("layout.common.components.chat"),
54
+ className: "history",
55
+ children: /* @__PURE__ */ jsx(AutoscrollContainer, { children: messages.map((current) => /* @__PURE__ */ jsx(
56
+ Box,
57
+ {
58
+ as: "pre",
59
+ className: `history__message ${current.messageType}`,
60
+ ...typeof current.message === "string" ? { dangerouslySetInnerHTML: { __html: current.message } } : { children: current.message }
61
+ },
62
+ current.id
63
+ )) })
64
+ }
65
+ );
66
+ },
67
+ Textarea: makeTextarea(this)
68
+ });
69
+ __privateAdd(this, _promptsHistory, []);
70
+ __privateAdd(this, _currentHistoryIndex, -1);
71
+ __publicField(this, "history", {
72
+ add: (prompt) => {
73
+ __privateSet(this, _currentHistoryIndex, -1);
74
+ if (prompt === __privateGet(this, _promptsHistory)[__privateGet(this, _promptsHistory).length]) {
75
+ return;
76
+ }
77
+ __privateSet(this, _promptsHistory, [
78
+ prompt,
79
+ ...__privateGet(this, _promptsHistory).slice(
80
+ Math.max(0, __privateGet(this, _promptsHistory).length - 10)
81
+ )
82
+ ]);
83
+ },
84
+ next: () => {
85
+ if (__privateGet(this, _promptsHistory)[__privateGet(this, _currentHistoryIndex) - 1])
86
+ return __privateGet(this, _promptsHistory)[--__privateWrapper(this, _currentHistoryIndex)._];
87
+ else {
88
+ __privateSet(this, _currentHistoryIndex, -1);
89
+ return "";
90
+ }
91
+ },
92
+ previous: () => {
93
+ if (__privateGet(this, _promptsHistory)[__privateGet(this, _currentHistoryIndex) + 1]) {
94
+ return __privateGet(this, _promptsHistory)[++__privateWrapper(this, _currentHistoryIndex)._];
95
+ }
96
+ },
97
+ useList: () => {
98
+ const [messages, setMessages] = useState(__privateGet(this, _messages));
99
+ useEffect(() => {
100
+ return this.on("listChange", (messages2) => setMessages(messages2));
101
+ }, []);
102
+ return messages;
103
+ }
104
+ });
105
+ __publicField(this, "messages", {
106
+ add: (message) => {
107
+ __privateGet(this, _messages).push(message);
108
+ this.emit("listChange", [...__privateGet(this, _messages)]);
109
+ },
110
+ clear: () => {
111
+ __privateSet(this, _messages, []);
112
+ this.emit("listChange", []);
113
+ }
114
+ });
115
+ if (welcomeMessage)
116
+ __privateGet(this, _messages).push(new ChatMessage(welcomeMessage, "system"));
117
+ }
118
+ }
119
+ _messages = new WeakMap();
120
+ _promptsHistory = new WeakMap();
121
+ _currentHistoryIndex = new WeakMap();
122
+
123
+ export { ChatController };
124
+ //# sourceMappingURL=ChatController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatController.js","sources":["../../../src/components/chat/ChatController.tsx"],"sourcesContent":["/* eslint-disable no-param-reassign */\nimport { getVariant } from '@apia/theme';\nimport { EventEmitter } from '@apia/util';\nimport { useEffect, useState } from 'react';\nimport { Box } from '@apia/theme';\nimport { AutoscrollContainer } from './AutoscrollContainer';\nimport { makeTextarea } from './Textarea';\nimport { ChatMessage } from './messages/ChatMessage';\n\nexport type TMessageType =\n | 'user'\n | 'system'\n | 'warning'\n | 'error'\n | 'information'\n | 'response'\n | 'multipleChoice';\n\nexport class ChatController extends EventEmitter<{\n listChange: ChatMessage[];\n messageSubmited?: string;\n}> {\n #messages: ChatMessage[] = [];\n\n constructor(\n public id: string,\n welcomeMessage?: string,\n ) {\n super();\n if (welcomeMessage)\n this.#messages.push(new ChatMessage(welcomeMessage, 'system'));\n }\n\n components = {\n MessageHistory: () => {\n const messages = this.history.useList();\n\n return (\n <Box\n {...getVariant('layout.common.components.chat')}\n className=\"history\"\n >\n <AutoscrollContainer>\n {messages.map((current) => (\n <Box\n as=\"pre\"\n className={`history__message ${current.messageType}`}\n key={current.id}\n {...(typeof current.message === 'string'\n ? { dangerouslySetInnerHTML: { __html: current.message } }\n : { children: current.message })}\n />\n ))}\n </AutoscrollContainer>\n </Box>\n );\n },\n Textarea: makeTextarea(this),\n };\n\n #promptsHistory: string[] = [];\n #currentHistoryIndex = -1;\n\n history = {\n add: (prompt: string) => {\n this.#currentHistoryIndex = -1;\n\n if (prompt === this.#promptsHistory[this.#promptsHistory.length]) {\n return;\n }\n\n this.#promptsHistory = [\n prompt,\n ...this.#promptsHistory.slice(\n Math.max(0, this.#promptsHistory.length - 10),\n ),\n ];\n },\n next: () => {\n if (this.#promptsHistory[this.#currentHistoryIndex - 1])\n return this.#promptsHistory[--this.#currentHistoryIndex];\n else {\n this.#currentHistoryIndex = -1;\n return '';\n }\n },\n previous: () => {\n if (this.#promptsHistory[this.#currentHistoryIndex + 1]) {\n return this.#promptsHistory[++this.#currentHistoryIndex];\n }\n },\n useList: () => {\n const [messages, setMessages] = useState<ChatMessage[]>(this.#messages);\n\n useEffect(() => {\n return this.on('listChange', (messages) => setMessages(messages));\n }, []);\n\n return messages;\n },\n };\n\n messages = {\n add: (message: ChatMessage) => {\n this.#messages.push(message);\n this.emit('listChange', [...this.#messages]);\n },\n clear: () => {\n this.#messages = [];\n this.emit('listChange', []);\n },\n };\n}\n"],"names":["messages"],"mappings":"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"}
@@ -0,0 +1,218 @@
1
+ import { jsxs, jsx } from '@apia/theme/jsx-runtime';
2
+ import { useState, useCallback } from 'react';
3
+ import { IconButton, SimpleButton } from '@apia/components';
4
+ import { Box, Textarea } from '@apia/theme';
5
+ import useHandleFileUpload, { WrongFormatError } from './files/useHandleFileUpload.js';
6
+ import { getLabel } from '@apia/util';
7
+ import { ChatMessage } from './messages/ChatMessage.js';
8
+
9
+ const makeTextarea = (gptController) => {
10
+ const NewTextarea = ({
11
+ hideDeleteButton,
12
+ isLoading: outIsLoading,
13
+ onSubmit,
14
+ preventAppendUserMessages
15
+ }) => {
16
+ const [isLoading, setIsLoading] = useState(false);
17
+ const submit = useCallback(
18
+ (text) => {
19
+ if (preventAppendUserMessages !== true)
20
+ gptController.messages.add(new ChatMessage(text, "user"));
21
+ gptController.history.add(text);
22
+ onSubmit(text).finally(() => {
23
+ setIsLoading(false);
24
+ });
25
+ },
26
+ [onSubmit, preventAppendUserMessages]
27
+ );
28
+ const handleSubmit = useCallback(
29
+ (ev) => {
30
+ ev.preventDefault();
31
+ const textarea = document.getElementById(
32
+ `GPTMessage${gptController.id}`
33
+ );
34
+ if (textarea.value) {
35
+ setIsLoading(true);
36
+ submit(textarea.value);
37
+ }
38
+ textarea.focus();
39
+ textarea.value = "";
40
+ },
41
+ [submit]
42
+ );
43
+ const onKeyDown = useCallback((ev) => {
44
+ if (ev.target.readOnly)
45
+ return;
46
+ if (ev.code === "Enter" && !ev.shiftKey) {
47
+ ev.preventDefault();
48
+ ev.target.closest("form")?.querySelector('button[type="submit"]')?.click();
49
+ }
50
+ }, []);
51
+ const { progress, handleFileUpload } = useHandleFileUpload({
52
+ onContent(content) {
53
+ document.getElementById(
54
+ `GPTMessage${gptController.id}`
55
+ ).value = content.join("\n\n");
56
+ }
57
+ });
58
+ const actualIsLoading = isLoading || progress !== 100 || outIsLoading;
59
+ const [dragging, setDragging] = useState(false);
60
+ const handleDragLeave = (ev) => {
61
+ ev.preventDefault();
62
+ setDragging(false);
63
+ };
64
+ const handleDrop = (ev) => {
65
+ ev.preventDefault();
66
+ setDragging(false);
67
+ const fileElement = document.getElementById(
68
+ `gptUploadFile__${gptController.id}`
69
+ );
70
+ fileElement.files = ev.dataTransfer.files;
71
+ const event = new Event("change", { bubbles: true });
72
+ fileElement.dispatchEvent(event);
73
+ };
74
+ const handleDragOver = (ev) => {
75
+ ev.preventDefault();
76
+ };
77
+ const handleDragEnter = (ev) => {
78
+ ev.preventDefault();
79
+ setDragging(true);
80
+ };
81
+ return /* @__PURE__ */ jsxs(
82
+ "form",
83
+ {
84
+ onDrop: handleDrop,
85
+ onDragOver: handleDragOver,
86
+ onDragEnter: handleDragEnter,
87
+ onDragLeave: handleDragLeave,
88
+ onSubmit: handleSubmit,
89
+ className: "gpt__form",
90
+ action: "",
91
+ children: [
92
+ dragging ? /* @__PURE__ */ jsx(
93
+ Box,
94
+ {
95
+ sx: {
96
+ height: "150px",
97
+ border: "3px dashed #aaa",
98
+ width: "100%",
99
+ display: "flex",
100
+ alignItems: "center",
101
+ justifyContent: "center"
102
+ },
103
+ children: getLabel("msgAiDragAndDrop").text
104
+ }
105
+ ) : /* @__PURE__ */ jsx(
106
+ Textarea,
107
+ {
108
+ onKeyDown,
109
+ id: `GPTMessage${gptController.id}`,
110
+ readOnly: actualIsLoading
111
+ }
112
+ ),
113
+ /* @__PURE__ */ jsxs(Box, { className: "gpt__buttonsContainer", children: [
114
+ /* @__PURE__ */ jsx(Box, { sx: { display: "none" }, children: /* @__PURE__ */ jsx(
115
+ "input",
116
+ {
117
+ type: "file",
118
+ className: "gptUploadFile",
119
+ id: `gptUploadFile__${gptController.id}`,
120
+ onChange: (ev) => {
121
+ handleFileUpload(ev).catch((e) => {
122
+ if (e instanceof WrongFormatError) {
123
+ setIsLoading(false);
124
+ gptController.messages.add(
125
+ new ChatMessage(
126
+ getLabel("msgAiFileExtensionError").text,
127
+ "error"
128
+ )
129
+ );
130
+ } else {
131
+ throw e;
132
+ }
133
+ });
134
+ }
135
+ }
136
+ ) }),
137
+ /* @__PURE__ */ jsx(
138
+ IconButton,
139
+ {
140
+ title: getLabel("btnUploadFile").text,
141
+ icon: "File",
142
+ variant: "icon-outline",
143
+ disabled: actualIsLoading,
144
+ onClick: () => {
145
+ document.getElementById(
146
+ `gptUploadFile__${gptController.id}`
147
+ ).click();
148
+ },
149
+ size: "Lg"
150
+ }
151
+ ),
152
+ /* @__PURE__ */ jsx(
153
+ SimpleButton,
154
+ {
155
+ title: getLabel("btnAiPrevious").tooltip,
156
+ variant: "outline",
157
+ type: "button",
158
+ onClick: () => {
159
+ const historyValue = gptController.history.previous();
160
+ if (historyValue)
161
+ document.getElementById(
162
+ `GPTMessage${gptController.id}`
163
+ ).value = historyValue;
164
+ },
165
+ size: "sm",
166
+ children: getLabel("btnAiPrevious").text
167
+ }
168
+ ),
169
+ /* @__PURE__ */ jsx(
170
+ SimpleButton,
171
+ {
172
+ title: getLabel("btnAiNext").tooltip,
173
+ variant: "outline",
174
+ type: "button",
175
+ onClick: () => {
176
+ const historyValue = gptController.history.next();
177
+ document.getElementById(
178
+ `GPTMessage${gptController.id}`
179
+ ).value = historyValue ?? "";
180
+ },
181
+ size: "sm",
182
+ children: getLabel("btnAiNext").text
183
+ }
184
+ ),
185
+ !hideDeleteButton && /* @__PURE__ */ jsx(
186
+ SimpleButton,
187
+ {
188
+ title: getLabel("btnAiDelete").tooltip,
189
+ variant: "outline",
190
+ type: "button",
191
+ onClick: () => document.getElementById(
192
+ `GPTMessage${gptController.id}`
193
+ ).value = "",
194
+ size: "sm",
195
+ children: getLabel("btnAiDelete").text
196
+ }
197
+ ),
198
+ /* @__PURE__ */ jsx(
199
+ SimpleButton,
200
+ {
201
+ title: getLabel("btnAiSend").tooltip,
202
+ isLoading: actualIsLoading,
203
+ type: "submit",
204
+ size: "sm",
205
+ children: getLabel("btnAiSend").text
206
+ }
207
+ )
208
+ ] })
209
+ ]
210
+ }
211
+ );
212
+ };
213
+ NewTextarea.displayName = "";
214
+ return NewTextarea;
215
+ };
216
+
217
+ export { makeTextarea };
218
+ //# sourceMappingURL=Textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.js","sources":["../../../src/components/chat/Textarea.tsx"],"sourcesContent":["/* eslint-disable no-param-reassign */\nimport { FormEvent, KeyboardEvent, useCallback, useState } from 'react';\nimport { ChatController } from './ChatController';\nimport { IconButton, SimpleButton } from '@apia/components';\nimport { Box, Textarea } from '@apia/theme';\nimport useHandleFileUpload, {\n WrongFormatError,\n} from './files/useHandleFileUpload';\nimport { getLabel } from '@apia/util';\nimport { ChatMessage } from './messages/ChatMessage';\n\nexport const makeTextarea = (gptController: ChatController) => {\n const NewTextarea = ({\n hideDeleteButton,\n isLoading: outIsLoading,\n onSubmit,\n preventAppendUserMessages,\n }: {\n hideDeleteButton?: boolean;\n isLoading?: boolean;\n onSubmit: (text: string) => Promise<void>;\n preventAppendUserMessages?: boolean;\n }) => {\n const [isLoading, setIsLoading] = useState(false);\n\n const submit = useCallback(\n (text: string) => {\n if (preventAppendUserMessages !== true)\n gptController.messages.add(new ChatMessage(text, 'user'));\n\n gptController.history.add(text);\n\n onSubmit(text).finally(() => {\n setIsLoading(false);\n });\n },\n [onSubmit, preventAppendUserMessages],\n );\n\n const handleSubmit = useCallback(\n (ev: FormEvent<HTMLFormElement>) => {\n ev.preventDefault();\n //setIsLoading(true);\n const textarea = document.getElementById(\n `GPTMessage${gptController.id}`,\n ) as HTMLTextAreaElement;\n\n if (textarea.value) {\n setIsLoading(true);\n submit(textarea.value);\n }\n\n textarea.focus();\n textarea.value = '';\n },\n [submit],\n );\n\n const onKeyDown = useCallback((ev: KeyboardEvent) => {\n if ((ev.target as HTMLTextAreaElement).readOnly) return;\n\n if (ev.code === 'Enter' && !ev.shiftKey) {\n ev.preventDefault();\n (ev.target as HTMLElement)\n .closest('form')\n ?.querySelector<HTMLButtonElement>('button[type=\"submit\"]')\n ?.click();\n }\n }, []);\n\n const { progress, handleFileUpload } = useHandleFileUpload({\n onContent(content) {\n (\n document.getElementById(\n `GPTMessage${gptController.id}`,\n ) as HTMLTextAreaElement\n ).value = content.join('\\n\\n');\n },\n });\n\n const actualIsLoading = isLoading || progress !== 100 || outIsLoading;\n\n const [dragging, setDragging] = useState(false);\n\n const handleDragLeave = (ev: React.DragEvent<HTMLElement>) => {\n ev.preventDefault();\n setDragging(false);\n };\n\n const handleDrop = (ev: React.DragEvent<HTMLFormElement>) => {\n ev.preventDefault();\n setDragging(false);\n const fileElement = document.getElementById(\n `gptUploadFile__${gptController.id}`,\n ) as HTMLInputElement;\n fileElement.files = ev.dataTransfer.files;\n const event = new Event('change', { bubbles: true });\n fileElement.dispatchEvent(event);\n };\n\n const handleDragOver = (ev: React.DragEvent<HTMLElement>) => {\n ev.preventDefault();\n };\n\n const handleDragEnter = (ev: React.DragEvent<HTMLElement>) => {\n ev.preventDefault();\n setDragging(true);\n };\n\n return (\n <form\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onSubmit={handleSubmit}\n className=\"gpt__form\"\n action=\"\"\n >\n {dragging ? (\n <Box\n sx={{\n height: '150px',\n border: '3px dashed #aaa',\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {getLabel('msgAiDragAndDrop').text}\n </Box>\n ) : (\n <Textarea\n onKeyDown={onKeyDown}\n id={`GPTMessage${gptController.id}`}\n readOnly={actualIsLoading}\n />\n )}\n\n <Box className=\"gpt__buttonsContainer\">\n <Box sx={{ display: 'none' }}>\n <input\n type=\"file\"\n className=\"gptUploadFile\"\n id={`gptUploadFile__${gptController.id}`}\n onChange={(ev) => {\n handleFileUpload(ev).catch((e) => {\n if (e instanceof WrongFormatError) {\n setIsLoading(false);\n gptController.messages.add(\n new ChatMessage(\n getLabel('msgAiFileExtensionError').text,\n 'error',\n ),\n );\n } else {\n throw e;\n }\n });\n }}\n />\n </Box>\n <IconButton\n title={getLabel('btnUploadFile').text}\n icon=\"File\"\n variant=\"icon-outline\"\n disabled={actualIsLoading}\n onClick={() => {\n (\n document.getElementById(\n `gptUploadFile__${gptController.id}`,\n ) as HTMLElement\n ).click();\n }}\n size=\"Lg\"\n />\n <SimpleButton\n title={getLabel('btnAiPrevious').tooltip}\n variant=\"outline\"\n type=\"button\"\n onClick={() => {\n const historyValue = gptController.history.previous();\n if (historyValue)\n (\n document.getElementById(\n `GPTMessage${gptController.id}`,\n ) as HTMLTextAreaElement\n ).value = historyValue;\n }}\n size=\"sm\"\n >\n {getLabel('btnAiPrevious').text}\n </SimpleButton>\n <SimpleButton\n title={getLabel('btnAiNext').tooltip}\n variant=\"outline\"\n type=\"button\"\n onClick={() => {\n const historyValue = gptController.history.next();\n (\n document.getElementById(\n `GPTMessage${gptController.id}`,\n ) as HTMLTextAreaElement\n ).value = historyValue ?? '';\n }}\n size=\"sm\"\n >\n {getLabel('btnAiNext').text}\n </SimpleButton>\n {!hideDeleteButton && (\n <SimpleButton\n title={getLabel('btnAiDelete').tooltip}\n variant=\"outline\"\n type=\"button\"\n onClick={() =>\n ((\n document.getElementById(\n `GPTMessage${gptController.id}`,\n ) as HTMLInputElement\n ).value = '')\n }\n size=\"sm\"\n >\n {getLabel('btnAiDelete').text}\n </SimpleButton>\n )}\n <SimpleButton\n title={getLabel('btnAiSend').tooltip}\n isLoading={actualIsLoading}\n type=\"submit\"\n size=\"sm\"\n >\n {getLabel('btnAiSend').text}\n </SimpleButton>\n </Box>\n </form>\n );\n };\n\n NewTextarea.displayName = '';\n\n return NewTextarea;\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { useState, useCallback } from 'react';
2
+ import getImageOcrMaker, { isImageFile } from '../../../files/ocr/getImageOcrMaker.js';
3
+ import getPdfReader, { isPdfFile } from '../../../files/pdf/getPdfReader.js';
4
+
5
+ class WrongFormatError extends Error {
6
+ constructor(fileName) {
7
+ super(`File format not supported: ${fileName}`);
8
+ }
9
+ }
10
+ function useHandleFileUpload({
11
+ onContent
12
+ }) {
13
+ const [progress, setProgress] = useState(100);
14
+ const handleFileUpload = useCallback(
15
+ async (ev) => {
16
+ setProgress(0);
17
+ const imageProcessor = getImageOcrMaker();
18
+ const pdfProcessor = getPdfReader();
19
+ await (async () => {
20
+ const obtainedText = [];
21
+ const files = ev.target.files;
22
+ const filesLength = ev.target.files?.length ?? 0;
23
+ if (files) {
24
+ for (let i = 0; i < filesLength; i++) {
25
+ const file = files[i];
26
+ if (!isImageFile(file) && !isPdfFile(file)) {
27
+ setProgress(100);
28
+ throw new WrongFormatError(file.name);
29
+ }
30
+ const handleProgress = (progress2) => {
31
+ setProgress(
32
+ i / filesLength * 100 + 1 / filesLength * 100 * (progress2 / 100)
33
+ );
34
+ };
35
+ let result = "";
36
+ if (imageProcessor.willProcessFile(file)) {
37
+ try {
38
+ result = (await imageProcessor.processFile(file, handleProgress))[0];
39
+ } catch (e) {
40
+ console.error(e);
41
+ }
42
+ } else if (pdfProcessor.willProcessFile(file)) {
43
+ result = (await pdfProcessor.processFile(file, handleProgress)).join("\n\n");
44
+ }
45
+ if (result) {
46
+ obtainedText.push(result);
47
+ }
48
+ setProgress((i + 1) / filesLength * 100);
49
+ }
50
+ }
51
+ onContent(obtainedText);
52
+ })();
53
+ ev.target.value = "";
54
+ },
55
+ [onContent]
56
+ );
57
+ return { progress, handleFileUpload };
58
+ }
59
+
60
+ export { WrongFormatError, useHandleFileUpload as default };
61
+ //# sourceMappingURL=useHandleFileUpload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHandleFileUpload.js","sources":["../../../../src/components/chat/files/useHandleFileUpload.ts"],"sourcesContent":["/* eslint-disable no-param-reassign */\nimport { ChangeEvent, useCallback, useState } from 'react';\nimport getImageOcrMaker, {\n isImageFile,\n} from '../../../files/ocr/getImageOcrMaker';\nimport getPdfReader, { isPdfFile } from '../../../files/pdf/getPdfReader';\n\nexport class WrongFormatError extends Error {\n constructor(fileName: string) {\n super(`File format not supported: ${fileName}`);\n }\n}\n\nexport default function useHandleFileUpload({\n onContent,\n}: {\n onContent: (content: string[]) => unknown;\n}) {\n const [progress, setProgress] = useState(100);\n\n const handleFileUpload = useCallback(\n async (ev: ChangeEvent<HTMLInputElement>) => {\n setProgress(0);\n const imageProcessor = getImageOcrMaker();\n const pdfProcessor = getPdfReader();\n\n await (async () => {\n const obtainedText: string[] = [];\n const files = ev.target.files;\n const filesLength = ev.target.files?.length ?? 0;\n if (files) {\n for (let i = 0; i < filesLength; i++) {\n const file = files[i];\n\n if (!isImageFile(file) && !isPdfFile(file)) {\n setProgress(100);\n throw new WrongFormatError(file.name);\n }\n\n const handleProgress = (progress: number) => {\n setProgress(\n (i / filesLength) * 100 +\n (1 / filesLength) * 100 * (progress / 100),\n );\n };\n\n let result = '';\n if (imageProcessor.willProcessFile(file)) {\n try {\n result = (\n await imageProcessor.processFile(file, handleProgress)\n )[0];\n } catch (e) {\n console.error(e);\n }\n } else if (pdfProcessor.willProcessFile(file)) {\n result = (\n await pdfProcessor.processFile(file, handleProgress)\n ).join('\\n\\n');\n try {\n } catch (e) {\n console.error(e);\n }\n }\n\n if (result) {\n obtainedText.push(result);\n }\n\n setProgress(((i + 1) / filesLength) * 100);\n }\n }\n onContent(obtainedText);\n })();\n\n ev.target.value = '';\n },\n [onContent],\n );\n\n return { progress, handleFileUpload };\n}\n"],"names":["progress"],"mappings":";;;;AAOO,MAAM,yBAAyB,KAAM,CAAA;AAAA,EAC1C,YAAY,QAAkB,EAAA;AAC5B,IAAM,KAAA,CAAA,CAAA,2BAAA,EAA8B,QAAQ,CAAE,CAAA,CAAA,CAAA;AAAA,GAChD;AACF,CAAA;AAEA,SAAwB,mBAAoB,CAAA;AAAA,EAC1C,SAAA;AACF,CAEG,EAAA;AACD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,GAAG,CAAA,CAAA;AAE5C,EAAA,MAAM,gBAAmB,GAAA,WAAA;AAAA,IACvB,OAAO,EAAsC,KAAA;AAC3C,MAAA,WAAA,CAAY,CAAC,CAAA,CAAA;AACb,MAAA,MAAM,iBAAiB,gBAAiB,EAAA,CAAA;AACxC,MAAA,MAAM,eAAe,YAAa,EAAA,CAAA;AAElC,MAAA,MAAA,CAAO,YAAY;AACjB,QAAA,MAAM,eAAyB,EAAC,CAAA;AAChC,QAAM,MAAA,KAAA,GAAQ,GAAG,MAAO,CAAA,KAAA,CAAA;AACxB,QAAA,MAAM,WAAc,GAAA,EAAA,CAAG,MAAO,CAAA,KAAA,EAAO,MAAU,IAAA,CAAA,CAAA;AAC/C,QAAA,IAAI,KAAO,EAAA;AACT,UAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,WAAA,EAAa,CAAK,EAAA,EAAA;AACpC,YAAM,MAAA,IAAA,GAAO,MAAM,CAAC,CAAA,CAAA;AAEpB,YAAA,IAAI,CAAC,WAAY,CAAA,IAAI,KAAK,CAAC,SAAA,CAAU,IAAI,CAAG,EAAA;AAC1C,cAAA,WAAA,CAAY,GAAG,CAAA,CAAA;AACf,cAAM,MAAA,IAAI,gBAAiB,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,aACtC;AAEA,YAAM,MAAA,cAAA,GAAiB,CAACA,SAAqB,KAAA;AAC3C,cAAA,WAAA;AAAA,gBACG,IAAI,WAAe,GAAA,GAAA,GACjB,CAAI,GAAA,WAAA,GAAe,OAAOA,SAAW,GAAA,GAAA,CAAA;AAAA,eAC1C,CAAA;AAAA,aACF,CAAA;AAEA,YAAA,IAAI,MAAS,GAAA,EAAA,CAAA;AACb,YAAI,IAAA,cAAA,CAAe,eAAgB,CAAA,IAAI,CAAG,EAAA;AACxC,cAAI,IAAA;AACF,gBAAA,MAAA,GAAA,CACE,MAAM,cAAe,CAAA,WAAA,CAAY,IAAM,EAAA,cAAc,GACrD,CAAC,CAAA,CAAA;AAAA,uBACI,CAAG,EAAA;AACV,gBAAA,OAAA,CAAQ,MAAM,CAAC,CAAA,CAAA;AAAA,eACjB;AAAA,aACS,MAAA,IAAA,YAAA,CAAa,eAAgB,CAAA,IAAI,CAAG,EAAA;AAC7C,cAAA,MAAA,GAAA,CACE,MAAM,YAAa,CAAA,WAAA,CAAY,MAAM,cAAc,CAAA,EACnD,KAAK,MAAM,CAAA,CAAA;AAIb,aACF;AAEA,YAAA,IAAI,MAAQ,EAAA;AACV,cAAA,YAAA,CAAa,KAAK,MAAM,CAAA,CAAA;AAAA,aAC1B;AAEA,YAAc,WAAA,CAAA,CAAA,CAAA,GAAI,CAAK,IAAA,WAAA,GAAe,GAAG,CAAA,CAAA;AAAA,WAC3C;AAAA,SACF;AACA,QAAA,SAAA,CAAU,YAAY,CAAA,CAAA;AAAA,OACrB,GAAA,CAAA;AAEH,MAAA,EAAA,CAAG,OAAO,KAAQ,GAAA,EAAA,CAAA;AAAA,KACpB;AAAA,IACA,CAAC,SAAS,CAAA;AAAA,GACZ,CAAA;AAEA,EAAO,OAAA,EAAE,UAAU,gBAAiB,EAAA,CAAA;AACtC;;;;"}
@@ -0,0 +1,14 @@
1
+ import { ReactNode } from 'react';
2
+ import { TMessageType } from '../ChatController.js';
3
+
4
+ declare class ChatMessage {
5
+ #private;
6
+ messageType: TMessageType;
7
+ id: number;
8
+ parseMessage(message: string): string;
9
+ constructor(message: ReactNode, messageType: TMessageType);
10
+ get message(): ReactNode;
11
+ }
12
+
13
+ export { ChatMessage };
14
+ //# sourceMappingURL=ChatMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatMessage.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+ var __accessCheck = (obj, member, msg) => {
8
+ if (!member.has(obj))
9
+ throw TypeError("Cannot " + msg);
10
+ };
11
+ var __privateGet = (obj, member, getter) => {
12
+ __accessCheck(obj, member, "read from private field");
13
+ return getter ? getter.call(obj) : member.get(obj);
14
+ };
15
+ var __privateAdd = (obj, member, value) => {
16
+ if (member.has(obj))
17
+ throw TypeError("Cannot add the same private member more than once");
18
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
19
+ };
20
+ var __privateSet = (obj, member, value, setter) => {
21
+ __accessCheck(obj, member, "write to private field");
22
+ setter ? setter.call(obj, value) : member.set(obj, value);
23
+ return value;
24
+ };
25
+ var _message;
26
+ let maxId = 0;
27
+ class ChatMessage {
28
+ constructor(message, messageType) {
29
+ this.messageType = messageType;
30
+ __publicField(this, "id");
31
+ __privateAdd(this, _message, void 0);
32
+ this.id = maxId++;
33
+ __privateSet(this, _message, message);
34
+ if (messageType === "response")
35
+ this.messageType = "system";
36
+ if (typeof message === "string")
37
+ __privateSet(this, _message, this.parseMessage(message));
38
+ }
39
+ parseMessage(message) {
40
+ let result = message;
41
+ result = result.replaceAll("[strong]", "<strong>");
42
+ result = result.replaceAll("[/strong]", "</strong>");
43
+ return result;
44
+ }
45
+ get message() {
46
+ return __privateGet(this, _message);
47
+ }
48
+ }
49
+ _message = new WeakMap();
50
+
51
+ export { ChatMessage };
52
+ //# sourceMappingURL=ChatMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatMessage.js","sources":["../../../../src/components/chat/messages/ChatMessage.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport { TMessageType } from '../ChatController';\n\nlet maxId = 0;\n\nexport class ChatMessage {\n id: number;\n #message: ReactNode;\n\n parseMessage(message: string) {\n let result = message;\n\n result = result.replaceAll('[strong]', '<strong>');\n result = result.replaceAll('[/strong]', '</strong>');\n\n return result;\n }\n\n constructor(message: ReactNode, public messageType: TMessageType) {\n this.id = maxId++;\n this.#message = message;\n\n if (messageType === 'response') this.messageType = 'system';\n if (typeof message === 'string') this.#message = this.parseMessage(message);\n }\n\n get message() {\n return this.#message;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA,QAAA,CAAA;AAGA,IAAI,KAAQ,GAAA,CAAA,CAAA;AAEL,MAAM,WAAY,CAAA;AAAA,EAavB,WAAA,CAAY,SAA2B,WAA2B,EAAA;AAA3B,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA,CAAA;AAZvC,IAAA,aAAA,CAAA,IAAA,EAAA,IAAA,CAAA,CAAA;AACA,IAAA,YAAA,CAAA,IAAA,EAAA,QAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAYE,IAAA,IAAA,CAAK,EAAK,GAAA,KAAA,EAAA,CAAA;AACV,IAAA,YAAA,CAAA,IAAA,EAAK,QAAW,EAAA,OAAA,CAAA,CAAA;AAEhB,IAAA,IAAI,WAAgB,KAAA,UAAA;AAAY,MAAA,IAAA,CAAK,WAAc,GAAA,QAAA,CAAA;AACnD,IAAA,IAAI,OAAO,OAAY,KAAA,QAAA;AAAU,MAAK,YAAA,CAAA,IAAA,EAAA,QAAA,EAAW,IAAK,CAAA,YAAA,CAAa,OAAO,CAAA,CAAA,CAAA;AAAA,GAC5E;AAAA,EAfA,aAAa,OAAiB,EAAA;AAC5B,IAAA,IAAI,MAAS,GAAA,OAAA,CAAA;AAEb,IAAS,MAAA,GAAA,MAAA,CAAO,UAAW,CAAA,UAAA,EAAY,UAAU,CAAA,CAAA;AACjD,IAAS,MAAA,GAAA,MAAA,CAAO,UAAW,CAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AAEnD,IAAO,OAAA,MAAA,CAAA;AAAA,GACT;AAAA,EAUA,IAAI,OAAU,GAAA;AACZ,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,QAAA,CAAA,CAAA;AAAA,GACd;AACF,CAAA;AAtBE,QAAA,GAAA,IAAA,OAAA,EAAA;;;;"}