Compare commits
15 commits
add-search
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
84a3c7e21e | ||
|
51bb3e0df8 | ||
|
6efb5b5d6f | ||
|
08774dd6f4 | ||
|
a77f93842a | ||
|
c81dd751e9 | ||
|
37a628ad09 | ||
0f3895bebd | |||
|
aeb7bd7634 | ||
|
0254061fa4 | ||
|
492e0765af | ||
|
469903dc9c | ||
|
0bc34bdbf0 | ||
|
9b3b5a5419 | ||
|
50a1a14f41 |
26 changed files with 5894 additions and 5282 deletions
27
README.md
27
README.md
|
@ -1,14 +1,22 @@
|
||||||
# Spitfire Browser Website
|
<p align="center">
|
||||||
|
<img src="https://weforgecode.xyz/Spitfire/Branding/raw/branch/main/icon5.svg" alt="Logo" width="64" height="64">
|
||||||
|
</p>
|
||||||
|
|
||||||
Spitfire Browser is a fast, secure, and elegant web browser built on Firefox. This repository contains the source code for the Spitfire Browser's official website.
|
<p align="center" style="font-size: 32px;">
|
||||||
|
<strong>Spitfire Browser Website</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
Unlike some other browser sites flexing with their 98.8% TypeScript (yikes), i keep it cool with minimal JavaScript just enough to get the job done.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
Spitfire Browser's website is built without Next.js, TypeScript, and Tailwind CSS or any other BS.
|
||||||
|
</p>
|
||||||
|
|
||||||
## TO-DO:
|
## TO-DO:
|
||||||
|
|
||||||
- [ ] Add screenshots
|
- [ ] Add browser download/screenshots for this web browser website (optional)
|
||||||
- [ ] Add search-engine test
|
|
||||||
- [ ] Add working downloads
|
|
||||||
- [X] Add blog/updates
|
|
||||||
- [ ] Add config file
|
|
||||||
|
|
||||||
### Blog entries should be fromated this way:
|
### Blog entries should be fromated this way:
|
||||||
|
|
||||||
|
@ -35,9 +43,10 @@ Vivamus luctus egestas leo. Phasellus faucibus molestie nisl. Etiam commodo dui
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
### Based on:
|
### Based on HTML template:
|
||||||
|
|
||||||
|
[Stellar](https://html5up.net/stellar) by HTML5 UP
|
||||||
|
|
||||||
Stellar by HTML5 UP
|
|
||||||
html5up.net | @ajlkn
|
html5up.net | @ajlkn
|
||||||
|
|
||||||
### Licence:
|
### Licence:
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -1,4 +1,4 @@
|
||||||
module my-web
|
module spitfire-browser-website
|
||||||
|
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
|
|
131
main.go
131
main.go
|
@ -6,7 +6,6 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -34,6 +33,11 @@ const (
|
||||||
discordWebhookURL = "YOUR_DISCORD_WEBHOOK_URL"
|
discordWebhookURL = "YOUR_DISCORD_WEBHOOK_URL"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Spitfire Browser by Internet Addict (https://spitfirebrowser.com)
|
||||||
|
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||||
|
*/
|
||||||
|
|
||||||
type Blog struct {
|
type Blog struct {
|
||||||
Name string
|
Name string
|
||||||
Entries []BlogEntry
|
Entries []BlogEntry
|
||||||
|
@ -101,14 +105,17 @@ func main() {
|
||||||
log.Fatalf("Error getting blogs: %v", err)
|
log.Fatalf("Error getting blogs: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start the periodic notification checker
|
||||||
|
go startNotificationChecker(10 * time.Minute)
|
||||||
|
|
||||||
// Start watching for changes in the data directory
|
// Start watching for changes in the data directory
|
||||||
go watchForChanges(dataDir)
|
go watchForChanges(dataDir)
|
||||||
|
|
||||||
// Serve static files (CSS, JS, etc.) from the /static directory
|
// Serve static files (CSS, JS, etc.) from the /static directory
|
||||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir))))
|
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir))))
|
||||||
|
|
||||||
// Serve files in the /data/news/ directory under /news-assets/
|
// Custom handler to serve only directories and their contents under /news-assets/
|
||||||
http.Handle("/news-assets/", http.StripPrefix("/news-assets/", http.FileServer(http.Dir(dataDir+"/news/"))))
|
http.Handle("/news-assets/", http.StripPrefix("/news-assets/", http.HandlerFunc(serveDirectoriesOnly)))
|
||||||
|
|
||||||
// Serve downloads.html at /downloads
|
// Serve downloads.html at /downloads
|
||||||
http.HandleFunc("/download", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/download", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -185,6 +192,15 @@ func main() {
|
||||||
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
|
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func startNotificationChecker(interval time.Duration) {
|
||||||
|
ticker := time.NewTicker(interval)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for range ticker.C {
|
||||||
|
checkAndSendNotifications()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func renderTemplate(w http.ResponseWriter, tmpl string, data interface{}) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, data interface{}) {
|
||||||
tmplPath := filepath.Join(templateDir, tmpl)
|
tmplPath := filepath.Join(templateDir, tmpl)
|
||||||
t, err := template.ParseFiles(tmplPath)
|
t, err := template.ParseFiles(tmplPath)
|
||||||
|
@ -205,6 +221,41 @@ func renderIndex(w http.ResponseWriter) {
|
||||||
renderTemplate(w, "index.html", nil)
|
renderTemplate(w, "index.html", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to add loading="lazy" to all img tags
|
||||||
|
func injectLazyLoading(htmlContent string) string {
|
||||||
|
// Split the content by <img tags to process them individually
|
||||||
|
parts := strings.Split(htmlContent, "<img")
|
||||||
|
|
||||||
|
// Start with the first part which is before any <img tag
|
||||||
|
modifiedContent := parts[0]
|
||||||
|
|
||||||
|
// Iterate over the remaining parts
|
||||||
|
for _, part := range parts[1:] {
|
||||||
|
// Find the closing bracket of the img tag
|
||||||
|
endOfTag := strings.Index(part, ">")
|
||||||
|
if endOfTag == -1 {
|
||||||
|
// If no closing bracket is found, add the remaining part as is
|
||||||
|
modifiedContent += "<img" + part
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the actual <img tag
|
||||||
|
imgTag := part[:endOfTag]
|
||||||
|
|
||||||
|
// Check if loading="lazy" is already present
|
||||||
|
if !strings.Contains(imgTag, "loading=") {
|
||||||
|
// Insert loading="lazy" before the closing of the img tag
|
||||||
|
imgTag = " loading=\"lazy\"" + imgTag
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild the full content with the modified img tag
|
||||||
|
modifiedContent += "<img" + imgTag + part[endOfTag:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return modifiedContent
|
||||||
|
}
|
||||||
|
|
||||||
|
// For redering HTML Blogs
|
||||||
func renderBlogEntry(w http.ResponseWriter, r *http.Request, blogName string, entryNumber int) {
|
func renderBlogEntry(w http.ResponseWriter, r *http.Request, blogName string, entryNumber int) {
|
||||||
var blog Blog
|
var blog Blog
|
||||||
for _, b := range blogs {
|
for _, b := range blogs {
|
||||||
|
@ -238,34 +289,32 @@ func renderBlogEntry(w http.ResponseWriter, r *http.Request, blogName string, en
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert .md to HTML
|
||||||
htmlContent := blackfriday.Run([]byte(entry.Content))
|
htmlContent := blackfriday.Run([]byte(entry.Content))
|
||||||
|
|
||||||
|
// Double check "/news-assets/" in URL of images
|
||||||
htmlContent = bytes.ReplaceAll(htmlContent, []byte("src=\"./"), []byte(fmt.Sprintf("src=\"/news-assets/%d/", entryNumber)))
|
htmlContent = bytes.ReplaceAll(htmlContent, []byte("src=\"./"), []byte(fmt.Sprintf("src=\"/news-assets/%d/", entryNumber)))
|
||||||
|
|
||||||
|
// Apply lazy loading to the generated HTML content
|
||||||
|
htmlContentWithLazyLoading := injectLazyLoading(string(htmlContent))
|
||||||
|
|
||||||
pageData := PageData{
|
pageData := PageData{
|
||||||
Title: entry.Title,
|
Title: entry.Title,
|
||||||
Date: entry.Date.Format("2006-01-02 15:04"),
|
Date: entry.Date.Format("2006-01-02 15:04"),
|
||||||
Desc: entry.Description,
|
Desc: entry.Description,
|
||||||
Author: entry.Author,
|
Author: entry.Author,
|
||||||
Content: template.HTML(htmlContent),
|
Content: template.HTML(htmlContentWithLazyLoading),
|
||||||
PrevLink: prevLink,
|
PrevLink: prevLink,
|
||||||
NextLink: nextLink,
|
NextLink: nextLink,
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTemplate(w, "news.html", pageData)
|
renderTemplate(w, "news.html", pageData)
|
||||||
|
|
||||||
// Handle notifications if they haven't been sent yet
|
|
||||||
if !entry.Notified {
|
|
||||||
sendNotifications(entry)
|
|
||||||
entry.Notified = true
|
|
||||||
saveNotifiedEntry(entry.Number)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBlogs(dir string) ([]Blog, error) {
|
func getBlogs(dir string) ([]Blog, error) {
|
||||||
var blogs []Blog
|
var blogs []Blog
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(dir)
|
files, err := os.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -286,7 +335,7 @@ func getBlogs(dir string) ([]Blog, error) {
|
||||||
func getBlogEntries(dir string) (Blog, error) {
|
func getBlogEntries(dir string) (Blog, error) {
|
||||||
var entries []BlogEntry
|
var entries []BlogEntry
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(dir)
|
files, err := os.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Blog{}, err
|
return Blog{}, err
|
||||||
}
|
}
|
||||||
|
@ -315,7 +364,7 @@ func getBlogEntries(dir string) (Blog, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseMarkdownFile(path string) (BlogEntry, error) {
|
func parseMarkdownFile(path string) (BlogEntry, error) {
|
||||||
content, err := ioutil.ReadFile(path)
|
content, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return BlogEntry{}, err
|
return BlogEntry{}, err
|
||||||
}
|
}
|
||||||
|
@ -433,6 +482,59 @@ func watchForChanges(dir string) {
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serveDirectoriesOnly handles requests and only serves directories and their contents.
|
||||||
|
func serveDirectoriesOnly(w http.ResponseWriter, r *http.Request) {
|
||||||
|
requestedPath := filepath.Join(dataDir, "news", r.URL.Path)
|
||||||
|
|
||||||
|
// Check if the requested path is a directory
|
||||||
|
fileInfo, err := os.Stat(requestedPath)
|
||||||
|
if err != nil {
|
||||||
|
http.NotFound(w, r) // If the path doesn't exist, return a 404
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block access to any files at the root level or the .git directory
|
||||||
|
if isRootLevel(requestedPath) || isRestrictedDirectory(requestedPath) {
|
||||||
|
http.NotFound(w, r) // Block access to root-level files like .md and the .git directory
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block access to any .md files at the root level
|
||||||
|
if isRootLevel(requestedPath) && strings.HasSuffix(requestedPath, ".md") {
|
||||||
|
http.NotFound(w, r) // Block access to root-level .md files
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the path is a directory, serve its contents
|
||||||
|
if fileInfo.IsDir() {
|
||||||
|
http.FileServer(http.Dir(requestedPath)).ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serve the file within the subdirectory
|
||||||
|
http.FileServer(http.Dir(filepath.Join(dataDir, "news"))).ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// isRootLevel checks if the file is at the root level of /news-assets/
|
||||||
|
func isRootLevel(path string) bool {
|
||||||
|
relPath, err := filepath.Rel(filepath.Join(dataDir, "news"), path)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// The relative path should not contain any slashes if it's at the root level
|
||||||
|
return !strings.Contains(relPath, string(os.PathSeparator))
|
||||||
|
}
|
||||||
|
|
||||||
|
// isRestrictedDirectory checks if the path is within a restricted directory like .git
|
||||||
|
func isRestrictedDirectory(path string) bool {
|
||||||
|
// Normalize the path
|
||||||
|
cleanPath := filepath.Clean(path)
|
||||||
|
|
||||||
|
// Check if the path contains .git directory or other restricted directories
|
||||||
|
return strings.Contains(cleanPath, string(os.PathSeparator)+".git") || strings.HasSuffix(cleanPath, ".git")
|
||||||
|
}
|
||||||
|
|
||||||
func handleFileChange(path string, isNew bool) {
|
func handleFileChange(path string, isNew bool) {
|
||||||
if filepath.Ext(path) == ".md" {
|
if filepath.Ext(path) == ".md" {
|
||||||
creationTimesM.Lock()
|
creationTimesM.Lock()
|
||||||
|
@ -444,6 +546,7 @@ func handleFileChange(path string, isNew bool) {
|
||||||
dir := filepath.Dir(path)
|
dir := filepath.Dir(path)
|
||||||
blogName := filepath.Base(dir)
|
blogName := filepath.Base(dir)
|
||||||
updateBlogEntries(blogName, path)
|
updateBlogEntries(blogName, path)
|
||||||
|
checkAndSendNotifications()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
63
rss.go
63
rss.go
|
@ -3,10 +3,11 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/feeds"
|
"github.com/gorilla/feeds"
|
||||||
"github.com/russross/blackfriday/v2" // Import the Markdown library
|
"github.com/russross/blackfriday/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func generateAtomFeed(w http.ResponseWriter, blogs []Blog, siteURL string) {
|
func generateAtomFeed(w http.ResponseWriter, blogs []Blog, siteURL string) {
|
||||||
|
@ -18,30 +19,50 @@ func generateAtomFeed(w http.ResponseWriter, blogs []Blog, siteURL string) {
|
||||||
Created: time.Now(),
|
Created: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add self link
|
||||||
|
feed.Link = &feeds.Link{Href: fmt.Sprintf("%s/rss", siteURL), Rel: "self"}
|
||||||
|
|
||||||
for _, blog := range blogs {
|
for _, blog := range blogs {
|
||||||
for _, entry := range blog.Entries {
|
for _, entry := range blog.Entries {
|
||||||
// Convert Markdown content to HTML
|
// Convert Markdown content to HTML
|
||||||
htmlContent := blackfriday.Run([]byte(entry.Content))
|
htmlContent := blackfriday.Run([]byte(entry.Content))
|
||||||
|
|
||||||
|
// Ensure all image paths are absolute URLs (Idiot proofing)
|
||||||
|
absoluteContent := strings.ReplaceAll(string(htmlContent), "src=\"/", fmt.Sprintf("src=\"%s/", siteURL))
|
||||||
|
|
||||||
|
// Ensure unique and stable ID
|
||||||
|
entryID := fmt.Sprintf("%s/%s/%d", siteURL, blog.Name, entry.Number)
|
||||||
|
|
||||||
|
// Create a summary if needed (using the first 200 characters of the content, for example)
|
||||||
|
summary := entry.Description
|
||||||
|
if summary == "" {
|
||||||
|
if len(entry.Content) > 200 {
|
||||||
|
summary = entry.Content[:200] + "..."
|
||||||
|
} else {
|
||||||
|
summary = entry.Content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
feed.Items = append(feed.Items, &feeds.Item{
|
feed.Items = append(feed.Items, &feeds.Item{
|
||||||
Title: entry.Title,
|
Title: entry.Title,
|
||||||
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/%d", siteURL, blog.Name, entry.Number), Rel: "alternate"},
|
Link: &feeds.Link{Href: entryID, Rel: "alternate"},
|
||||||
Description: entry.Description, // This can be used as the summary
|
Description: summary, // This can be used as the summary
|
||||||
Author: &feeds.Author{Name: entry.Author},
|
Author: &feeds.Author{Name: entry.Author},
|
||||||
Id: fmt.Sprintf("%s/%s/%d", siteURL, blog.Name, entry.Number),
|
Id: entryID,
|
||||||
Updated: entry.Date,
|
Updated: entry.Date,
|
||||||
Content: string(htmlContent),
|
Content: absoluteContent,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate Atom feed with the correct content-type and charset
|
||||||
|
w.Header().Set("Content-Type", "application/atom+xml; charset=UTF-8")
|
||||||
atom, err := feed.ToAtom()
|
atom, err := feed.ToAtom()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error generating Atom feed", http.StatusInternalServerError)
|
http.Error(w, "Error generating Atom feed", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/atom+xml")
|
|
||||||
w.Write([]byte(atom))
|
w.Write([]byte(atom))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,27 +75,47 @@ func generateBlogAtomFeed(w http.ResponseWriter, blog Blog, siteURL string) {
|
||||||
Created: time.Now(),
|
Created: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add self link
|
||||||
|
feed.Link = &feeds.Link{Href: fmt.Sprintf("%s/%s/rss", siteURL, blog.Name), Rel: "self"}
|
||||||
|
|
||||||
for _, entry := range blog.Entries {
|
for _, entry := range blog.Entries {
|
||||||
// Convert Markdown content to HTML
|
// Convert Markdown content to HTML
|
||||||
htmlContent := blackfriday.Run([]byte(entry.Content))
|
htmlContent := blackfriday.Run([]byte(entry.Content))
|
||||||
|
|
||||||
|
// Ensure all image paths are absolute URLs (Idiot proofing)
|
||||||
|
absoluteContent := strings.ReplaceAll(string(htmlContent), "src=\"/", fmt.Sprintf("src=\"%s/", siteURL))
|
||||||
|
|
||||||
|
// Ensure unique and stable ID
|
||||||
|
entryID := fmt.Sprintf("%s/%s/%d", siteURL, blog.Name, entry.Number)
|
||||||
|
|
||||||
|
// Create a summary if needed (using the first 200 characters of the content, for example)
|
||||||
|
summary := entry.Description
|
||||||
|
if summary == "" {
|
||||||
|
if len(entry.Content) > 200 {
|
||||||
|
summary = entry.Content[:200] + "..."
|
||||||
|
} else {
|
||||||
|
summary = entry.Content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
feed.Items = append(feed.Items, &feeds.Item{
|
feed.Items = append(feed.Items, &feeds.Item{
|
||||||
Title: entry.Title,
|
Title: entry.Title,
|
||||||
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/%d", siteURL, blog.Name, entry.Number), Rel: "alternate"},
|
Link: &feeds.Link{Href: entryID, Rel: "alternate"},
|
||||||
Description: entry.Description, // This can be used as the summary
|
Description: summary, // This can be used as the summary
|
||||||
Author: &feeds.Author{Name: entry.Author},
|
Author: &feeds.Author{Name: entry.Author},
|
||||||
Id: fmt.Sprintf("%s/%s/%d", siteURL, blog.Name, entry.Number),
|
Id: entryID,
|
||||||
Updated: entry.Date,
|
Updated: entry.Date,
|
||||||
Content: string(htmlContent),
|
Content: absoluteContent,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate Atom feed with the correct content-type and charset
|
||||||
|
w.Header().Set("Content-Type", "application/atom+xml; charset=UTF-8")
|
||||||
atom, err := feed.ToAtom()
|
atom, err := feed.ToAtom()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error generating Atom feed", http.StatusInternalServerError)
|
http.Error(w, "Error generating Atom feed", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/atom+xml")
|
|
||||||
w.Write([]byte(atom))
|
w.Write([]byte(atom))
|
||||||
}
|
}
|
||||||
|
|
21
run.bat
Normal file
21
run.bat
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
REM Default values
|
||||||
|
set PORT=8080
|
||||||
|
|
||||||
|
REM Parse command-line arguments
|
||||||
|
:parse_args
|
||||||
|
if "%~1"=="" goto run_app
|
||||||
|
if "%~1"=="-p" (
|
||||||
|
set PORT=%~2
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
goto parse_args
|
||||||
|
) else (
|
||||||
|
echo Unknown parameter passed: %~1
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
:run_app
|
||||||
|
REM Run the Go application with the parsed flags
|
||||||
|
go run discord.go rss.go telegram.go save.go main.go -p=%PORT%
|
36
save.go
36
save.go
|
@ -2,35 +2,49 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadNotifiedEntries() {
|
func loadNotifiedEntries() {
|
||||||
data, err := ioutil.ReadFile(notifiedFilePath)
|
file, err := os.Open(notifiedFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return // No file, no entries notified yet
|
return
|
||||||
}
|
}
|
||||||
log.Fatalf("Error reading notified entries file: %v", err)
|
log.Fatalf("Error loading notified entries: %v", err)
|
||||||
}
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
err = json.Unmarshal(data, ¬ifiedEntries)
|
err = json.NewDecoder(file).Decode(¬ifiedEntries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error parsing notified entries file: %v", err)
|
log.Fatalf("Error decoding notified entries: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveNotifiedEntry(entryNumber int) {
|
func saveNotifiedEntry(entryNumber int) {
|
||||||
notifiedEntries[entryNumber] = true
|
notifiedEntries[entryNumber] = true
|
||||||
data, err := json.Marshal(notifiedEntries)
|
file, err := os.Create(notifiedFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error serializing notified entries: %v", err)
|
log.Fatalf("Error saving notified entries: %v", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = json.NewEncoder(file).Encode(notifiedEntries)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error encoding notified entries: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(notifiedFilePath, data, 0644)
|
func checkAndSendNotifications() {
|
||||||
if err != nil {
|
for _, blog := range blogs {
|
||||||
log.Fatalf("Error writing notified entries file: %v", err)
|
for _, entry := range blog.Entries {
|
||||||
|
if !entry.Notified && !time.Now().Before(entry.Date) {
|
||||||
|
sendNotifications(entry)
|
||||||
|
entry.Notified = true
|
||||||
|
saveNotifiedEntry(entry.Number)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,51 @@
|
||||||
img {
|
/* Global settings for images and videos */
|
||||||
|
img, video {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 85%;
|
||||||
|
height: auto;
|
||||||
|
margin: 20px auto; /* Centers the image/video horizontally and adds space above and below */
|
||||||
|
border-radius: 10px; /* Add rounded corners */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Exclude images inside the .icons class from global settings */
|
||||||
|
ul.icons img {
|
||||||
|
display: inline; /* Override display: block */
|
||||||
|
width: auto; /* Override width: 100% */
|
||||||
|
border-radius: 0; /* Remove rounded corners */
|
||||||
|
margin-top: 0; /* Remove top margin */
|
||||||
|
margin-bottom: 0; /* Remove bottom margin */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Align blog text and links */
|
||||||
.align-blog p, a, em {
|
.align-blog p, a, em {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .align-blog h1, h2, h3, h4, h5 {
|
/* Increase margin top for all headings */
|
||||||
} */
|
.align-blog h1,
|
||||||
|
.align-blog h2,
|
||||||
|
.align-blog h3,
|
||||||
|
.align-blog h4,
|
||||||
|
.align-blog h5,
|
||||||
|
.align-blog h6 {
|
||||||
|
margin-top: 30px; /* Adjust this value to increase space above headings */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icons specific styles */
|
||||||
|
ul.icons {
|
||||||
|
cursor: default;
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.icons li {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 0.65em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.icons li:last-child {
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
|
@ -24,3 +24,19 @@
|
||||||
height: 48px;
|
height: 48px;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.the-slider img {
|
||||||
|
width: 90%;
|
||||||
|
height: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#particles-js {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1; /* This value must be lower than other elements! */
|
||||||
|
}
|
||||||
|
|
|
@ -1,64 +1,139 @@
|
||||||
.fancy-gallery {
|
/* Adjust the gallery wrapper */
|
||||||
display: grid;
|
.gallery-wrapper {
|
||||||
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
|
||||||
gap: 20px;
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gallery-item {
|
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 15px;
|
|
||||||
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
|
|
||||||
transform: scale(1);
|
|
||||||
transition: transform 0.4s ease-in-out, filter 0.4s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gallery-item img {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
max-width: 800px;
|
||||||
object-fit: cover;
|
margin: 0 auto; /* Center the gallery */
|
||||||
transition: transform 0.6s ease, filter 0.6s ease;
|
overflow: hidden; /* Ensure content is within bounds */
|
||||||
}
|
}
|
||||||
|
|
||||||
.gallery-item::before {
|
.gallery-wrapper img {
|
||||||
content: '';
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border: 1px solid #dddddd3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Slick carousel specific styles */
|
||||||
|
.slick-prev, .slick-next {
|
||||||
|
background: #444; /* Button background color */
|
||||||
|
border: none; /* Remove any border */
|
||||||
|
border-radius: 50%; /* Make the buttons circular */
|
||||||
|
color: #fff; /* Text color */
|
||||||
|
font-size: 18px; /* Font size for the arrow */
|
||||||
|
height: 40px; /* Button height */
|
||||||
|
width: 40px; /* Button width */
|
||||||
|
line-height: 40px; /* Center text vertically */
|
||||||
|
text-align: center; /* Center text horizontally */
|
||||||
|
z-index: 1000; /* Make sure buttons are above the carousel images */
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 50%; /* Position vertically centered */
|
||||||
left: 0;
|
transform: translateY(-50%);
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(45deg, rgba(255, 0, 150, 0.3), rgba(0, 204, 255, 0.3));
|
|
||||||
mix-blend-mode: overlay;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.6s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gallery-item:hover {
|
.slick-prev {
|
||||||
transform: scale(1.05);
|
left: 0px;
|
||||||
filter: brightness(1.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gallery-item:hover img {
|
.slick-next {
|
||||||
transform: scale(1.1) rotate(2deg);
|
right: 0px;
|
||||||
filter: grayscale(20%)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gallery-item:hover::before {
|
/* Center the dots under the image */
|
||||||
opacity: 1;
|
.slick-dots {
|
||||||
}
|
text-align: center;
|
||||||
/*
|
margin-top: 15px; /* Space between image and dots */
|
||||||
@keyframes pulse {
|
padding-left: 0;
|
||||||
0%, 100% {
|
list-style: none;
|
||||||
transform: scale(1);
|
|
||||||
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: scale(1.02);
|
|
||||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gallery-item {
|
.slick-dots li {
|
||||||
animation: pulse 5s infinite;
|
display: inline-block; /* Align dots horizontally */
|
||||||
} */
|
margin: 0 8px; /* Space between dots */
|
||||||
|
}
|
||||||
|
|
||||||
|
.slick-dots li button {
|
||||||
|
background: #ccc; /* Dot background color */
|
||||||
|
border: none; /* Remove any border */
|
||||||
|
border-radius: 50%; /* Make the dots circular */
|
||||||
|
width: 12px; /* Dot width */
|
||||||
|
height: 12px; /* Dot height */
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slick-dots li button::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 16px; /* Adjusted circle width */
|
||||||
|
height: 16px; /* Adjusted circle height */
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 2px solid #ccc; /* Circle border color */
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slick-dots li.slick-active button::before {
|
||||||
|
background-color: #fff; /* Active dot background color */
|
||||||
|
border-color: #fff; /* Active dot border color */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is what I get for global styling and using templates */
|
||||||
|
|
||||||
|
/* Override the border-radius to remove rounded corners */
|
||||||
|
.slick-prev, .slick-next {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
background: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If you want a specific shape, like a square or a different background */
|
||||||
|
.slick-prev, .slick-next {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the active dot buttons are not rounded */
|
||||||
|
.slick-dots li button {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slick-dots li button::before {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* General button override */
|
||||||
|
button[type="button"][role="tab"] {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
background: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
border: none !important;
|
||||||
|
color: inherit !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore the round shape for the dots */
|
||||||
|
.slick-dots li button {
|
||||||
|
border-radius: 50% !important;
|
||||||
|
background: #ccc !important;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the pseudo-element is also circular */
|
||||||
|
.slick-dots li button::before {
|
||||||
|
border-radius: 50% !important;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the active dot */
|
||||||
|
.slick-dots li.slick-active button::before {
|
||||||
|
background-color: #fff;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
|
@ -5,8 +5,8 @@
|
||||||
@import 'assets/webfonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdu.woff2';
|
@import 'assets/webfonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdu.woff2';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Stellar by HTML5 UP
|
Spitfire Browser by Internet Addict (https://weforgecode.xyz/Spitfire/Website)
|
||||||
html5up.net | @ajlkn
|
Based on Stellar by HTML5 UP | @ajlkn
|
||||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ input, select, textarea {
|
||||||
|
|
||||||
body, input, select, textarea {
|
body, input, select, textarea {
|
||||||
font-family: "Source Sans Pro", Helvetica, sans-serif;
|
font-family: "Source Sans Pro", Helvetica, sans-serif;
|
||||||
font-size: 17pt;
|
font-size: 14pt;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
line-height: 1.65;
|
line-height: 1.65;
|
||||||
}
|
}
|
||||||
|
@ -159,10 +159,10 @@ input, select, textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
-moz-transition: color 0.2s ease, border-bottom 0.2s ease;
|
-moz-transition: color 0.3s ease, border-bottom 0.3s ease;
|
||||||
-webkit-transition: color 0.2s ease, border-bottom 0.2s ease;
|
-webkit-transition: color 0.3s ease, border-bottom 0.3s ease;
|
||||||
-ms-transition: color 0.2s ease, border-bottom 0.2s ease;
|
-ms-transition: color 0.3s ease, border-bottom 0.3s ease;
|
||||||
transition: color 0.2s ease, border-bottom 0.2s ease;
|
transition: color 0.3s ease, border-bottom 0.3s ease;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom: dotted 1px;
|
border-bottom: dotted 1px;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -1836,10 +1836,10 @@ input, select, textarea {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-ms-appearance: none;
|
-ms-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
-moz-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
-moz-transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
-webkit-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
-webkit-transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
-ms-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
-ms-transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 0;
|
border: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -2218,10 +2218,10 @@ input, select, textarea {
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
-moz-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
-moz-transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
-webkit-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
-webkit-transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
-ms-transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
-ms-transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -3220,10 +3220,10 @@ input, select, textarea {
|
||||||
/* Nav */
|
/* Nav */
|
||||||
|
|
||||||
#nav {
|
#nav {
|
||||||
-moz-transition: background-color 0.2s ease, border-top-left-radius 0.2s ease, border-top-right-radius 0.2s ease, padding 0.2s ease;
|
-moz-transition: background-color 0.3s ease, border-top-left-radius 0.3s ease, border-top-right-radius 0.3s ease, padding 0.3s ease;
|
||||||
-webkit-transition: background-color 0.2s ease, border-top-left-radius 0.2s ease, border-top-right-radius 0.2s ease, padding 0.2s ease;
|
-webkit-transition: background-color 0.3s ease, border-top-left-radius 0.3s ease, border-top-right-radius 0.3s ease, padding 0.3s ease;
|
||||||
-ms-transition: background-color 0.2s ease, border-top-left-radius 0.2s ease, border-top-right-radius 0.2s ease, padding 0.2s ease;
|
-ms-transition: background-color 0.3s ease, border-top-left-radius 0.3s ease, border-top-right-radius 0.3s ease, padding 0.3s ease;
|
||||||
transition: background-color 0.2s ease, border-top-left-radius 0.2s ease, border-top-right-radius 0.2s ease, padding 0.2s ease;
|
transition: background-color 0.3s ease, border-top-left-radius 0.3s ease, border-top-right-radius 0.3s ease, padding 0.3s ease;
|
||||||
background-color: #0a0a0a;
|
background-color: #0a0a0a;
|
||||||
color: #fafafa;
|
color: #fafafa;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -3277,10 +3277,10 @@ input, select, textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav ul li {
|
#nav ul li {
|
||||||
-moz-transition: margin 0.2s ease;
|
-moz-transition: margin 0.3s ease;
|
||||||
-webkit-transition: margin 0.2s ease;
|
-webkit-transition: margin 0.3s ease;
|
||||||
-ms-transition: margin 0.2s ease;
|
-ms-transition: margin 0.3s ease;
|
||||||
transition: margin 0.2s ease;
|
transition: margin 0.3s ease;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 0.35em;
|
margin: 0 0.35em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -3288,10 +3288,10 @@ input, select, textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav ul li a {
|
#nav ul li a {
|
||||||
-moz-transition: font-size 0.2s ease;
|
-moz-transition: font-size 0.3s ease;
|
||||||
-webkit-transition: font-size 0.2s ease;
|
-webkit-transition: font-size 0.3s ease;
|
||||||
-ms-transition: font-size 0.2s ease;
|
-ms-transition: font-size 0.3s ease;
|
||||||
transition: font-size 0.2s ease;
|
transition: font-size 0.3s ease;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 2.25em;
|
height: 2.25em;
|
||||||
line-height: 2.25em;
|
line-height: 2.25em;
|
||||||
|
@ -3301,15 +3301,19 @@ input, select, textarea {
|
||||||
box-shadow: inset 0 0 0 1px transparent;
|
box-shadow: inset 0 0 0 1px transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav ul li a:hover {
|
|
||||||
background-color: #080808;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav ul li a.active {
|
#nav ul li a.active {
|
||||||
background-color: #000000;
|
transition: all 0.3s ease;
|
||||||
|
background-color: #1a1a1a;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#nav ul li a:hover {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#nav.alt {
|
#nav.alt {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
2
static/css/slick.min.css
vendored
Normal file
2
static/css/slick.min.css
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.slick-slider{position:relative;display:block;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;display:block;overflow:hidden;margin:0;padding:0}.slick-list:focus{outline:0}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-list,.slick-slider .slick-track{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.slick-track{position:relative;top:0;left:0;display:block;margin-left:auto;margin-right:auto}.slick-track:after,.slick-track:before{display:table;content:''}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{display:none;float:left;height:100%;min-height:1px}[dir=rtl] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-arrow.slick-hidden{display:none}
|
||||||
|
/*# sourceMappingURL=/sm/fb3ed351cd5c0f1f30f88778ee1f9b056598e6d25ac4fdcab1eebcd8be521cd9.map */
|
BIN
static/images/favicon.png
Normal file
BIN
static/images/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Stellar by HTML5 UP
|
Spitfire Browser by Internet Addict (https://weforgecode.xyz/Spitfire/Website)
|
||||||
html5up.net | @ajlkn
|
Based on Stellar by HTML5 UP | @ajlkn
|
||||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
9
static/js/particles.min.js
vendored
Normal file
9
static/js/particles.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
110
static/js/particlesjs-config-alt.json
Normal file
110
static/js/particlesjs-config-alt.json
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
{
|
||||||
|
"particles": {
|
||||||
|
"number": {
|
||||||
|
"value": 160,
|
||||||
|
"density": {
|
||||||
|
"enable": true,
|
||||||
|
"value_area": 800
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"value": "#ffffff"
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"type": "circle",
|
||||||
|
"stroke": {
|
||||||
|
"width": 0,
|
||||||
|
"color": "#000000"
|
||||||
|
},
|
||||||
|
"polygon": {
|
||||||
|
"nb_sides": 5
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"src": "img/github.svg",
|
||||||
|
"width": 100,
|
||||||
|
"height": 100
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"opacity": {
|
||||||
|
"value": 1,
|
||||||
|
"random": true,
|
||||||
|
"anim": {
|
||||||
|
"enable": true,
|
||||||
|
"speed": 1,
|
||||||
|
"opacity_min": 0,
|
||||||
|
"sync": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"value": 3,
|
||||||
|
"random": true,
|
||||||
|
"anim": {
|
||||||
|
"enable": false,
|
||||||
|
"speed": 4,
|
||||||
|
"size_min": 0.3,
|
||||||
|
"sync": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"line_linked": {
|
||||||
|
"enable": false,
|
||||||
|
"distance": 150,
|
||||||
|
"color": "#ffffff",
|
||||||
|
"opacity": 0.4,
|
||||||
|
"width": 1
|
||||||
|
},
|
||||||
|
"move": {
|
||||||
|
"enable": true,
|
||||||
|
"speed": 1,
|
||||||
|
"direction": "none",
|
||||||
|
"random": true,
|
||||||
|
"straight": false,
|
||||||
|
"out_mode": "out",
|
||||||
|
"bounce": false,
|
||||||
|
"attract": {
|
||||||
|
"enable": false,
|
||||||
|
"rotateX": 600,
|
||||||
|
"rotateY": 600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interactivity": {
|
||||||
|
"detect_on": "canvas",
|
||||||
|
"events": {
|
||||||
|
"onhover": {
|
||||||
|
"enable": true,
|
||||||
|
"mode": "bubble"
|
||||||
|
},
|
||||||
|
"onclick": {
|
||||||
|
"enable": true,
|
||||||
|
"mode": "repulse"
|
||||||
|
},
|
||||||
|
"resize": true
|
||||||
|
},
|
||||||
|
"modes": {
|
||||||
|
"grab": {
|
||||||
|
"distance": 400,
|
||||||
|
"line_linked": {
|
||||||
|
"opacity": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bubble": {
|
||||||
|
"distance": 250,
|
||||||
|
"size": 0,
|
||||||
|
"duration": 2,
|
||||||
|
"opacity": 0,
|
||||||
|
"speed": 3
|
||||||
|
},
|
||||||
|
"repulse": {
|
||||||
|
"distance": 400,
|
||||||
|
"duration": 0.4
|
||||||
|
},
|
||||||
|
"push": {
|
||||||
|
"particles_nb": 4
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"particles_nb": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"retina_detect": true
|
||||||
|
}
|
110
static/js/particlesjs-config.json
Normal file
110
static/js/particlesjs-config.json
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
{
|
||||||
|
"particles": {
|
||||||
|
"number": {
|
||||||
|
"value": 160,
|
||||||
|
"density": {
|
||||||
|
"enable": true,
|
||||||
|
"value_area": 800
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"value": "#ffffff"
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"type": "circle",
|
||||||
|
"stroke": {
|
||||||
|
"width": 0,
|
||||||
|
"color": "#000000"
|
||||||
|
},
|
||||||
|
"polygon": {
|
||||||
|
"nb_sides": 5
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"src": "img/github.svg",
|
||||||
|
"width": 10,
|
||||||
|
"height": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"opacity": {
|
||||||
|
"value": 0.7,
|
||||||
|
"random": true,
|
||||||
|
"anim": {
|
||||||
|
"enable": true,
|
||||||
|
"speed": 0.47948982282851027,
|
||||||
|
"opacity_min": 0,
|
||||||
|
"sync": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"value": 2,
|
||||||
|
"random": true,
|
||||||
|
"anim": {
|
||||||
|
"enable": false,
|
||||||
|
"speed": 4,
|
||||||
|
"size_min": 0.3,
|
||||||
|
"sync": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"line_linked": {
|
||||||
|
"enable": false,
|
||||||
|
"distance": 150,
|
||||||
|
"color": "#ffffff",
|
||||||
|
"opacity": 0.4,
|
||||||
|
"width": 1
|
||||||
|
},
|
||||||
|
"move": {
|
||||||
|
"enable": true,
|
||||||
|
"speed": 0,
|
||||||
|
"direction": "none",
|
||||||
|
"random": true,
|
||||||
|
"straight": false,
|
||||||
|
"out_mode": "out",
|
||||||
|
"bounce": false,
|
||||||
|
"attract": {
|
||||||
|
"enable": false,
|
||||||
|
"rotateX": 600,
|
||||||
|
"rotateY": 600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interactivity": {
|
||||||
|
"detect_on": "canvas",
|
||||||
|
"events": {
|
||||||
|
"onhover": {
|
||||||
|
"enable": true,
|
||||||
|
"mode": "bubble"
|
||||||
|
},
|
||||||
|
"onclick": {
|
||||||
|
"enable": true,
|
||||||
|
"mode": "repulse"
|
||||||
|
},
|
||||||
|
"resize": true
|
||||||
|
},
|
||||||
|
"modes": {
|
||||||
|
"grab": {
|
||||||
|
"distance": 400,
|
||||||
|
"line_linked": {
|
||||||
|
"opacity": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bubble": {
|
||||||
|
"distance": 250,
|
||||||
|
"size": 0,
|
||||||
|
"duration": 2,
|
||||||
|
"opacity": 0,
|
||||||
|
"speed": 3
|
||||||
|
},
|
||||||
|
"repulse": {
|
||||||
|
"distance": 400,
|
||||||
|
"duration": 0.4
|
||||||
|
},
|
||||||
|
"push": {
|
||||||
|
"particles_nb": 4
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"particles_nb": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"retina_detect": true
|
||||||
|
}
|
16
static/js/slick-conf.js
Normal file
16
static/js/slick-conf.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('.the-slider').slick({
|
||||||
|
dots: true,
|
||||||
|
infinite: true,
|
||||||
|
speed: 300,
|
||||||
|
slidesToShow: 1,
|
||||||
|
adaptiveHeight: true,
|
||||||
|
autoplay: true,
|
||||||
|
autoplaySpeed: 2000,
|
||||||
|
prevArrow: '<button type="button" class="slick-prev">❮</button>',
|
||||||
|
nextArrow: '<button type="button" class="slick-next">❯</button>',
|
||||||
|
customPaging: function(slider, i) {
|
||||||
|
return '<button type="button">' + '</button>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
1
static/js/slick.min.js
vendored
Normal file
1
static/js/slick.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
||||||
///
|
///
|
||||||
/// Stellar by HTML5 UP
|
// Spitfire Browser by Internet Addict (https://weforgecode.xyz/Spitfire/Website)
|
||||||
/// html5up.net | @ajlkn
|
// Based on Stellar by HTML5 UP | @ajlkn
|
||||||
/// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||||
///
|
///
|
||||||
|
|
||||||
/* Icons */
|
/* Icons */
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<!--
|
<!--
|
||||||
Stellar by HTML5 UP
|
Spitfire Browser by Internet Addict (https://weforgecode.xyz/Spitfire/Website)
|
||||||
html5up.net | @ajlkn
|
Based on Stellar by HTML5 UP | @ajlkn
|
||||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||||
-->
|
-->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="icon" type="image/png" href="favicon.png">
|
<link rel="icon" type="image/png" href="static/images/favicon.png">
|
||||||
<title>Spitfire Browser - Downloads</title>
|
<title>Spitfire Browser - Downloads</title>
|
||||||
<meta content="🌐 Spitfire Browser" property="og:title" />
|
<meta content="🌐 Spitfire Browser" property="og:title" />
|
||||||
<meta content="Privacy respecting user friendly web browser." property="og:description" />
|
<meta content="Privacy respecting user friendly web browser." property="og:description" />
|
||||||
<meta content="https://spitfirebrowser.com/" property="og:url" />
|
<meta content="https://spitfirebrowser.com/" property="og:url" />
|
||||||
<meta content="https://spitfirebrowser.com/favicon.png" property="og:image" />
|
<meta content="https://spitfirebrowser.com/static/images/favicon.png" property="og:image" />
|
||||||
<meta content="#f1f1f1" data-react-helmet="true" name="theme-color" />
|
<meta content="#f1f1f1" data-react-helmet="true" name="theme-color" />
|
||||||
<meta name="darkreader-lock">
|
<meta name="darkreader-lock">
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Top Floater Footer -->
|
<!-- Top Floater Footer -->
|
||||||
<div style="background-color: red; color: white; text-align: center; padding: 10px 0; position: fixed; top: 0; width: 100%; z-index: 1000;">
|
<div style="background-color: red; color: white; text-align: center; padding: 10px 0; position: fixed; bottom: 0; width: 100%; z-index: 1000;">
|
||||||
🚧👷♂️ This site is under construction! Please check back later. 👷♀️🚧
|
🚧👷♂️ This site is under construction! Please check back later. 👷♀️🚧
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<!--
|
<!--
|
||||||
Stellar by HTML5 UP
|
Spitfire Browser by Internet Addict (https://weforgecode.xyz/Spitfire/Website)
|
||||||
html5up.net | @ajlkn
|
Based on Stellar by HTML5 UP | @ajlkn
|
||||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||||
-->
|
-->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="icon" type="image/png" href="favicon.png">
|
<link rel="icon" type="image/png" href="static/images/favicon.png">
|
||||||
<title>Spitfire Browser - Downloads</title>
|
<title>Spitfire Browser - Downloads</title>
|
||||||
<meta content="🌐 Spitfire Browser" property="og:title" />
|
<meta content="🌐 Spitfire Browser" property="og:title" />
|
||||||
<meta content="Privacy respecting user friendly web browser." property="og:description" />
|
<meta content="Privacy respecting user friendly web browser." property="og:description" />
|
||||||
<meta content="https://spitfirebrowser.com/" property="og:url" />
|
<meta content="https://spitfirebrowser.com/" property="og:url" />
|
||||||
<meta content="https://spitfirebrowser.com/favicon.png" property="og:image" />
|
<meta content="https://spitfirebrowser.com/static/images/favicon.png" property="og:image" />
|
||||||
<meta content="#f1f1f1" data-react-helmet="true" name="theme-color" />
|
<meta content="#f1f1f1" data-react-helmet="true" name="theme-color" />
|
||||||
<meta name="darkreader-lock">
|
<meta name="darkreader-lock">
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Top Floater Footer -->
|
<!-- Top Floater Footer -->
|
||||||
<div style="background-color: red; color: white; text-align: center; padding: 10px 0; position: fixed; top: 0; width: 100%; z-index: 1000;">
|
<div style="background-color: red; color: white; text-align: center; padding: 10px 0; position: fixed; bottom: 0; width: 100%; z-index: 1000;">
|
||||||
🚧👷♂️ This site is under construction! Please check back later. 👷♀️🚧
|
🚧👷♂️ This site is under construction! Please check back later. 👷♀️🚧
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<!--
|
<!--
|
||||||
Spitfire Browser by Internet Addict
|
Spitfire Browser by Internet Addict (https://weforgecode.xyz/Spitfire/Website)
|
||||||
Based on Stellar by HTML5 UP
|
Based on Stellar by HTML5 UP | @ajlkn
|
||||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||||
-->
|
-->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="icon" type="image/png" href="favicon.png">
|
<link rel="icon" type="image/png" href="static/images/favicon.png">
|
||||||
<title>Spitfire Browser - Fast. Secure. Elegant.</title>
|
<title>Spitfire Browser - Fast. Secure. Elegant.</title>
|
||||||
<meta content="🌐 Spitfire Browser" property="og:title" />
|
<meta content="🌐 Spitfire Browser" property="og:title" />
|
||||||
<meta content="Privacy respecting user friendly web browser." property="og:description" />
|
<meta content="Privacy respecting user friendly web browser." property="og:description" />
|
||||||
<meta content="https://spitfirebrowser.com/" property="og:url" />
|
<meta content="https://spitfirebrowser.com/" property="og:url" />
|
||||||
<meta content="https://spitfirebrowser.com/favicon.png" property="og:image" />
|
<meta content="https://spitfirebrowser.com/static/images/favicon.png" property="og:image" />
|
||||||
<meta content="#f1f1f1" data-react-helmet="true" name="theme-color" />
|
<meta content="#f1f1f1" data-react-helmet="true" name="theme-color" />
|
||||||
<meta name="darkreader-lock">
|
<meta name="darkreader-lock">
|
||||||
|
|
||||||
|
@ -21,19 +21,23 @@
|
||||||
<link rel="stylesheet" href="/static/css/stars.css" />
|
<link rel="stylesheet" href="/static/css/stars.css" />
|
||||||
<link rel="stylesheet" href="/static/css/fancy-gallery.css" />
|
<link rel="stylesheet" href="/static/css/fancy-gallery.css" />
|
||||||
<link rel="stylesheet" href="/static/css/extras.css" />
|
<link rel="stylesheet" href="/static/css/extras.css" />
|
||||||
|
<link rel="stylesheet" href="/static/css/slick.min.css" />
|
||||||
<noscript><link rel="stylesheet" href="/static/css/noscript.css" /></noscript>
|
<noscript><link rel="stylesheet" href="/static/css/noscript.css" /></noscript>
|
||||||
</head>
|
</head>
|
||||||
<body class="is-preload">
|
<body class="is-preload">
|
||||||
|
|
||||||
<!-- Star Background Divs -->
|
<!-- Star Background Divs -->
|
||||||
<div id="star-background">
|
<div id="star-background">
|
||||||
|
<div id="particles-js"></div>
|
||||||
|
<noscript>
|
||||||
<div id="stars"></div>
|
<div id="stars"></div>
|
||||||
<div id="stars2"></div>
|
<div id="stars2"></div>
|
||||||
<div id="stars3"></div>
|
<div id="stars3"></div>
|
||||||
|
</noscript>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Top Floater Footer -->
|
<!-- Top Floater Footer -->
|
||||||
<div style="background-color: red; color: white; text-align: center; padding: 10px 0; position: fixed; top: 0; width: 100%; z-index: 1000;">
|
<div style="background-color: red; color: white; text-align: center; padding: 10px 0; position: fixed; bottom: 0; width: 100%; z-index: 1000;">
|
||||||
🚧👷♂️ This site is under construction! Please check back later. 👷♀️🚧
|
🚧👷♂️ This site is under construction! Please check back later. 👷♀️🚧
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -47,6 +51,7 @@
|
||||||
</span>
|
</span>
|
||||||
<h1>Spitfire Browser</h1>
|
<h1>Spitfire Browser</h1>
|
||||||
<p>Fast. Secure. Elegant.</p>
|
<p>Fast. Secure. Elegant.</p>
|
||||||
|
<br>
|
||||||
<a href="/download" class="button">Download Now</a>
|
<a href="/download" class="button">Download Now</a>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
@ -55,8 +60,8 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#intro" class="active">Introduction</a></li>
|
<li><a href="#intro" class="active">Introduction</a></li>
|
||||||
<li><a href="#features">Features</a></li>
|
<li><a href="#features">Features</a></li>
|
||||||
|
<li><a href="#search">Search</a></li>
|
||||||
<li><a href="#security">Security</a></li>
|
<li><a href="#security">Security</a></li>
|
||||||
<li><a href="#cta">Get Started</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
@ -68,18 +73,21 @@
|
||||||
<header class="major">
|
<header class="major">
|
||||||
<h2>Welcome to Spitfire Browser</h2>
|
<h2>Welcome to Spitfire Browser</h2>
|
||||||
</header>
|
</header>
|
||||||
<p>Spitfire Browser is your gateway to a fast, secure, and elegant browsing experience. Built on Firefox, Spitfire includes essential features like ad blocking, enhanced security, and anonymous browsing with Warp search engine.</p>
|
<p>Spitfire Browser is your gateway to a fast, secure, and elegant browsing experience. Built on Firefox, Spitfire includes essential features like ad blocking, enhanced security, and anonymous browsing with Ocásek search engine.</p>
|
||||||
<div class="box alt">
|
<br> <!-- br? I call it super.fancy.tailor.r.css.react.native.way.to.add.super.padding.on.top.of.images.T3.js.express.lodash.moment.axios.jquery.vue.nft.d3.angular.bloat.typescript.webpack.web3.babel.parcel.T4 -->
|
||||||
<div class="fancy-gallery">
|
<div class="gallery-wrapper">
|
||||||
<div class="gallery-item"><img src="/static/images/screenshots/1.png" alt="Screenshot 1" /></div>
|
<div class="the-slider"> <!-- Is this fucking centered? -->
|
||||||
<div class="gallery-item"><img src="/static/images/screenshots/1.png" alt="Screenshot 2" /></div>
|
<div><img src="/static/images/screenshots/1.png" alt="Screenshot 1"></div>
|
||||||
|
<div><img src="/static/images/screenshots/1.png" alt="Screenshot 2"></div>
|
||||||
|
<div><img src="/static/images/screenshots/1.png" alt="Screenshot 3"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="actions">
|
<!-- <ul class="actions js-disabled">
|
||||||
<li><a href="#features" class="button">More Screenshots</a></li>
|
<li><a href="#intro" class="button">See More Screenshots</a></li>
|
||||||
</ul>
|
</ul> -->
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Features Section -->
|
<!-- Features Section -->
|
||||||
<section id="features" class="main special">
|
<section id="features" class="main special">
|
||||||
<header class="major">
|
<header class="major">
|
||||||
|
@ -114,11 +122,20 @@
|
||||||
<li>
|
<li>
|
||||||
<span class="icon solid major style6 fa-search"></span>
|
<span class="icon solid major style6 fa-search"></span>
|
||||||
<h3>Anonymous Search</h3>
|
<h3>Anonymous Search</h3>
|
||||||
<p><a herf="https://search.spitfirebrowser.com/">Warp search engine</a> allows you to browse Google results anonymously.</p>
|
<p><a herf="#search">Ocásek search engine</a> allows you to browse Google results anonymously.</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Try Search -->
|
||||||
|
<section id="search" class="main special">
|
||||||
|
<header class="major">
|
||||||
|
<h2>Try Searching</h2>
|
||||||
|
<p></p>
|
||||||
|
</header>
|
||||||
|
<iframe src="https://search.spitfirebrowser.com" width="100%" height="700px" style="border:none; border-radius: 10px; overflow:hidden;"></iframe>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Security Section -->
|
<!-- Security Section -->
|
||||||
<section id="security" class="main special">
|
<section id="security" class="main special">
|
||||||
<header class="major">
|
<header class="major">
|
||||||
|
@ -192,13 +209,13 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#" class="icon alt">
|
<a href="https://weforgecode.xyz/Spitfire" class="icon alt">
|
||||||
<img src="/static/images/icons/brands/git-alt.svg" alt="Forgejo">
|
<img src="/static/images/icons/brands/git-alt.svg" alt="Forgejo">
|
||||||
<span class="label">Forgejo</span>
|
<span class="label">Forgejo</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#" class="icon alt">
|
<a href="https://www.youtube.com/@Internet.Addict" class="icon alt">
|
||||||
<img src="/static/images/icons/brands/youtube.svg" alt="YouTube">
|
<img src="/static/images/icons/brands/youtube.svg" alt="YouTube">
|
||||||
<span class="label">YouTube</span>
|
<span class="label">YouTube</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -213,13 +230,23 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="/static/js/jquery.min.js" defer></script>
|
<script src="/static/js/jquery.min.js"></script>
|
||||||
|
<script src="/static/js/slick.min.js"></script>
|
||||||
<script src="/static/js/jquery.scrollex.min.js" defer></script>
|
<script src="/static/js/jquery.scrollex.min.js" defer></script>
|
||||||
<script src="/static/js/jquery.scrolly.min.js" defer></script>
|
<script src="/static/js/jquery.scrolly.min.js" defer></script>
|
||||||
<script src="/static/js/browser.min.js" defer></script>
|
<script src="/static/js/browser.min.js" defer></script>
|
||||||
<script src="/static/js/breakpoints.min.js" defer></script>
|
<script src="/static/js/breakpoints.min.js" defer></script>
|
||||||
<script src="/static/js/util.js" defer></script>
|
<script src="/static/js/util.js" defer></script>
|
||||||
<script src="/static/js/main.js" defer></script>
|
<script src="/static/js/main.js" defer></script>
|
||||||
|
<script src="/static/js/slick-conf.js" defer></script>
|
||||||
|
<script src="/static/js/particles.min.js"></script>
|
||||||
|
<script>
|
||||||
|
/* particlesJS.load(@dom-id, @path-json, @callback (optional)); */
|
||||||
|
particlesJS.load('particles-js', '/static/js/particlesjs-config.json', function() {
|
||||||
|
console.log('callback - particles.js config loaded');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<!--
|
<!--
|
||||||
Stellar by HTML5 UP
|
Spitfire Browser by Internet Addict (https://weforgecode.xyz/Spitfire/Website)
|
||||||
html5up.net | @ajlkn
|
Based on Stellar by HTML5 UP | @ajlkn
|
||||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||||
-->
|
-->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="icon" type="image/png" href="favicon.png">
|
<link rel="icon" type="image/png" href="static/images/favicon.png">
|
||||||
<title>{{.Title}}</title>
|
<title>{{.Title}}</title>
|
||||||
<meta content="🌐 {{.Title}}" property="og:title" />
|
<meta content="🌐 {{.Title}}" property="og:title" />
|
||||||
<meta content="Privacy respecting user friendly web browser." property="og:description" />
|
<meta content="Privacy respecting user friendly web browser." property="og:description" />
|
||||||
<meta content="https://spitfirebrowser.com/" property="og:url" />
|
<meta content="https://spitfirebrowser.com/" property="og:url" />
|
||||||
<meta content="https://spitfirebrowser.com/favicon.png" property="og:image" />
|
<meta content="https://spitfirebrowser.com/static/images/favicon.png" property="og:image" />
|
||||||
<meta content="#f1f1f1" data-react-helmet="true" name="theme-color" />
|
<meta content="#f1f1f1" data-react-helmet="true" name="theme-color" />
|
||||||
<meta name="darkreader-lock">
|
<meta name="darkreader-lock">
|
||||||
|
|
||||||
|
@ -27,15 +27,18 @@
|
||||||
|
|
||||||
<!-- Star Background Divs -->
|
<!-- Star Background Divs -->
|
||||||
<div id="star-background">
|
<div id="star-background">
|
||||||
|
<div id="particles-js"></div>
|
||||||
|
<noscript>
|
||||||
<div id="stars"></div>
|
<div id="stars"></div>
|
||||||
<div id="stars2"></div>
|
<div id="stars2"></div>
|
||||||
<div id="stars3"></div>
|
<div id="stars3"></div>
|
||||||
|
</noscript>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Top Floater Footer -->
|
<!-- Top Floater Footer
|
||||||
<div style="background-color: red; color: white; text-align: center; padding: 10px 0; position: fixed; top: 0; width: 100%; z-index: 1000;">
|
<div style="background-color: red; color: white; text-align: center; padding: 10px 0; position: fixed; top: 0; width: 100%; z-index: 1000;">
|
||||||
🚧👷♂️ This site is under construction! Please check back later. 👷♀️🚧
|
🚧👷♂️ This site is under construction! Please check back later. 👷♀️🚧
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<!-- Wrapper -->
|
<!-- Wrapper -->
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
|
@ -58,13 +61,19 @@
|
||||||
</header>
|
</header>
|
||||||
<footer class="major">
|
<footer class="major">
|
||||||
<ul class="actions special">
|
<ul class="actions special">
|
||||||
{{if .PrevLink}}
|
<li>
|
||||||
<li><a href="{{.PrevLink}}" class="button primary small">Previous</a></li>
|
<a href="{{if .PrevLink}}{{.PrevLink}}{{else}}#{{end}}"
|
||||||
{{end}}
|
class="button primary small {{if not .PrevLink}}disabled{{end}}">
|
||||||
|
Previous
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li><a href="/" class="button primary small">Home</a></li>
|
<li><a href="/" class="button primary small">Home</a></li>
|
||||||
{{if .NextLink}}
|
<li>
|
||||||
<li><a href="{{.NextLink}}" class="button primary small">Next</a></li>
|
<a href="{{if .NextLink}}{{.NextLink}}{{else}}#{{end}}"
|
||||||
{{end}}
|
class="button primary small {{if not .NextLink}}disabled{{end}}">
|
||||||
|
Next
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
@ -110,6 +119,13 @@
|
||||||
<script src="/static/js/breakpoints.min.js" defer></script>
|
<script src="/static/js/breakpoints.min.js" defer></script>
|
||||||
<script src="/static/js/util.js" defer></script>
|
<script src="/static/js/util.js" defer></script>
|
||||||
<script src="/static/js/main.js" defer></script>
|
<script src="/static/js/main.js" defer></script>
|
||||||
|
<script src="/static/js/particles.min.js"></script>
|
||||||
|
<script>
|
||||||
|
/* particlesJS.load(@dom-id, @path-json, @callback (optional)); */
|
||||||
|
particlesJS.load('particles-js', '/static/js/particlesjs-config.json', function() {
|
||||||
|
console.log('callback - particles.js config loaded');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue