Muuuuuch faster, local vector search, local embedding service and api
This commit is contained in:
parent
4effccf3a7
commit
492fa9209b
|
|
@ -1,6 +1,6 @@
|
|||
@page "/"
|
||||
@page "/menu/{topic?}"
|
||||
@inherits SharedDisplayLogic
|
||||
@inherits MainPageBase
|
||||
@using BLAIzor.Models
|
||||
@using BLAIzor.Services
|
||||
@using BLAIzor.Components.Partials
|
||||
|
|
@ -10,21 +10,15 @@
|
|||
@using System.Net
|
||||
@using System.Text.Json
|
||||
@using Sidio.Sitemap.Blazor
|
||||
@* @inject AIService ChatGptService *@
|
||||
@rendermode InteractiveServer
|
||||
@* @inject IJSRuntime jsRuntime; *@
|
||||
@* @inject IConfiguration configuration *@
|
||||
@inject ContentService _contentService
|
||||
@* @inject ContentEditorService _contentEditorService *@
|
||||
@* @inject ScopedContentService _scopedContentService *@
|
||||
@* @inject IEmailSender _emailService *@
|
||||
@inject NavigationManager _navigationManager
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject DesignTemplateService DesignTemplateService
|
||||
@inject CssTemplateService CssTemplateService
|
||||
@inject CssInjectorService CssService
|
||||
@* @inject HttpClient Http *@
|
||||
@attribute [Sitemap]
|
||||
|
||||
<ErrorBoundary>
|
||||
<ChildContent>
|
||||
<div class="page" style="z-index: 1">
|
||||
|
|
@ -264,7 +258,7 @@
|
|||
// Load the CSS template for the selected brand from the database
|
||||
var designTemplate = await DesignTemplateService.GetByIdAsync((int)SiteInfo.TemplateId!);
|
||||
var cssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync((int)SiteInfo.TemplateId);
|
||||
CollectionName = designTemplate.QDrandCollectionName;
|
||||
TemplateCollectionName = designTemplate.QDrandCollectionName;
|
||||
|
||||
if (cssTemplate != null)
|
||||
{
|
||||
|
|
@ -284,11 +278,11 @@
|
|||
if(!string.IsNullOrWhiteSpace(topic))
|
||||
{
|
||||
UserInput = topic;
|
||||
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, Menu, true);
|
||||
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, Menu, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, Menu);
|
||||
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, TemplateCollectionName, Menu);
|
||||
}
|
||||
// HtmlContent = await ChatGptService.GetChatGptWelcomeMessage();
|
||||
// UserInput = "Sumerize for me, what is this website about, and what can I do on this website?";
|
||||
|
|
@ -413,7 +407,7 @@
|
|||
var menu = await GetMenuList(SiteId);
|
||||
HtmlContent.Clear();
|
||||
string input = "Please tell me more about: " + UserInput;
|
||||
await ChatGptService.ProcessUserIntent(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu);
|
||||
await ChatGptService.ProcessUserIntent(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
||||
UserInput = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ using UglyToad.PdfPig.DocumentLayoutAnalysis;
|
|||
|
||||
namespace BLAIzor.Components.Pages
|
||||
{
|
||||
public class SharedDisplayLogic : ComponentBase
|
||||
public class MainPageBase : ComponentBase
|
||||
{
|
||||
public string SelectedBrandName = "default";
|
||||
[Inject] protected ScopedContentService _scopedContentService { get; set; }
|
||||
|
|
@ -22,10 +22,10 @@ namespace BLAIzor.Components.Pages
|
|||
[Inject] protected IJSRuntime jsRuntime { get; set; }
|
||||
[Inject] protected AIService ChatGptService { get; set; }
|
||||
|
||||
public static readonly Dictionary<string, SharedDisplayLogic> _instances = new();
|
||||
public static readonly Dictionary<string, MainPageBase> _instances = new();
|
||||
|
||||
public string SessionId;
|
||||
public static SharedDisplayLogic myHome;
|
||||
public static MainPageBase myHome;
|
||||
|
||||
public int SiteId;
|
||||
public SiteInfo SiteInfo;
|
||||
|
|
@ -33,7 +33,7 @@ namespace BLAIzor.Components.Pages
|
|||
public string TextContent = "";
|
||||
public string StatusContent = "";
|
||||
public string UserInput = string.Empty;
|
||||
public string CollectionName = "html_snippets";
|
||||
public string TemplateCollectionName = "html_snippets";
|
||||
|
||||
public bool VoiceEnabled;
|
||||
public bool TTSEnabled;
|
||||
|
|
@ -123,9 +123,9 @@ namespace BLAIzor.Components.Pages
|
|||
|
||||
var requestJson = JsonSerializer.Serialize(requestContent);
|
||||
string voiceId;
|
||||
if (SiteInfo.voiceId != null)
|
||||
if (SiteInfo.VoiceId != null)
|
||||
{
|
||||
voiceId = SiteInfo.voiceId;
|
||||
voiceId = SiteInfo.VoiceId;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -199,7 +199,7 @@ namespace BLAIzor.Components.Pages
|
|||
{
|
||||
HtmlContent.Clear();
|
||||
var menu = await GetMenuList(SiteId);
|
||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu);
|
||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
||||
UserInput = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -214,11 +214,11 @@ namespace BLAIzor.Components.Pages
|
|||
var menuItem = (await GetMenuItems(SiteId)).Where(m => m.Name == input).FirstOrDefault();
|
||||
if (menuItem == null)
|
||||
{
|
||||
await ChatGptService.ProcessContentRequest(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu, forceUnmodified);
|
||||
await ChatGptService.ProcessContentRequest(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu, forceUnmodified);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ChatGptService.ProcessContentRequest(SessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu, forceUnmodified);
|
||||
await ChatGptService.ProcessContentRequest(SessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu, forceUnmodified);
|
||||
}
|
||||
UserInput = string.Empty;
|
||||
}
|
||||
|
|
@ -302,7 +302,7 @@ namespace BLAIzor.Components.Pages
|
|||
Console.WriteLine("Button clicked!");
|
||||
var menu = await GetMenuList(SiteId);
|
||||
HtmlContent.Clear();
|
||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu);
|
||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
||||
UserInput = string.Empty;
|
||||
}
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
@page "/preview/{siteid:int}"
|
||||
@page "/preview/{siteid:int}/{topic?}"
|
||||
@inherits SharedDisplayLogic
|
||||
@inherits MainPageBase
|
||||
@using BLAIzor.Models
|
||||
@using BLAIzor.Services
|
||||
@using Google.Cloud.Speech.V1
|
||||
|
|
@ -10,21 +10,14 @@
|
|||
@using System.Text.Json
|
||||
@using System.Net
|
||||
|
||||
@* @inject AIService ChatGptService *@
|
||||
@rendermode InteractiveServer
|
||||
@* @inject IJSRuntime jsRuntime; *@
|
||||
@* @inject IConfiguration configuration *@
|
||||
@inject ContentService _contentService
|
||||
@* @inject ContentEditorService _contentEditorService *@
|
||||
@* @inject ScopedContentService _scopedContentService *@
|
||||
@inject IEmailSender _emailService
|
||||
@inject NavigationManager _navigationManager
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject DesignTemplateService DesignTemplateService
|
||||
@inject CssTemplateService CssTemplateService
|
||||
@inject CssInjectorService CssService
|
||||
@* @inject HttpClient Http *@
|
||||
|
||||
|
||||
<div class="page" style="z-index: 1">
|
||||
<NavMenu MenuString="@Menu" OnMenuClicked=@MenuClick></NavMenu>
|
||||
|
|
@ -99,9 +92,7 @@
|
|||
@{
|
||||
if (!string.IsNullOrEmpty(HtmlContent.ToString()))
|
||||
{
|
||||
// <div class="pt-5 @FirstColumnClass">
|
||||
// @((MarkupString)HtmlContent.ToString())
|
||||
// </div>
|
||||
|
||||
if (isEmailFormVisible)
|
||||
{
|
||||
<div class="conteiner-fluid">
|
||||
|
|
@ -330,7 +321,7 @@
|
|||
// Load the CSS template for the selected brand from the database
|
||||
var designTemplate = await DesignTemplateService.GetByIdAsync((int)SiteInfo.TemplateId!);
|
||||
var cssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync((int)SiteInfo.TemplateId);
|
||||
CollectionName = designTemplate.QDrandCollectionName;
|
||||
TemplateCollectionName = designTemplate.QDrandCollectionName;
|
||||
|
||||
if (cssTemplate != null)
|
||||
{
|
||||
|
|
@ -354,11 +345,11 @@
|
|||
if (!string.IsNullOrWhiteSpace(topic))
|
||||
{
|
||||
UserInput = topic;
|
||||
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, Menu, true);
|
||||
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, Menu, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, Menu);
|
||||
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, TemplateCollectionName, Menu);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -429,7 +420,7 @@
|
|||
{
|
||||
HtmlContent.Clear();
|
||||
var menu = await GetMenuList(SiteId);
|
||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu);
|
||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
||||
UserInput = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ else if (ExtractedMenuItems.Any())
|
|||
<MenuItemContentEditor Subject=@subject MenuItem="item" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
|
||||
}
|
||||
<div class="card-footer">
|
||||
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
||||
|
||||
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
||||
</div>
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ else if (ExtractedMenuItems.Any())
|
|||
|
||||
</div>
|
||||
|
||||
|
||||
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
||||
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||
|
|
@ -163,6 +163,7 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
|||
if (selectedPoint != null)
|
||||
{
|
||||
model.Content = selectedPoint.result.payload.content;
|
||||
model.ContentDescription = selectedPoint.result.payload.description;
|
||||
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
||||
}
|
||||
|
||||
|
|
@ -246,6 +247,7 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
|||
if (item != null)
|
||||
{
|
||||
//item.MenuItem.
|
||||
item.MenuItem.Name = updatedItem.MenuItem.Name;
|
||||
item.Content = updatedItem.Content;
|
||||
}
|
||||
}
|
||||
|
|
@ -287,10 +289,12 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
|||
foreach (var menuItemToReorder in menuItems)
|
||||
{
|
||||
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
|
||||
Console.WriteLine($"{menuItemToReorder.Name}, {menuItemToReorder.SortOrder}");
|
||||
}
|
||||
foreach (var extractedMenuItemToReorder in ExtractedMenuItems)
|
||||
{
|
||||
extractedMenuItemToReorder.MenuItem.SortOrder = ExtractedMenuItems.IndexOf(extractedMenuItemToReorder);
|
||||
Console.WriteLine($"{extractedMenuItemToReorder.MenuItem.Name}, {extractedMenuItemToReorder.MenuItem.SortOrder}");
|
||||
}
|
||||
JSRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ else if (extractedMenuItems.Any())
|
|||
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" SessionId="SessionId" />
|
||||
<div class="card-footer">
|
||||
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
||||
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
||||
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ else if (extractedMenuItems.Any())
|
|||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
||||
|
||||
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
|
||||
}
|
||||
|
|
@ -133,6 +133,7 @@ else if (!string.IsNullOrEmpty(errorMessage))
|
|||
if (selectedPoint != null)
|
||||
{
|
||||
model.Content = selectedPoint.result.payload.content;
|
||||
model.ContentDescription = selectedPoint.result.payload.description;
|
||||
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
||||
}
|
||||
|
||||
|
|
@ -182,6 +183,7 @@ else if (!string.IsNullOrEmpty(errorMessage))
|
|||
var newItem = new MenuItemModel("New menu item", "");
|
||||
//TODO Fix
|
||||
extractedMenuItems.Add(newItem);
|
||||
isLoading = false;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -17,14 +17,20 @@
|
|||
}
|
||||
<button class="btn btn-primary mb-2" @onclick="GenerateContent" disabled="@IsLoading">Generate by AI</button>
|
||||
@* <textarea class="form-control border-0 text-white" @bind="GeneratedContent" rows="5"></textarea> *@
|
||||
<RadzenHtmlEditor @bind-Value=@GeneratedContent style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
||||
<RadzenHtmlEditorUndo />
|
||||
<RadzenHtmlEditorRedo />
|
||||
<RadzenHtmlEditorSource />
|
||||
</RadzenHtmlEditor>
|
||||
<InputFile class="btn btn-default" type="file" multiple OnChange=HandleFileUpload accept=".mp3,.mp4,.jpg,.png" />
|
||||
<div class="row">
|
||||
|
||||
<EventConsole @ref=@console />
|
||||
<RadzenTextArea @bind-Value=@MenuItem.ContentDescription></RadzenTextArea>
|
||||
</div>
|
||||
<div class="row">
|
||||
<RadzenHtmlEditor @bind-Value=@GeneratedContent style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
||||
<RadzenHtmlEditorUndo />
|
||||
<RadzenHtmlEditorRedo />
|
||||
<RadzenHtmlEditorSource />
|
||||
</RadzenHtmlEditor>
|
||||
</div>
|
||||
<InputFile class="btn btn-default" type="file" multiple OnChange=HandleFileUpload accept=".mp3,.mp4,.jpg,.png" />
|
||||
|
||||
@* <EventConsole @ref=@console /> *@
|
||||
@if (IsLoading)
|
||||
{
|
||||
<p>Loading content...</p>
|
||||
|
|
@ -40,15 +46,17 @@
|
|||
|
||||
private bool IsLoading = false;
|
||||
private string GeneratedContent = string.Empty;
|
||||
// private string Description = string.Empty;
|
||||
private string? userId;
|
||||
private string? userName;
|
||||
private AuthenticationState? authState;
|
||||
|
||||
EventConsole console;
|
||||
//EventConsole console;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
GeneratedContent = MenuItem.Content;
|
||||
// Description = MenuItem.ContentDescription;
|
||||
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
if (authState.User.Identity?.IsAuthenticated == true)
|
||||
{
|
||||
|
|
@ -103,33 +111,33 @@
|
|||
|
||||
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
||||
{
|
||||
console.Log($"Paste: {args.Html}");
|
||||
// console.Log($"Paste: {args.Html}");
|
||||
MenuItem.Content = args.Html;
|
||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||
}
|
||||
|
||||
async Task OnChange(string html)
|
||||
{
|
||||
console.Log($"Change: {html}");
|
||||
// console.Log($"Change: {html}");
|
||||
MenuItem.Content = html;
|
||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||
}
|
||||
|
||||
async Task OnInput(string html)
|
||||
{
|
||||
console.Log($"Input: {html}");
|
||||
// console.Log($"Input: {html}");
|
||||
MenuItem.Content = html;
|
||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||
}
|
||||
|
||||
void OnExecute(HtmlEditorExecuteEventArgs args)
|
||||
{
|
||||
console.Log($"Execute: {args.CommandName}");
|
||||
//console.Log($"Execute: {args.CommandName}");
|
||||
}
|
||||
|
||||
void OnUploadComplete(UploadCompleteEventArgs args)
|
||||
{
|
||||
console.Log($"Upload complete: {args.RawResponse}");
|
||||
//console.Log($"Upload complete: {args.RawResponse}");
|
||||
}
|
||||
|
||||
private async Task HandleFileUpload(InputFileChangeEventArgs e)
|
||||
|
|
@ -167,7 +175,7 @@
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
console.Log($"Error uploading files: {ex.Message}");
|
||||
// console.Log($"Error uploading files: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,645 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using BLAIzor.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BLAIzor.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250615203806_EmbeddingServiceAndDefaultLanguage")]
|
||||
partial class EmbeddingServiceAndDefaultLanguage
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("CssContent")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("DesignTemplateId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("LastUpdated")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DesignTemplateId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("CssTemplates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsDeprecated")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsPrivate")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsPublished")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("QDrandCollectionName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Tags")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("TemplateName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("TemplatePhotoUrl")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("Version")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("DesignTemplates");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 1,
|
||||
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
Description = "The default template",
|
||||
IsDeprecated = false,
|
||||
IsPrivate = false,
|
||||
IsPublished = false,
|
||||
QDrandCollectionName = "html_snippets",
|
||||
Status = "Draft",
|
||||
Tags = "system",
|
||||
TemplateName = "Default Site",
|
||||
TemplatePhotoUrl = "/images/default-logo.png",
|
||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
||||
Version = 1
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("JsonDefinition")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("SiteInfoId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<int>("Version")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SiteInfoId", "Slug")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("FormDefinitions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("PointId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid?>("QdrantPointId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<bool>("ShowInMainMenu")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("SiteInfoId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("SortOrder")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("StoredHtml")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SiteInfoId");
|
||||
|
||||
b.ToTable("MenuItems");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("BackgroundVideo")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("BrandLogoUrl")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("DefaultColor")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("DefaultLanguage")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("DefaultUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("DomainUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("EmbeddingService")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Entity")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsPublished")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Persona")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("STTActive")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("SiteDescription")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("SiteName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("TTSActive")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int?>("TemplateId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("VoiceId")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TemplateId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("SiteInfos");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 1,
|
||||
BrandLogoUrl = "/images/default-logo.png",
|
||||
DefaultColor = "#FFFFFF",
|
||||
DefaultUrl = "https://ai.poppixel.cloud",
|
||||
DomainUrl = "poppixel.cloud",
|
||||
IsPublished = false,
|
||||
STTActive = false,
|
||||
SiteName = "Default Site",
|
||||
TTSActive = false,
|
||||
TemplateId = 1,
|
||||
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex")
|
||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex")
|
||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
||||
AccessFailedCount = 0,
|
||||
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
||||
Email = "adam.g@aycode.com",
|
||||
EmailConfirmed = true,
|
||||
LockoutEnabled = false,
|
||||
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
||||
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
||||
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
||||
PhoneNumberConfirmed = false,
|
||||
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
||||
TwoFactorEnabled = false,
|
||||
UserName = "adam.g@aycode.com"
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("nvarchar(128)");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("nvarchar(128)");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("nvarchar(128)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("nvarchar(128)");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
||||
{
|
||||
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
||||
.WithOne("CssTemplate")
|
||||
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("DesignTemplate");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
||||
{
|
||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
||||
.WithMany("FormDefinitions")
|
||||
.HasForeignKey("SiteInfoId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("SiteInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
||||
{
|
||||
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
||||
.WithMany("MenuItems")
|
||||
.HasForeignKey("SiteInfoId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("SiteInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
||||
{
|
||||
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
||||
.WithMany("Sites")
|
||||
.HasForeignKey("TemplateId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Template");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
||||
{
|
||||
b.Navigation("CssTemplate")
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Sites");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
||||
{
|
||||
b.Navigation("FormDefinitions");
|
||||
|
||||
b.Navigation("MenuItems");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BLAIzor.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EmbeddingServiceAndDefaultLanguage : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "voiceId",
|
||||
table: "SiteInfos",
|
||||
newName: "VoiceId");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "BackgroundVideo",
|
||||
table: "SiteInfos",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DefaultLanguage",
|
||||
table: "SiteInfos",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "EmbeddingService",
|
||||
table: "SiteInfos",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "StoredHtml",
|
||||
table: "MenuItems",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(max)");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "SiteInfos",
|
||||
keyColumn: "Id",
|
||||
keyValue: 1,
|
||||
columns: new[] { "BackgroundVideo", "DefaultLanguage", "EmbeddingService" },
|
||||
values: new object[] { null, null, null });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "BackgroundVideo",
|
||||
table: "SiteInfos");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DefaultLanguage",
|
||||
table: "SiteInfos");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "EmbeddingService",
|
||||
table: "SiteInfos");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "VoiceId",
|
||||
table: "SiteInfos",
|
||||
newName: "voiceId");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "StoredHtml",
|
||||
table: "MenuItems",
|
||||
type: "nvarchar(max)",
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(max)",
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -193,7 +193,6 @@ namespace BLAIzor.Migrations
|
|||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("StoredHtml")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
|
@ -211,12 +210,18 @@ namespace BLAIzor.Migrations
|
|||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("BackgroundVideo")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("BrandLogoUrl")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("DefaultColor")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("DefaultLanguage")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("DefaultUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
|
@ -225,6 +230,9 @@ namespace BLAIzor.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("EmbeddingService")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Entity")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
|
|
@ -253,7 +261,7 @@ namespace BLAIzor.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("voiceId")
|
||||
b.Property<string>("VoiceId")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
public string? Variant { get; set; } // 👈 NEW: e.g. "image-left", "image-right", "no-image"
|
||||
public string SampleHtml { get; set; } //for design purposes
|
||||
public List<string> Slots { get; set; } // e.g. ["title", "subtitle", "image", "cta"]
|
||||
public float[] Vectors { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace BLAIzor.Models
|
|||
|
||||
public bool ShowInMainMenu { get; set; } = false;
|
||||
|
||||
public string StoredHtml { get; set; }
|
||||
public string? StoredHtml { get; set; }
|
||||
|
||||
public Guid? QdrantPointId { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace BLAIzor.Models
|
|||
{
|
||||
public MenuItem MenuItem { get; set; }
|
||||
public string Content { get; set; } = string.Empty;
|
||||
public string ContentDescription { get; set; } = string.Empty;
|
||||
|
||||
public MenuItemModel(string name)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@ namespace BLAIzor.Models
|
|||
public int? TemplateId { get; set; }
|
||||
public bool TTSActive { get; set; } = false;
|
||||
public bool STTActive { get; set; } = false;
|
||||
public string? voiceId { get; set; }
|
||||
public string? VoiceId { get; set; }
|
||||
public string? Persona { get; set; }
|
||||
public string? Entity { get; set; }
|
||||
public string? DefaultLanguage { get; set; }
|
||||
public string? BackgroundVideo { get; set; }
|
||||
|
||||
public string? EmbeddingService { get; set; }
|
||||
|
||||
// Navigation property for IdentityUser
|
||||
public IdentityUser User { get; set; }
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace BLAIzor.Models
|
|||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Content { get; set; }
|
||||
public float[] Vectors { get; set; }
|
||||
public DateTime LastUpdated { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ builder.Services.AddSingleton<ContentService>();
|
|||
builder.Services.AddScoped<ScopedContentService>();
|
||||
builder.Services.AddScoped<QDrantService>();
|
||||
builder.Services.AddScoped<OpenAIEmbeddingService>();
|
||||
builder.Services.AddScoped<LocalEmbeddingService>();
|
||||
builder.Services.AddScoped<HtmlSnippetProcessor>();
|
||||
builder.Services
|
||||
.AddHttpContextAccessor()
|
||||
|
|
@ -64,6 +65,7 @@ builder.Services.AddScoped<DeepSeekApiService>();
|
|||
builder.Services.AddScoped<OpenAiRealtimeService>();
|
||||
builder.Services.AddScoped<CerebrasAPIService>();
|
||||
builder.Services.AddScoped<CssInjectorService>();
|
||||
builder.Services.AddScoped<LocalVectorSearchService>();
|
||||
builder.Services.AddHostedService<TempFileCleanupService>();
|
||||
builder.Services.AddServerSideBlazor().AddCircuitOptions(options => options.DetailedErrors = true).AddHubOptions(options =>
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -13,8 +13,11 @@ namespace BLAIzor.Services
|
|||
private readonly QDrantService _qDrantService;
|
||||
private readonly HtmlSnippetProcessor _htmlSnippetProcessor;
|
||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
||||
private readonly ScopedContentService _scopedContentService;
|
||||
|
||||
public ContentEditorService(/*AIService aiService,*/ OpenAIApiService openAIApiService, /*ApplicationDbContext context,*/ QDrantService qDrantService, HtmlSnippetProcessor htmlSnippetProcessor, IServiceScopeFactory serviceScopeFactory)
|
||||
public static IConfiguration? _configuration;
|
||||
|
||||
public ContentEditorService(/*AIService aiService,*/ OpenAIApiService openAIApiService, /*ApplicationDbContext context,*/ QDrantService qDrantService, HtmlSnippetProcessor htmlSnippetProcessor, IServiceScopeFactory serviceScopeFactory, ScopedContentService scopedContentService, IConfiguration? configuration)
|
||||
{
|
||||
//_aiService = aiService;
|
||||
_openAIApiService = openAIApiService;
|
||||
|
|
@ -22,8 +25,14 @@ namespace BLAIzor.Services
|
|||
_qDrantService = qDrantService;
|
||||
_htmlSnippetProcessor = htmlSnippetProcessor;
|
||||
_serviceScopeFactory = serviceScopeFactory;
|
||||
_scopedContentService = scopedContentService;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
private string GetAiEmbeddingSettings() =>
|
||||
_configuration?.GetSection("AiSettings")?.GetValue<string>("EmbeddingService") ?? string.Empty;
|
||||
|
||||
|
||||
// Existing methods
|
||||
public async Task<List<string>> GetMenuSuggestionsAsync(string sessionId, string prompt)
|
||||
{
|
||||
|
|
@ -152,7 +161,7 @@ namespace BLAIzor.Services
|
|||
{
|
||||
try
|
||||
{
|
||||
//check if Collection is created already
|
||||
|
||||
|
||||
if (!hasCollection)
|
||||
{
|
||||
|
|
@ -160,7 +169,29 @@ namespace BLAIzor.Services
|
|||
await _qDrantService.CreateQdrantCollectionAsync("Site" + SiteId.ToString());
|
||||
hasCollection = true;
|
||||
}
|
||||
var updateQdrantList = ExtractedMenuItems.OrderBy(mi => mi.MenuItem.PointId).ToList();
|
||||
else
|
||||
{
|
||||
//check if Collection is really created already
|
||||
var collection = await _qDrantService.GetCollectionCount("Site" + SiteId.ToString());
|
||||
if(collection != null)
|
||||
{
|
||||
var siteInfo = await _scopedContentService.GetSiteInfoByIdAsync(SiteId);
|
||||
if(siteInfo.EmbeddingService != null)
|
||||
{
|
||||
var currentEmbeddingServiceName = GetAiEmbeddingSettings();
|
||||
if (siteInfo.EmbeddingService == currentEmbeddingServiceName)
|
||||
{
|
||||
//drop existing collection
|
||||
await _qDrantService.DeleteCollectionAsync("Site" + SiteId.ToString());
|
||||
//create will automatically handle the new vector size
|
||||
await _qDrantService.CreateQdrantCollectionAsync("Site" + SiteId.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var updateQdrantList = ExtractedMenuItems.OrderBy(mi => mi.MenuItem.PointId).ToList();
|
||||
|
||||
for (int i = 0; i < updateQdrantList.Count(); i++)
|
||||
{
|
||||
|
|
@ -180,16 +211,23 @@ namespace BLAIzor.Services
|
|||
content.Type = "page";
|
||||
content.SiteId = SiteId;
|
||||
content.Name = ExtractedMenuItems[i].MenuItem.Name;
|
||||
content.Description = $"A section called {ExtractedMenuItems[i].MenuItem.Name} of a website of {subject}";
|
||||
if (ExtractedMenuItems[i].ContentDescription == null)
|
||||
{
|
||||
content.Description = $"A section called {ExtractedMenuItems[i].MenuItem.Name} of a website of {subject}";
|
||||
}
|
||||
else
|
||||
{
|
||||
content.Description = ExtractedMenuItems[i].ContentDescription;
|
||||
}
|
||||
content.Content = ExtractedMenuItems[i].Content;
|
||||
content.LastUpdated = DateTime.UtcNow;
|
||||
|
||||
menuItem.QdrantPointId = guid;
|
||||
menuItem.PointId = i;
|
||||
await _htmlSnippetProcessor.ProcessAndStoreWebContentAsync(i, content, SiteId);
|
||||
}
|
||||
else
|
||||
{
|
||||
menuItem.PointId = i;
|
||||
menuItem.QdrantPointId = ExtractedMenuItems[i].MenuItem.QdrantPointId;
|
||||
}
|
||||
|
||||
|
|
@ -214,6 +252,7 @@ namespace BLAIzor.Services
|
|||
}
|
||||
else
|
||||
{
|
||||
thisItem.PointId = menuItem.PointId;
|
||||
thisItem.QdrantPointId = menuItem.QdrantPointId;
|
||||
thisItem.SortOrder = ExtractedMenuItems[i].MenuItem.SortOrder;
|
||||
thisItem.ShowInMainMenu = ExtractedMenuItems[i].MenuItem.ShowInMainMenu;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
using BLAIzor.Models;
|
||||
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||
|
|
@ -16,16 +17,18 @@ namespace BLAIzor.Services
|
|||
|
||||
public class HtmlSnippetProcessor
|
||||
{
|
||||
private readonly OpenAIEmbeddingService _embeddingService;
|
||||
private readonly OpenAIEmbeddingService _openAIEmbeddingService;
|
||||
private readonly LocalEmbeddingService _localEmbeddingService;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly QDrantService _drantService;
|
||||
public static IConfiguration? _configuration;
|
||||
private string _qdrantApiKey;
|
||||
|
||||
public HtmlSnippetProcessor(QDrantService drantService, IConfiguration? configuration)
|
||||
public HtmlSnippetProcessor(QDrantService drantService, OpenAIEmbeddingService openAIEmbeddingService, LocalEmbeddingService localEmbeddingService, IConfiguration? configuration)
|
||||
{
|
||||
_drantService = drantService;
|
||||
_embeddingService = new OpenAIEmbeddingService();
|
||||
_openAIEmbeddingService = openAIEmbeddingService;
|
||||
_localEmbeddingService = localEmbeddingService;
|
||||
_httpClient = new HttpClient();
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
|
@ -35,6 +38,9 @@ namespace BLAIzor.Services
|
|||
return _configuration?.GetSection("QDrant")?.GetValue<string>("ApiKey") ?? string.Empty;
|
||||
}
|
||||
|
||||
private string GetAiEmbeddingSettings() =>
|
||||
_configuration?.GetSection("AiSettings")?.GetValue<string>("EmbeddingService") ?? string.Empty;
|
||||
|
||||
//public async Task ProcessAndStoreSnippetsAsync()
|
||||
//{
|
||||
// _qdrantApiKey = GetApiKey();
|
||||
|
|
@ -101,7 +107,20 @@ namespace BLAIzor.Services
|
|||
$"Variant: {snippet.Variant ?? "default"}. " +
|
||||
$"Tags: {snippet.Tags}. " +
|
||||
$"HTML: {snippet.Html}";
|
||||
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
|
||||
float[] embedding = [];
|
||||
|
||||
var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||
//if (embeddingServiceProvider == "local")
|
||||
//{
|
||||
// embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
//}
|
||||
embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
|
||||
|
||||
// Add data for batch insertion
|
||||
ids.Add(snippet.Id);
|
||||
|
|
@ -110,7 +129,7 @@ namespace BLAIzor.Services
|
|||
{
|
||||
["type"] = snippet.Type,
|
||||
["name"] = snippet.Name,
|
||||
["variant"] = string.IsNullOrWhiteSpace(snippet.Variant)? "" : snippet.Variant,
|
||||
["variant"] = string.IsNullOrWhiteSpace(snippet.Variant) ? "" : snippet.Variant,
|
||||
["tags"] = snippet.Tags,
|
||||
["description"] = snippet.Description,
|
||||
["html"] = snippet.Html,
|
||||
|
|
@ -133,94 +152,113 @@ namespace BLAIzor.Services
|
|||
}
|
||||
}
|
||||
|
||||
public async Task ProcessAndStoreWebContentsAsync(List<WebPageContent> pageContentList, int siteId)
|
||||
{
|
||||
_qdrantApiKey = GetApiKey();
|
||||
//public async Task ProcessAndStoreWebContentsAsync(List<WebPageContent> pageContentList, int siteId)
|
||||
//{
|
||||
// _qdrantApiKey = GetApiKey();
|
||||
|
||||
var ids = new List<int>();
|
||||
var vectors = new List<float[]>();
|
||||
var payloads = new List<MapField<string, Value>>();
|
||||
// var ids = new List<int>();
|
||||
// var vectors = new List<float[]>();
|
||||
// var payloads = new List<MapField<string, Value>>();
|
||||
|
||||
foreach (var content in pageContentList)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Combine details to generate the embedding
|
||||
var combinedText = $"{content.Name}: Description: {content.Description}, complete text: {content.Content}";
|
||||
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
// foreach (var content in pageContentList)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// // Combine details to generate the embedding
|
||||
// var combinedText = $"{content.Name}: Description: {content.Description}, complete text: {content.Content}";
|
||||
|
||||
// Add data for batch insertion
|
||||
ids.Add(content.Id);
|
||||
vectors.Add(embedding);
|
||||
// float[] embedding = [];
|
||||
|
||||
// var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||
// if (embeddingServiceProvider == "local")
|
||||
// {
|
||||
// embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
// }
|
||||
|
||||
// // Add data for batch insertion
|
||||
// ids.Add(content.Id);
|
||||
// vectors.Add(embedding);
|
||||
|
||||
|
||||
payloads.Add(new MapField<string, Value>
|
||||
{
|
||||
["uid"] = content.UId,
|
||||
["type"] = content.Type,
|
||||
["siteId"] = content.SiteId,
|
||||
//["menuItemId"] = content.MenuItemId,
|
||||
["name"] = content.Name,
|
||||
["description"] = content.Description,
|
||||
["content"] = content.Content,
|
||||
["lastUpdated"] = content.LastUpdated.ToString()
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error processing content {content.Name}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
// payloads.Add(new MapField<string, Value>
|
||||
// {
|
||||
// ["uid"] = content.UId,
|
||||
// ["type"] = content.Type,
|
||||
// ["siteId"] = content.SiteId,
|
||||
// //["menuItemId"] = content.MenuItemId,
|
||||
// ["name"] = content.Name,
|
||||
// ["description"] = content.Description,
|
||||
// ["content"] = content.Content,
|
||||
// ["lastUpdated"] = content.LastUpdated.ToString()
|
||||
// });
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"Error processing content {content.Name}: {ex.Message}");
|
||||
// }
|
||||
// }
|
||||
|
||||
if (ids.Count > 0)
|
||||
{
|
||||
await _drantService.QDrantInsertManyAsync(ids, vectors, payloads, "Site"+siteId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("No points were processed successfully.");
|
||||
}
|
||||
}
|
||||
// if (ids.Count > 0)
|
||||
// {
|
||||
// await _drantService.QDrantInsertManyAsync(ids, vectors, payloads, "Site" + siteId);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine("No points were processed successfully.");
|
||||
// }
|
||||
//}
|
||||
|
||||
public async Task ProcessAndStoreWebContentAsync(int id, WebPageContent pageContent, int siteId)
|
||||
{
|
||||
_qdrantApiKey = GetApiKey();
|
||||
|
||||
|
||||
float[] vectors = [];
|
||||
var payload = new MapField<string, Value>();
|
||||
|
||||
try
|
||||
{
|
||||
// Combine details to generate the embedding
|
||||
var combinedText = $"{pageContent.Name}: {pageContent.Description} - {pageContent.Content}";
|
||||
float[] embedding = [];
|
||||
|
||||
try
|
||||
var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||
if (embeddingServiceProvider == "local")
|
||||
{
|
||||
// Combine details to generate the embedding
|
||||
var combinedText = $"{pageContent.Name}: {pageContent.Description} - {pageContent.Content}";
|
||||
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
|
||||
// Add data for batch insertion
|
||||
|
||||
vectors = embedding;
|
||||
|
||||
|
||||
payload = new MapField<string, Value>
|
||||
{
|
||||
["uid"] = pageContent.UId,
|
||||
["type"] = pageContent.Type,
|
||||
["siteId"] = pageContent.SiteId,
|
||||
//["menuItemId"] = pageContent.MenuItemId,
|
||||
["name"] = pageContent.Name,
|
||||
["description"] = pageContent.Description,
|
||||
["content"] = pageContent.Content,
|
||||
["lastUpdated"] = pageContent.LastUpdated.ToString()
|
||||
};
|
||||
embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
}
|
||||
catch (Exception ex)
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Error processing content {pageContent.Name}: {ex.Message}");
|
||||
embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||
}
|
||||
|
||||
// Add data for batch insertion
|
||||
|
||||
await _drantService.QDrantInsertPointAsync(id, vectors, payload, "Site"+siteId);
|
||||
vectors = embedding;
|
||||
|
||||
|
||||
payload = new MapField<string, Value>
|
||||
{
|
||||
["uid"] = pageContent.UId,
|
||||
["type"] = pageContent.Type,
|
||||
["siteId"] = pageContent.SiteId,
|
||||
//["menuItemId"] = pageContent.MenuItemId,
|
||||
["name"] = pageContent.Name,
|
||||
["description"] = pageContent.Description,
|
||||
["content"] = pageContent.Content,
|
||||
["lastUpdated"] = pageContent.LastUpdated.ToString()
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error processing content {pageContent.Name}: {ex.Message}");
|
||||
}
|
||||
|
||||
|
||||
await _drantService.QDrantInsertPointAsync(id, vectors, payload, "Site" + siteId);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
public class LocalEmbeddingService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly string _localOllamaUrl = "http://localhost:11434/api/embeddings";
|
||||
|
||||
public LocalEmbeddingService()
|
||||
{
|
||||
_httpClient = new HttpClient();
|
||||
}
|
||||
|
||||
public async Task<float[]> GenerateEmbeddingAsync(string text)
|
||||
{
|
||||
var payload = new
|
||||
{
|
||||
model = "bge-m3",
|
||||
prompt = text
|
||||
};
|
||||
|
||||
var content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await _httpClient.PostAsync(_localOllamaUrl, content);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<OllamaEmbeddingResponse>(responseContent);
|
||||
return result.Embedding;
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorText = await response.Content.ReadAsStringAsync();
|
||||
throw new Exception($"Failed to generate embedding: {response.StatusCode} - {errorText}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class OllamaEmbeddingResponse
|
||||
{
|
||||
[JsonProperty("embedding")]
|
||||
public float[] Embedding { get; set; }
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
using BLAIzor.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace BLAIzor.Services
|
||||
{
|
||||
public class LocalVectorSearchService
|
||||
{
|
||||
//private List<WebPageContent> _cachedContents = new();
|
||||
//private List<HtmlSnippet> _cachedSnippets = new();
|
||||
private int _cachedContentVersion = -1;
|
||||
private int _cachedSnippetVersion = -1;
|
||||
|
||||
// Inject any needed services (e.g. DbContext, versioning service)
|
||||
public LocalVectorSearchService()
|
||||
{
|
||||
}
|
||||
|
||||
//public void SetContentCache(List<WebPageContent> contents, int contentVersion)
|
||||
//{
|
||||
// _cachedContents = contents;
|
||||
// _cachedContentVersion = contentVersion;
|
||||
//}
|
||||
|
||||
//public void SetSnippetCache(List<HtmlSnippet> snippets, int snippetVersion)
|
||||
//{
|
||||
// _cachedSnippets = snippets;
|
||||
// _cachedSnippetVersion = snippetVersion;
|
||||
//}
|
||||
|
||||
public bool IsContentVersionOutdated(int currentVersion)
|
||||
=> currentVersion != _cachedContentVersion;
|
||||
|
||||
public bool IsSnippetVersionOutdated(int currentVersion)
|
||||
=> currentVersion != _cachedSnippetVersion;
|
||||
|
||||
public List<WebPageContent> SearchContent(float[] queryVector, List<WebPageContent> cachedContents, int maxResults = 5)
|
||||
{
|
||||
return cachedContents
|
||||
.Select(c => new
|
||||
{
|
||||
Content = c,
|
||||
Similarity = CosineSimilarity(queryVector, c.Vectors)
|
||||
})
|
||||
.OrderByDescending(x => x.Similarity)
|
||||
.Take(maxResults)
|
||||
.Select(x => x.Content)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public List<HtmlSnippet> SearchSnippets(float[] queryVector, List<HtmlSnippet> cachedSnippets, int maxResults = 5)
|
||||
{
|
||||
return cachedSnippets
|
||||
.Select(s => new
|
||||
{
|
||||
Snippet = s,
|
||||
Similarity = CosineSimilarity(queryVector, s.Vectors)
|
||||
})
|
||||
.OrderByDescending(x => x.Similarity)
|
||||
.Take(maxResults)
|
||||
.Select(x => x.Snippet)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private float CosineSimilarity(float[] vectorA, float[] vectorB)
|
||||
{
|
||||
if (vectorA == null || vectorB == null || vectorA.Length != vectorB.Length)
|
||||
return 0f;
|
||||
|
||||
float dot = 0f, magA = 0f, magB = 0f;
|
||||
|
||||
for (int i = 0; i < vectorA.Length; i++)
|
||||
{
|
||||
dot += vectorA[i] * vectorB[i];
|
||||
magA += vectorA[i] * vectorA[i];
|
||||
magB += vectorB[i] * vectorB[i];
|
||||
}
|
||||
|
||||
if (magA == 0 || magB == 0)
|
||||
return 0f;
|
||||
|
||||
return dot / ((float)Math.Sqrt(magA) * (float)Math.Sqrt(magB));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3,6 +3,7 @@ using Google.Protobuf.Collections;
|
|||
using Newtonsoft.Json;
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
|
||||
namespace BLAIzor.Services
|
||||
|
|
@ -20,6 +21,9 @@ namespace BLAIzor.Services
|
|||
_configuration = configuration;
|
||||
}
|
||||
|
||||
private string GetAiEmbeddingSettings() =>
|
||||
_configuration?.GetSection("AiSettings")?.GetValue<string>("EmbeddingService") ?? string.Empty;
|
||||
|
||||
public string GetApiKey()
|
||||
{
|
||||
if (_configuration == null)
|
||||
|
|
@ -47,32 +51,51 @@ namespace BLAIzor.Services
|
|||
return Convert.ToInt32(result);
|
||||
}
|
||||
|
||||
public async Task CreateQdrantCollectionAsync()
|
||||
{
|
||||
_apiKey = GetApiKey();
|
||||
var httpClient = new HttpClient();
|
||||
//public async Task CreateQdrantCollectionAsync()
|
||||
//{
|
||||
// _apiKey = GetApiKey();
|
||||
// var httpClient = new HttpClient();
|
||||
|
||||
httpClient.DefaultRequestHeaders.Clear();
|
||||
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
|
||||
// httpClient.DefaultRequestHeaders.Clear();
|
||||
// httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
|
||||
|
||||
var collectionName = "web_content";
|
||||
var createCollectionPayload = new
|
||||
{
|
||||
vectors = new { size = 1536, distance = "Cosine" } // Adjust size based on embedding model
|
||||
};
|
||||
// var collectionName = "web_content";
|
||||
|
||||
var content = new StringContent(JsonConvert.SerializeObject(createCollectionPayload), Encoding.UTF8, "application/json");
|
||||
var response = await httpClient.PutAsync($"{qdrantUrl}/collections/{collectionName}", content);
|
||||
// var createCollectionPayload = new
|
||||
// {
|
||||
// vectors = new { size = 0, distance = "" } // Adjust size based on embedding model
|
||||
// };
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
Console.WriteLine("Collection created successfully!" + response.Content.ReadAsStringAsync());
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Failed to create collection: {response.StatusCode}");
|
||||
}
|
||||
}
|
||||
// var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||
// if (embeddingServiceProvider == "local")
|
||||
// {
|
||||
// createCollectionPayload = new
|
||||
// {
|
||||
// vectors = new { size = 1024, distance = "Cosine" } // Adjust size based on embedding model
|
||||
// };
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// createCollectionPayload = new
|
||||
// {
|
||||
// vectors = new { size = 1536, distance = "Cosine" } // Adjust size based on embedding model
|
||||
// };
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// var content = new StringContent(JsonConvert.SerializeObject(createCollectionPayload), Encoding.UTF8, "application/json");
|
||||
// var response = await httpClient.PutAsync($"{qdrantUrl}/collections/{collectionName}", content);
|
||||
|
||||
// if (response.IsSuccessStatusCode)
|
||||
// {
|
||||
// Console.WriteLine("Collection created successfully!" + response.Content.ReadAsStringAsync());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine($"Failed to create collection: {response.StatusCode}");
|
||||
// }
|
||||
//}
|
||||
|
||||
public async Task<string> GetCollectionBySiteIdAsync(int siteId)
|
||||
{
|
||||
|
|
@ -127,9 +150,25 @@ namespace BLAIzor.Services
|
|||
|
||||
var createCollectionPayload = new
|
||||
{
|
||||
vectors = new { size = 1536, distance = "Cosine" } // Adjust size based on embedding model
|
||||
vectors = new { size = 0, distance = "" } // Adjust size based on embedding model
|
||||
};
|
||||
|
||||
var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||
if (embeddingServiceProvider == "local")
|
||||
{
|
||||
createCollectionPayload = new
|
||||
{
|
||||
vectors = new { size = 1024, distance = "Cosine" } // Adjust size based on embedding model
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
createCollectionPayload = new
|
||||
{
|
||||
vectors = new { size = 1536, distance = "Cosine" } // Adjust size based on embedding model
|
||||
};
|
||||
}
|
||||
|
||||
var content = new StringContent(JsonConvert.SerializeObject(createCollectionPayload), Encoding.UTF8, "application/json");
|
||||
var response = await httpClient.PutAsync($"{qdrantUrl}/collections/{collectionName}", content);
|
||||
|
||||
|
|
@ -256,15 +295,6 @@ namespace BLAIzor.Services
|
|||
_apiKey = GetApiKey();
|
||||
var httpClient = new HttpClient();
|
||||
|
||||
//httpClient.DefaultRequestHeaders.Clear();
|
||||
//httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
|
||||
|
||||
//var queryPayload = new
|
||||
//{
|
||||
// vector = queryVector,
|
||||
// limit = limit
|
||||
//};
|
||||
|
||||
var client = new QdrantClient(
|
||||
host: _qdrantHost,
|
||||
https: true,
|
||||
|
|
@ -408,6 +438,15 @@ namespace BLAIzor.Services
|
|||
|
||||
}
|
||||
|
||||
public async Task DeleteCollectionAsync(string collectionName)
|
||||
{
|
||||
|
||||
_apiKey = GetApiKey();
|
||||
|
||||
var client = new QdrantClient(_qdrantHost, 6334, true, _apiKey);
|
||||
await client.DeleteCollectionAsync(collectionName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class PointResult
|
||||
|
|
@ -438,6 +477,11 @@ namespace BLAIzor.Services
|
|||
public int id { get; set; }
|
||||
public HtmlSnippet payload { get; set; }
|
||||
public List<double> vector { get; set; }
|
||||
|
||||
public float[] GetFloatVector()
|
||||
{
|
||||
return vector?.Select(d => (float)d).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -460,6 +504,10 @@ namespace BLAIzor.Services
|
|||
public int id { get; set; }
|
||||
public ContentPayload payload { get; set; }
|
||||
public List<double> vector { get; set; }
|
||||
public float[] GetFloatVector()
|
||||
{
|
||||
return vector?.Select(d => (float)d).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public class ContentPayload
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ namespace BLAIzor.Services
|
|||
public string CurrentDOM { get; set; }
|
||||
public string currentLocale { get; set; }
|
||||
public string SelectedDocument { get; set; } = "Poppixel.docx";
|
||||
|
||||
private string _selectedBrandName;
|
||||
public string SelectedBrandName
|
||||
{
|
||||
|
|
@ -33,6 +32,8 @@ namespace BLAIzor.Services
|
|||
}
|
||||
}
|
||||
|
||||
public List<HtmlSnippet> AvailableTemplateSnippets { get; set; }
|
||||
public List<WebPageContent> AvailableSiteContent { get; set; }
|
||||
public event Action OnBrandNameChanged;
|
||||
public int SelectedSiteId { get; set; } = 1;
|
||||
//public string SelectedDocument { get; set; } = "Poppixel.docx";
|
||||
|
|
@ -64,8 +65,6 @@ namespace BLAIzor.Services
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<SiteInfo?> GetSiteInfoWithFormsByIdAsync(int siteId)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@
|
|||
"AiSettings": {
|
||||
"Provider": "cerebras",
|
||||
//"Provider": "chatgpt",
|
||||
"VoiceActivated": true
|
||||
"VoiceActivated": true,
|
||||
"EmbeddingService": "openai"
|
||||
//"EmbeddingService": "local"
|
||||
},
|
||||
"DeepSeek": {
|
||||
"ApiKey": "sk-b97350ccb28c4129b5df08835bf2ea5f"
|
||||
|
|
@ -33,6 +35,7 @@
|
|||
"Model": "llama-3.3-70b"
|
||||
//"Model": "llama-4-scout-17b-16e-instruct"
|
||||
//"Model": "qwen-3-32b"
|
||||
//"Model": "deepseek-r1-distill-llama-70b"
|
||||
//"Model": "llama3.1-8b"
|
||||
},
|
||||
"OpenAI": {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,471 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Quicksand&display=swap');
|
||||
|
||||
|
||||
/*search*/
|
||||
|
||||
|
||||
p {
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border: 0;
|
||||
color: #000000;
|
||||
/* width: 98%; */
|
||||
font-weight: bold;
|
||||
border-radius: 10px;
|
||||
/*min-height: 50px;*/
|
||||
transition: all 0.2s ease;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.menubtn {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border: 0;
|
||||
color: #000000;
|
||||
/* width: 98%; */
|
||||
font-weight: bold;
|
||||
border-radius: 10px;
|
||||
height: 40px;
|
||||
transition: all 0.2s ease;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 20px !important;
|
||||
}
|
||||
|
||||
|
||||
input.search_bar{
|
||||
border: none;
|
||||
outline: none;
|
||||
width: 75px;
|
||||
border-radius: 55px;
|
||||
margin: 0 auto;
|
||||
font-size: 1.3em;
|
||||
color: #0d2840;
|
||||
padding: 15px 30px 15px 45px;
|
||||
transition: all .3s cubic-bezier(0,0,.5,1.5);
|
||||
box-shadow: 0 3px 10px -2px rgba(0,0,0,.1);
|
||||
background: rgba(255, 255, 255, 0.3) url(https://i.imgur.com/seveWIw.png) no-repeat center center;
|
||||
}
|
||||
|
||||
input.search_bar:focus{
|
||||
width: 100%;
|
||||
background-position: calc(100% - 35px) center
|
||||
}
|
||||
|
||||
/*Removes default x in search fields (webkit only i guess)*/
|
||||
input[type=search]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
/*Changes the color of the placeholder*/
|
||||
::-webkit-input-placeholder {
|
||||
color: #0d2840;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
:-moz-placeholder {
|
||||
color: #0d2840;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
color: #0d2840;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
color: #0d2840;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
/*search*/
|
||||
|
||||
/*Search2*/
|
||||
.searchBox {
|
||||
width: 60px;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
height: 60px;
|
||||
border-radius: 40px;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
transition: 0.8s;
|
||||
}
|
||||
|
||||
.searchInput:active > .searchBox{
|
||||
width:100%
|
||||
}
|
||||
.searchInput:focus > .searchBox {
|
||||
width: 100%
|
||||
}
|
||||
.searchInput::placeholder {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.searchBox:hover {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.searchBox:hover > .searchInput {
|
||||
width: calc(100% - 60px);
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.searchBox:hover > .searchButton {
|
||||
background: white;
|
||||
color: #2f3640;
|
||||
}
|
||||
|
||||
.searchButton {
|
||||
color: white;
|
||||
float: right;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background-color: #e9bb86;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.searchInput {
|
||||
border: none;
|
||||
background: none;
|
||||
outline: none;
|
||||
font-size: 1.3em !important;
|
||||
color: #e9bb86 !important;
|
||||
float: left;
|
||||
padding: 0;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
transition: 0.4s;
|
||||
line-height: 40px;
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
/*Search2*/
|
||||
|
||||
|
||||
.event {
|
||||
border-radius: 20px !important;
|
||||
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||
backdrop-filter: blur(20px);
|
||||
border: 0;
|
||||
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
/*card design*/
|
||||
.card {
|
||||
border-radius: 10px !important;
|
||||
overflow: hidden;
|
||||
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||
backdrop-filter: blur(20px);
|
||||
border: 0;
|
||||
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
|
||||
transition: all 0.15s ease;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.1), 0 10px 8px rgba(0, 0, 0, 0.015);
|
||||
}
|
||||
|
||||
.card-body .card-title {
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.3px;
|
||||
font-size: 24px;
|
||||
color: #121212;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0.3px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card .container {
|
||||
width: 88%;
|
||||
/*background: #F0EEF8;*/
|
||||
border-radius: 30px;
|
||||
/*height: 140px;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.container:hover > img {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.container img {
|
||||
/*padding: 75px;*/
|
||||
/*margin-top: -40px;
|
||||
margin-bottom: -40px;*/
|
||||
transition: 0.4s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #9b7d5a;
|
||||
}
|
||||
|
||||
.btn:focus {
|
||||
background: #9b7d5a;
|
||||
outline: 0;
|
||||
}
|
||||
/*card design*/
|
||||
|
||||
/*bg*/
|
||||
|
||||
|
||||
:root {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Quicksand', sans-serif;
|
||||
color: #f2d8bb;
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background-color: #000;
|
||||
/*background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));*/
|
||||
/*background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;*/
|
||||
/*background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;*/
|
||||
background-repeat: no-repeat;
|
||||
/*animation: 10s movement linear infinite;*/
|
||||
}
|
||||
|
||||
body::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.myspan {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 5rem;
|
||||
color: transparent;
|
||||
text-shadow: 0px 0px 1px rgba(255, 255, 255, .6), 0px 4px 4px rgba(0, 0, 0, .05);
|
||||
letter-spacing: .2rem;
|
||||
}
|
||||
|
||||
/*@keyframes movement {
|
||||
0%, 100% {
|
||||
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;
|
||||
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;
|
||||
}
|
||||
|
||||
25% {
|
||||
background-size: 100vmax 100vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 60vmax 60vmax;
|
||||
background-position: -60vmax -90vmax, 50vmax -40vmax, 0vmax -20vmax, -40vmax -20vmax, 40vmax 60vmax;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-size: 80vmax 80vmax, 110vmax 110vmax, 80vmax 80vmax, 60vmax 60vmax, 80vmax 80vmax;
|
||||
background-position: -50vmax -70vmax, 40vmax -30vmax, 10vmax 0vmax, 20vmax 10vmax, 30vmax 70vmax;
|
||||
}
|
||||
|
||||
75% {
|
||||
background-size: 90vmax 90vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 70vmax 70vmax;
|
||||
background-position: -50vmax -40vmax, 50vmax -30vmax, 20vmax 0vmax, -10vmax 10vmax, 40vmax 60vmax;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/*bg*/
|
||||
|
||||
.mytextarea {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(20px);
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
border-width: 0px;
|
||||
height: unset !important;
|
||||
}
|
||||
|
||||
.mytextarea:active {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.mytextarea:focus-visible {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
border-width: 0px !important;
|
||||
outline: -webkit-focus-ring-color auto 0px;
|
||||
outline-color: transparent;
|
||||
}
|
||||
|
||||
.navbar-toggler {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.7rem;
|
||||
color: #e9bb86;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 15px;
|
||||
display: unset !important;
|
||||
}
|
||||
|
||||
.form-select > option {
|
||||
background-color: rgba(255, 255, 255, 0.2)
|
||||
}
|
||||
|
||||
.contactform-overlay {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
padding: 100px;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
/* padding-top: 10vh; */
|
||||
backdrop-filter: blur(20px);
|
||||
/* background-color: rgba(1, 1, 1, .4); */
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: rgba(255,255,255,0.4);
|
||||
border-radius: 15px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
form-control::placeholder{
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.contactform-close-overlay {
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
}
|
||||
|
||||
.contactform-popup-content {
|
||||
height: 80vh;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.contactform-popup-close {
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
z-index: 80;
|
||||
}
|
||||
|
||||
.calendly-overlay {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
top: 0px;
|
||||
/* padding-top: 10vh; */
|
||||
backdrop-filter: blur(20px);
|
||||
/* background-color: rgba(1, 1, 1, .4); */
|
||||
}
|
||||
|
||||
.calendly-close-overlay {
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
}
|
||||
|
||||
.calendly-popup-content {
|
||||
height: 80vh;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.calendly-popup-close {
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
z-index: 80;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
height: 100vh;
|
||||
/*display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;*/
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-link {
|
||||
font-size: 1.4em;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-item:not(:last-child) {
|
||||
border-bottom: 0px solid white;
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #1c120c;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.text-dark {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
max-height: 50vh !important;
|
||||
width: auto;
|
||||
}
|
||||
|
|
@ -0,0 +1,471 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Quicksand&display=swap');
|
||||
|
||||
|
||||
/*search*/
|
||||
|
||||
|
||||
p {
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border: 0;
|
||||
color: #000000;
|
||||
/* width: 98%; */
|
||||
font-weight: bold;
|
||||
border-radius: 10px;
|
||||
/*min-height: 50px;*/
|
||||
transition: all 0.2s ease;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.menubtn {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border: 0;
|
||||
color: #000000;
|
||||
/* width: 98%; */
|
||||
font-weight: bold;
|
||||
border-radius: 10px;
|
||||
height: 40px;
|
||||
transition: all 0.2s ease;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 20px !important;
|
||||
}
|
||||
|
||||
|
||||
input.search_bar{
|
||||
border: none;
|
||||
outline: none;
|
||||
width: 75px;
|
||||
border-radius: 55px;
|
||||
margin: 0 auto;
|
||||
font-size: 1.3em;
|
||||
color: #0d2840;
|
||||
padding: 15px 30px 15px 45px;
|
||||
transition: all .3s cubic-bezier(0,0,.5,1.5);
|
||||
box-shadow: 0 3px 10px -2px rgba(0,0,0,.1);
|
||||
background: rgba(255, 255, 255, 0.3) url(https://i.imgur.com/seveWIw.png) no-repeat center center;
|
||||
}
|
||||
|
||||
input.search_bar:focus{
|
||||
width: 100%;
|
||||
background-position: calc(100% - 35px) center
|
||||
}
|
||||
|
||||
/*Removes default x in search fields (webkit only i guess)*/
|
||||
input[type=search]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
/*Changes the color of the placeholder*/
|
||||
::-webkit-input-placeholder {
|
||||
color: #0d2840;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
:-moz-placeholder {
|
||||
color: #0d2840;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
color: #0d2840;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
color: #0d2840;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
/*search*/
|
||||
|
||||
/*Search2*/
|
||||
.searchBox {
|
||||
width: 60px;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
height: 60px;
|
||||
border-radius: 40px;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
transition: 0.8s;
|
||||
}
|
||||
|
||||
.searchInput:active > .searchBox{
|
||||
width:100%
|
||||
}
|
||||
.searchInput:focus > .searchBox {
|
||||
width: 100%
|
||||
}
|
||||
.searchInput::placeholder {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.searchBox:hover {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.searchBox:hover > .searchInput {
|
||||
width: calc(100% - 60px);
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.searchBox:hover > .searchButton {
|
||||
background: white;
|
||||
color: #2f3640;
|
||||
}
|
||||
|
||||
.searchButton {
|
||||
color: white;
|
||||
float: right;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background-color: #e9bb86;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.searchInput {
|
||||
border: none;
|
||||
background: none;
|
||||
outline: none;
|
||||
font-size: 1.3em !important;
|
||||
color: #e9bb86 !important;
|
||||
float: left;
|
||||
padding: 0;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
transition: 0.4s;
|
||||
line-height: 40px;
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
/*Search2*/
|
||||
|
||||
|
||||
.event {
|
||||
border-radius: 20px !important;
|
||||
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||
backdrop-filter: blur(20px);
|
||||
border: 0;
|
||||
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
/*card design*/
|
||||
.card {
|
||||
border-radius: 10px !important;
|
||||
overflow: hidden;
|
||||
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||
backdrop-filter: blur(20px);
|
||||
border: 0;
|
||||
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
|
||||
transition: all 0.15s ease;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.1), 0 10px 8px rgba(0, 0, 0, 0.015);
|
||||
}
|
||||
|
||||
.card-body .card-title {
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.3px;
|
||||
font-size: 24px;
|
||||
color: #121212;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0.3px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card .container {
|
||||
width: 88%;
|
||||
/*background: #F0EEF8;*/
|
||||
border-radius: 30px;
|
||||
/*height: 140px;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.container:hover > img {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.container img {
|
||||
/*padding: 75px;*/
|
||||
/*margin-top: -40px;
|
||||
margin-bottom: -40px;*/
|
||||
transition: 0.4s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #9b7d5a;
|
||||
}
|
||||
|
||||
.btn:focus {
|
||||
background: #9b7d5a;
|
||||
outline: 0;
|
||||
}
|
||||
/*card design*/
|
||||
|
||||
/*bg*/
|
||||
|
||||
|
||||
:root {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Quicksand', sans-serif;
|
||||
color: #f2d8bb;
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background-color: #000;
|
||||
/*background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));*/
|
||||
/*background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;*/
|
||||
/*background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;*/
|
||||
background-repeat: no-repeat;
|
||||
/*animation: 10s movement linear infinite;*/
|
||||
}
|
||||
|
||||
body::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.myspan {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 5rem;
|
||||
color: transparent;
|
||||
text-shadow: 0px 0px 1px rgba(255, 255, 255, .6), 0px 4px 4px rgba(0, 0, 0, .05);
|
||||
letter-spacing: .2rem;
|
||||
}
|
||||
|
||||
/*@keyframes movement {
|
||||
0%, 100% {
|
||||
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;
|
||||
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;
|
||||
}
|
||||
|
||||
25% {
|
||||
background-size: 100vmax 100vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 60vmax 60vmax;
|
||||
background-position: -60vmax -90vmax, 50vmax -40vmax, 0vmax -20vmax, -40vmax -20vmax, 40vmax 60vmax;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-size: 80vmax 80vmax, 110vmax 110vmax, 80vmax 80vmax, 60vmax 60vmax, 80vmax 80vmax;
|
||||
background-position: -50vmax -70vmax, 40vmax -30vmax, 10vmax 0vmax, 20vmax 10vmax, 30vmax 70vmax;
|
||||
}
|
||||
|
||||
75% {
|
||||
background-size: 90vmax 90vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 70vmax 70vmax;
|
||||
background-position: -50vmax -40vmax, 50vmax -30vmax, 20vmax 0vmax, -10vmax 10vmax, 40vmax 60vmax;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/*bg*/
|
||||
|
||||
.mytextarea {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(20px);
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
border-width: 0px;
|
||||
height: unset !important;
|
||||
}
|
||||
|
||||
.mytextarea:active {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.mytextarea:focus-visible {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
border-width: 0px !important;
|
||||
outline: -webkit-focus-ring-color auto 0px;
|
||||
outline-color: transparent;
|
||||
}
|
||||
|
||||
.navbar-toggler {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.7rem;
|
||||
color: #e9bb86;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 15px;
|
||||
display: unset !important;
|
||||
}
|
||||
|
||||
.form-select > option {
|
||||
background-color: rgba(255, 255, 255, 0.2)
|
||||
}
|
||||
|
||||
.contactform-overlay {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
padding: 100px;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
/* padding-top: 10vh; */
|
||||
backdrop-filter: blur(20px);
|
||||
/* background-color: rgba(1, 1, 1, .4); */
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: rgba(255,255,255,0.4);
|
||||
border-radius: 15px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
form-control::placeholder{
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.contactform-close-overlay {
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
}
|
||||
|
||||
.contactform-popup-content {
|
||||
height: 80vh;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.contactform-popup-close {
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
z-index: 80;
|
||||
}
|
||||
|
||||
.calendly-overlay {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
top: 0px;
|
||||
/* padding-top: 10vh; */
|
||||
backdrop-filter: blur(20px);
|
||||
/* background-color: rgba(1, 1, 1, .4); */
|
||||
}
|
||||
|
||||
.calendly-close-overlay {
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
}
|
||||
|
||||
.calendly-popup-content {
|
||||
height: 80vh;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.calendly-popup-close {
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
z-index: 80;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
height: 100vh;
|
||||
/*display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;*/
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-link {
|
||||
font-size: 1.4em;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-item:not(:last-child) {
|
||||
border-bottom: 0px solid white;
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #1c120c;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.text-dark {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
max-height: 50vh !important;
|
||||
width: auto;
|
||||
}
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.card {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
height: 100vh;
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-link {
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-item:not(:last-child) {
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #022c28;
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #d0eae9 !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #022c28;
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
color: aqua;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-size: 1rem; /* Base size */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 700;
|
||||
font-size: 2.5rem;
|
||||
padding-top: 30px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
font-size: 2rem;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.searchInput::placeholder {
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: -100px;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
transform: translateX(calc((100% - 100vw) / 2));
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
max-height: 50vh;
|
||||
width: auto;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.sp-img {
|
||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
.col {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 5px;
|
||||
display: unset !important;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.list-group-item,
|
||||
.bg-light {
|
||||
background-color: rgb(11 24 23 / 76%) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
--bs-text-opacity: 1;
|
||||
color: aqua;
|
||||
}
|
||||
|
||||
/* 🔽 Mobile Responsiveness */
|
||||
@media (max-width: 768px) {
|
||||
h1 { font-size: 2rem; }
|
||||
h2 { font-size: 1.6rem; }
|
||||
h3 { font-size: 1.4rem; }
|
||||
p, li { font-size: 1rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
h1 { font-size: 1.6rem; }
|
||||
h2 { font-size: 1.3rem; }
|
||||
h3 { font-size: 1.1rem; }
|
||||
p, li { font-size: 0.95rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,168 +0,0 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.card {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
height: 100vh;
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-link {
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-item:not(:last-child) {
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #022c28;
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #d0eae9 !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #022c28;
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
color: aqua;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-size: 1rem; /* Base size */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 700;
|
||||
font-size: 2.5rem;
|
||||
padding-top: 30px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
font-size: 2rem;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.searchInput::placeholder {
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: -100px;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
transform: translateX(calc((100% - 100vw) / 2));
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
max-height: 50vh;
|
||||
width: auto;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.sp-img {
|
||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
.col {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 5px;
|
||||
display: unset !important;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.list-group-item,
|
||||
.bg-light {
|
||||
background-color: rgb(11 24 23 / 76%) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
--bs-text-opacity: 1;
|
||||
color: aqua;
|
||||
}
|
||||
|
||||
/* 🔽 Mobile Responsiveness */
|
||||
@media (max-width: 768px) {
|
||||
h1 { font-size: 2rem; }
|
||||
h2 { font-size: 1.6rem; }
|
||||
h3 { font-size: 1.4rem; }
|
||||
p, li { font-size: 1rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
h1 { font-size: 1.6rem; }
|
||||
h2 { font-size: 1.3rem; }
|
||||
h3 { font-size: 1.1rem; }
|
||||
p, li { font-size: 0.95rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.card {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
height: 100vh;
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-link {
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-item:not(:last-child) {
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #022c28;
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #d0eae9 !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #022c28;
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
color: aqua;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-size: 1rem; /* Base size */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 700;
|
||||
font-size: 2.5rem;
|
||||
padding-top: 30px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
font-size: 2rem;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.searchInput::placeholder {
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: -100px;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
transform: translateX(calc((100% - 100vw) / 2));
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
max-height: 50vh;
|
||||
width: auto;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.sp-img {
|
||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
.col {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 5px;
|
||||
display: unset !important;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.list-group-item,
|
||||
.bg-light {
|
||||
background-color: rgb(11 24 23 / 76%) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
--bs-text-opacity: 1;
|
||||
color: aqua;
|
||||
}
|
||||
|
||||
/* 🔽 Mobile Responsiveness */
|
||||
@media (max-width: 768px) {
|
||||
h1 { font-size: 2rem; }
|
||||
h2 { font-size: 1.6rem; }
|
||||
h3 { font-size: 1.4rem; }
|
||||
p, li { font-size: 1rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
h1 { font-size: 1.6rem; }
|
||||
h2 { font-size: 1.3rem; }
|
||||
h3 { font-size: 1.1rem; }
|
||||
p, li { font-size: 0.95rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,168 +0,0 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.card {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
height: 100vh;
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-link {
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-item:not(:last-child) {
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #022c28;
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #d0eae9 !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #022c28;
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
color: aqua;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-size: 1rem; /* Base size */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 700;
|
||||
font-size: 2.5rem;
|
||||
padding-top: 30px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
font-size: 2rem;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.searchInput::placeholder {
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: -100px;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
transform: translateX(calc((100% - 100vw) / 2));
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
max-height: 50vh;
|
||||
width: auto;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.sp-img {
|
||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
.col {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 5px;
|
||||
display: unset !important;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.list-group-item,
|
||||
.bg-light {
|
||||
background-color: rgb(11 24 23 / 76%) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
--bs-text-opacity: 1;
|
||||
color: aqua;
|
||||
}
|
||||
|
||||
/* 🔽 Mobile Responsiveness */
|
||||
@media (max-width: 768px) {
|
||||
h1 { font-size: 2rem; }
|
||||
h2 { font-size: 1.6rem; }
|
||||
h3 { font-size: 1.4rem; }
|
||||
p, li { font-size: 1rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
h1 { font-size: 1.6rem; }
|
||||
h2 { font-size: 1.3rem; }
|
||||
h3 { font-size: 1.1rem; }
|
||||
p, li { font-size: 0.95rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.card {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
height: 100vh;
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-link {
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-item:not(:last-child) {
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #022c28;
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #d0eae9 !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #022c28;
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
color: aqua;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-size: 1rem; /* Base size */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 700;
|
||||
font-size: 2.5rem;
|
||||
padding-top: 30px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
font-size: 2rem;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.searchInput::placeholder {
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: -100px;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
transform: translateX(calc((100% - 100vw) / 2));
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
max-height: 50vh;
|
||||
width: auto;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.sp-img {
|
||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
.col {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 5px;
|
||||
display: unset !important;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.list-group-item,
|
||||
.bg-light {
|
||||
background-color: rgb(11 24 23 / 76%) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
--bs-text-opacity: 1;
|
||||
color: aqua;
|
||||
}
|
||||
|
||||
/* 🔽 Mobile Responsiveness */
|
||||
@media (max-width: 768px) {
|
||||
h1 { font-size: 2rem; }
|
||||
h2 { font-size: 1.6rem; }
|
||||
h3 { font-size: 1.4rem; }
|
||||
p, li { font-size: 1rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
h1 { font-size: 1.6rem; }
|
||||
h2 { font-size: 1.3rem; }
|
||||
h3 { font-size: 1.1rem; }
|
||||
p, li { font-size: 0.95rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
.card {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #f2d8bb !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
height: 100vh;
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-link {
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.navbar-collapse .nav-item:not(:last-child) {
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #022c28;
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #d0eae9 !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #022c28;
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
color: aqua;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-size: 1rem; /* Base size */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 700;
|
||||
font-size: 2.5rem;
|
||||
padding-top: 30px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
font-size: 2rem;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #d0eae9;
|
||||
background-color: #014d4e;
|
||||
border: 0px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #086262;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-bottom: 30px;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.searchInput::placeholder {
|
||||
color: #d0eae9;
|
||||
}
|
||||
|
||||
#myVideo {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: -100px;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
transform: translateX(calc((100% - 100vw) / 2));
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
max-height: 50vh;
|
||||
width: auto;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.sp-img {
|
||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
.col {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 5px;
|
||||
display: unset !important;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.list-group-item,
|
||||
.bg-light {
|
||||
background-color: rgb(11 24 23 / 76%) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
--bs-text-opacity: 1;
|
||||
color: aqua;
|
||||
}
|
||||
|
||||
/* 🔽 Mobile Responsiveness */
|
||||
@media (max-width: 768px) {
|
||||
h1 { font-size: 2rem; }
|
||||
h2 { font-size: 1.6rem; }
|
||||
h3 { font-size: 1.4rem; }
|
||||
p, li { font-size: 1rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
h1 { font-size: 1.6rem; }
|
||||
h2 { font-size: 1.3rem; }
|
||||
h3 { font-size: 1.1rem; }
|
||||
p, li { font-size: 0.95rem; }
|
||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
||||
p {text-align: justify;}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 864 KiB |
Loading…
Reference in New Issue