cf-uploadermain.tsx1 match
2`ZXhwb3J0IGRlZmF1bHQgewoJYXN5bmMgZmV0Y2gocmVxdWVzdCwgZW52LCBjdHgpIHsKCQljb25zdCByZXFVcmwgPSBuZXcgVVJMKHJlcXVlc3QudXJsKTsKCQljb25zb2xlLmxvZyhyZXFVcmwpCgkJaWYgKHJlcVVybC5wYXRobmFtZS5pbmNsdWRlcygiZmV0Y2giKSl7CgkJCWNvbnN0IHVybCA9IGRlY29kZVVSSUNvbXBvbmVudChuZXcgVVJMKHJlcXVlc3QudXJsKS5zZWFyY2hQYXJhbXMuZ2V0KCJkZXN0aW5hdGlvbiIpKTsKCQkJY29uc3QgcmVmZXJlciA9IGRlY29kZVVSSUNvbXBvbmVudChuZXcgVVJMKHJlcXVlc3QudXJsKS5zZWFyY2hQYXJhbXMuZ2V0KCJyZWZlcmVyIikpPz9yZXF1ZXN0LmhlYWRlcnMucmVmZXJlcjsKCQkJbGV0IHJlc3BvbnNlOwoJCQlpZiAodXJsKSB7CgkJCQlyZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCx7CgkJCQkJbWV0aG9kOidIRUFEJywKCQkJCQloZWFkZXJzOnsKCQkJCQkJLi4ucmVxdWVzdC5oZWFkZXJzLAoJCQkJCQkiQ29va2llIjoiIiwKCQkJCQkJUmVmZXJlcjoiaHR0cHM6Ly9hd2lzaC5wcm8iLAoJCQkJCQkiVXNlci1BZ2VudCI6ICJNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0OyBydjoxMzguMCkgR2Vja28vMjAxMDAxMDEgRmlyZWZveC8xMzguMCIsCgkJCQkJCSJBY2NlcHQiOiAiKi8qIiwKCQkJCQkJIkFjY2VwdC1MYW5ndWFnZSI6ICJlbi1VUyxlbjtxPTAuNSIsCgkJCQkJCSJTZWMtRmV0Y2gtRGVzdCI6ICJlbXB0eSIsCgkJCQkJCSJTZWMtRmV0Y2gtTW9kZSI6ICJjb3JzIiwKCQkJCQkJIlNlYy1GZXRjaC1TaXRlIjogImNyb3NzLXNpdGUiLAoJCQkJCQkiUHJhZ21hIjogIm5vLWNhY2hlIiwKCQkJCQkJIkNhY2hlLUNvbnRyb2wiOiAibm8tY2FjaGUiLAoJCQkJCQkiWC1SZXF1ZXN0ZWQtV2l0aCI6ICJYTUxIdHRwUmVxdWVzdCIKCQkJCQl9CgkJCQl9KTsKCQkJCXJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKHJlc3BvbnNlLmJvZHksIHJlc3BvbnNlKTsKCQkJfSBlbHNlIHsKCQkJCXJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKCJFUlIiLHtzdGF0dXM6NDAwfSkKCQkJCWNvbnNvbGUubG9nKCJFcnIiKQoJCQl9CgkJCXJldHVybiByZXNwb25zZTsKCQl9CgkJZWxzZSB7CgkJY29uc3QgZGF0YSA9IGF3YWl0IHJlcXVlc3QuanNvbigpID8/IHt9OwoJCWNvbnN0IGlucHV0RGF0YSA9IGRhdGEuZGF0YSA/PyBbXTsKCQljb25zdCByZXNwb25zZSA9IHsgZGF0YTogW10gfTsKCQljb25zdCB1cGxvYWRQcm9taXNlcyA9IGlucHV0RGF0YS5tYXAoYXN5bmMgKGVsZW1lbnQsIGluZGV4KSA9PiB7CgkJCWNvbnNvbGUubG9nKGAke2luZGV4ICsgMX0vJHtpbnB1dERhdGEubGVuZ3RofWApOwoJCQl0cnkgewoJCQkJY29uc3QgdXJsID0gZWxlbWVudC51cmk7CgkJCQlpZiAodXJsLmVuZHNXaXRoKCIvIikpIHVybC5zbGljZSgwLCAtMSk7CiAgCQkJCWNvbnN0IGxhc3RTbGFzaCA9IHVybC5sYXN0SW5kZXhPZignLycpOwogIAkJCQljb25zdCB1ZmlsZSA9IHVybC5zdWJzdHJpbmcobGFzdFNsYXNoICsgMSk7CgogIAkJCQljb25zdCBsaW5rUmVnZXggPSAvaHR0cHM6XC9cL2Fub25kcm9wXC5uZXRcLyhcZCspL2dtOwogIAkJCQljb25zdCB1cGxvYWRSZXEgPSBhd2FpdCBmZXRjaChgaHR0cHM6Ly9hbm9uZHJvcC5uZXQvcmVtb3RldXBsb2FkdXJsP2tleT0xMzY2NzU4ODQ4MDk3OTQ3NzIzJnVybD0ke2VuY29kZVVSSUNvbXBvbmVudCh1cmwpfSZzZXNzaW9uX2hhc2g9MTM2Njc1ODg0ODA5Nzk0NzcyMy0ke2VuY29kZVVSSUNvbXBvbmVudCh1cmwpfSJgLCB7CiAgICAJCQkJbWV0aG9kOiAiR0VUIiwKICAgIAkJCQloZWFkZXJzOiB7CgkJCQkJCSJVc2VyLUFnZW50IjogIk1vemlsbGEvNS4wIChXaW5kb3dzIE5UIDEwLjA7IFdpbjY0OyB4NjQ7IHJ2OjEzOC4wKSBHZWNrby8yMDEwMDEwMSBGaXJlZm94LzEzOC4wIiwKCQkJCQkJIkFjY2VwdCI6ICIqLyoiLAoJCQkJCQkiQWNjZXB0LUxhbmd1YWdlIjogImVuLVVTLGVuO3E9MC41IiwKCQkJCQkJIkFsdC1Vc2VkIjogImFub25kcm9wLm5ldCIsCgkJCQkJCSJTZWMtRmV0Y2gtRGVzdCI6ICJlbXB0eSIsCgkJCQkJCSJTZWMtRmV0Y2gtTW9kZSI6ICJjb3JzIiwKCQkJCQkJIlNlYy1GZXRjaC1TaXRlIjogInNhbWUtb3JpZ2luIiwKCQkJCQkJIlByaW9yaXR5IjogInU9MCIsCgkJCQkJCSJQcmFnbWEiOiAibm8tY2FjaGUiLAoJCQkJCQkiQ2FjaGUtQ29udHJvbCI6ICJuby1jYWNoZSIKCQkJCQl9CgkJCQl9KTsKICAJCQkJY29uc3QgdXBsb2FkUmVzcCA9IGF3YWl0IHVwbG9hZFJlcS50ZXh0KCk7CiAgCQkJCWNvbnN0IHV1cmwgPSBgaHR0cHM6Ly9hbm9uZHJvcC5uZXQvJHtsaW5rUmVnZXguZXhlYyh1cGxvYWRSZXNwKVsxXX0vJHt1ZmlsZX0/ZG93bmxvYWQ9dHJ1ZWA7CgkJCQljb25zdCBmb3JtID0gbmV3IEZvcm1EYXRhKCk7CgkJCQljb25zdCBmaWxlID0gbmV3IEZpbGUoW2F3YWl0IChhd2FpdCBmZXRjaCh1dXJsKSkuYmxvYigpXSwiZmlsZS50eHQiKQoJCQkJZm9ybS5hcHBlbmQoJ2ZpbGUnLGZpbGUpOwoJCQkJY29uc3QgcmVxID0gYXdhaXQgZmV0Y2goImh0dHBzOi8vdG1wZmlsZXMub3JnL2FwaS92MS91cGxvYWQiLHsKCQkJCQltZXRob2Q6J1BPU1QnLAoJCQkJCWJvZHk6Zm9ybQoJCQkJfSk7CgkJCQljb25zdCByZXNwID0gYXdhaXQgKGF3YWl0IHJlcS5qc29uKCkpLmRhdGEudXJsOwoJCQkJcmV0dXJuIHsKCQkJCQlkdXJhdGlvbjogZWxlbWVudC5kdXJhdGlvbiwKCQkJCQl1cmk6IGBodHRwczovL3RtcGZpbGVzLm9yZy9kbC8ke3Jlc3Auc3BsaXQoIi8vdG1wZmlsZXMub3JnLyIpWzFdfWAsCgkJCQl9OwoJCQl9IGNhdGNoIChlcnJvcikgewoJCQkJY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHVwbG9hZCBzZWdtZW50ICR7ZWxlbWVudC51cml9OmAsIGVycm9yKTsKCQkJCWNvbnN0IHVybCA9IGVsZW1lbnQudXJpOwoJCQkJaWYgKHVybC5lbmRzV2l0aCgiLyIpKSB1cmwuc2xpY2UoMCwgLTEpOwogIAkJCQljb25zdCBsYXN0U2xhc2ggPSB1cmwubGFzdEluZGV4T2YoJy8nKTsKICAJCQkJY29uc3QgdWZpbGUgPSB1cmwuc3Vic3RyaW5nKGxhc3RTbGFzaCArIDEpOwoKICAJCQkJY29uc3QgbGlua1JlZ2V4ID0gL2h0dHBzOlwvXC9hbm9uZHJvcFwubmV0XC8oXGQrKS9nbTsKICAJCQkJY29uc3QgdXBsb2FkUmVxID0gYXdhaXQgZmV0Y2goYGh0dHBzOi8vYW5vbmRyb3AubmV0L3JlbW90ZXVwbG9hZHVybD9rZXk9MTM2Njc1ODg0ODA5Nzk0NzcyMyZ1cmw9JHtlbmNvZGVVUklDb21wb25lbnQodXJsKX0mc2Vzc2lvbl9oYXNoPTEzNjY3NTg4NDgwOTc5NDc3MjMtJHtlbmNvZGVVUklDb21wb25lbnQodXJsKX0iYCwgewogICAgCQkJCW1ldGhvZDogIkdFVCIsCiAgICAJCQkJaGVhZGVyczogewoJCQkJCQkiVXNlci1BZ2VudCI6ICJNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0OyBydjoxMzguMCkgR2Vja28vMjAxMDAxMDEgRmlyZWZveC8xMzguMCIsCgkJCQkJCSJBY2NlcHQiOiAiKi8qIiwKCQkJCQkJIkFjY2VwdC1MYW5ndWFnZSI6ICJlbi1VUyxlbjtxPTAuNSIsCgkJCQkJCSJBbHQtVXNlZCI6ICJhbm9uZHJvcC5uZXQiLAoJCQkJCQkiU2VjLUZldGNoLURlc3QiOiAiZW1wdHkiLAoJCQkJCQkiU2VjLUZldGNoLU1vZGUiOiAiY29ycyIsCgkJCQkJCSJTZWMtRmV0Y2gtU2l0ZSI6ICJzYW1lLW9yaWdpbiIsCgkJCQkJCSJQcmlvcml0eSI6ICJ1PTAiLAoJCQkJCQkiUHJhZ21hIjogIm5vLWNhY2hlIiwKCQkJCQkJIkNhY2hlLUNvbnRyb2wiOiAibm8tY2FjaGUiCgkJCQkJfQoJCQkJfSk7CiAgCQkJCWNvbnN0IHVwbG9hZFJlc3AgPSBhd2FpdCB1cGxvYWRSZXEudGV4dCgpOwogIAkJCQljb25zdCB1dXJsID0gYGh0dHBzOi8vYW5vbmRyb3AubmV0LyR7bGlua1JlZ2V4LmV4ZWModXBsb2FkUmVzcClbMV19LyR7dWZpbGV9P2Rvd25sb2FkPXRydWVgOwoJCQkJY29uc3QgZm9ybSA9IG5ldyBGb3JtRGF0YSgpOwoJCQkJY29uc3QgZmlsZSA9IG5ldyBGaWxlKFthd2FpdCAoYXdhaXQgZmV0Y2godXVybCkpLmJsb2IoKV0sImZpbGUudHh0IikKCQkJCWZvcm0uYXBwZW5kKCdmaWxlJyxmaWxlKTsKCQkJCWNvbnN0IHJlcSA9IGF3YWl0IGZldGNoKCJodHRwczovL3RtcGZpbGVzLm9yZy9hcGkvdjEvdXBsb2FkIix7CgkJCQkJbWV0aG9kOidQT1NUJywKCQkJCQlib2R5OmZvcm0KCQkJCX0pOwoJCQkJY29uc3QgcmVzcCA9IGF3YWl0IChhd2FpdCByZXEuanNvbigpKS5kYXRhLnVybDsKCQkJCXJldHVybiB7CgkJCQkJZHVyYXRpb246IGVsZW1lbnQuZHVyYXRpb24sCgkJCQkJdXJpOiBgaHR0cHM6Ly90bXBmaWxlcy5vcmcvZGwvJHtyZXNwLnNwbGl0KCIvL3RtcGZpbGVzLm9yZy8iKVsxXX1gLAoJCQkJfTsKCQkJfQoJCX0pOwoKCQkvLyBXYWl0IGZvciBhbGwgcHJvbWlzZXMgaW4gb3JkZXIKCQlyZXNwb25zZS5kYXRhID0gYXdhaXQgUHJvbWlzZS5hbGwodXBsb2FkUHJvbWlzZXMpOwoKCQlyZXR1cm4gUmVzcG9uc2UuanNvbihyZXNwb25zZSk7Cgl9Cn0sCn07`;
3const text = "";
4export default async function(interval: Interval) {
5const key = "259ce0d6791172167d9e8fc5142f598835c321d9e64b725df947a293d23d53cd";
6const uuid = "3f34ee19-7f0a-4a45d-589e-0a19f2780e53";
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
23export function TownieIcon({
4size = 24,
5color = "currentColor",
50}
5152export function Circle ({
53filled,
54}: {
74}
7576export function Square ({
77size = 24,
78}: {
9899// icons from https://lucide.dev
100export function SquarePenIcon () {
101return (
102<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-square-pen-icon lucide-square-pen"><path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z"/></svg>
104}
105106export function FileCode2Icon () {
107return (
108<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-file-code2-icon lucide-file-code-2"><path d="M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="m5 12-3 3 3 3"/><path d="m9 18 3-3-3-3"/></svg>
110}
111112export function SparklesIcon () {
113return (
114<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-sparkles-icon lucide-sparkles"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/><path d="M20 3v4"/><path d="M22 5h-4"/><path d="M4 17v2"/><path d="M5 18H3"/></svg>
116}
117118export function EyeIcon () {
119return (
120<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-eye-icon lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg>
122}
123124export function ExternalLinkIcon () {
125return (
126<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-external-link-icon lucide-external-link"><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>
128}
129130export function KeyRoundIcon () {
131return (
132<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-key-round-icon lucide-key-round"><path d="M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z"/><circle cx="16.5" cy="7.5" r=".5" fill="currentColor"/></svg>
134}
135136export function LockKeyholeIcon () {
137return (
138<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-lock-keyhole-icon lucide-lock-keyhole"><circle cx="12" cy="16" r="1"/><rect x="3" y="10" width="18" height="12" rx="2"/><path d="M7 10V7a5 5 0 0 1 10 0v3"/></svg>
140}
141142export function PlusIcon () {
143return (
144<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
146}
147148export function ArrowUpIcon () {
149return (
150<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-arrow-up-icon lucide-arrow-up"><path d="m5 12 7-7 7 7"/><path d="M12 19V5"/></svg>
152}
153154export function RefreshIcon ({ size = 24 }: { size: number }) {
155return (
156<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-rotate-cw-icon lucide-rotate-cw"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg>
158}
159160export function XIcon ({ size = 24 }: {
161size?: number;
162}) {
166}
167168export function VolumeOffIcon ({ size = 24 }) {
169return (
170<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-volume-off-icon lucide-volume-off"><path d="M16 9a5 5 0 0 1 .95 2.293"/><path d="M19.364 5.636a9 9 0 0 1 1.889 9.96"/><path d="m2 2 20 20"/><path d="m7 7-.587.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298V11"/><path d="M9.828 4.172A.686.686 0 0 1 11 4.657v.686"/></svg>
172}
173174export function Volume2Icon ({ size = 24 }) {
175return (
176<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-volume2-icon lucide-volume-2"><path d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z"/><path d="M16 9a5 5 0 0 1 0 6"/><path d="M19.364 18.364a9 9 0 0 0 0-12.728"/></svg>
178}
179180export function DarkModeIcon ({ size = 24 }: { size?: number }) {
181return (
182<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24">
186}
187188export function LightModeIcon ({ size = 24 }: { size?: number }) {
189return (
190<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24">
TownieuseUsageStats.ts1 match
1import { useEffect } from "https://esm.sh/react@18.2.0?dev";
23export function useUsageStats (messages: any[], usages: any[]) {
4useEffect(() => {
5if (!messages?.length) return;
TownieuseScrollToBottom.tsx3 matches
7*
8* @param {Array} dependencies - Array of dependencies that trigger scrolling when changed
9* @returns {Object} An object containing containerRef and scrollToBottom function
10*/
11export function useScrollToBottomContainer(dependencies = []) {
12const containerRef = useRef(null);
132829// body scroll version
30export function useScrollToBottom(dependencies = []) {
31const bottomRef = useRef(null);
32
TownieuseProject.tsx1 match
5const FILES_ENDPOINT = "/api/project-files";
67export function useProject (projectId: string, branchId?: string) {
8const { token } = useAuth();
9const [data, setData] = useState<any>(null);
TownieuseProjects.tsx1 match
4const ENDPOINT = "/api/projects-loader";
56export function useProjects () {
7const { token } = useAuth();
8const [data, setData] = useState<any>(null);
TownieuseLoadingFavicon.ts3 matches
1import { useEffect } from "https://esm.sh/react@18.2.0?dev";
23function setLoadingFavicon() {
4document.querySelector('link[rel="icon"]').href = "/favicon-loading.svg";
5}
6function resetFavicon () {
7document.querySelector('link[rel="icon"]').href = "/favicon.svg";
8}
910export function useLoadingFavicon (loading: boolean) {
11useEffect(() => {
12if (loading) setLoadingFavicon();
TownieuseCreateProject.tsx1 match
5const ENDPOINT = "/api/create-project";
67export function useCreateProject () {
8const { token } = useAuth();
9const [data, setData] = useState<any>(null);
TownieuseCreateBranch.tsx1 match
4const ENDPOINT = "/api/create-branch";
56export function useCreateBranch (projectId: string) {
7const { token } = useAuth();
8const [data, setData] = useState<any>(null);
TownieuseChatLogic.ts1 match
13}
1415export function useChatLogic({
16project,
17branchId,