Error loading configurations. Please make sure configs-list.json exists.
';
});
// Populate the sidebar with configuration links
function populateConfigList(configurations) {
// Sort configurations alphabetically by name
configurations.sort((a, b) => a.name.localeCompare(b.name));
// Clear existing list
configList.innerHTML = '';
// Add each configuration to the list
configurations.forEach(config => {
const listItem = document.createElement('li');
const link = document.createElement('a');
link.href = '#';
link.textContent = config.name;
link.setAttribute('data-filename', config.filename);
link.addEventListener('click', function(e) {
e.preventDefault();
loadConfiguration(config.filename);
});
listItem.appendChild(link);
configList.appendChild(listItem);
});
}
// Load a specific configuration
function loadConfiguration(filename) {
fetch(`generated-configs/${filename}`)
.then(response => response.json())
.then(config => {
displayConfiguration(config);
})
.catch(error => {
console.error('Error loading configuration:', error);
configDisplay.innerHTML = '
Error loading configuration
';
});
}
// Display a configuration in the main content area
function displayConfiguration(config) {
if (!config) {
configDisplay.innerHTML = '
Error: Configuration data is missing or invalid.
';
welcomeMessage.style.display = 'none';
configDisplay.style.display = 'block';
return;
}
// Hide welcome message and show configuration display
welcomeMessage.style.display = 'none';
configDisplay.style.display = 'block';
// Create HTML for the configuration
let html = `
${config.avatar ? `` : ''}
${config.name}
Description
${config.description}
System Prompt
${config.systemPrompt.replace(//g, '>')}
`;
configDisplay.innerHTML = html;
}
// Search functionality
searchButton.addEventListener('click', performSearch);
searchInput.addEventListener('keyup', function(e) {
if (e.key === 'Enter') {
performSearch(searchInput.value);
}
});
// Reset search functionality
resetSearchButton.addEventListener('click', function() {
searchInput.value = '';
if (mobileSearchInput) mobileSearchInput.value = '';
populateConfigList(allConfigurations);
});
// Mobile search button
if (mobileSearchButton) {
mobileSearchButton.addEventListener('click', function() {
performSearch(mobileSearchInput.value);
});
}
// Mobile reset button
if (mobileResetButton) {
mobileResetButton.addEventListener('click', function() {
if (mobileSearchInput) mobileSearchInput.value = '';
populateConfigList(allConfigurations);
});
}
// Mobile search input
if (mobileSearchInput) {
mobileSearchInput.addEventListener('keyup', function(e) {
if (e.key === 'Enter') {
performSearch(mobileSearchInput.value);
}
});
}
// Mobile random config button
if (mobileRandomConfigBtn) {
mobileRandomConfigBtn.addEventListener('click', function(e) {
e.preventDefault();
loadRandomConfiguration();
});
}
function performSearch(inputValue) {
const searchTerm = (inputValue || searchInput.value).toLowerCase().trim();
// Sync the search inputs
searchInput.value = searchTerm;
if (mobileSearchInput) {
mobileSearchInput.value = searchTerm;
}
if (searchTerm === '') {
populateConfigList(allConfigurations);
return;
}
const filteredConfigs = allConfigurations.filter(config =>
config.name.toLowerCase().includes(searchTerm) ||
config.description.toLowerCase().includes(searchTerm) ||
config.systemPrompt.toLowerCase().includes(searchTerm)
);
populateConfigList(filteredConfigs);
}
// Modal close event
modalClose.addEventListener('click', function() {
avatarModal.style.display = "none";
});
// Close modal when clicking outside the image
window.addEventListener('click', function(event) {
if (event.target === avatarModal) {
avatarModal.style.display = "none";
}
});
});
// Helper function to escape special characters in JavaScript strings
function escapeJS(string) {
return string
.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\t/g, '\\t');
}
// Open modal for avatar image
function openModal(src, name) {
const modal = document.getElementById('avatar-modal');
const modalImg = document.getElementById('modal-img');
const modalCaption = document.getElementById('modal-caption');
modal.style.display = "block";
modalImg.src = src;
modalCaption.innerHTML = name;
}
// Copy text to clipboard
function copyToClipboard(text) {
navigator.clipboard.writeText(text)
.then(() => {
showToast('System prompt copied to clipboard!');
})
.catch(err => {
console.error('Failed to copy text: ', err);
// Fallback for browsers that don't support clipboard API
fallbackCopyToClipboard(text);
});
}
// Copy all configuration details to clipboard
function copyAllToClipboard(name, description, systemPrompt) {
const text = `# ${name}\n\n${description}\n\n## System Prompt\n\n${systemPrompt}`;
navigator.clipboard.writeText(text)
.then(() => {
showToast('All configuration details copied to clipboard!');
})
.catch(err => {
console.error('Failed to copy text: ', err);
// Fallback for browsers that don't support clipboard API
fallbackCopyToClipboard(text);
});
}
// Download configuration as markdown file
function downloadMarkdown(name, description, systemPrompt) {
const text = `# ${name}\n\n${description}\n\n## System Prompt\n\n${systemPrompt}`;
const blob = new Blob([text], { type: 'text/markdown' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${name.replace(/[^a-z0-9]/gi, '-').toLowerCase()}.md`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
// Show toast notification
function showToast(message) {
// Create toast element if it doesn't exist
let toast = document.getElementById('toast');
if (!toast) {
toast = document.createElement('div');
toast.id = 'toast';
document.body.appendChild(toast);
// Add CSS for toast
const style = document.createElement('style');
style.textContent = `
#toast {
position: fixed;
bottom: 30px;
left: 50%;
transform: translate(-50%, 0);
background-color: rgba(106, 13, 173, 0.9);
color: white;
padding: 10px 20px;
border-radius: 5px;
z-index: 1000;
font-family: 'Orbitron', sans-serif;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
opacity: 0;
transition: opacity 0.3s;
text-align: center;
}
@media (max-width: 768px) {
#toast {
bottom: 20px; /* Position at the bottom with space */
}
}
#toast.show {
opacity: 1;
}
`;
document.head.appendChild(style);
}
// Set message and show toast
toast.textContent = message;
toast.classList.add('show');
// Hide toast after 3 seconds
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
// Fallback clipboard function for browsers without clipboard API
function fallbackCopyToClipboard(text) {
// Create textarea element
const textArea = document.createElement('textarea');
textArea.value = text;
// Make the textarea out of viewport
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.appendChild(textArea);
// Select and copy
textArea.focus();
textArea.select();
let success = false;
try {
success = document.execCommand('copy');
} catch (err) {
console.error('Fallback: Oops, unable to copy', err);
}
document.body.removeChild(textArea);
if (success) {
showToast('Copied to clipboard!');
} else {
showToast('Failed to copy text. Your browser may not support this feature.');
}
}
// Set active state for mobile navigation
document.addEventListener('DOMContentLoaded', function() {
// Set active class for current page in mobile nav
const currentPath = window.location.pathname;
const mobileNavItems = document.querySelectorAll('.mobile-nav-item');
mobileNavItems.forEach(item => {
const itemPath = item.getAttribute('href');
if (itemPath === currentPath || (currentPath === '/' && itemPath === '/')) {
item.classList.add('active');
} else {
item.classList.remove('active');
}
});
// Sync search inputs
const searchInput = document.getElementById('search-input');
const mobileSearchInput = document.getElementById('mobile-search-input');
if (searchInput && mobileSearchInput) {
// Sync desktop to mobile
searchInput.addEventListener('input', function() {
mobileSearchInput.value = this.value;
});
// Sync mobile to desktop
mobileSearchInput.addEventListener('input', function() {
searchInput.value = this.value;
});
}
});