Merge pull request #879 from khoj-ai/features/migrate-to-spring-ui
Migrate all existing pages except login to the new spring ui
|
@ -1,56 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Khoj: An AI Personal Assistant for your digital brain</title>
|
|
||||||
<link rel="icon" type="image/png" sizes="128x128" href="/static/assets/icons/favicon-128x128.png?v={{ khoj_version }}">
|
|
||||||
<link rel="manifest" href="/static/khoj.webmanifest?v={{ khoj_version }}">
|
|
||||||
<link rel="stylesheet" href="/static/assets/khoj.css?v={{ khoj_version }}">
|
|
||||||
</head>
|
|
||||||
<body class="not-found">
|
|
||||||
<!--Add Header Logo and Nav Pane-->
|
|
||||||
{% import 'utils.html' as utils %}
|
|
||||||
{{ utils.heading_pane(user_photo, username, is_active, has_documents) }}
|
|
||||||
|
|
||||||
<header class=”header”>
|
|
||||||
<h1>Oops, this is awkward. Looks like there's nothing here.</h1>
|
|
||||||
</header>
|
|
||||||
<a class="redirect-link" href="/">Go Home</a>
|
|
||||||
|
|
||||||
<footer class=”footer”>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
||||||
<style>
|
|
||||||
body.not-found {
|
|
||||||
padding: 0 10%
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--background-color);
|
|
||||||
color: var(--main-text-color);
|
|
||||||
text-align: center;
|
|
||||||
font-family: var(--font-family);
|
|
||||||
font-size: medium;
|
|
||||||
font-weight: 300;
|
|
||||||
line-height: 1.5em;
|
|
||||||
height: 100vh;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body a.redirect-link {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: var(--primary);
|
|
||||||
text-decoration: none;
|
|
||||||
border: 1px solid var(--main-text-color);
|
|
||||||
color: var(--main-text-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body a.redirect-link:hover {
|
|
||||||
background-color: var(--main-text-color);
|
|
||||||
color: var(--primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</html>
|
|
|
@ -1,312 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0 maximum-scale=1.0">
|
|
||||||
<title>Khoj - Agents</title>
|
|
||||||
|
|
||||||
<link rel="icon" type="image/png" sizes="128x128" href="/static/assets/icons/favicon-128x128.png?v={{ khoj_version }}">
|
|
||||||
<link rel="manifest" href="/static/khoj.webmanifest?v={{ khoj_version }}">
|
|
||||||
<link rel="stylesheet" href="/static/assets/khoj.css?v={{ khoj_version }}">
|
|
||||||
</head>
|
|
||||||
<script type="text/javascript" src="/static/assets/utils.js?v={{ khoj_version }}"></script>
|
|
||||||
<body>
|
|
||||||
<!--Add Header Logo and Nav Pane-->
|
|
||||||
{% import 'utils.html' as utils %}
|
|
||||||
{{ utils.heading_pane(user_photo, username, is_active, has_documents) }}
|
|
||||||
<div id="agent-metadata-wrapper">
|
|
||||||
<div id="agent-metadata">
|
|
||||||
<div id="agent-avatar-wrapper">
|
|
||||||
<div id="agent-settings-header">Agent Settings</div>
|
|
||||||
</div>
|
|
||||||
<div class="divider"></div>
|
|
||||||
<div id="agent-data-wrapper">
|
|
||||||
<div id="agent-avatar-wrapper">
|
|
||||||
<img id="agent-avatar" src="{{ agent.avatar }}" alt="Agent Avatar">
|
|
||||||
<input type="text" id="agent-name-input" value="{{ agent.name }}" {% if agent.creator_not_self %} disabled {% endif %}>
|
|
||||||
</div>
|
|
||||||
<div id="agent-instructions">
|
|
||||||
Personality
|
|
||||||
<button id="toggle-agent-tuning" onclick="toggleAgentTuning()">↓</button>
|
|
||||||
</div>
|
|
||||||
<div id="agent-tuning">
|
|
||||||
<p>{{ agent.personality }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="divider"></div>
|
|
||||||
<div id="agent-public">
|
|
||||||
<p>Public</p>
|
|
||||||
<label class="switch">
|
|
||||||
<input type="checkbox" {% if agent.public %} checked {% endif %} {% if agent.creator_not_self %} disabled {% endif %}>
|
|
||||||
<span class="slider round"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<p id="agent-creator" style="display: none;">Creator: {{ agent.creator }}</p>
|
|
||||||
<p id="agent-managed-by-admin" style="display: none;">ⓘ This agent is managed by the administrator</p>
|
|
||||||
<button onclick="openChat('{{ agent.slug }}')">Chat</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="footer">
|
|
||||||
<a href="/agents">All Agents</a>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background-color: var(--background-color);
|
|
||||||
display: grid;
|
|
||||||
color: var(--main-text-color);
|
|
||||||
text-align: center;
|
|
||||||
font-family: var(--font-family);
|
|
||||||
font-size: medium;
|
|
||||||
font-weight: 300;
|
|
||||||
line-height: 1.5em;
|
|
||||||
height: 100vh;
|
|
||||||
margin: 0;
|
|
||||||
grid-template-rows: auto 1fr auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agent-settings-header {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.divider {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-bottom: 2px solid var(--main-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
div#footer {
|
|
||||||
width: auto;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: var(--background-color);
|
|
||||||
border-top: 1px solid var(--main-text-color);
|
|
||||||
text-align: left;
|
|
||||||
margin-top: 12px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#footer a {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agent-data-wrapper button {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 10px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: var(--summer-sun);
|
|
||||||
font: inherit;
|
|
||||||
color: var(--main-text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agent-data-wrapper button:hover {
|
|
||||||
background-color: var(--primary-hover);
|
|
||||||
box-shadow: 0 0 10px var(--primary-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
input#agent-name-input {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: left;
|
|
||||||
background-color: #EEEEEE;
|
|
||||||
color: var(--main-text-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 8px;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agent-instructions {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
#agent-metadata {
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
border-radius: 5px;
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
||||||
text-align: left;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#agent-avatar-wrapper {
|
|
||||||
margin-right: 10px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
#agent-avatar {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
border-radius: 50%;
|
|
||||||
object-fit: cover;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#agent-name {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
#agent-tuning, #agent-public, #agent-creator, #agent-managed-by-admin {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
#agent-tuning p {
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
|
|
||||||
#agent-metadata p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#agent-public {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto 1fr;
|
|
||||||
grid-gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 50px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch input {
|
|
||||||
opacity: 0;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider {
|
|
||||||
position: absolute;
|
|
||||||
cursor: pointer;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: #ccc;
|
|
||||||
-webkit-transition: .4s;
|
|
||||||
transition: .4s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider:before {
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
left: 4px;
|
|
||||||
bottom: 4px;
|
|
||||||
background-color: white;
|
|
||||||
-webkit-transition: .4s;
|
|
||||||
transition: .4s;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:checked + .slider {
|
|
||||||
background-color: var(--primary-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus + .slider {
|
|
||||||
box-shadow: 0 0 1px var(--primary-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
input:checked + .slider:before {
|
|
||||||
-webkit-transform: translateX(26px);
|
|
||||||
-ms-transform: translateX(26px);
|
|
||||||
transform: translateX(26px);
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agent-data-wrapper {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-gap: 10px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Rounded sliders */
|
|
||||||
.slider.round {
|
|
||||||
border-radius: 34px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider.round:before {
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agent-tuning {
|
|
||||||
max-height: 1000px;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: max-height 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
button#toggle-agent-tuning {
|
|
||||||
background-color: var(--primary) !important;
|
|
||||||
font-size: small !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 700px) {
|
|
||||||
body {
|
|
||||||
grid-template-columns: auto min(70vw, 100%) auto;
|
|
||||||
}
|
|
||||||
body > * {
|
|
||||||
grid-column: 2;
|
|
||||||
}
|
|
||||||
#agent-metadata-wrapper {
|
|
||||||
display: block;
|
|
||||||
width: min(30vw, 100%);
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
async function openChat(agentSlug) {
|
|
||||||
let response = await fetch(`/api/chat/sessions?agent_slug=${agentSlug}`, { method: "POST" });
|
|
||||||
let data = await response.json();
|
|
||||||
if (response.status == 200) {
|
|
||||||
window.location.href = "/";
|
|
||||||
} else {
|
|
||||||
alert("Failed to start chat session");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleAgentTuning() {
|
|
||||||
var agentTuning = document.getElementById('agent-tuning');
|
|
||||||
var toggleButton = document.getElementById('toggle-agent-tuning');
|
|
||||||
if (agentTuning.style.maxHeight === '0px') {
|
|
||||||
toggleButton.textContent = '↓';
|
|
||||||
agentTuning.style.maxHeight = '500px';
|
|
||||||
} else {
|
|
||||||
toggleButton.textContent = '↑';
|
|
||||||
agentTuning.style.maxHeight = '0px';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the agent-managed-by-admin paragraph if the agent is managed by the admin
|
|
||||||
// compare agent.managed_by_admin as a lowercase string to "true"
|
|
||||||
let isManagedByAdmin = "{{ agent.managed_by_admin }}".toLowerCase() === "true";
|
|
||||||
if (isManagedByAdmin) {
|
|
||||||
document.getElementById("agent-managed-by-admin").style.display = "block";
|
|
||||||
} else {
|
|
||||||
document.getElementById("agent-creator").style.display = "block";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resize the input field based on the length of the value
|
|
||||||
let input = document.getElementById("agent-name-input");
|
|
||||||
input.addEventListener("input", resizeInput);
|
|
||||||
resizeInput.call(input);
|
|
||||||
function resizeInput() {
|
|
||||||
this.style.width = this.value.length + 1 + "ch";
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</html>
|
|
|
@ -1,276 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0 maximum-scale=1.0">
|
|
||||||
<title>Khoj - Agents</title>
|
|
||||||
|
|
||||||
<link rel="icon" type="image/png" sizes="128x128" href="/static/assets/icons/favicon-128x128.png?v={{ khoj_version }}">
|
|
||||||
<link rel="manifest" href="/static/khoj.webmanifest?v={{ khoj_version }}">
|
|
||||||
<link rel="stylesheet" href="/static/assets/khoj.css?v={{ khoj_version }}">
|
|
||||||
</head>
|
|
||||||
<script type="text/javascript" src="/static/assets/utils.js?v={{ khoj_version }}"></script>
|
|
||||||
<body>
|
|
||||||
<!--Add Header Logo and Nav Pane-->
|
|
||||||
{% import 'utils.html' as utils %}
|
|
||||||
{{ utils.heading_pane(user_photo, username, is_active, has_documents) }}
|
|
||||||
|
|
||||||
<div id="agents-list">
|
|
||||||
<div id="agents-header">
|
|
||||||
<h1 id="agents-list-title">Chat with an Agent</h1>
|
|
||||||
<!-- <div id="create-agent">
|
|
||||||
<a href="/agents/create"><svg class="new-convo-button" viewBox="0 0 35 35" fill="#000000" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M16 0c-8.836 0-16 7.163-16 16s7.163 16 16 16c8.837 0 16-7.163 16-16s-7.163-16-16-16zM16 30.032c-7.72 0-14-6.312-14-14.032s6.28-14 14-14 14 6.28 14 14-6.28 14.032-14 14.032zM23 15h-6v-6c0-0.552-0.448-1-1-1s-1 0.448-1 1v6h-6c-0.552 0-1 0.448-1 1s0.448 1 1 1h6v6c0 0.552 0.448 1 1 1s1-0.448 1-1v-6h6c0.552 0 1-0.448 1-1s-0.448-1-1-1z"></path>
|
|
||||||
</svg></a>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
|
||||||
<div id="agents">
|
|
||||||
{% for agent in agents %}
|
|
||||||
<div class="agent">
|
|
||||||
<a href="/agent/{{ agent.slug }}">
|
|
||||||
<div class="agent-avatar">
|
|
||||||
<img src="{{ agent.avatar }}" alt="{{ agent.name }}">
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div class="agent-info">
|
|
||||||
<a href="/agent/{{ agent.slug }}">
|
|
||||||
<h2>{{ agent.name }}</h2>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="agent-info">
|
|
||||||
<button onclick="openChat('{{ agent.slug }}')">
|
|
||||||
<img class="send-icon" src="/static/assets/icons/send.svg" alt="Chat">
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="agent-personality">
|
|
||||||
<a href="/agent/{{ agent.slug }}">
|
|
||||||
<p>
|
|
||||||
{{ agent.personality }}
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="footer">
|
|
||||||
<a href="/">Back to Chat</a>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
document.getElementById("agents-nav").classList.add("khoj-nav-selected");
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background-color: var(--background-color);
|
|
||||||
display: grid;
|
|
||||||
color: var(--main-text-color);
|
|
||||||
text-align: center;
|
|
||||||
font-family: var(--font-family);
|
|
||||||
font-size: medium;
|
|
||||||
font-weight: 300;
|
|
||||||
line-height: 1.5em;
|
|
||||||
height: 100vh;
|
|
||||||
margin: 0;
|
|
||||||
grid-template-rows: auto 1fr auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1#agents-list-title {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-personality p {
|
|
||||||
white-space: inherit;
|
|
||||||
overflow: hidden;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.agent-personality {
|
|
||||||
text-align: left;
|
|
||||||
grid-column: span 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.agent-info {
|
|
||||||
font-size: medium;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.agent-info a,
|
|
||||||
div.agent-info h2 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.agent img {
|
|
||||||
width: 78px;
|
|
||||||
height: 78px;
|
|
||||||
border-radius: 50%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.agent a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--main-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agents-header {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agents-header a,
|
|
||||||
div.agent-info button {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 4px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: var(--summer-sun);
|
|
||||||
font: inherit;
|
|
||||||
color: var(--main-text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agents-header a:hover,
|
|
||||||
div.agent-info button:hover {
|
|
||||||
background-color: var(--primary-hover);
|
|
||||||
box-shadow: 0 0 10px var(--primary-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
div#footer {
|
|
||||||
width: auto;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: var(--background-color);
|
|
||||||
border-top: 1px solid var(--main-text-color);
|
|
||||||
text-align: left;
|
|
||||||
margin-top: 12px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#footer a {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.agent {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto 1fr auto;
|
|
||||||
gap: 20px;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
|
||||||
border-radius: 8px;
|
|
||||||
background: linear-gradient(18.48deg,rgba(252, 213, 87, 0.25) 2.76%,rgba(197, 0, 0, 0) 17.23%),linear-gradient(200.6deg,rgba(244, 229, 68, 0.25) 4.13%,rgba(230, 26, 26, 0) 20.54%);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.agent-info {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#agents {
|
|
||||||
display: grid;
|
|
||||||
gap: 20px;
|
|
||||||
padding: 20px;
|
|
||||||
width: 75%;
|
|
||||||
margin-right: auto;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.new-convo-button {
|
|
||||||
width: 20px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.send-icon {
|
|
||||||
width: 50px !important;
|
|
||||||
height: 50px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 700px) {
|
|
||||||
body {
|
|
||||||
grid-template-columns: auto min(70vw, 100%) auto;
|
|
||||||
}
|
|
||||||
body > * {
|
|
||||||
grid-column: 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 700px) {
|
|
||||||
div#agents {
|
|
||||||
width: 90%;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
.loader {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: inline-block;
|
|
||||||
border-top: 4px solid var(--primary-color);
|
|
||||||
border-right: 4px solid transparent;
|
|
||||||
box-sizing: border-box;
|
|
||||||
animation: rotation 1s linear infinite;
|
|
||||||
}
|
|
||||||
.loader::after {
|
|
||||||
content: '';
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border-left: 4px solid var(--summer-sun);
|
|
||||||
border-bottom: 4px solid transparent;
|
|
||||||
animation: rotation 0.5s linear infinite reverse;
|
|
||||||
}
|
|
||||||
@keyframes rotation {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
async function openChat(agentSlug) {
|
|
||||||
// Create a loading animation
|
|
||||||
let loadingTextEl = document.createElement("div");
|
|
||||||
loadingTextEl.textContent = 'Booting your agent...';
|
|
||||||
|
|
||||||
let loadingAnimationEl = document.createElement("span");
|
|
||||||
loadingAnimationEl.className = "loader";
|
|
||||||
|
|
||||||
let loadingEl = document.createElement("div");
|
|
||||||
loadingEl.style.position = "fixed";
|
|
||||||
loadingEl.style.top = "0";
|
|
||||||
loadingEl.style.right = "0";
|
|
||||||
loadingEl.style.bottom = "0";
|
|
||||||
loadingEl.style.left = "0";
|
|
||||||
loadingEl.style.display = "flex";
|
|
||||||
loadingEl.style.justifyContent = "center";
|
|
||||||
loadingEl.style.alignItems = "center";
|
|
||||||
loadingEl.style.backgroundColor = "rgba(0, 0, 0, 0.5)"; // Semi-transparent black
|
|
||||||
|
|
||||||
loadingEl.append(loadingTextEl, loadingAnimationEl);
|
|
||||||
document.body.appendChild(loadingEl);
|
|
||||||
|
|
||||||
let response = await fetch(`/api/chat/sessions?agent_slug=${agentSlug}`, { method: "POST" });
|
|
||||||
let data = await response.json();
|
|
||||||
if (response.status == 200) {
|
|
||||||
window.location.href = "/";
|
|
||||||
} else if(response.status == 403 || response.status == 401) {
|
|
||||||
window.location.href = "/login?next=/agent/" + agentId;
|
|
||||||
} else {
|
|
||||||
alert("Failed to start chat session");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</html>
|
|
|
@ -1,3 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M704 288h-281.6l177.6-202.88a32 32 0 0 0-48.32-42.24l-224 256a30.08 30.08 0 0 0-2.24 3.84 32 32 0 0 0-2.88 4.16v1.92a32 32 0 0 0 0 5.12A32 32 0 0 0 320 320a32 32 0 0 0 0 4.8 32 32 0 0 0 0 5.12v1.92a32 32 0 0 0 2.88 4.16 30.08 30.08 0 0 0 2.24 3.84l224 256a32 32 0 1 0 48.32-42.24L422.4 352H704a224 224 0 0 1 224 224v128a224 224 0 0 1-224 224H320a232 232 0 0 1-28.16-1.6 32 32 0 0 0-35.84 27.84 32 32 0 0 0 27.84 35.52A295.04 295.04 0 0 0 320 992h384a288 288 0 0 0 288-288v-128a288 288 0 0 0-288-288zM103.04 760a32 32 0 0 0-62.08 16A289.92 289.92 0 0 0 140.16 928a32 32 0 0 0 40-49.92 225.6 225.6 0 0 1-77.12-118.08zM64 672a32 32 0 0 0 22.72-9.28 37.12 37.12 0 0 0 6.72-10.56A32 32 0 0 0 96 640a33.6 33.6 0 0 0-9.28-22.72 32 32 0 0 0-10.56-6.72 32 32 0 0 0-34.88 6.72A32 32 0 0 0 32 640a32 32 0 0 0 2.56 12.16 37.12 37.12 0 0 0 6.72 10.56A32 32 0 0 0 64 672z" fill="#231815" /></svg>
|
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
|
||||||
|
|
||||||
<title>collapse</title>
|
|
||||||
<desc>Created with Sketch Beta.</desc>
|
|
||||||
<defs>
|
|
||||||
|
|
||||||
</defs>
|
|
||||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
|
||||||
<g id="Icon-Set" sketch:type="MSLayerGroup" transform="translate(-360.000000, -1191.000000)" fill="#000000">
|
|
||||||
<path d="M387.887,1203.04 L381.326,1203.04 L392.014,1192.4 L390.614,1191.01 L379.938,1201.64 L379.969,1195.16 C379.969,1194.61 379.526,1194.17 378.979,1194.17 C378.433,1194.17 377.989,1194.61 377.989,1195.16 L377.989,1204.03 C377.989,1204.32 378.111,1204.56 378.302,1204.72 C378.481,1204.9 378.73,1205.01 379.008,1205.01 L387.887,1205.01 C388.434,1205.01 388.876,1204.57 388.876,1204.03 C388.876,1203.48 388.434,1203.04 387.887,1203.04 L387.887,1203.04 Z M372.992,1208.99 L364.113,1208.99 C363.566,1208.99 363.124,1209.43 363.124,1209.97 C363.124,1210.52 363.566,1210.96 364.113,1210.96 L370.674,1210.96 L359.986,1221.6 L361.386,1222.99 L372.063,1212.36 L372.031,1218.84 C372.031,1219.39 372.474,1219.83 373.021,1219.83 C373.567,1219.83 374.011,1219.39 374.011,1218.84 L374.011,1209.97 C374.011,1209.68 373.889,1209.44 373.697,1209.28 C373.519,1209.1 373.27,1208.99 372.992,1208.99 L372.992,1208.99 Z" id="collapse" sketch:type="MSShapeGroup">
|
|
||||||
|
|
||||||
</path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 10 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122.88 122.88"><defs><style>.cls-1{fill:#00a912;}.cls-1,.cls-2{fill-rule:evenodd;}.cls-2{fill:#fff;}</style></defs><title>confirm</title><path class="cls-1" d="M61.44,0A61.44,61.44,0,1,1,0,61.44,61.44,61.44,0,0,1,61.44,0Z"/><path class="cls-2" d="M42.37,51.68,53.26,62,79,35.87c2.13-2.16,3.47-3.9,6.1-1.19l8.53,8.74c2.8,2.77,2.66,4.4,0,7L58.14,85.34c-5.58,5.46-4.61,5.79-10.26.19L28,65.77c-1.18-1.28-1.05-2.57.24-3.84l9.9-10.27c1.5-1.58,2.7-1.44,4.22,0Z"/></svg>
|
|
Before Width: | Height: | Size: 549 B |
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path opacity="0.4" d="M22 11.1V6.9C22 3.4 20.6 2 17.1 2H12.9C9.4 2 8 3.4 8 6.9V8H11.1C14.6 8 16 9.4 16 12.9V16H17.1C20.6 16 22 14.6 22 11.1Z" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path fill="#00ff00" d="M16 17.1V12.9C16 9.4 14.6 8 11.1 8H6.9C3.4 8 2 9.4 2 12.9V17.1C2 20.6 3.4 22 6.9 22H11.1C14.6 22 16 20.6 16 17.1Z" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M6.08008 14.9998L8.03008 16.9498L11.9201 13.0498" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 829 B |
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path opacity="0.4" d="M16 12.9V17.1C16 20.6 14.6 22 11.1 22H6.9C3.4 22 2 20.6 2 17.1V12.9C2 9.4 3.4 8 6.9 8H11.1C14.6 8 16 9.4 16 12.9Z" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M22 6.9V11.1C22 14.6 20.6 16 17.1 16H16V12.9C16 9.4 14.6 8 11.1 8H8V6.9C8 3.4 9.4 2 12.9 2H17.1C20.6 2 22 3.4 22 6.9Z" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 669 B |
Before Width: | Height: | Size: 19 KiB |
|
@ -1,26 +0,0 @@
|
||||||
<svg
|
|
||||||
width="800px"
|
|
||||||
height="800px"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<path
|
|
||||||
d="M 2.8842937,6.1960452 H 21.225537"
|
|
||||||
stroke="#000000"
|
|
||||||
stroke-width="2.29266"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
<path
|
|
||||||
d="M 5.1769491,9.6350283 7.1273225,20.362133 c 0.1982115,1.090158 1.1476689,1.8825 2.2556753,1.8825 h 5.3437782 c 1.10804,0 2.057543,-0.792456 2.255743,-1.8825 L 18.932881,9.6350283"
|
|
||||||
stroke="#000000"
|
|
||||||
stroke-width="2.29266"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
<path
|
|
||||||
d="m 8.6159322,3.9033897 c 0,-1.266199 1.0264559,-2.2926552 2.2926548,-2.2926552 h 2.292656 c 1.266234,0 2.292655,1.0264562 2.292655,2.2926552 V 6.1960452 H 8.6159322 Z"
|
|
||||||
stroke="#000000"
|
|
||||||
stroke-width="2.29266"
|
|
||||||
stroke-linecap="round" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 914 B |
|
@ -1,7 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="#FFF" stroke-miterlimit="10" stroke-width="2" viewBox="0 0 96 96">
|
|
||||||
<path stroke="#979593" d="M67.1716 7H27c-1.1046 0-2 .8954-2 2v78c0 1.1046.8954 2 2 2h58c1.1046 0 2-.8954 2-2V26.8284c0-.5304-.2107-1.0391-.5858-1.4142L68.5858 7.5858C68.2107 7.2107 67.702 7 67.1716 7z"/>
|
|
||||||
<path fill="none" stroke="#979593" d="M67 7v18c0 1.1046.8954 2 2 2h18"/>
|
|
||||||
<path fill="#C8C6C4" d="M79 61H48v-2h31c.5523 0 1 .4477 1 1s-.4477 1-1 1zm0-6H48v-2h31c.5523 0 1 .4477 1 1s-.4477 1-1 1zm0-6H48v-2h31c.5523 0 1 .4477 1 1s-.4477 1-1 1zm0-6H48v-2h31c.5523 0 1 .4477 1 1s-.4477 1-1 1zm0 24H48v-2h31c.5523 0 1 .4477 1 1s-.4477 1-1 1z"/>
|
|
||||||
<path fill="#185ABD" d="M12 74h32c2.2091 0 4-1.7909 4-4V38c0-2.2091-1.7909-4-4-4H12c-2.2091 0-4 1.7909-4 4v32c0 2.2091 1.7909 4 4 4z"/>
|
|
||||||
<path d="M21.6245 60.6455c.0661.522.109.9769.1296 1.3657h.0762c.0306-.3685.0889-.8129.1751-1.3349.0862-.5211.1703-.961.2517-1.319L25.7911 44h4.5702l3.6562 15.1272c.183.7468.3353 1.6973.457 2.8532h.0608c.0508-.7979.1777-1.7184.3809-2.7615L37.8413 44H42l-5.1183 22h-4.86l-3.4885-14.5744c-.1016-.4197-.2158-.9663-.3428-1.6417-.127-.6745-.2057-1.1656-.236-1.4724h-.0608c-.0407.358-.1195.8896-.2364 1.595-.1169.7062-.211 1.2273-.2819 1.565L24.1 66h-4.9357L14 44h4.2349l3.1843 15.3882c.0709.3165.1392.7362.2053 1.2573z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.3 KiB |
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill="none">
|
|
||||||
<path fill="#000000" fill-rule="evenodd" d="M15.198 3.52a1.612 1.612 0 012.223 2.336L6.346 16.421l-2.854.375 1.17-3.272L15.197 3.521zm3.725-1.322a3.612 3.612 0 00-5.102-.128L3.11 12.238a1 1 0 00-.253.388l-1.8 5.037a1 1 0 001.072 1.328l4.8-.63a1 1 0 00.56-.267L18.8 7.304a3.612 3.612 0 00.122-5.106zM12 17a1 1 0 100 2h6a1 1 0 100-2h-6z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 571 B |
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 8.29344C22 11.7692 19.1708 14.5869 15.6807 14.5869C15.0439 14.5869 13.5939 14.4405 12.8885 13.8551L12.0067 14.7333C11.4883 15.2496 11.6283 15.4016 11.8589 15.652C11.9551 15.7565 12.0672 15.8781 12.1537 16.0505C12.1537 16.0505 12.8885 17.075 12.1537 18.0995C11.7128 18.6849 10.4783 19.5045 9.06754 18.0995L8.77362 18.3922C8.77362 18.3922 9.65538 19.4167 8.92058 20.4412C8.4797 21.0267 7.30403 21.6121 6.27531 20.5876L5.2466 21.6121C4.54119 22.3146 3.67905 21.9048 3.33616 21.6121L2.45441 20.7339C1.63143 19.9143 2.1115 19.0264 2.45441 18.6849L10.0963 11.0743C10.0963 11.0743 9.3615 9.90338 9.3615 8.29344C9.3615 4.81767 12.1907 2 15.6807 2C19.1708 2 22 4.81767 22 8.29344ZM15.681 10.4889C16.8984 10.4889 17.8853 9.50601 17.8853 8.29353C17.8853 7.08105 16.8984 6.09814 15.681 6.09814C14.4635 6.09814 13.4766 7.08105 13.4766 8.29353C13.4766 9.50601 14.4635 10.4889 15.681 10.4889Z" fill="#1C274C"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="208" height="128" viewBox="0 0 208 128"><rect width="198" height="118" x="5" y="5" ry="10" stroke="#000" stroke-width="10" fill="none"/><path d="M30 98V30h20l20 25 20-25h20v68H90V59L70 84 50 59v39zm125 0l-30-33h20V30h20v35h20z"/></svg>
|
|
Before Width: | Height: | Size: 283 B |
|
@ -1,23 +0,0 @@
|
||||||
<svg
|
|
||||||
shape-rendering="geometricPrecision"
|
|
||||||
text-rendering="geometricPrecision"
|
|
||||||
image-rendering="optimizeQuality"
|
|
||||||
fill-rule="evenodd"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<ellipse
|
|
||||||
style="fill:none;;stroke:#000000;stroke-width:50;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
cx="256.91525"
|
|
||||||
cy="255.90652"
|
|
||||||
rx="229.04117"
|
|
||||||
ry="228.01408" />
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:50;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 256.81156,119.9742 0.54637,272.93295" />
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:50;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="M 112.29371,257.08475 H 399.09612" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 949 B |
|
@ -1,4 +0,0 @@
|
||||||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M6.017 4.313l55.333 -4.087c6.797 -0.583 8.543 -0.19 12.817 2.917l17.663 12.443c2.913 2.14 3.883 2.723 3.883 5.053v68.243c0 4.277 -1.553 6.807 -6.99 7.193L24.467 99.967c-4.08 0.193 -6.023 -0.39 -8.16 -3.113L3.3 79.94c-2.333 -3.113 -3.3 -5.443 -3.3 -8.167V11.113c0 -3.497 1.553 -6.413 6.017 -6.8z" fill="#fff"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M61.35 0.227l-55.333 4.087C1.553 4.7 0 7.617 0 11.113v60.66c0 2.723 0.967 5.053 3.3 8.167l13.007 16.913c2.137 2.723 4.08 3.307 8.16 3.113l64.257 -3.89c5.433 -0.387 6.99 -2.917 6.99 -7.193V20.64c0 -2.21 -0.873 -2.847 -3.443 -4.733L74.167 3.143c-4.273 -3.107 -6.02 -3.5 -12.817 -2.917zM25.92 19.523c-5.247 0.353 -6.437 0.433 -9.417 -1.99L8.927 11.507c-0.77 -0.78 -0.383 -1.753 1.557 -1.947l53.193 -3.887c4.467 -0.39 6.793 1.167 8.54 2.527l9.123 6.61c0.39 0.197 1.36 1.36 0.193 1.36l-54.933 3.307 -0.68 0.047zM19.803 88.3V30.367c0 -2.53 0.777 -3.697 3.103 -3.893L86 22.78c2.14 -0.193 3.107 1.167 3.107 3.693v57.547c0 2.53 -0.39 4.67 -3.883 4.863l-60.377 3.5c-3.493 0.193 -5.043 -0.97 -5.043 -4.083zm59.6 -54.827c0.387 1.75 0 3.5 -1.75 3.7l-2.91 0.577v42.773c-2.527 1.36 -4.853 2.137 -6.797 2.137 -3.107 0 -3.883 -0.973 -6.21 -3.887l-19.03 -29.94v28.967l6.02 1.363s0 3.5 -4.857 3.5l-13.39 0.777c-0.39 -0.78 0 -2.723 1.357 -3.11l3.497 -0.97v-38.3L30.48 40.667c-0.39 -1.75 0.58 -4.277 3.3 -4.473l14.367 -0.967 19.8 30.327v-26.83l-5.047 -0.58c-0.39 -2.143 1.163 -3.7 3.103 -3.89l13.4 -0.78z" fill="#000"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.5 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg viewBox="0 0 320 320" xmlns="http://www.w3.org/2000/svg"><path d="m297.06 130.97c7.26-21.79 4.76-45.66-6.85-65.48-17.46-30.4-52.56-46.04-86.84-38.68-15.25-17.18-37.16-26.95-60.13-26.81-35.04-.08-66.13 22.48-76.91 55.82-22.51 4.61-41.94 18.7-53.31 38.67-17.59 30.32-13.58 68.54 9.92 94.54-7.26 21.79-4.76 45.66 6.85 65.48 17.46 30.4 52.56 46.04 86.84 38.68 15.24 17.18 37.16 26.95 60.13 26.8 35.06.09 66.16-22.49 76.94-55.86 22.51-4.61 41.94-18.7 53.31-38.67 17.57-30.32 13.55-68.51-9.94-94.51zm-120.28 168.11c-14.03.02-27.62-4.89-38.39-13.88.49-.26 1.34-.73 1.89-1.07l63.72-36.8c3.26-1.85 5.26-5.32 5.24-9.07v-89.83l26.93 15.55c.29.14.48.42.52.74v74.39c-.04 33.08-26.83 59.9-59.91 59.97zm-128.84-55.03c-7.03-12.14-9.56-26.37-7.15-40.18.47.28 1.3.79 1.89 1.13l63.72 36.8c3.23 1.89 7.23 1.89 10.47 0l77.79-44.92v31.1c.02.32-.13.63-.38.83l-64.41 37.19c-28.69 16.52-65.33 6.7-81.92-21.95zm-16.77-139.09c7-12.16 18.05-21.46 31.21-26.29 0 .55-.03 1.52-.03 2.2v73.61c-.02 3.74 1.98 7.21 5.23 9.06l77.79 44.91-26.93 15.55c-.27.18-.61.21-.91.08l-64.42-37.22c-28.63-16.58-38.45-53.21-21.95-81.89zm221.26 51.49-77.79-44.92 26.93-15.54c.27-.18.61-.21.91-.08l64.42 37.19c28.68 16.57 38.51 53.26 21.94 81.94-7.01 12.14-18.05 21.44-31.2 26.28v-75.81c.03-3.74-1.96-7.2-5.2-9.06zm26.8-40.34c-.47-.29-1.3-.79-1.89-1.13l-63.72-36.8c-3.23-1.89-7.23-1.89-10.47 0l-77.79 44.92v-31.1c-.02-.32.13-.63.38-.83l64.41-37.16c28.69-16.55 65.37-6.7 81.91 22 6.99 12.12 9.52 26.31 7.15 40.1zm-168.51 55.43-26.94-15.55c-.29-.14-.48-.42-.52-.74v-74.39c.02-33.12 26.89-59.96 60.01-59.94 14.01 0 27.57 4.92 38.34 13.88-.49.26-1.33.73-1.89 1.07l-63.72 36.8c-3.26 1.85-5.26 5.31-5.24 9.06l-.04 89.79zm14.63-31.54 34.65-20.01 34.65 20v40.01l-34.65 20-34.65-20z"/></svg>
|
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 7.8 KiB |
|
@ -1,23 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg enable-background="new 0 0 334.371 380.563" version="1.1" viewBox="0 0 14 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
|
|
||||||
<g transform="matrix(.04589 0 0 .04589 -.66877 -.73379)">
|
|
||||||
<polygon points="51.791 356.65 51.791 23.99 204.5 23.99 282.65 102.07 282.65 356.65" fill="#fff" stroke-width="212.65"/>
|
|
||||||
<path d="m201.19 31.99 73.46 73.393v243.26h-214.86v-316.66h141.4m6.623-16h-164.02v348.66h246.85v-265.9z" stroke-width="21.791"/>
|
|
||||||
</g>
|
|
||||||
<g transform="matrix(.04589 0 0 .04589 -.66877 -.73379)">
|
|
||||||
<polygon points="282.65 356.65 51.791 356.65 51.791 23.99 204.5 23.99 206.31 25.8 206.31 100.33 280.9 100.33 282.65 102.07" fill="#fff" stroke-width="212.65"/>
|
|
||||||
<path d="m198.31 31.99v76.337h76.337v240.32h-214.86v-316.66h138.52m9.5-16h-164.02v348.66h246.85v-265.9l-6.43-6.424h-69.907v-69.842z" stroke-width="21.791"/>
|
|
||||||
</g>
|
|
||||||
<g transform="matrix(.04589 0 0 .04589 -.66877 -.73379)" stroke-width="21.791">
|
|
||||||
<polygon points="258.31 87.75 219.64 87.75 219.64 48.667 258.31 86.38"/>
|
|
||||||
<path d="m227.64 67.646 12.41 12.104h-12.41v-12.104m-5.002-27.229h-10.998v55.333h54.666v-12.742z"/>
|
|
||||||
</g>
|
|
||||||
<g transform="matrix(.04589 0 0 .04589 -.66877 -.73379)" fill="#ed1c24" stroke-width="212.65">
|
|
||||||
<polygon points="311.89 284.49 22.544 284.49 22.544 167.68 37.291 152.94 37.291 171.49 297.15 171.49 297.15 152.94 311.89 167.68"/>
|
|
||||||
<path d="m303.65 168.63 1.747 1.747v107.62h-276.35v-107.62l1.747-1.747v9.362h272.85v-9.362m-12.999-31.385v27.747h-246.86v-27.747l-27.747 27.747v126h302.35v-126z"/>
|
|
||||||
</g>
|
|
||||||
<rect x="1.7219" y="7.9544" width="10.684" height="4.0307" fill="none"/>
|
|
||||||
<g transform="matrix(.04589 0 0 .04589 1.7219 11.733)" fill="#fff" stroke-width="21.791"><path d="m9.216 0v-83.2h30.464q6.784 0 12.928 1.408 6.144 1.28 10.752 4.608 4.608 3.2 7.296 8.576 2.816 5.248 2.816 13.056 0 7.68-2.816 13.184-2.688 5.504-7.296 9.088-4.608 3.456-10.624 5.248-6.016 1.664-12.544 1.664h-8.96v26.368zm22.016-43.776h7.936q6.528 0 9.6-3.072 3.2-3.072 3.2-8.704t-3.456-7.936-9.856-2.304h-7.424z"/><path d="m87.04 0v-83.2h24.576q9.472 0 17.28 2.304 7.936 2.304 13.568 7.296t8.704 12.8q3.2 7.808 3.2 18.816t-3.072 18.944-8.704 13.056q-5.504 5.12-13.184 7.552-7.552 2.432-16.512 2.432zm22.016-17.664h1.28q4.48 0 8.448-1.024 3.968-1.152 6.784-3.84 2.944-2.688 4.608-7.424t1.664-12.032-1.664-11.904-4.608-7.168q-2.816-2.56-6.784-3.456-3.968-1.024-8.448-1.024h-1.28z"/><path d="m169.22 0v-83.2h54.272v18.432h-32.256v15.872h27.648v18.432h-27.648v30.464z"/></g>
|
|
||||||
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.4 KiB |
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M21.2799 6.40005L11.7399 15.94C10.7899 16.89 7.96987 17.33 7.33987 16.7C6.70987 16.07 7.13987 13.25 8.08987 12.3L17.6399 2.75002C17.8754 2.49308 18.1605 2.28654 18.4781 2.14284C18.7956 1.99914 19.139 1.92124 19.4875 1.9139C19.8359 1.90657 20.1823 1.96991 20.5056 2.10012C20.8289 2.23033 21.1225 2.42473 21.3686 2.67153C21.6147 2.91833 21.8083 3.21243 21.9376 3.53609C22.0669 3.85976 22.1294 4.20626 22.1211 4.55471C22.1128 4.90316 22.0339 5.24635 21.8894 5.5635C21.7448 5.88065 21.5375 6.16524 21.2799 6.40005V6.40005Z" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M11 4H6C4.93913 4 3.92178 4.42142 3.17163 5.17157C2.42149 5.92172 2 6.93913 2 8V18C2 19.0609 2.42149 20.0783 3.17163 20.8284C3.92178 21.5786 4.93913 22 6 22H17C19.21 22 20 20.2 20 18V13" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100px" height="100px"><path fill="#fefdef" d="M29.614,12.307h-1.268c-4.803,0-8.732,3.93-8.732,8.732v61.535c0,4.803,3.93,8.732,8.732,8.732h43.535c4.803,0,8.732-3.93,8.732-8.732v-50.02C72.74,24.68,68.241,20.182,60.367,12.307H41.614"/><path fill="#1f212b" d="M71.882,92.307H28.347c-5.367,0-9.732-4.366-9.732-9.732V21.04c0-5.367,4.366-9.732,9.732-9.732h1.268c0.552,0,1,0.448,1,1s-0.448,1-1,1h-1.268c-4.264,0-7.732,3.469-7.732,7.732v61.535c0,4.264,3.469,7.732,7.732,7.732h43.535c4.264,0,7.732-3.469,7.732-7.732V32.969L59.953,13.307H41.614c-0.552,0-1-0.448-1-1s0.448-1,1-1h18.752c0.265,0,0.52,0.105,0.707,0.293l20.248,20.248c0.188,0.188,0.293,0.442,0.293,0.707v50.02C81.614,87.941,77.248,92.307,71.882,92.307z"/><path fill="#fef6aa" d="M60.114,12.807v10.986c0,4.958,4.057,9.014,9.014,9.014h11.986"/><path fill="#1f212b" d="M81.114 33.307H69.129c-5.247 0-9.515-4.268-9.515-9.515V12.807c0-.276.224-.5.5-.5s.5.224.5.5v10.985c0 4.695 3.82 8.515 8.515 8.515h11.985c.276 0 .5.224.5.5S81.391 33.307 81.114 33.307zM75.114 51.307c-.276 0-.5-.224-.5-.5v-3c0-.276.224-.5.5-.5s.5.224.5.5v3C75.614 51.083 75.391 51.307 75.114 51.307zM75.114 59.307c-.276 0-.5-.224-.5-.5v-6c0-.276.224-.5.5-.5s.5.224.5.5v6C75.614 59.083 75.391 59.307 75.114 59.307zM67.956 86.307H32.272c-4.223 0-7.658-3.45-7.658-7.689V25.955c0-2.549 1.264-4.931 3.382-6.371.228-.156.54-.095.695.132.155.229.096.54-.132.695-1.844 1.254-2.944 3.326-2.944 5.544v52.663c0 3.688 2.987 6.689 6.658 6.689h35.685c3.671 0 6.658-3.001 6.658-6.689V60.807c0-.276.224-.5.5-.5s.5.224.5.5v17.811C75.614 82.857 72.179 86.307 67.956 86.307z"/><path fill="#1f212b" d="M39.802 14.307l-.117 11.834c0 2.21-2.085 3.666-4.036 3.666-1.951 0-4.217-1.439-4.217-3.649l.037-12.58c0-1.307 1.607-2.451 2.801-2.451 1.194 0 2.345 1.149 2.345 2.456l.021 10.829c0 0-.083.667-1.005.645-.507-.012-1.145-.356-1.016-.906v-9.843h-.813l-.021 9.708c0 1.38.54 1.948 1.875 1.948s1.959-.714 1.959-2.094V13.665c0-2.271-1.36-3.5-3.436-3.5s-3.564 1.261-3.564 3.532l.032 12.11c0 3.04 2.123 4.906 4.968 4.906 2.845 0 5-1.71 5-4.75V14.307H39.802zM53.114 52.307h-23c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h23c.276 0 .5.224.5.5S53.391 52.307 53.114 52.307zM44.114 59.307h-14c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h14c.276 0 .5.224.5.5S44.391 59.307 44.114 59.307zM70.114 59.307h-24c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h24c.276 0 .5.224.5.5S70.391 59.307 70.114 59.307zM61.114 66.307h-11c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h11c.276 0 .5.224.5.5S61.391 66.307 61.114 66.307zM71.114 66.307h-8c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h8c.276 0 .5.224.5.5S71.391 66.307 71.114 66.307zM48.114 66.307h-18c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h18c.276 0 .5.224.5.5S48.391 66.307 48.114 66.307zM70.114 73.307h-13c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h13c.276 0 .5.224.5.5S70.391 73.307 70.114 73.307zM54.114 73.307h-24c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h24c.276 0 .5.224.5.5S54.391 73.307 54.114 73.307z"/></svg>
|
|
Before Width: | Height: | Size: 2.9 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 512"><path fill-rule="nonzero" d="M256 0c70.69 0 134.7 28.66 181.02 74.98C483.34 121.31 512 185.31 512 256c0 70.69-28.66 134.7-74.98 181.02C390.7 483.34 326.69 512 256 512c-70.69 0-134.69-28.66-181.02-74.98C28.66 390.7 0 326.69 0 256c0-70.69 28.66-134.69 74.98-181.02C121.31 28.66 185.31 0 256 0zm-21.49 301.51v-2.03c.16-13.46 1.48-24.12 4.07-32.05 2.54-7.92 6.19-14.37 10.97-19.25 4.77-4.92 10.51-9.39 17.22-13.46 4.31-2.74 8.22-5.78 11.68-9.18 3.45-3.36 6.19-7.27 8.23-11.69 2.02-4.37 3.04-9.24 3.04-14.62 0-6.4-1.52-11.94-4.57-16.66-3-4.68-7.06-8.28-12.04-10.87-5.03-2.54-10.61-3.81-16.76-3.81-5.53 0-10.81 1.11-15.89 3.45-5.03 2.29-9.25 5.89-12.55 10.77-3.3 4.87-5.23 11.12-5.74 18.74h-32.91c.51-12.95 3.81-23.92 9.85-32.91 6.1-8.99 14.13-15.8 24.08-20.42 10.01-4.62 21.08-6.9 33.16-6.9 13.31 0 24.89 2.43 34.84 7.41 9.96 4.93 17.73 11.83 23.27 20.67 5.48 8.84 8.28 19.1 8.28 30.88 0 8.08-1.27 15.34-3.81 21.79-2.54 6.45-6.1 12.24-10.77 17.27-4.68 5.08-10.21 9.54-16.71 13.41-6.15 3.86-11.12 7.82-14.88 11.93-3.81 4.11-6.56 8.99-8.28 14.58-1.73 5.63-2.69 12.59-2.84 20.92v2.03h-30.94zm16.36 65.82c-5.94-.04-11.02-2.13-15.29-6.35-4.26-4.21-6.35-9.34-6.35-15.33 0-5.89 2.09-10.97 6.35-15.19 4.27-4.21 9.35-6.35 15.29-6.35 5.84 0 10.92 2.14 15.18 6.35 4.32 4.22 6.45 9.3 6.45 15.19 0 3.96-1.01 7.62-2.99 10.87-1.98 3.3-4.57 5.94-7.82 7.87-3.25 1.93-6.86 2.9-10.82 2.94zM417.71 94.29C376.33 52.92 319.15 27.32 256 27.32c-63.15 0-120.32 25.6-161.71 66.97C52.92 135.68 27.32 192.85 27.32 256c0 63.15 25.6 120.33 66.97 161.71 41.39 41.37 98.56 66.97 161.71 66.97 63.15 0 120.33-25.6 161.71-66.97 41.37-41.38 66.97-98.56 66.97-161.71 0-63.15-25.6-120.32-66.97-161.71z"/></svg>
|
|
Before Width: | Height: | Size: 1.8 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg viewBox="-4.08 -4.08 32.16 32.16" fill="none" xmlns="http://www.w3.org/2000/svg" transform="rotate(0)" stroke="#000000" stroke-width="0.40800000000000003"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M11 13L15.4564 8.5M11 13L6.38202 9.57695C5.7407 9.07229 5.94107 8.06115 6.72742 7.834L20 4L17.117 15.9189C16.9651 16.6489 16.0892 16.9637 15.5 16.5L13.5 15M11 13V18L13.5 15M11 13L13.5 15M7 20L9 18M4 19L8.5 14.5M4 15L6.5 12.5" stroke="#464455" stroke-linecap="round" stroke-linejoin="round"></path> </g></svg>
|
|
Before Width: | Height: | Size: 635 B |
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="-0.5 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M6.75 15C8.13071 15 9.25 13.8807 9.25 12.5C9.25 11.1193 8.13071 10 6.75 10C5.36929 10 4.25 11.1193 4.25 12.5C4.25 13.8807 5.36929 15 6.75 15Z" stroke="#0F0F0F" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M17.25 8C18.6307 8 19.75 6.88071 19.75 5.5C19.75 4.11929 18.6307 3 17.25 3C15.8693 3 14.75 4.11929 14.75 5.5C14.75 6.88071 15.8693 8 17.25 8Z" stroke="#0F0F0F" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M17.25 22C18.6307 22 19.75 20.8807 19.75 19.5C19.75 18.1193 18.6307 17 17.25 17C15.8693 17 14.75 18.1193 14.75 19.5C14.75 20.8807 15.8693 22 17.25 22Z" stroke="#0F0F0F" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M13.49 17.05L10.45 15.06" stroke="#0F0F0F" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M13.48 7.96001L10.46 9.94001" stroke="#0F0F0F" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M19 6C20.5 7.5 21 10 21 12C21 14 20.5 16.5 19 18M16 8.99998C16.5 9.49998 17 10.5 17 12C17 13.5 16.5 14.5 16 15M3 10.5V13.5C3 14.6046 3.5 15.5 5.5 16C7.5 16.5 9 21 12 21C14 21 14 3 12 3C9 3 7.5 7.5 5.5 8C3.5 8.5 3 9.39543 3 10.5Z" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 555 B |
|
@ -1,37 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 384 512"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="stop-solid.svg"
|
|
||||||
inkscape:version="1.3 (0e150ed, 2023-07-21)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="0.4609375"
|
|
||||||
inkscape:cx="192"
|
|
||||||
inkscape:cy="256"
|
|
||||||
inkscape:window-width="1312"
|
|
||||||
inkscape:window-height="449"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="88"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="svg1" />
|
|
||||||
<!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
|
||||||
<path
|
|
||||||
d="M0 128C0 92.7 28.7 64 64 64H320c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z"
|
|
||||||
id="path1"
|
|
||||||
style="fill:#aa0000" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.3 KiB |
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg fill="#000000" width="800px" height="800px" viewBox="-7.5 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<title>thumbs-down</title>
|
|
||||||
<path d="M5.92 25.24c-0.64 0-1.36-0.2-2.2-0.64-0.28-0.16-0.44-0.44-0.44-0.76v-14.96c0-0.36 0.24-0.72 0.6-0.8 0.2-0.040 4.8-1.32 8.16-1.32 1.36 0 2.36 0.2 3 0.6 0.88 0.56 1.44 1.52 1.6 2.92 0.36 2.44-0.52 5.92-1.44 6.96-0.8 0.88-2.36 1.040-3.84 1.2-0.72 0.080-1.72 0.2-2 0.36s-0.44 1.4-0.52 2.12c-0.24 1.84-0.6 4.32-2.92 4.32zM4.92 23.32c0.48 0.2 0.8 0.24 1 0.24 0.72 0 1-0.88 1.24-2.84 0.2-1.36 0.36-2.68 1.24-3.28 0.6-0.4 1.6-0.52 2.76-0.64 0.96-0.12 2.44-0.28 2.8-0.68 0.48-0.52 1.36-3.36 1.040-5.6-0.080-0.6-0.32-1.4-0.84-1.72-0.24-0.12-0.8-0.36-2.12-0.36-2.44 0-5.76 0.76-7.12 1.080 0 0 0 13.8 0 13.8zM0.84 18.64c-0.48 0-0.84-0.36-0.84-0.84v-8.92c0-0.48 0.36-0.84 0.84-0.84s0.84 0.36 0.84 0.84v8.96c0 0.44-0.36 0.8-0.84 0.8z"></path>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1,019 B |
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg fill="#000000" width="800px" height="800px" viewBox="-7.5 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<title>thumbs-up</title>
|
|
||||||
<path d="M12.040 25.24v0c-3.36 0-7.96-1.24-8.16-1.32-0.36-0.080-0.6-0.44-0.6-0.8v-14.96c0-0.32 0.16-0.6 0.44-0.76 0.84-0.44 1.56-0.64 2.2-0.64 2.32 0 2.68 2.48 2.92 4.28 0.080 0.72 0.24 1.92 0.52 2.12s1.28 0.28 2 0.36c1.52 0.16 3.080 0.32 3.84 1.2 0.92 1.040 1.8 4.52 1.44 6.96-0.2 1.4-0.76 2.36-1.6 2.92-0.68 0.44-1.68 0.64-3 0.64zM4.92 22.48c1.36 0.32 4.64 1.080 7.12 1.080 1.32 0 1.92-0.24 2.12-0.36 0.52-0.32 0.76-1.12 0.84-1.72 0.32-2.24-0.56-5.080-1.040-5.6-0.36-0.4-1.84-0.56-2.8-0.68-1.16-0.12-2.12-0.24-2.76-0.64-0.88-0.6-1.080-1.92-1.24-3.28-0.28-1.96-0.52-2.84-1.24-2.84-0.2 0-0.52 0.040-1 0.24 0 0 0 13.8 0 13.8zM0.84 23.96c-0.48 0-0.84-0.36-0.84-0.84v-8.92c0-0.48 0.36-0.84 0.84-0.84s0.84 0.36 0.84 0.84v8.96c0 0.44-0.36 0.8-0.84 0.8z"></path>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1 KiB |
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M3.95442 10.166C4.04608 9.76202 3.79293 9.36025 3.38898 9.26859C2.98504 9.17693 2.58327 9.43009 2.49161 9.83403L3.95442 10.166ZM5.49981 4.73283C5.19117 5.00907 5.1649 5.48322 5.44115 5.79187C5.71739 6.10051 6.19154 6.12678 6.50019 5.85053L5.49981 4.73283ZM15 14.25C14.5858 14.25 14.25 14.5858 14.25 15C14.25 15.4142 14.5858 15.75 15 15.75L15 14.25ZM17.25 18.7083C17.25 19.1225 17.5858 19.4583 18 19.4583C18.4142 19.4583 18.75 19.1225 18.75 18.7083H17.25ZM5.25 18.7083C5.25 19.1225 5.58579 19.4583 6 19.4583C6.41421 19.4583 6.75 19.1225 6.75 18.7083H5.25ZM9 15L8.99998 15.75H9V15ZM11 15.75C11.4142 15.75 11.75 15.4142 11.75 15C11.75 14.5858 11.4142 14.25 11 14.25V15.75ZM12 3.75C16.5563 3.75 20.25 7.44365 20.25 12H21.75C21.75 6.61522 17.3848 2.25 12 2.25V3.75ZM12 20.25C7.44365 20.25 3.75 16.5563 3.75 12H2.25C2.25 17.3848 6.61522 21.75 12 21.75V20.25ZM20.25 12C20.25 16.5563 16.5563 20.25 12 20.25V21.75C17.3848 21.75 21.75 17.3848 21.75 12H20.25ZM3.75 12C3.75 11.3688 3.82074 10.7551 3.95442 10.166L2.49161 9.83403C2.33338 10.5313 2.25 11.2564 2.25 12H3.75ZM6.50019 5.85053C7.96026 4.54373 9.88655 3.75 12 3.75V2.25C9.50333 2.25 7.22428 3.1894 5.49981 4.73283L6.50019 5.85053ZM14.25 9C14.25 10.2426 13.2426 11.25 12 11.25V12.75C14.0711 12.75 15.75 11.0711 15.75 9H14.25ZM12 11.25C10.7574 11.25 9.75 10.2426 9.75 9H8.25C8.25 11.0711 9.92893 12.75 12 12.75V11.25ZM9.75 9C9.75 7.75736 10.7574 6.75 12 6.75V5.25C9.92893 5.25 8.25 6.92893 8.25 9H9.75ZM12 6.75C13.2426 6.75 14.25 7.75736 14.25 9H15.75C15.75 6.92893 14.0711 5.25 12 5.25V6.75ZM15 15.75C15.6008 15.75 16.1482 16.0891 16.5769 16.6848C17.0089 17.2852 17.25 18.0598 17.25 18.7083H18.75C18.75 17.7371 18.4052 16.6575 17.7944 15.8086C17.1801 14.9551 16.2275 14.25 15 14.25L15 15.75ZM6.75 18.7083C6.75 18.0598 6.99109 17.2852 7.42315 16.6848C7.85183 16.0891 8.39919 15.75 8.99998 15.75L9.00002 14.25C7.77253 14.25 6.81989 14.9551 6.20564 15.8086C5.59477 16.6575 5.25 17.7371 5.25 18.7083H6.75ZM9 15.75H11V14.25H9V15.75Z" fill="#000000"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.2 KiB |
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M6 11L6 13" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M9 9L9 15" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M15 9L15 15" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M18 11L18 13" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M12 11L12 13" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 758 B |
|
@ -1,2 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" stroke-width="3" stroke="#000000" fill="none"><circle cx="34.52" cy="11.43" r="5.82"/><circle cx="53.63" cy="31.6" r="5.82"/><circle cx="34.52" cy="50.57" r="5.82"/><circle cx="15.16" cy="42.03" r="5.82"/><circle cx="15.16" cy="19.27" r="5.82"/><circle cx="34.51" cy="29.27" r="4.7"/><line x1="20.17" y1="16.3" x2="28.9" y2="12.93"/><line x1="38.6" y1="15.59" x2="49.48" y2="27.52"/><line x1="50.07" y1="36.2" x2="38.67" y2="46.49"/><line x1="18.36" y1="24.13" x2="30.91" y2="46.01"/><line x1="20.31" y1="44.74" x2="28.7" y2="48.63"/><line x1="17.34" y1="36.63" x2="31.37" y2="16.32"/><line x1="20.52" y1="21.55" x2="30.34" y2="27.1"/><line x1="39.22" y1="29.8" x2="47.81" y2="30.45"/><line x1="34.51" y1="33.98" x2="34.52" y2="44.74"/></svg>
|
|
Before Width: | Height: | Size: 951 B |
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
|
|
||||||
<title>Whatsapp-color</title>
|
|
||||||
<desc>Created with Sketch.</desc>
|
|
||||||
<defs>
|
|
||||||
|
|
||||||
</defs>
|
|
||||||
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
||||||
<g id="Color-" transform="translate(-700.000000, -360.000000)" fill="#67C15E">
|
|
||||||
<path d="M723.993033,360 C710.762252,360 700,370.765287 700,383.999801 C700,389.248451 701.692661,394.116025 704.570026,398.066947 L701.579605,406.983798 L710.804449,404.035539 C714.598605,406.546975 719.126434,408 724.006967,408 C737.237748,408 748,397.234315 748,384.000199 C748,370.765685 737.237748,360.000398 724.006967,360.000398 L723.993033,360.000398 L723.993033,360 Z M717.29285,372.190836 C716.827488,371.07628 716.474784,371.034071 715.769774,371.005401 C715.529728,370.991464 715.262214,370.977527 714.96564,370.977527 C714.04845,370.977527 713.089462,371.245514 712.511043,371.838033 C711.806033,372.557577 710.056843,374.23638 710.056843,377.679202 C710.056843,381.122023 712.567571,384.451756 712.905944,384.917648 C713.258648,385.382743 717.800808,392.55031 724.853297,395.471492 C730.368379,397.757149 732.00491,397.545307 733.260074,397.27732 C735.093658,396.882308 737.393002,395.527239 737.971421,393.891043 C738.54984,392.25405 738.54984,390.857171 738.380255,390.560912 C738.211068,390.264652 737.745308,390.095816 737.040298,389.742615 C736.335288,389.389811 732.90737,387.696673 732.25849,387.470894 C731.623543,387.231179 731.017259,387.315995 730.537963,387.99333 C729.860819,388.938653 729.198006,389.89831 728.661785,390.476494 C728.238619,390.928051 727.547144,390.984595 726.969123,390.744481 C726.193254,390.420348 724.021298,389.657798 721.340985,387.273388 C719.267356,385.42535 717.856938,383.125756 717.448104,382.434484 C717.038871,381.729275 717.405907,381.319529 717.729948,380.938852 C718.082653,380.501232 718.421026,380.191036 718.77373,379.781688 C719.126434,379.372738 719.323884,379.160897 719.549599,378.681068 C719.789645,378.215575 719.62006,377.735746 719.450874,377.382942 C719.281687,377.030139 717.871269,373.587317 717.29285,372.190836 Z" id="Whatsapp">
|
|
||||||
|
|
||||||
</path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.4 KiB |
8476
src/khoj/interface/web/assets/markdown-it.min.js
vendored
1823
src/khoj/interface/web/assets/org.min.js
vendored
5
src/khoj/interface/web/assets/pico.min.css
vendored
3
src/khoj/interface/web/assets/purify.min.js
vendored
|
@ -1,139 +0,0 @@
|
||||||
{% extends "base_config.html" %}
|
|
||||||
{% block content %}
|
|
||||||
<div class="page">
|
|
||||||
<div class="section">
|
|
||||||
<h2 class="section-title">
|
|
||||||
<img class="card-icon" src="/static/assets/icons/computer.png?v={{ khoj_version }}" alt="files">
|
|
||||||
<span class="card-title-text">Files</span>
|
|
||||||
<div class="instructions">
|
|
||||||
<p class="card-description">Manage files from your computer</p>
|
|
||||||
<p id="get-desktop-client" class="card-description">Get the Khoj <a href="https://khoj.dev/downloads">Desktop</a>, <a href="https://docs.khoj.dev/#/obsidian?id=setup">Obsidian</a> or <a href="https://docs.khoj.dev/#/emacs?id=setup">Emacs</a> app to sync documents from your computer</p>
|
|
||||||
</div>
|
|
||||||
</h2>
|
|
||||||
<div class="section-manage-files">
|
|
||||||
<div id="delete-all-files" class="delete-all-files">
|
|
||||||
<button id="delete-all-files-button" type="submit" title="Remove all computer files from Khoj">🗑️ Delete all</button>
|
|
||||||
</div>
|
|
||||||
<div class="indexed-files">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<style>
|
|
||||||
#desktop-client {
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
.indexed-files {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.content-name {
|
|
||||||
font-size: smaller;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function removeFile(path) {
|
|
||||||
fetch('/api/content/file?filename=' + path, {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.ok ? response.json() : Promise.reject(response))
|
|
||||||
.then(data => {
|
|
||||||
if (data.status == "ok") {
|
|
||||||
getAllComputerFilenames();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all currently indexed files
|
|
||||||
function getAllComputerFilenames() {
|
|
||||||
fetch('/api/content/computer')
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
var indexedFiles = document.getElementsByClassName("indexed-files")[0];
|
|
||||||
indexedFiles.innerHTML = "";
|
|
||||||
|
|
||||||
if (data.length == 0) {
|
|
||||||
document.getElementById("delete-all-files").style.display = "none";
|
|
||||||
let noFilesElement = document.createElement("div");
|
|
||||||
noFilesElement.classList.add("card-description");
|
|
||||||
noFilesElement.textContent = "No documents synced with Khoj";
|
|
||||||
indexedFiles.appendChild(noFilesElement);
|
|
||||||
} else {
|
|
||||||
document.getElementById("get-desktop-client").style.display = "none";
|
|
||||||
document.getElementById("delete-all-files").style.display = "block";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var filename of data) {
|
|
||||||
let fileElement = document.createElement("div");
|
|
||||||
fileElement.classList.add("file-element");
|
|
||||||
|
|
||||||
let fileExtension = filename.split('.').pop();
|
|
||||||
if (fileExtension === "org")
|
|
||||||
image_name = "org.svg"
|
|
||||||
else if (fileExtension === "pdf")
|
|
||||||
image_name = "pdf.svg"
|
|
||||||
else if (fileExtension === "markdown" || fileExtension === "md")
|
|
||||||
image_name = "markdown.svg"
|
|
||||||
else if (fileExtension === "docx")
|
|
||||||
image_name = "docx.svg"
|
|
||||||
else
|
|
||||||
image_name = "plaintext.svg"
|
|
||||||
|
|
||||||
let fileIconElement = document.createElement("img");
|
|
||||||
fileIconElement.classList.add("card-icon");
|
|
||||||
fileIconElement.src = `/static/assets/icons/${image_name}`;
|
|
||||||
fileIconElement.alt = "File";
|
|
||||||
fileElement.appendChild(fileIconElement);
|
|
||||||
|
|
||||||
let fileNameElement = document.createElement("div");
|
|
||||||
fileNameElement.classList.add("content-name");
|
|
||||||
fileNameElement.textContent = filename;
|
|
||||||
fileElement.appendChild(fileNameElement);
|
|
||||||
|
|
||||||
let buttonContainer = document.createElement("div");
|
|
||||||
buttonContainer.classList.add("remove-button-container");
|
|
||||||
let removeFileButton = document.createElement("button");
|
|
||||||
removeFileButton.classList.add("remove-file-button");
|
|
||||||
removeFileButton.textContent = "🗑️";
|
|
||||||
removeFileButton.addEventListener("click", ((filename) => {
|
|
||||||
return () => {
|
|
||||||
removeFile(filename);
|
|
||||||
};
|
|
||||||
})(filename));
|
|
||||||
buttonContainer.appendChild(removeFileButton);
|
|
||||||
fileElement.appendChild(buttonContainer);
|
|
||||||
indexedFiles.appendChild(fileElement);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all currently indexed files on page load
|
|
||||||
getAllComputerFilenames();
|
|
||||||
|
|
||||||
let deleteAllComputerFilesButton = document.getElementById("delete-all-files-button");
|
|
||||||
deleteAllComputerFilesButton.addEventListener("click", function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
originalDeleteAllComputerFilesButtonText = deleteAllComputerFilesButton.textContent;
|
|
||||||
deleteAllComputerFilesButton.textContent = "🗑️ Deleting...";
|
|
||||||
deleteAllComputerFilesButton.disabled = true;
|
|
||||||
|
|
||||||
fetch('/api/content/computer', {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.finally(() => {
|
|
||||||
getAllComputerFilenames();
|
|
||||||
deleteAllComputerFilesButton.textContent = originalDeleteAllComputerFilesButtonText;
|
|
||||||
deleteAllComputerFilesButton.disabled = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
|
@ -1,94 +0,0 @@
|
||||||
{% extends "base_config.html" %}
|
|
||||||
{% block content %}
|
|
||||||
<div class="page">
|
|
||||||
<div class="section">
|
|
||||||
<h2 class="section-title">
|
|
||||||
<img class="card-icon" src="/static/assets/icons/notion.svg?v={{ khoj_version }}" alt="Notion">
|
|
||||||
<span class="card-title-text">Notion</span>
|
|
||||||
<div class="instructions">
|
|
||||||
<a href="https://docs.khoj.dev/data-sources/notion_integration">ⓘ Help</a>
|
|
||||||
</div>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<label for="token">Token</label>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input type="text" id="token" name="pat" value="{{ current_config['token'] }}">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="section">
|
|
||||||
<div id="success" style="display: none;"></div>
|
|
||||||
<button id="submit" type="submit">Sync to Update</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
const submit = document.getElementById("submit");
|
|
||||||
|
|
||||||
submit.addEventListener("click", function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const token = document.getElementById("token").value;
|
|
||||||
|
|
||||||
if (token == "") {
|
|
||||||
document.getElementById("success").textContent = "❌ Please enter a Notion Token.";
|
|
||||||
document.getElementById("success").style.display = "block";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const submitButton = document.getElementById("submit");
|
|
||||||
submitButton.disabled = true;
|
|
||||||
submitButton.textContent = "Syncing...";
|
|
||||||
|
|
||||||
// Save Notion config on server
|
|
||||||
const csrfToken = document.cookie.split('; ').find(row => row.startsWith('csrftoken'))?.split('=')[1];
|
|
||||||
fetch('/api/content/notion', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-CSRFToken': csrfToken,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
"token": token,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => { data["status"] === "ok" ? data : Promise.reject(data) })
|
|
||||||
.catch(error => {
|
|
||||||
document.getElementById("success").textContent = "⚠️ Failed to save Notion settings.";
|
|
||||||
document.getElementById("success").style.display = "block";
|
|
||||||
submitButton.textContent = "⚠️ Failed to save settings";
|
|
||||||
setTimeout(function() {
|
|
||||||
submitButton.textContent = "Save";
|
|
||||||
submitButton.disabled = false;
|
|
||||||
}, 2000);
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Index Notion content on server
|
|
||||||
fetch('/api/update?t=notion')
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => { data["status"] == "ok" ? data : Promise.reject(data) })
|
|
||||||
.then(data => {
|
|
||||||
document.getElementById("success").style.display = "none";
|
|
||||||
submitButton.textContent = "✅ Successfully updated";
|
|
||||||
setTimeout(function() {
|
|
||||||
submitButton.textContent = "Save";
|
|
||||||
submitButton.disabled = false;
|
|
||||||
}, 2000);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
document.getElementById("success").textContent = "⚠️ Failed to save Notion content.";
|
|
||||||
document.getElementById("success").style.display = "block";
|
|
||||||
submitButton.textContent = "⚠️ Failed to save content";
|
|
||||||
setTimeout(function() {
|
|
||||||
submitButton.textContent = "Save";
|
|
||||||
submitButton.disabled = false;
|
|
||||||
}, 2000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
|
@ -1,470 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0 maximum-scale=1.0">
|
|
||||||
<title>Khoj - Search</title>
|
|
||||||
|
|
||||||
<link rel="icon" type="image/png" sizes="128x128" href="/static/assets/icons/favicon-128x128.png?v={{ khoj_version }}">
|
|
||||||
<link rel="apple-touch-icon" href="/static/assets/icons/favicon-128x128.png?v={{ khoj_version }}">
|
|
||||||
<link rel="manifest" href="/static/khoj.webmanifest?v={{ khoj_version }}">
|
|
||||||
<link rel="stylesheet" href="/static/assets/khoj.css?v={{ khoj_version }}">
|
|
||||||
</head>
|
|
||||||
<script type="text/javascript" src="/static/assets/org.min.js?v={{ khoj_version }}"></script>
|
|
||||||
<script type="text/javascript" src="/static/assets/markdown-it.min.js?v={{ khoj_version }}"></script>
|
|
||||||
<script type="text/javascript" src="/static/assets/utils.js?v={{ khoj_version }}"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function render_image(item) {
|
|
||||||
return `
|
|
||||||
<div class="results-image">
|
|
||||||
<a href="${item.entry}" class="image-link">
|
|
||||||
<img id=${item.score} src="${item.entry}?${Math.random()}"
|
|
||||||
title="Effective Score: ${item.score}, Meta: ${item.additional.metadata_score}, Image: ${item.additional.image_score}"
|
|
||||||
class="image">
|
|
||||||
</a>
|
|
||||||
</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function render_org(query, data, classPrefix="") {
|
|
||||||
return data.map(function (item) {
|
|
||||||
var orgParser = new Org.Parser();
|
|
||||||
var orgDocument = orgParser.parse(item.entry);
|
|
||||||
var orgHTMLDocument = orgDocument.convert(Org.ConverterHTML, { htmlClassPrefix: classPrefix });
|
|
||||||
return `<div class="results-org">` + orgHTMLDocument.toString() + `</div>`;
|
|
||||||
}).join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function render_markdown(query, data) {
|
|
||||||
var md = window.markdownit();
|
|
||||||
return data.map(function (item) {
|
|
||||||
let rendered = "";
|
|
||||||
if (item.additional.file.startsWith("http")) {
|
|
||||||
lines = item.entry.split("\n");
|
|
||||||
rendered = md.render(`${lines[0]}\t[*](${item.additional.file})\n${lines.slice(1).join("\n")}`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rendered = md.render(`${item.entry}`);
|
|
||||||
}
|
|
||||||
return `<div class="results-markdown">` + rendered + `</div>`;
|
|
||||||
}).join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function render_pdf(query, data) {
|
|
||||||
return data.map(function (item) {
|
|
||||||
let compiled_lines = item.additional.compiled.split("\n");
|
|
||||||
let filename = compiled_lines.shift();
|
|
||||||
let text_match = compiled_lines.join("\n")
|
|
||||||
return `<div class="results-pdf">` + `<h2>${filename}</h2>\n<p>${text_match}</p>` + `</div>`;
|
|
||||||
}).join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function render_html(query, data) {
|
|
||||||
return data.map(function (item) {
|
|
||||||
let document = new DOMParser().parseFromString(item.entry, "text/html");
|
|
||||||
// Scrub the HTML to remove any script tags and associated content
|
|
||||||
let script_tags = document.querySelectorAll("script");
|
|
||||||
for (let i = 0; i < script_tags.length; i++) {
|
|
||||||
script_tags[i].remove();
|
|
||||||
}
|
|
||||||
// Scrub the HTML to remove any style tags and associated content
|
|
||||||
let style_tags = document.querySelectorAll("style");
|
|
||||||
for (let i = 0; i < style_tags.length; i++) {
|
|
||||||
style_tags[i].remove();
|
|
||||||
}
|
|
||||||
// Scrub the HTML to remove any noscript tags and associated content
|
|
||||||
let noscript_tags = document.querySelectorAll("noscript");
|
|
||||||
for (let i = 0; i < noscript_tags.length; i++) {
|
|
||||||
noscript_tags[i].remove();
|
|
||||||
}
|
|
||||||
// Scrub the HTML to remove any iframe tags and associated content
|
|
||||||
let iframe_tags = document.querySelectorAll("iframe");
|
|
||||||
for (let i = 0; i < iframe_tags.length; i++) {
|
|
||||||
iframe_tags[i].remove();
|
|
||||||
}
|
|
||||||
// Scrub the HTML to remove any object tags and associated content
|
|
||||||
let object_tags = document.querySelectorAll("object");
|
|
||||||
for (let i = 0; i < object_tags.length; i++) {
|
|
||||||
object_tags[i].remove();
|
|
||||||
}
|
|
||||||
// Scrub the HTML to remove any embed tags and associated content
|
|
||||||
let embed_tags = document.querySelectorAll("embed");
|
|
||||||
for (let i = 0; i < embed_tags.length; i++) {
|
|
||||||
embed_tags[i].remove();
|
|
||||||
}
|
|
||||||
let scrubbedHTML = document.body.outerHTML;
|
|
||||||
return `<div class="results-html">` + scrubbedHTML + `</div>`;
|
|
||||||
}).join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function render_xml(query, data) {
|
|
||||||
return data.map(function (item) {
|
|
||||||
return `<div class="results-xml">` +
|
|
||||||
`<b><a href="${item.additional.file}">${item.additional.heading}</a></b>` +
|
|
||||||
`<xml>${item.entry}</xml>` +
|
|
||||||
`</div>`
|
|
||||||
}).join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function render_multiple(query, data, type) {
|
|
||||||
let html = "";
|
|
||||||
data.forEach(item => {
|
|
||||||
if (item.additional.file.endsWith(".org")) {
|
|
||||||
html += render_org(query, [item], "org-");
|
|
||||||
} else if (
|
|
||||||
item.additional.file.endsWith(".md") ||
|
|
||||||
item.additional.file.endsWith(".markdown") ||
|
|
||||||
(item.additional.file.includes("issues") && item.additional.source === "github") ||
|
|
||||||
(item.additional.file.includes("commit") && item.additional.source === "github")
|
|
||||||
)
|
|
||||||
{
|
|
||||||
html += render_markdown(query, [item]);
|
|
||||||
} else if (item.additional.file.endsWith(".pdf")) {
|
|
||||||
html += render_pdf(query, [item]);
|
|
||||||
} else if (item.additional.source === "notion") {
|
|
||||||
html += `<div class="results-notion">` + `<b><a href="${item.additional.file}">${item.additional.heading}</a></b>` + `<p>${item.entry}</p>` + `</div>`;
|
|
||||||
} else if (item.additional.file.endsWith(".html")) {
|
|
||||||
html += render_html(query, [item]);
|
|
||||||
} else if (item.additional.file.endsWith(".xml")) {
|
|
||||||
html += render_xml(query, [item])
|
|
||||||
} else {
|
|
||||||
html += `<div class="results-plugin">` + `<b><a href="${item.additional.file}">${item.additional.heading}</a></b>` + `<p>${item.entry}</p>` + `</div>`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
function render_results(data, query, type) {
|
|
||||||
let results = "";
|
|
||||||
if (type === "markdown") {
|
|
||||||
results = render_markdown(query, data);
|
|
||||||
} else if (type === "org") {
|
|
||||||
results = render_org(query, data, "org-");
|
|
||||||
} else if (type === "image") {
|
|
||||||
results = data.map(render_image).join('');
|
|
||||||
} else if (type === "pdf") {
|
|
||||||
results = render_pdf(query, data);
|
|
||||||
} else if (type === "github" || type === "all" || type === "notion") {
|
|
||||||
results = render_multiple(query, data, type);
|
|
||||||
} else {
|
|
||||||
results = data.map((item) => `<div class="results-plugin">` + `<p>${item.entry}</p>` + `</div>`).join("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any POST rendering goes here.
|
|
||||||
|
|
||||||
let renderedResults = document.createElement("div");
|
|
||||||
renderedResults.id = `results-${type}`;
|
|
||||||
renderedResults.innerHTML = results;
|
|
||||||
|
|
||||||
// For all elements that are of type img in the results html and have a src with 'avatar' in the URL, add the class 'avatar'
|
|
||||||
// This is used to make the avatar images round
|
|
||||||
let images = renderedResults.querySelectorAll("img[src*='avatar']");
|
|
||||||
for (let i = 0; i < images.length; i++) {
|
|
||||||
images[i].classList.add("avatar");
|
|
||||||
}
|
|
||||||
|
|
||||||
return renderedResults.outerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
function search(rerank=false) {
|
|
||||||
// Extract required fields for search from form
|
|
||||||
query = document.getElementById("query").value.trim();
|
|
||||||
type = document.getElementById("type").value;
|
|
||||||
results_count = localStorage.getItem("khojResultsCount") || 5;
|
|
||||||
console.log(`Query: ${query}, Type: ${type}, Results Count: ${results_count}`);
|
|
||||||
|
|
||||||
// Short circuit on empty query
|
|
||||||
if (query.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If set query field in url query param on rerank
|
|
||||||
if (rerank)
|
|
||||||
setQueryFieldInUrl(query);
|
|
||||||
|
|
||||||
// Execute Search and Render Results
|
|
||||||
url = createRequestUrl(query, type, results_count || 5, rerank);
|
|
||||||
fetch(url, {
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
document.getElementById("results").innerHTML = render_results(data, query, type);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let debounceTimeout;
|
|
||||||
function incrementalSearch(event) {
|
|
||||||
// Run incremental search only after waitTime passed since the last key press
|
|
||||||
let waitTime = 300;
|
|
||||||
clearTimeout(debounceTimeout);
|
|
||||||
debounceTimeout = setTimeout(() => {
|
|
||||||
type = document.getElementById("type").value;
|
|
||||||
// Search with reranking on 'Enter'
|
|
||||||
let should_rerank = event.key === 'Enter';
|
|
||||||
search(rerank=should_rerank);
|
|
||||||
}, waitTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
function populate_type_dropdown() {
|
|
||||||
// Populate type dropdown field with enabled content types only
|
|
||||||
fetch("/api/content/types")
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(enabled_types => {
|
|
||||||
// Show warning if no content types are enabled, or just one ("all")
|
|
||||||
if (enabled_types[0] === "all" && enabled_types.length === 1) {
|
|
||||||
document.getElementById("results").innerHTML = "<div id='results-error'>To use Khoj search, setup your content plugins on the Khoj <a class='inline-chat-link' href='/settings'>settings page</a>.</div>";
|
|
||||||
document.getElementById("query").setAttribute("disabled", "disabled");
|
|
||||||
document.getElementById("query").setAttribute("placeholder", "Configure Khoj to enable search");
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("type").innerHTML =
|
|
||||||
enabled_types
|
|
||||||
.map(type => `<option value="${type}">${type.slice(0,1).toUpperCase() + type.slice(1)}</option>`)
|
|
||||||
.join('');
|
|
||||||
|
|
||||||
return enabled_types;
|
|
||||||
})
|
|
||||||
.then(enabled_types => {
|
|
||||||
// Set type field to content type passed in URL query parameter, if valid
|
|
||||||
var type_via_url = new URLSearchParams(window.location.search).get("t");
|
|
||||||
if (type_via_url && enabled_types.includes(type_via_url))
|
|
||||||
document.getElementById("type").value = type_via_url;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function createRequestUrl(query, type, results_count, rerank) {
|
|
||||||
// Generate Backend API URL to execute Search
|
|
||||||
let url = `/api/search?q=${encodeURIComponent(query)}&n=${results_count}&client=web`;
|
|
||||||
// If type is not 'all', append type to URL
|
|
||||||
if (type !== 'all')
|
|
||||||
url += `&t=${type}`;
|
|
||||||
// Rerank is only supported by text types
|
|
||||||
if (type !== "image")
|
|
||||||
url += `&r=${rerank}`;
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTypeFieldInUrl(type) {
|
|
||||||
var url = new URL(window.location.href);
|
|
||||||
url.searchParams.set("t", type.value);
|
|
||||||
window.history.pushState({}, "", url.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setQueryFieldInUrl(query) {
|
|
||||||
var url = new URL(window.location.href);
|
|
||||||
url.searchParams.set("q", query);
|
|
||||||
window.history.pushState({}, "", url.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = function () {
|
|
||||||
// Dynamically populate type dropdown based on enabled content types and type passed as URL query parameter
|
|
||||||
populate_type_dropdown();
|
|
||||||
|
|
||||||
// Fill query field with value passed in URL query parameters, if any.
|
|
||||||
var query_via_url = new URLSearchParams(window.location.search).get("q");
|
|
||||||
if (query_via_url)
|
|
||||||
document.getElementById("query").value = query_via_url;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!--Add Header Logo and Nav Pane-->
|
|
||||||
{% import 'utils.html' as utils %}
|
|
||||||
{{ utils.heading_pane(user_photo, username, is_active, has_documents) }}
|
|
||||||
|
|
||||||
<!--Add Text Box To Enter Query, Trigger Incremental Search OnChange -->
|
|
||||||
<input type="text" id="query" class="option" onkeyup=incrementalSearch(event) autofocus="autofocus" placeholder="Search your knowledge base using natural language">
|
|
||||||
|
|
||||||
<div id="options">
|
|
||||||
<!--Add Dropdown to Select Query Type -->
|
|
||||||
<select id="type" class="option" onchange="setTypeFieldInUrl(this)"></select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Section to Render Results -->
|
|
||||||
<div id="results"></div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
document.getElementById("search-nav").classList.add("khoj-nav-selected");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@media only screen and (max-width: 700px) {
|
|
||||||
body {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: 1fr auto auto auto minmax(80px, 100%);
|
|
||||||
font-size: small!important;
|
|
||||||
}
|
|
||||||
body > * {
|
|
||||||
grid-column: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media only screen and (min-width: 700px) {
|
|
||||||
body {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr min(70vw, 100%) 1fr;
|
|
||||||
grid-template-rows: 1fr auto auto auto minmax(80px, 100%);
|
|
||||||
padding-top: 60vw;
|
|
||||||
}
|
|
||||||
body > * {
|
|
||||||
grid-column: 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
background: var(--background-color);
|
|
||||||
color: var(--main-text-color);
|
|
||||||
font-family: var(--font-family);
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 300;
|
|
||||||
line-height: 1.5em;
|
|
||||||
}
|
|
||||||
body > * {
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
#options {
|
|
||||||
padding: 0;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
#options > * {
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: 1px solid var(--main-text-color);
|
|
||||||
background: #f9fafc
|
|
||||||
}
|
|
||||||
.option:hover {
|
|
||||||
box-shadow: 0 0 11px #aaa;
|
|
||||||
}
|
|
||||||
#options > button {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#query {
|
|
||||||
font-size: larger;
|
|
||||||
}
|
|
||||||
#results {
|
|
||||||
font-size: medium;
|
|
||||||
margin: 0px;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
.results-image {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
}
|
|
||||||
.image-link {
|
|
||||||
place-self: center;
|
|
||||||
}
|
|
||||||
.image {
|
|
||||||
width: 20vw;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid var(--main-text-color);
|
|
||||||
}
|
|
||||||
#json {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
.results-pdf,
|
|
||||||
.results-notion,
|
|
||||||
.results-html,
|
|
||||||
.results-plugin {
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
.results-markdown,
|
|
||||||
.results-github {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.results-org {
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
.results-org h3 {
|
|
||||||
margin: 20px 0 0 0;
|
|
||||||
font-size: larger;
|
|
||||||
}
|
|
||||||
span.org-task-status {
|
|
||||||
color: white;
|
|
||||||
padding: 3.5px 3.5px 0;
|
|
||||||
margin-right: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
background-color: #eab308;
|
|
||||||
font-size: medium;
|
|
||||||
}
|
|
||||||
span.org-task-status.todo {
|
|
||||||
background-color: #3b82f6
|
|
||||||
}
|
|
||||||
span.org-task-status.done {
|
|
||||||
background-color: #22c55e;
|
|
||||||
}
|
|
||||||
span.org-task-tag {
|
|
||||||
color: white;
|
|
||||||
padding: 3.5px 3.5px 0;
|
|
||||||
margin-right: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: 1px solid var(--main-text-color);
|
|
||||||
background-color: #ef4444;
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
max-width: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #3b82f6;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.avatar {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#results-error,
|
|
||||||
div.results-markdown,
|
|
||||||
div.results-notion,
|
|
||||||
div.results-org,
|
|
||||||
div.results-plugin,
|
|
||||||
div.results-html,
|
|
||||||
div.results-pdf {
|
|
||||||
text-align: left;
|
|
||||||
box-shadow: 2px 2px 2px var(--primary-hover);
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px 0;
|
|
||||||
border: 4px solid rgb(229, 229, 229);
|
|
||||||
}
|
|
||||||
|
|
||||||
div#results-error {
|
|
||||||
box-shadow: 2px 2px 2px #FF5722;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes gradient {
|
|
||||||
0% {
|
|
||||||
background-position: 0% 50%;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
background-position: 100% 50%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
background-position: 0% 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a.khoj-logo {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,27 +1,16 @@
|
||||||
# System Packages
|
# System Packages
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from fastapi import APIRouter, Request
|
from fastapi import APIRouter, Request
|
||||||
from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse
|
from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
from starlette.authentication import requires
|
from starlette.authentication import requires
|
||||||
|
|
||||||
from khoj.database.adapters import (
|
from khoj.database.adapters import get_user_github_config
|
||||||
AgentAdapters,
|
|
||||||
PublicConversationAdapters,
|
|
||||||
get_user_github_config,
|
|
||||||
get_user_notion_config,
|
|
||||||
)
|
|
||||||
from khoj.database.models import KhojUser
|
|
||||||
from khoj.routers.helpers import get_next_url, get_user_config
|
from khoj.routers.helpers import get_next_url, get_user_config
|
||||||
from khoj.utils import constants, state
|
from khoj.utils import constants
|
||||||
from khoj.utils.rawconfig import (
|
from khoj.utils.rawconfig import GithubContentConfig, GithubRepoConfig
|
||||||
GithubContentConfig,
|
|
||||||
GithubRepoConfig,
|
|
||||||
NotionContentConfig,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Initialize Router
|
# Initialize Router
|
||||||
web_client = APIRouter()
|
web_client = APIRouter()
|
||||||
|
@ -30,39 +19,36 @@ templates = Jinja2Templates([constants.web_directory, constants.next_js_director
|
||||||
|
|
||||||
# Create Routes
|
# Create Routes
|
||||||
@web_client.get("/", response_class=FileResponse)
|
@web_client.get("/", response_class=FileResponse)
|
||||||
@requires(["authenticated"], redirect="login_page")
|
|
||||||
def index(request: Request):
|
def index(request: Request):
|
||||||
user = request.user.object
|
return templates.TemplateResponse("index.html", context={"request": request})
|
||||||
user_config = get_user_config(user, request)
|
|
||||||
|
|
||||||
return templates.TemplateResponse("chat.html", context=user_config)
|
|
||||||
|
|
||||||
|
|
||||||
@web_client.post("/", response_class=FileResponse)
|
@web_client.post("/", response_class=FileResponse)
|
||||||
@requires(["authenticated"], redirect="login_page")
|
@requires(["authenticated"], redirect="login_page")
|
||||||
def index_post(request: Request):
|
def index_post(request: Request):
|
||||||
user = request.user.object
|
return templates.TemplateResponse("index.html", context={"request": request})
|
||||||
user_config = get_user_config(user, request)
|
|
||||||
|
|
||||||
return templates.TemplateResponse("chat.html", context=user_config)
|
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/search", response_class=FileResponse)
|
@web_client.get("/search", response_class=FileResponse)
|
||||||
@requires(["authenticated"], redirect="login_page")
|
@requires(["authenticated"], redirect="login_page")
|
||||||
def search_page(request: Request):
|
def search_page(request: Request):
|
||||||
user = request.user.object
|
return templates.TemplateResponse(
|
||||||
user_config = get_user_config(user, request)
|
"search/index.html",
|
||||||
|
context={
|
||||||
return templates.TemplateResponse("search.html", context=user_config)
|
"request": request,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/chat", response_class=FileResponse)
|
@web_client.get("/chat", response_class=FileResponse)
|
||||||
@requires(["authenticated"], redirect="login_page")
|
@requires(["authenticated"], redirect="login_page")
|
||||||
def chat_page(request: Request):
|
def chat_page(request: Request):
|
||||||
user = request.user.object
|
return templates.TemplateResponse(
|
||||||
user_config = get_user_config(user, request)
|
"chat/index.html",
|
||||||
|
context={
|
||||||
return templates.TemplateResponse("chat.html", context=user_config)
|
"request": request,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/experimental", response_class=FileResponse)
|
@web_client.get("/experimental", response_class=FileResponse)
|
||||||
|
@ -113,38 +99,10 @@ def agents_page(request: Request):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/agent/{agent_slug}", response_class=HTMLResponse)
|
|
||||||
def agent_page(request: Request, agent_slug: str):
|
|
||||||
user: KhojUser = request.user.object if request.user.is_authenticated else None
|
|
||||||
user_config = get_user_config(user, request)
|
|
||||||
agent = AgentAdapters.get_agent_by_slug(agent_slug)
|
|
||||||
|
|
||||||
if agent == None:
|
|
||||||
user_config["has_documents"] = False
|
|
||||||
return templates.TemplateResponse("404.html", context=user_config)
|
|
||||||
|
|
||||||
user_config["agent"] = {
|
|
||||||
"slug": agent.slug,
|
|
||||||
"avatar": agent.avatar,
|
|
||||||
"name": agent.name,
|
|
||||||
"personality": agent.personality,
|
|
||||||
"public": agent.public,
|
|
||||||
"creator": agent.creator.username if agent.creator else None,
|
|
||||||
"managed_by_admin": agent.managed_by_admin,
|
|
||||||
"chat_model": agent.chat_model.chat_model,
|
|
||||||
"creator_not_self": agent.creator != user,
|
|
||||||
}
|
|
||||||
|
|
||||||
return templates.TemplateResponse("agent.html", context=user_config)
|
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/settings", response_class=HTMLResponse)
|
@web_client.get("/settings", response_class=HTMLResponse)
|
||||||
@requires(["authenticated"], redirect="login_page")
|
@requires(["authenticated"], redirect="login_page")
|
||||||
def config_page(request: Request):
|
def config_page(request: Request):
|
||||||
user: KhojUser = request.user.object
|
return templates.TemplateResponse("settings/index.html", context={"request": request})
|
||||||
user_config = get_user_config(user, request, is_detailed=True)
|
|
||||||
|
|
||||||
return templates.TemplateResponse("settings.html", context=user_config)
|
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/settings/content/github", response_class=HTMLResponse)
|
@web_client.get("/settings/content/github", response_class=HTMLResponse)
|
||||||
|
@ -177,82 +135,23 @@ def github_config_page(request: Request):
|
||||||
return templates.TemplateResponse("content_source_github_input.html", context=user_config)
|
return templates.TemplateResponse("content_source_github_input.html", context=user_config)
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/settings/content/notion", response_class=HTMLResponse)
|
|
||||||
@requires(["authenticated"], redirect="login_page")
|
|
||||||
def notion_config_page(request: Request):
|
|
||||||
user = request.user.object
|
|
||||||
user_config = get_user_config(user, request)
|
|
||||||
|
|
||||||
current_notion_config = get_user_notion_config(user)
|
|
||||||
token = current_notion_config.token if current_notion_config else ""
|
|
||||||
current_config = NotionContentConfig(token=token)
|
|
||||||
current_config = json.loads(current_config.model_dump_json())
|
|
||||||
|
|
||||||
user_config["current_config"] = current_config
|
|
||||||
return templates.TemplateResponse("content_source_notion_input.html", context=user_config)
|
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/settings/content/computer", response_class=HTMLResponse)
|
|
||||||
@requires(["authenticated"], redirect="login_page")
|
|
||||||
def computer_config_page(request: Request):
|
|
||||||
user = request.user.object if request.user.is_authenticated else None
|
|
||||||
user_config = get_user_config(user, request)
|
|
||||||
|
|
||||||
return templates.TemplateResponse("content_source_computer_input.html", context=user_config)
|
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/share/chat/{public_conversation_slug}", response_class=HTMLResponse)
|
@web_client.get("/share/chat/{public_conversation_slug}", response_class=HTMLResponse)
|
||||||
def view_public_conversation(request: Request):
|
def view_public_conversation(request: Request):
|
||||||
public_conversation_slug = request.path_params.get("public_conversation_slug")
|
return templates.TemplateResponse(
|
||||||
public_conversation = PublicConversationAdapters.get_public_conversation_by_slug(public_conversation_slug)
|
"share/chat/index.html",
|
||||||
if not public_conversation:
|
context={
|
||||||
return templates.TemplateResponse(
|
"request": request,
|
||||||
"404.html",
|
},
|
||||||
context={
|
|
||||||
"request": request,
|
|
||||||
"khoj_version": state.khoj_version,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
user = request.user.object if request.user.is_authenticated else None
|
|
||||||
user_config = get_user_config(user, request)
|
|
||||||
user_config["public_conversation_slug"] = public_conversation_slug
|
|
||||||
user_config["google_client_id"] = os.environ.get("GOOGLE_CLIENT_ID")
|
|
||||||
|
|
||||||
all_agents = AgentAdapters.get_all_accessible_agents(request.user.object if request.user.is_authenticated else None)
|
|
||||||
|
|
||||||
# Filter out the current agent
|
|
||||||
all_agents = [agent for agent in all_agents if agent != public_conversation.agent]
|
|
||||||
agents_packet = []
|
|
||||||
for agent in all_agents:
|
|
||||||
agents_packet.append(
|
|
||||||
{
|
|
||||||
"slug": agent.slug,
|
|
||||||
"avatar": agent.avatar,
|
|
||||||
"name": agent.name,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
user_config["agents"] = agents_packet
|
|
||||||
|
|
||||||
redirect_uri = str(request.app.url_path_for("auth"))
|
|
||||||
next_url = str(
|
|
||||||
request.app.url_path_for("view_public_conversation", public_conversation_slug=public_conversation_slug)
|
|
||||||
)
|
)
|
||||||
user_config["redirect_uri"] = f"{redirect_uri}?next={next_url}"
|
|
||||||
|
|
||||||
return templates.TemplateResponse("public_conversation.html", context=user_config)
|
|
||||||
|
|
||||||
|
|
||||||
@web_client.get("/automations", response_class=HTMLResponse)
|
@web_client.get("/automations", response_class=HTMLResponse)
|
||||||
def automations_config_page(
|
def automations_config_page(
|
||||||
request: Request,
|
request: Request,
|
||||||
subject: Optional[str] = None,
|
|
||||||
crontime: Optional[str] = None,
|
|
||||||
queryToRun: Optional[str] = None,
|
|
||||||
):
|
):
|
||||||
user = request.user.object if request.user.is_authenticated else None
|
return templates.TemplateResponse(
|
||||||
user_config = get_user_config(user, request)
|
"automations/index.html",
|
||||||
user_config["subject"] = subject if subject else ""
|
context={
|
||||||
user_config["crontime"] = crontime if crontime else ""
|
"request": request,
|
||||||
user_config["queryToRun"] = queryToRun if queryToRun else ""
|
},
|
||||||
|
)
|
||||||
return templates.TemplateResponse("config_automation.html", context=user_config)
|
|
||||||
|
|