updates for darkmode, letting users not need a username to chat, and icons
This commit is contained in:
parent
da5363f578
commit
9c92f38eaa
|
|
@ -1,11 +1,29 @@
|
||||||
<div
|
<div
|
||||||
class="min-h-[calc(100vh-128px)] md:min-h-[calc(100vh-160px)] pt-8 md:pt-16 flex flex-col items-start max-w-[690px] m-auto gap-10 pb-5 text-sm"
|
class="min-h-[calc(100vh-128px)] md:min-h-[calc(100vh-160px)] pt-8 md:pt-16 flex flex-col items-start max-w-[690px] m-auto gap-10 pb-5 text-sm"
|
||||||
>
|
>
|
||||||
<h1 class="text-xl">About This Template</h1>
|
<h1 class="text-xl">About This App</h1>
|
||||||
|
|
||||||
<div class="max-w-[573px]">
|
<div class="max-w-[573px]">
|
||||||
|
<p>
|
||||||
|
This chatbot combines a knowledge graph with a Large Language Model (LLM) to provide verifiable responses to prompts. The data is stewarded by
|
||||||
|
<a class="link link-primary whitespace-nowrap" href="https://www.refidao.com/" target="_blank" rel="noreferrer">ReFiDAO<span class="-scale-x-100 scale-y-100 inline-block">⎋</span></a>
|
||||||
|
and is stored on
|
||||||
|
<a class="link link-primary whitespace-nowrap" href="https://origintrail.io/" target="_blank" rel="noreferrer">OriginTrail</a>
|
||||||
|
's decentralized knowledge graph. <br>
|
||||||
|
The LLM, an OpenAI GPT model, is used for reasoning and summarization.<br>
|
||||||
|
Previous prompts & replies are not kept in context, to save costs.<br>
|
||||||
|
|
||||||
|
Feel free to
|
||||||
|
<a class="link link-primary whitespace-nowrap" href="/Chat">Submit Feedback</a>
|
||||||
|
directly in the app, or reach out to
|
||||||
|
<a class="link link-primary whitespace-nowrap" href="https://twitter.com/zaldarren" target="_blank" rel="noreferrer">Darren Zal<span class="-scale-x-100 scale-y-100 inline-block">⎋</span></a>
|
||||||
|
.<br>
|
||||||
|
|
||||||
|
Check out the code on
|
||||||
|
<a class="link link-primary whitespace-nowrap" href="https://github.com/DarrenZal/NatLangKG" target="_blank" rel="noreferrer">GitHub<span class="-scale-x-100 scale-y-100 inline-block">⎋</span></a>
|
||||||
|
</p><br>
|
||||||
<p class="mb-5">
|
<p class="mb-5">
|
||||||
<a
|
The front end is built with <a
|
||||||
class="link link-primary whitespace-nowrap"
|
class="link link-primary whitespace-nowrap"
|
||||||
href="https://github.com/fission-codes/webnative"
|
href="https://github.com/fission-codes/webnative"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|
@ -13,9 +31,7 @@
|
||||||
Webnative SDK
|
Webnative SDK
|
||||||
<span class="-scale-x-100 scale-y-100 inline-block">⎋</span>
|
<span class="-scale-x-100 scale-y-100 inline-block">⎋</span>
|
||||||
</a>
|
</a>
|
||||||
is a true local-first edge computing stack.
|
,a true local-first edge computing stack. <br>
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You can fork this
|
You can fork this
|
||||||
<a
|
<a
|
||||||
class="link link-primary whitespace-nowrap"
|
class="link link-primary whitespace-nowrap"
|
||||||
|
|
@ -38,3 +54,17 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.blue-link {
|
||||||
|
|
||||||
|
color: blue;
|
||||||
|
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,17 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { sessionStore } from '$src/stores'
|
import { sessionStore } from '$src/stores'
|
||||||
|
|
||||||
let username = $sessionStore.username;
|
// Initialize username as 'guest' by default
|
||||||
|
let username = 'guest';
|
||||||
|
|
||||||
|
// Reactive statement to update username if sessionStore changes
|
||||||
|
$: {
|
||||||
|
if ($sessionStore.username) {
|
||||||
|
username = $sessionStore.username;
|
||||||
|
} else {
|
||||||
|
username = 'guest';
|
||||||
|
}
|
||||||
|
}
|
||||||
const messages = writable([])
|
const messages = writable([])
|
||||||
let newMessage = ''
|
let newMessage = ''
|
||||||
let isLoading = writable(false) // To track loading state
|
let isLoading = writable(false) // To track loading state
|
||||||
|
|
@ -16,26 +26,12 @@
|
||||||
|
|
||||||
let chatHistory = []
|
let chatHistory = []
|
||||||
|
|
||||||
// Ensure there are at least two messages (a query and a response)
|
|
||||||
/* if ($messages.length >= 2) {
|
|
||||||
// Extract the last query and response (excluding the current query)
|
|
||||||
const lastQueryIndex = $messages.length - 2
|
|
||||||
chatHistory = $messages
|
|
||||||
.slice(lastQueryIndex - 1, lastQueryIndex + 1)
|
|
||||||
.map(msg => {
|
|
||||||
return {
|
|
||||||
role: msg.startsWith('Query:') ? 'user' : 'assistant',
|
|
||||||
content: msg.replace(/^Query: |^Result: /, '')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} */
|
|
||||||
|
|
||||||
// Send both the new message and the correct chat history
|
// Send both the new message and the correct chat history
|
||||||
const response = await axios.post('https://myseelia.life/query', {
|
const response = await axios.post('https://myseelia.life/query', {
|
||||||
question: newMessage,
|
question: newMessage,
|
||||||
history: chatHistory,
|
history: chatHistory,
|
||||||
username: username // Send username
|
username: username // Send username
|
||||||
});
|
})
|
||||||
console.log('Response:', response.data)
|
console.log('Response:', response.data)
|
||||||
|
|
||||||
let resultText = ''
|
let resultText = ''
|
||||||
|
|
@ -98,78 +94,74 @@
|
||||||
return 'other'
|
return 'other'
|
||||||
}
|
}
|
||||||
|
|
||||||
let feedbackMessage = '';
|
let feedbackMessage = ''
|
||||||
|
|
||||||
async function sendFeedback() {
|
async function sendFeedback() {
|
||||||
if (feedbackMessage.trim() !== '') {
|
if (feedbackMessage.trim() !== '') {
|
||||||
// Send feedback to the server
|
// Send feedback to the server
|
||||||
await axios.post('https://myseelia.life/feedback', {
|
await axios.post('https://myseelia.life/feedback', {
|
||||||
username: username,
|
username: username,
|
||||||
feedback: feedbackMessage
|
feedback: feedbackMessage
|
||||||
});
|
})
|
||||||
|
|
||||||
// Reset feedbackMessage
|
// Reset feedbackMessage
|
||||||
feedbackMessage = '';
|
feedbackMessage = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoExpand(event) {
|
||||||
|
const textarea = event.target
|
||||||
|
textarea.style.height = 'auto' // Reset the height
|
||||||
|
textarea.style.height = textarea.scrollHeight + 'px' // Set the height to match scroll height
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if username}
|
<!-- {#if username} -->
|
||||||
<section class="chat-container">
|
<section class="chat-container">
|
||||||
<div class="messages">
|
<div class="messages dark:text-white">
|
||||||
{#each $messages as message}
|
{#each $messages as message}
|
||||||
<div class={`message ${getMessageType(message)}`}>
|
<div class={`message ${getMessageType(message)}`}>
|
||||||
{@html message} <!-- Use @html here -->
|
{@html message}
|
||||||
</div>
|
<!-- Use @html here -->
|
||||||
{/each}
|
</div>
|
||||||
</div>
|
{/each}
|
||||||
<div class="input-container">
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
<textarea
|
||||||
|
class="input auto-expand"
|
||||||
|
placeholder="Type a message..."
|
||||||
|
bind:value={newMessage}
|
||||||
|
on:keydown={handleKeydown}
|
||||||
|
on:input={autoExpand}
|
||||||
|
rows="3"
|
||||||
|
disabled={$isLoading}
|
||||||
|
/>
|
||||||
|
<button on:click={sendMessage} disabled={$isLoading}>
|
||||||
|
{#if $isLoading}Loading...{:else}Send{/if}
|
||||||
|
</button>
|
||||||
|
{#if $isLoading}
|
||||||
|
<div class="loading">Processing...</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="feedback-container">
|
||||||
<textarea
|
<textarea
|
||||||
placeholder="Type a message..."
|
class="input"
|
||||||
bind:value={newMessage}
|
placeholder="Leave your feedback..."
|
||||||
on:keydown={handleKeydown}
|
bind:value={feedbackMessage}
|
||||||
rows="3"
|
rows="3"
|
||||||
disabled={$isLoading}
|
/>
|
||||||
></textarea>
|
<button on:click={sendFeedback}>Submit Feedback</button>
|
||||||
<button on:click={sendMessage} disabled={$isLoading}>
|
|
||||||
{#if $isLoading}Loading...{:else}Send{/if}
|
|
||||||
</button>
|
|
||||||
{#if $isLoading}
|
|
||||||
<div class="loading">Processing...</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<!-- {:else}
|
||||||
<div class="feedback-container">
|
<div class="connect-prompt">
|
||||||
<textarea placeholder="Leave your feedback..." bind:value={feedbackMessage} rows="3"></textarea>
|
<p>Please connect to create a username before chatting.</p>
|
||||||
<button on:click={sendFeedback}>Submit Feedback</button>
|
</div>
|
||||||
</div>
|
{/if} -->
|
||||||
{:else}
|
|
||||||
<!-- Prompt to Connect and Create Username -->
|
|
||||||
<div class="connect-prompt">
|
|
||||||
<p>Please connect to create a username before chatting.</p>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.chat-container {
|
|
||||||
margin-bottom: 20px; /* Adds buffer of white space */
|
|
||||||
}
|
|
||||||
.messages {
|
.messages {
|
||||||
/* Styles for the messages container */
|
margin-bottom: 20px; /* Adds buffer of white space */
|
||||||
}
|
|
||||||
.message {
|
|
||||||
/* Styles for individual messages */
|
|
||||||
}
|
|
||||||
.message.query {
|
|
||||||
color: #0000ff; /* Blue color for Query */
|
|
||||||
}
|
|
||||||
|
|
||||||
.message.sparql-result {
|
|
||||||
color: #008000; /* Green color for SPARQL result */
|
|
||||||
}
|
|
||||||
|
|
||||||
.message.entity-matching-result {
|
|
||||||
color: #0f2857; /* Orange color for Entity Matching Result */
|
|
||||||
}
|
}
|
||||||
.input-container {
|
.input-container {
|
||||||
/* Styles for the input area */
|
/* Styles for the input area */
|
||||||
|
|
@ -177,12 +169,6 @@ async function sendFeedback() {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-bottom: 20px; /* Adds buffer of white space at the bottom */
|
padding-bottom: 20px; /* Adds buffer of white space at the bottom */
|
||||||
}
|
}
|
||||||
.input-container textarea {
|
|
||||||
width: 80%; /* Adjust as needed */
|
|
||||||
margin-right: 10px;
|
|
||||||
font-size: 16px; /* Larger font size */
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
.input-container button {
|
.input-container button {
|
||||||
width: 15%; /* Adjust as needed */
|
width: 15%; /* Adjust as needed */
|
||||||
height: 50px; /* Larger height */
|
height: 50px; /* Larger height */
|
||||||
|
|
@ -194,25 +180,45 @@ async function sendFeedback() {
|
||||||
color: #888888;
|
color: #888888;
|
||||||
}
|
}
|
||||||
.feedback-container {
|
.feedback-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
.feedback-container textarea {
|
.feedback-container textarea,
|
||||||
width: 80%;
|
.input-container textarea {
|
||||||
margin-right: 10px;
|
width: 80%;
|
||||||
font-size: 16px;
|
margin-right: 10px;
|
||||||
padding: 10px;
|
font-size: 16px;
|
||||||
}
|
padding: 10px;
|
||||||
.feedback-container button {
|
overflow-y: hidden; /* Prevent scrollbar */
|
||||||
width: 15%;
|
resize: none; /* Disable manual resize */
|
||||||
height: 50px;
|
height: auto; /* Set initial height to auto */
|
||||||
font-size: 16px;
|
min-height: 50px; /* Minimum height */
|
||||||
padding: 5px 10px;
|
}
|
||||||
}
|
.feedback-container button {
|
||||||
.connect-prompt {
|
width: 15%;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
.connect-prompt {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
input {
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
}
|
||||||
|
/* Add a class to handle the auto-expanding feature */
|
||||||
|
.auto-expand {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* JavaScript will adjust this height as the user types */
|
||||||
|
.auto-expand::after {
|
||||||
|
content: attr(data-replicated-value) ' ';
|
||||||
|
white-space: pre-wrap;
|
||||||
|
display: block;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,20 @@
|
||||||
<h1 class="text-xl">Welcome, {$sessionStore.username}!</h1>
|
<h1 class="text-xl">Welcome, {$sessionStore.username}!</h1>
|
||||||
|
|
||||||
<div class="flex flex-col items-start justify-center gap-5">
|
<div class="flex flex-col items-start justify-center gap-5">
|
||||||
|
<h2 class="text-lg">ReFi Chat</h2>
|
||||||
<p>
|
<p>
|
||||||
Myseelia is a decentralized knowledge graph for collective intelligence.
|
ReFi Chat is a chatbot that answers questions about Regenerative Finance (ReFi).<br>
|
||||||
|
</p>
|
||||||
|
<a class="btn btn-primary" href="/Chat">Try ReFi Chat</a>
|
||||||
|
<p>
|
||||||
|
Learn about this app
|
||||||
|
<a class="link link-primary whitespace-nowrap" href="/about">here</a>
|
||||||
|
<br>
|
||||||
</p>
|
</p>
|
||||||
<a class="btn btn-primary" href="/gallery">Try the Myseelia App</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col items-start justify-center gap-5">
|
<div class="flex flex-col items-start justify-center gap-5">
|
||||||
<h2 class="text-lg">Device Connection Demo</h2>
|
<h2 class="text-lg">Additional Device Connection</h2>
|
||||||
<p>
|
<p>
|
||||||
With Webnative SDK, a user’s account lives only on their connected devices
|
With Webnative SDK, a user’s account lives only on their connected devices
|
||||||
— entirely under their control. It’s easy for them to connect as many
|
— entirely under their control. It’s easy for them to connect as many
|
||||||
|
|
@ -27,3 +33,18 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.blue-link {
|
||||||
|
|
||||||
|
color: blue;
|
||||||
|
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,13 @@
|
||||||
<div
|
<div
|
||||||
class="min-h-[calc(100vh-96px)] flex flex-col items-start justify-center max-w-[700px] m-auto gap-6 pb-5 text-sm"
|
class="min-h-[calc(100vh-96px)] flex flex-col items-start justify-center max-w-[700px] m-auto gap-6 pb-5 text-sm"
|
||||||
>
|
>
|
||||||
<h1 class="text-xl">Welcome to the {appName}</h1>
|
<h1 class="text-xl">Welcome to {appName}</h1>
|
||||||
|
<a class="btn btn-primary" href="/Chat">Try ReFi Chat</a>
|
||||||
<div class="max-w-[590px]">
|
<div class="max-w-[590px]">
|
||||||
<p class="mb-5">
|
<p class="mb-5">
|
||||||
Webnative SDK is a true local-first edge computing stack. Effortlessly
|
This app uses passwordless login <br />
|
||||||
give your users:
|
<br />
|
||||||
|
<a class="btn btn-primary btn-sm !h-10" href="/connect">Connect</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul class="mb-6 pl-6 list-disc">
|
|
||||||
<li>
|
|
||||||
<span class="font-bold">modern, passwordless accounts</span>
|
|
||||||
, without a complex and costly cloud-native back-end
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="font-bold">user-controlled data</span>
|
|
||||||
, secured by default with our encrypted-at-rest file storage protocol
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="font-bold">local-first functionality</span>
|
|
||||||
, including the ability to work offline and collaborate across multiple devices
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<a class="btn btn-primary btn-sm !h-10" href="/connect">Connect</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<svg
|
||||||
|
width="23"
|
||||||
|
height="23"
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 115.98 122.88"
|
||||||
|
style="enable-background:new 0 0 115.98 122.88"
|
||||||
|
xml:space="preserve"
|
||||||
|
>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d="M17.2,0h59.47c4.73,0,9.03,1.93,12.15,5.05c3.12,3.12,5.05,7.42,5.05,12.15v38.36c0,4.73-1.93,9.03-5.05,12.15 c-3.12,3.12-7.42,5.05-12.15,5.05H46.93L20.81,95.21c-1.21,1.04-3.04,0.9-4.08-0.32c-0.51-0.6-0.74-1.34-0.69-2.07l1.39-20.07H17.2 c-4.73,0-9.03-1.93-12.15-5.05C1.93,64.59,0,60.29,0,55.56V17.2c0-4.73,1.93-9.03,5.05-12.15C8.16,1.93,12.46,0,17.2,0L17.2,0z M102.31,27.98c3.37,0.65,6.39,2.31,8.73,4.65c3.05,3.05,4.95,7.26,4.95,11.9v38.36c0,4.64-1.89,8.85-4.95,11.9 c-3.05,3.05-7.26,4.95-11.9,4.95h-0.61l1.42,20.44l0,0c0.04,0.64-0.15,1.3-0.6,1.82c-0.91,1.07-2.52,1.19-3.58,0.28l-26.22-23.2 H35.01l17.01-17.3h36.04c7.86,0,14.3-6.43,14.3-14.3V29.11C102.35,28.73,102.34,28.35,102.31,27.98L102.31,27.98z M25.68,43.68 c-1.6,0-2.9-1.3-2.9-2.9c0-1.6,1.3-2.9,2.9-2.9h30.35c1.6,0,2.9,1.3,2.9,2.9c0,1.6-1.3,2.9-2.9,2.9H25.68L25.68,43.68z M25.68,29.32c-1.6,0-2.9-1.3-2.9-2.9c0-1.6,1.3-2.9,2.9-2.9H68.7c1.6,0,2.9,1.3,2.9,2.9c0,1.6-1.3,2.9-2.9,2.9H25.68L25.68,29.32z M76.66,5.8H17.2c-3.13,0-5.98,1.28-8.05,3.35C7.08,11.22,5.8,14.06,5.8,17.2v38.36c0,3.13,1.28,5.98,3.35,8.05 c2.07,2.07,4.92,3.35,8.05,3.35h3.34v0.01l0.19,0.01c1.59,0.11,2.8,1.49,2.69,3.08l-1.13,16.26L43.83,67.8 c0.52-0.52,1.24-0.84,2.04-0.84h30.79c3.13,0,5.98-1.28,8.05-3.35c2.07-2.07,3.35-4.92,3.35-8.05V17.2c0-3.13-1.28-5.98-3.35-8.05 C82.65,7.08,79.8,5.8,76.66,5.8L76.66,5.8z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -9,7 +9,7 @@
|
||||||
import PhotoGallery from '$components/icons/PhotoGallery.svelte'
|
import PhotoGallery from '$components/icons/PhotoGallery.svelte'
|
||||||
import Settings from '$components/icons/Settings.svelte'
|
import Settings from '$components/icons/Settings.svelte'
|
||||||
import InfoThinIcon from '$components/icons/InfoThinIcon.svelte'
|
import InfoThinIcon from '$components/icons/InfoThinIcon.svelte'
|
||||||
import Share from '$components/icons/Share.svelte'
|
import Chat from '$components/icons/Chat.svelte'
|
||||||
|
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{
|
{
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
{
|
{
|
||||||
label: 'Chat',
|
label: 'Chat',
|
||||||
href: '/Chat',
|
href: '/Chat',
|
||||||
icon: Share
|
icon: Chat
|
||||||
},
|
},
|
||||||
/* {
|
/* {
|
||||||
label: 'Profile',
|
label: 'Profile',
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
// icon: PhotoGallery
|
// icon: PhotoGallery
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
label: 'About This Template',
|
label: 'About This App',
|
||||||
href: '/about/',
|
href: '/about/',
|
||||||
icon: About
|
icon: About
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export const appName = 'Myseelia'
|
export const appName = 'ReFiChat'
|
||||||
export const appDescription = 'Knowledge Network for Collective Intelligence.'
|
export const appDescription = 'Knowledge Network for Collective Intelligence.'
|
||||||
export const appURL = 'https://webnative.netlify.app'
|
export const appURL = 'https://webnative.netlify.app'
|
||||||
export const appImageURL = `${appURL}/preview.png`
|
export const appImageURL = `${appURL}/preview.png`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue