diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..6503c41 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,134 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +gia.nebieridze@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..06b47f6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,3 @@ +Looks like there's already a license file for this project. +[?25l? Do you want to replace it? › (y/N)✔ Do you want to replace it? … no +[?25hExiting... diff --git a/README.md b/README.md new file mode 100644 index 0000000..68183f2 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# scrpt diff --git a/package.json b/package.json new file mode 100644 index 0000000..1fa4750 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "ai-widget", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/src/scrpt.js b/src/scrpt.js new file mode 100644 index 0000000..3ba9789 --- /dev/null +++ b/src/scrpt.js @@ -0,0 +1,327 @@ +const xPositions = ['left', 'right']; +const yPositions = ['top', 'bottom']; +const nm = 'scrpt'; +const chatWidth = '400px'; +const domain = 'http://161.35.71.150'; +class Scrpt { + loadInterval; + constructor({ position = 'bottom-right', appName = '' } = {}) { + this.position = this.getPosition(position); + this.open = false; + this.inputText = ''; + this.appName = appName; + + if (!position.includes('-')) { + throw new Error("position must include - symbol. for example bottom-right"); + } + if (!yPositions.includes(position.split('-')[0])) { + throw new Error("y position must be top or bottom"); + } + if (!xPositions.includes(position.split('-')[1])) { + throw new Error("x position must be left or right"); + } + if (appName === '') { + throw new Error("invalid app name"); + } + this.getChatInitialData(appName).then(_ => { + this.initialize(); + }); + this.createStyles(); + } + + getPosition(position) { + const [y, x] = position.split('-'); + return { + [y]: '40px', + [x]: '40px', + }; + } + + initialize() { + const container = document.createElement('div'); + container.style.position = 'fixed'; + container.style.zIndex = '9999'; + Object.keys(this.position) + .forEach(key => container.style[key] = this.position[key]); + + document.body.appendChild(container); + + const buttonContainer = document.createElement('div'); + buttonContainer.classList.add(`${nm}-button-container`); + + const chatIcon = document.createElement('span'); + chatIcon.innerHTML = + ` + + + `; + chatIcon.classList.add(`${nm}-icon`); + this.chatIcon = chatIcon; + + const closeIcon = document.createElement('span'); + closeIcon.innerHTML = ` + + `; + closeIcon.classList.add(`${nm}-icon`, `${nm}-hidden`); + this.closeIcon = closeIcon; + + this.chatContainer = document.createElement('div'); + this.chatContainer.classList.add(`${nm}-hidden`, `${nm}-chat-container`); + this.chatContainer.style.width = chatWidth; + + this.createChatContainerContent(); + + buttonContainer.appendChild(this.chatIcon); + buttonContainer.appendChild(this.closeIcon); + + buttonContainer.addEventListener('click', this.toggleOpen.bind(this)); + + container.appendChild(this.chatContainer); + container.appendChild(buttonContainer); + this.chatContent.innerHTML += this.chatStripe(true, this.welcomeMessage, ''); + } + + createStyles() { + const styleTag = document.createElement('style'); + document.head.appendChild(styleTag); + styleTag.innerHTML = ` + ${nm}-button-container,${nm}-scrpt-header{background:linear-gradient(to bottom right,#4294e3,#8f12fd)}${nm}-clearfix::after{content:"";clear:both;display:table}${nm}-icon{cursor:pointer;width:100%;position:absolute;top:11px;left:13px;transition:transform .3s;color:#fff}${nm}-hidden{transform:scale(0)}${nm}-button-container{width:70px;height:70px;border-radius:50%}${nm}-chat-container{box-shadow:0 0 18px 8px rgba(0,0,0,.1);right:-25px;bottom:75px;position:absolute;transition:max-height .2s;background-color:#fff;border-radius:10px}${nm}-chat-container.hidden{max-height:0}${nm}-scrpt-header{display:inline-block;width:100%;margin:0;padding:10px;color:#fff;border-top-left-radius:10px;border-top-right-radius:10px}${nm}-chat-container form input{padding:20px;display:inline-block;width:calc(100% - 50px);border:0;background-color:#f7f7f7}${nm}-chat-container form input:focus{outline:0}${nm}-chat-container form button{cursor:pointer;color:#8f12fd;background-color:#f7f7f7;border:0;border-radius:4px;padding:20px 10px}${nm}-scrpt-chat-bottom-menu{padding-top:20px;list-style-type:none;text-align:center;padding-left:0;margin-left:0}${nm}-scrpt-chat-bottom-menu li{display:inline-block;padding-left:30px;padding-right:30px;cursor:pointer}${nm}-bottom-menu-icon{padding-bottom:5px;display:inline-block}${nm}-chat-content{display:block;width:100%;padding:10px;height:510px;overflow-y:scroll;position:relative;box-shadow:0 4px 2px -2px rgba(0,0,0,.1)}${nm}-fullscreen-button{border:0;background-color:#fff;border-radius:100%;padding-bottom:3px;float:right;margin-left:4px}${nm}-bubble-income,${nm}-bubble-outcome{border-top-left-radius:10px;border-top-right-radius:10px}${nm}-msg-box{display:inline-block;width:80%}${nm}-msg-box p{padding:7px}${nm}-income{float:left}${nm}-outcome{float:right}${nm}-bubble-outcome{background-color:gray;color:#fff;border-bottom-left-radius:10px}${nm}-bubble-income{background-color:#f7f7f7;color:#424242;border-bottom-right-radius:10px} + `; + } + + createChatContainerContent() { + const clrfx = document.createElement('span'); + clrfx.classList.add(`${nm}-clearfix`); + + this.chatContainer.innerHTML = ''; + const title = document.createElement('div'); + title.classList.add(`${nm}-scrpt-header`); + + const closeButton = document.createElement('button'); + closeButton.innerHTML = ` + + `; + closeButton.classList.add(`${nm}-close-button`); + closeButton.addEventListener("click", () => this.closeChat()); + + title.appendChild(closeButton); + + this.fullScreenButton = document.createElement('button'); + this.fullScreenButton.innerHTML = ` + + `; + this.fullScreenButton.classList.add(`${nm}-fullscreen-button`); + this.fullScreenButton.addEventListener("click", () => this.fullscreenchat()); + title.appendChild(this.fullScreenButton); + + + const form = document.createElement('form'); + form.classList.add(`${nm}-content`); + + const text = document.createElement('input'); + text.requered = true; + text.id = `${nm}-text`; + text.type = "text"; + text.placeholder = this.inputText; + + this.btn = document.createElement('button'); + this.btn.innerHTML = ` + + `; + + this.chatContent = document.createElement('div'); + this.chatContent.classList.add(`${nm}-chat-content`); + form.appendChild(this.chatContent); + form.appendChild(clrfx); + + form.appendChild(text); + form.appendChild(this.btn); + form.addEventListener('submit', this.submit.bind(this)); + + + const bottomMenuContainer = document.createElement('ul'); + bottomMenuContainer.classList.add(`${nm}-scrpt-chat-bottom-menu`); + + const bottomMenuContainerItems = [ + { + icon: ` + + + `, + text: 'Home', + click: function () { + alert(this.text); + } + }, + { + icon: ` + + + + `, + text: 'Chat', + click: function () { + alert(this.text); + } + }, + { + icon: ` + + + + `, + text: 'Help', + click: function () { + alert(this.text); + } + }, + ]; + + bottomMenuContainerItems.forEach(item => { + let li = document.createElement('li'); + let span = document.createElement('span'); + span.classList.add(`${nm}-bottom-menu-icon`); + span.innerHTML = item.icon; + li.appendChild(span); + let br = document.createElement('br'); + li.appendChild(br); + let text = document.createElement('span'); + text.innerHTML = item.text; + li.appendChild(text); + bottomMenuContainer.appendChild(li); + }); + + this.chatContainer.appendChild(title); + this.chatContainer.appendChild(form); + this.chatContainer.appendChild(clrfx); + this.chatContainer.appendChild(bottomMenuContainer); + } + + async submit(e) { + e.preventDefault(); + let id = this.generateUniqueId(); + let inpt = document.getElementById(`${nm}-text`); + let q = inpt.value; + if (q.trim() === '') { + return; + } + this.chatContent.innerHTML += this.chatStripe(false, q, ''); + inpt.disabled = true; + inpt.value = ''; + this.btn.disabled = true; + + let result = await this.makeRequest("POST", `${domain}/answer?name=${this.appName}`, { + question: q + }); + result = JSON.parse(result); + this.chatContent.innerHTML += this.chatStripe(true, ' ', id); + const messageDiv = document.getElementById(id); + + this.typeText(messageDiv, result.answer); + + } + + toggleOpen() { + this.open = !this.open; + if (this.open) { + this.openChat(); + } else { + this.closeChat(); + } + } + + fullscreenchat() { + if (this.chatContainer.style.width === chatWidth) { + this.chatContainer.style.width = `${window.innerWidth - 30}px`; + this.chatContainer.style.height = `${window.innerHeight - 125}px`; + } else { + this.chatContainer.style.width = chatWidth; + this.chatContainer.style.height = `auto`; + } + } + + closeChat() { + this.open = false; + // this.createChatContainerContent(); + this.chatIcon.classList.remove(`${nm}-hidden`); + this.closeIcon.classList.add(`${nm}-hidden`); + this.chatContainer.classList.add(`${nm}-hidden`); + } + + openChat() { + this.chatIcon.classList.add(`${nm}-hidden`); + this.closeIcon.classList.remove(`${nm}-hidden`); + this.chatContainer.classList.remove(`${nm}-hidden`); + } + + typeText(element, text) { + let index = 0; + let interval = setInterval(() => { + if (index < text.length) { + element.innerHTML += text.charAt(index); + index++; + this.chatContent.scrollTop = this.chatContent.scrollHeight; + } else { + clearInterval(interval); + let inpt = document.getElementById(`${nm}-text`); + inpt.disabled = false; + this.btn.disabled = false; + } + }, 20); + } + + uuidv4() { + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); + } + + generateUniqueId() { + return this.uuidv4(); + } + + chatStripe(isAi, value, uniqueID) { + return (` +
+

${value}

+
+ `); + }; + + + async getChatInitialData(appName) { + let result = await this.makeRequest("GET", `${domain}/api/project/${appName}/init`); + let data = JSON.parse(result); + this.welcomeMessage = data.data.welcome_message; + this.inputText = data.data.input_text; + } + + makeRequest(method, url, params = {}) { + return new Promise(function (resolve, reject) { + let xhr = new XMLHttpRequest(); + xhr.open(method, url); + xhr.setRequestHeader('Content-type', 'application/json') + xhr.onload = function () { + if (this.status >= 200 && this.status < 300) { + resolve(xhr.response); + } else { + reject({ + status: this.status, + statusText: xhr.statusText + }); + } + }; + xhr.onerror = function () { + reject({ + status: this.status, + statusText: xhr.statusText + }); + }; + if (Object.keys(params).length !== 0) { + xhr.send(JSON.stringify(params)); + } else { + xhr.send(); + } + }); + } +} \ No newline at end of file diff --git a/src/scrpt.min.js b/src/scrpt.min.js new file mode 100644 index 0000000..dc5bdb7 --- /dev/null +++ b/src/scrpt.min.js @@ -0,0 +1 @@ +const xPositions = ["left", "right"], yPositions = ["top", "bottom"], nm = "scrpt", chatWidth = "400px", domain = "http://164.90.239.9:8000"; class Scrpt { loadInterval; constructor({ position: t = "bottom-right", appName: e = "" } = {}) { if (this.position = this.getPosition(t), this.open = !1, this.inputText = "", this.appName = e, !t.includes("-")) throw Error("position must include - symbol. for example bottom-right"); if (!yPositions.includes(t.split("-")[0])) throw Error("y position must be top or bottom"); if (!xPositions.includes(t.split("-")[1])) throw Error("x position must be left or right"); if ("" === e) throw Error("invalid app name"); this.getChatInitialData(e).then((t => { this.initialize() })), this.createStyles() } getPosition(t) { let [e, n] = t.split("-"); return { [e]: "40px", [n]: "40px" } } initialize() { let t = document.createElement("div"); t.style.position = "fixed", t.style.zIndex = "9999", Object.keys(this.position).forEach((e => t.style[e] = this.position[e])), document.body.appendChild(t); let e = document.createElement("div"); e.classList.add(`${nm}-button-container`); let n = document.createElement("span"); n.innerHTML = '\n \n \n ', n.classList.add(`${nm}-icon`), this.chatIcon = n; let i = document.createElement("span"); i.innerHTML = '\n \n ', i.classList.add(`${nm}-icon`, `${nm}-hidden`), this.closeIcon = i, this.chatContainer = document.createElement("div"), this.chatContainer.classList.add(`${nm}-hidden`, `${nm}-chat-container`), this.chatContainer.style.width = "400px", this.createChatContainerContent(), e.appendChild(this.chatIcon), e.appendChild(this.closeIcon), e.addEventListener("click", this.toggleOpen.bind(this)), t.appendChild(this.chatContainer), t.appendChild(e), this.chatContent.innerHTML += this.chatStripe(!0, this.welcomeMessage, "") } createStyles() { let t = document.createElement("style"); document.head.appendChild(t), t.innerHTML = `\n ${nm}-button-container,${nm}-scrpt-header{background:linear-gradient(to bottom right,#4294e3,#8f12fd)}${nm}-clearfix::after{content:"";clear:both;display:table}${nm}-icon{cursor:pointer;width:100%;position:absolute;top:11px;left:13px;transition:transform .3s;color:#fff}${nm}-hidden{transform:scale(0)}${nm}-button-container{width:70px;height:70px;border-radius:50%}${nm}-chat-container{box-shadow:0 0 18px 8px rgba(0,0,0,.1);right:-25px;bottom:75px;position:absolute;transition:max-height .2s;background-color:#fff;border-radius:10px}${nm}-chat-container.hidden{max-height:0}${nm}-scrpt-header{display:inline-block;width:100%;margin:0;padding:10px;color:#fff;border-top-left-radius:10px;border-top-right-radius:10px}${nm}-chat-container form input{padding:20px;display:inline-block;width:calc(100% - 50px);border:0;background-color:#f7f7f7}${nm}-chat-container form input:focus{outline:0}${nm}-chat-container form button{cursor:pointer;color:#8f12fd;background-color:#f7f7f7;border:0;border-radius:4px;padding:20px 10px}${nm}-scrpt-chat-bottom-menu{padding-top:20px;list-style-type:none;text-align:center;padding-left:0;margin-left:0}${nm}-scrpt-chat-bottom-menu li{display:inline-block;padding-left:30px;padding-right:30px;cursor:pointer}${nm}-bottom-menu-icon{padding-bottom:5px;display:inline-block}${nm}-chat-content{display:block;width:100%;padding:10px;height:510px;overflow-y:scroll;position:relative;box-shadow:0 4px 2px -2px rgba(0,0,0,.1)}${nm}-fullscreen-button{border:0;background-color:#fff;border-radius:100%;padding-bottom:3px;float:right;margin-left:4px}${nm}-bubble-income,${nm}-bubble-outcome{border-top-left-radius:10px;border-top-right-radius:10px}${nm}-msg-box{display:inline-block;width:80%}${nm}-msg-box p{padding:7px}${nm}-income{float:left}${nm}-outcome{float:right}${nm}-bubble-outcome{background-color:gray;color:#fff;border-bottom-left-radius:10px}${nm}-bubble-income{background-color:#f7f7f7;color:#424242;border-bottom-right-radius:10px}\n ` } createChatContainerContent() { let t = document.createElement("span"); t.classList.add(`${nm}-clearfix`), this.chatContainer.innerHTML = ""; let e = document.createElement("div"); e.classList.add(`${nm}-scrpt-header`); let n = document.createElement("button"); n.innerHTML = '\n \n ', n.classList.add(`${nm}-close-button`), n.addEventListener("click", (() => this.closeChat())), e.appendChild(n), this.fullScreenButton = document.createElement("button"), this.fullScreenButton.innerHTML = '\n \n ', this.fullScreenButton.classList.add(`${nm}-fullscreen-button`), this.fullScreenButton.addEventListener("click", (() => this.fullscreenchat())), e.appendChild(this.fullScreenButton); let i = document.createElement("form"); i.classList.add(`${nm}-content`); let a = document.createElement("input"); a.requered = !0, a.id = `${nm}-text`, a.type = "text", a.placeholder = this.inputText, this.btn = document.createElement("button"), this.btn.innerHTML = '\n \n ', this.chatContent = document.createElement("div"), this.chatContent.classList.add(`${nm}-chat-content`), i.appendChild(this.chatContent), i.appendChild(t), i.appendChild(a), i.appendChild(this.btn), i.addEventListener("submit", this.submit.bind(this)); let o = document.createElement("ul"); o.classList.add(`${nm}-scrpt-chat-bottom-menu`), [{ icon: '\n \n \n ', text: "Home", click: function () { alert(this.text) } }, { icon: '\n \n \n \n ', text: "Chat", click: function () { alert(this.text) } }, { icon: '\n \n \n \n ', text: "Help", click: function () { alert(this.text) } }].forEach((t => { let e = document.createElement("li"), n = document.createElement("span"); n.classList.add(`${nm}-bottom-menu-icon`), n.innerHTML = t.icon, e.appendChild(n); let i = document.createElement("br"); e.appendChild(i); let a = document.createElement("span"); a.innerHTML = t.text, e.appendChild(a), o.appendChild(e) })), this.chatContainer.appendChild(e), this.chatContainer.appendChild(i), this.chatContainer.appendChild(t), this.chatContainer.appendChild(o) } async submit(t) { t.preventDefault(); let e = this.generateUniqueId(), n = document.getElementById(`${nm}-text`), i = n.value; if ("" === i.trim()) return; this.chatContent.innerHTML += this.chatStripe(!1, i, ""), n.disabled = !0, n.value = "", this.btn.disabled = !0; let a = await this.makeRequest("POST", `${domain}/answer?name=${this.appName}`, { question: i }); a = JSON.parse(a), this.chatContent.innerHTML += this.chatStripe(!0, " ", e); let o = document.getElementById(e); this.typeText(o, a.answer) } toggleOpen() { this.open = !this.open, this.open ? this.openChat() : this.closeChat() } fullscreenchat() { "400px" === this.chatContainer.style.width ? (this.chatContainer.style.width = window.innerWidth - 30 + "px", this.chatContainer.style.height = window.innerHeight - 125 + "px") : (this.chatContainer.style.width = "400px", this.chatContainer.style.height = "auto") } closeChat() { this.open = !1, this.chatIcon.classList.remove(`${nm}-hidden`), this.closeIcon.classList.add(`${nm}-hidden`), this.chatContainer.classList.add(`${nm}-hidden`) } openChat() { this.chatIcon.classList.add(`${nm}-hidden`), this.closeIcon.classList.remove(`${nm}-hidden`), this.chatContainer.classList.remove(`${nm}-hidden`) } typeText(t, e) { let n = 0, i = setInterval((() => { n < e.length ? (t.innerHTML += e.charAt(n), n++, this.chatContent.scrollTop = this.chatContent.scrollHeight) : (clearInterval(i), document.getElementById(`${nm}-text`).disabled = !1, this.btn.disabled = !1) }), 20) } uuidv4() { return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (t => (t ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> t / 4).toString(16))) } generateUniqueId() { return this.uuidv4() } chatStripe(t, e, n) { return `\n
\n

${e}

\n
\n ` } async getChatInitialData(t) { let e = JSON.parse(await this.makeRequest("GET", `${domain}/api/project/${t}/init`)); this.welcomeMessage = e.data.welcome_message, this.inputText = e.data.input_text } makeRequest(t, e, n = {}) { return new Promise((function (i, a) { let o = new XMLHttpRequest; o.open(t, e), o.setRequestHeader("Content-type", "application/json"), o.onload = function () { this.status >= 200 && this.status < 300 ? i(o.response) : a({ status: this.status, statusText: o.statusText }) }, o.onerror = function () { a({ status: this.status, statusText: o.statusText }) }, 0 !== Object.keys(n).length ? o.send(JSON.stringify(n)) : o.send() })) } } \ No newline at end of file