siru 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/siru/post.rb ADDED
@@ -0,0 +1,92 @@
1
+ module Siru
2
+ class Post
3
+ attr_reader :file_path, :front_matter, :content, :rendered_content
4
+
5
+ def initialize(file_path)
6
+ @file_path = file_path
7
+ parse_file
8
+ end
9
+
10
+ def title
11
+ @front_matter['title'] || File.basename(@file_path, '.md').tr('-', ' ').capitalize
12
+ end
13
+
14
+ def date
15
+ date_str = @front_matter['date']
16
+ return Date.today unless date_str
17
+
18
+ if date_str.is_a?(String)
19
+ Date.parse(date_str)
20
+ else
21
+ date_str
22
+ end
23
+ end
24
+
25
+ def draft?
26
+ @front_matter['draft'] == true
27
+ end
28
+
29
+ def slug
30
+ @front_matter['slug'] || File.basename(@file_path, '.md')
31
+ end
32
+
33
+ def url
34
+ "/posts/#{slug}/"
35
+ end
36
+
37
+ def summary
38
+ @front_matter['summary'] || @content.split("\n\n").first&.strip || ''
39
+ end
40
+
41
+ def tags
42
+ @front_matter['tags'] || []
43
+ end
44
+
45
+ private
46
+
47
+ def parse_file
48
+ raw_content = File.read(@file_path)
49
+
50
+ if raw_content.start_with?('+++')
51
+ # TOML front matter
52
+ parts = raw_content.split('+++', 3)
53
+ @front_matter = TOML.load(parts[1]) if parts[1]
54
+ @content = parts[2]&.strip || ''
55
+ elsif raw_content.start_with?('---')
56
+ # YAML front matter
57
+ parsed = FrontMatterParser.parse(raw_content)
58
+ @front_matter = parsed.front_matter
59
+ @content = parsed.content
60
+ else
61
+ @front_matter = {}
62
+ @content = raw_content
63
+ end
64
+
65
+ @front_matter ||= {}
66
+ @rendered_content = render_markdown(@content)
67
+ end
68
+
69
+ def render_markdown(content)
70
+ renderer = Redcarpet::Render::HTML.new(
71
+ filter_html: false,
72
+ no_intra_emphasis: true,
73
+ fenced_code_blocks: true,
74
+ autolink: true,
75
+ strikethrough: true,
76
+ superscript: true,
77
+ tables: true
78
+ )
79
+
80
+ markdown = Redcarpet::Markdown.new(renderer, {
81
+ autolink: true,
82
+ tables: true,
83
+ fenced_code_blocks: true,
84
+ strikethrough: true,
85
+ superscript: true,
86
+ no_intra_emphasis: true
87
+ })
88
+
89
+ markdown.render(content)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,57 @@
1
+ module Siru
2
+ class Server
3
+ def initialize(site, options = {})
4
+ @site = site
5
+ @options = options
6
+ @port = options[:port] || 3000
7
+ @watch = options[:watch] || false
8
+ @output_dir = 'public'
9
+ end
10
+
11
+ def start
12
+ puts "Starting Siru server on port #{@port}..."
13
+
14
+ # Build the site initially
15
+ builder = Builder.new(@site, @options)
16
+ builder.build
17
+
18
+ # Set up file watching if enabled
19
+ setup_watcher if @watch
20
+
21
+ # Start the web server
22
+ server = WEBrick::HTTPServer.new(
23
+ Port: @port,
24
+ DocumentRoot: @output_dir,
25
+ Logger: WEBrick::Log.new('/dev/null'),
26
+ AccessLog: []
27
+ )
28
+
29
+ trap('INT') { server.shutdown }
30
+
31
+ puts "Server running at http://localhost:#{@port}/"
32
+ puts "Press Ctrl+C to stop"
33
+
34
+ server.start
35
+ end
36
+
37
+ private
38
+
39
+ def setup_watcher
40
+ listener = Listen.to('.', only: /\.(md|toml|yaml|yml|liquid|html|css|js)$/) do |modified, added, removed|
41
+ puts "Files changed: #{(modified + added + removed).join(', ')}"
42
+ puts "Rebuilding..."
43
+
44
+ # Reload site configuration and rebuild
45
+ config = Config.load
46
+ @site = Site.new(config, @options)
47
+ builder = Builder.new(@site, @options)
48
+ builder.build
49
+
50
+ puts "Rebuild complete!"
51
+ end
52
+
53
+ listener.start
54
+ end
55
+ end
56
+ end
57
+
data/lib/siru/site.rb ADDED
@@ -0,0 +1,47 @@
1
+ module Siru
2
+ class Site
3
+ attr_reader :config, :posts, :theme
4
+
5
+ def initialize(config, options = {})
6
+ @config = config
7
+ @options = options
8
+ @theme = Theme.new(config['theme'])
9
+ @posts = load_posts
10
+ end
11
+
12
+ def title
13
+ @config['title']
14
+ end
15
+
16
+ def base_url
17
+ @config['baseURL']
18
+ end
19
+
20
+ def params
21
+ @config['params'] || {}
22
+ end
23
+
24
+ def language_code
25
+ @config['languageCode'] || 'en-us'
26
+ end
27
+
28
+ private
29
+
30
+ def load_posts
31
+ posts = []
32
+ content_dir = 'content'
33
+
34
+ return posts unless Dir.exist?(content_dir)
35
+
36
+ Dir.glob(File.join(content_dir, '**', '*.md')).each do |file|
37
+ post = Post.new(file)
38
+ # Include drafts if --draft option is set
39
+ if @options[:draft] || !post.draft?
40
+ posts << post
41
+ end
42
+ end
43
+
44
+ posts.sort_by(&:date).reverse
45
+ end
46
+ end
47
+ end
data/lib/siru/theme.rb ADDED
@@ -0,0 +1,56 @@
1
+ module Siru
2
+ class Theme
3
+ attr_reader :name, :path
4
+
5
+ def initialize(name)
6
+ @name = name
7
+ @path = find_theme_path(name)
8
+ end
9
+
10
+ def layout_path(layout_name)
11
+ if File.exist?(File.join(@path, 'layouts', "#{layout_name}.liquid"))
12
+ File.join(@path, 'layouts', "#{layout_name}.liquid")
13
+ else
14
+ # Fall back to built-in theme
15
+ builtin_path = File.join(__dir__, '..', '..', 'themes', @name, 'layouts', "#{layout_name}.liquid")
16
+ File.exist?(builtin_path) ? builtin_path : nil
17
+ end
18
+ end
19
+
20
+ def has_layout?(layout_name)
21
+ !layout_path(layout_name).nil?
22
+ end
23
+
24
+ def render_layout(layout_name, variables = {})
25
+ path = layout_path(layout_name)
26
+ return '' unless path
27
+
28
+ template = Liquid::Template.parse(File.read(path))
29
+ template.render(variables)
30
+ end
31
+
32
+ def static_files
33
+ static_path = File.join(@path, 'static')
34
+ return [] unless Dir.exist?(static_path)
35
+
36
+ Dir.glob(File.join(static_path, '**', '*')).select { |f| File.file?(f) }
37
+ end
38
+
39
+ private
40
+
41
+ def find_theme_path(name)
42
+ # Check local themes directory first
43
+ local_path = File.join('themes', name)
44
+ return File.expand_path(local_path) if Dir.exist?(local_path)
45
+
46
+ # Fall back to built-in theme
47
+ builtin_path = File.join(__dir__, '..', '..', 'themes', name)
48
+ return File.expand_path(builtin_path) if Dir.exist?(builtin_path)
49
+
50
+ # Create basic theme structure if not found
51
+ FileUtils.mkdir_p(File.join('themes', name, 'layouts'))
52
+ FileUtils.mkdir_p(File.join('themes', name, 'static'))
53
+ File.expand_path(File.join('themes', name))
54
+ end
55
+ end
56
+ end
data/lib/siru.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'redcarpet'
2
+ require 'liquid'
3
+ require 'toml'
4
+ require 'parslet'
5
+ require 'sassc'
6
+ require 'listen'
7
+ require 'webrick'
8
+ require 'front_matter_parser'
9
+ require 'fileutils'
10
+ require 'pathname'
11
+ require 'yaml'
12
+
13
+ require_relative 'siru/cli'
14
+ require_relative 'siru/site'
15
+ require_relative 'siru/post'
16
+ require_relative 'siru/theme'
17
+ require_relative 'siru/server'
18
+ require_relative 'siru/builder'
19
+ require_relative 'siru/config'
20
+
21
+ module Siru
22
+ VERSION = "0.3.0"
23
+ end
data/siru.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "siru"
3
+ spec.version = "0.3.0"
4
+ spec.authors = ["Tim Apple"]
5
+ spec.email = ["tim.apple@hey.com"]
6
+ spec.summary = "A Hugo-inspired static site generator built in Ruby"
7
+ spec.description = "Siru is a fast, flexible static site generator inspired by Hugo, built in Ruby with support for themes, markdown processing, and live reloading."
8
+ spec.homepage = "https://github.com/timappledotcom/siru"
9
+ spec.license = "GPL-3.0"
10
+ spec.required_ruby_version = ">= 3.0.0"
11
+
12
+ spec.files = Dir.glob("{lib,bin,themes,templates}/**/*") + %w[README.md Gemfile siru.gemspec]
13
+ spec.bindir = "bin"
14
+ spec.executables = ["siru"]
15
+ spec.require_paths = ["lib"]
16
+
17
+ spec.add_dependency "redcarpet", "~> 3.6"
18
+ spec.add_dependency "liquid", "~> 5.4"
19
+ spec.add_dependency "toml", "~> 0.3"
20
+ spec.add_dependency "sassc", "~> 2.4"
21
+ spec.add_dependency "listen", "~> 3.8"
22
+ spec.add_dependency "webrick", "~> 1.8"
23
+ spec.add_dependency "front_matter_parser", "~> 1.0"
24
+ spec.add_dependency "base64"
25
+ spec.add_dependency "logger"
26
+ spec.add_dependency "parslet"
27
+
28
+ spec.add_development_dependency "rspec", "~> 3.12"
29
+ spec.add_development_dependency "rubocop", "~> 1.56"
30
+ end
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html lang="{{ site.language_code }}" style="--bg: {{ bg_color }}">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{ page_title }} - {{ site.title }}</title>
7
+ <link rel="stylesheet" href="/assets/style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ </head>
10
+ <body class="bg-[--bg] text-black antialiased duration-200 ease-out dark:text-white">
11
+ <header class="mx-auto max-w-3xl px-8 py-4">
12
+ <nav class="flex items-center justify-between">
13
+ <a href="/" class="text-xl font-bold">{{ site.title }}</a>
14
+ <div class="flex space-x-4">
15
+ {% if site.params.twitter %}
16
+ <a href="https://twitter.com/{{ site.params.twitter }}" class="text-blue-500 hover:text-blue-600">Twitter</a>
17
+ {% endif %}
18
+ {% if site.params.github %}
19
+ <a href="https://github.com/{{ site.params.github }}" class="text-gray-700 hover:text-gray-900">GitHub</a>
20
+ {% endif %}
21
+ {% if site.params.mastodon %}
22
+ <a href="{{ site.params.mastodon }}" class="text-purple-600 hover:text-purple-700">Mastodon</a>
23
+ {% endif %}
24
+ {% if site.params.bluesky %}
25
+ <a href="https://bsky.app/profile/{{ site.params.bluesky }}" class="text-sky-600 hover:text-sky-700">Bluesky</a>
26
+ {% endif %}
27
+ </div>
28
+ </nav>
29
+ </header>
30
+
31
+ <main class="prose prose-neutral dark:prose-invert mx-auto min-h-[calc(100vh-9rem)] max-w-3xl px-8 pt-14 pb-16">
32
+ {{ content }}
33
+ </main>
34
+
35
+ <footer class="mx-auto max-w-3xl px-8 py-4 text-center text-sm text-gray-600 dark:text-gray-400">
36
+ <p>&copy; {{ "now" | date: "%Y" }} {{ site.title }}. Powered by <a href="https://github.com/timappledotcom/siru" class="text-blue-600 hover:text-blue-700">Siru</a>.</p>
37
+ </footer>
38
+ </body>
39
+ </html>
@@ -0,0 +1,17 @@
1
+ {% if site.params.bio %}
2
+ <div class="mb-12 -mt-2 flex items-center">
3
+ <div>
4
+ <div class="mt-3 mb-1 text-2xl font-medium text-black dark:text-white">{{ site.title }}</div>
5
+ <div class="break-words">{{ site.params.bio }}</div>
6
+ </div>
7
+ </div>
8
+ {% endif %}
9
+
10
+ {% for post in posts %}
11
+ <section class="relative my-10 first-of-type:mt-0 last-of-type:mb-0">
12
+ <h2 class="my-0">{{ post.title }}</h2>
13
+ <time class="text-xs antialiased opacity-60">{{ post.date | date: "%B %d, %Y" }}</time>
14
+ <div class="mt-2">{{ post.summary }}</div>
15
+ <a class="absolute inset-0 text-[0px]" href="{{ post.url }}">{{ post.title }}</a>
16
+ </section>
17
+ {% endfor %}
@@ -0,0 +1,13 @@
1
+ {% layout "default/baseof" %} {% block "contents" %}
2
+ <main>
3
+ <article>
4
+ <header>
5
+ <h1>{{ post.title }}</h1>
6
+ <time>{{ post.date | date: "%B %d, %Y" }}</time>
7
+ </header>
8
+ <section>{{ post.rendered_content }}</section>
9
+ <footer>Tags: {% for tag in post.tags %} <a href="/tags/{{ tag }}">{{ tag }}</a> {% unless forloop.last %}, {% endunless %}{% endfor %}
10
+ </footer>
11
+ </article>
12
+ </main>
13
+ {% endblock %}
@@ -0,0 +1,18 @@
1
+ <article>
2
+ <header class="mb-14">
3
+ <h1 class="my-0! pb-2.5">{{ post.title }}</h1>
4
+ <div class="text-xs antialiased opacity-60">
5
+ <time>{{ post.date | date: "%B %d, %Y" }}</time>
6
+ </div>
7
+ </header>
8
+
9
+ <section>{{ post.rendered_content }}</section>
10
+
11
+ {% if post.tags and post.tags.size > 0 %}
12
+ <footer class="mt-12 flex flex-wrap">
13
+ {% for tag in post.tags %}
14
+ <a class="mb-1.5 rounded-lg bg-black/[3%] px-5 py-1 no-underline hover:bg-black/[6%] ltr:mr-1.5 rtl:ml-1.5 dark:bg-white/[8%] dark:hover:bg-white/[12%]" href="/tags/{{ tag | downcase | replace: ' ', '-' }}">{{ tag }}</a>
15
+ {% endfor %}
16
+ </footer>
17
+ {% endif %}
18
+ </article>
@@ -0,0 +1,24 @@
1
+ body {
2
+ font-family: 'Helvetica Neue', Arial, sans-serif;
3
+ background-color: #faf8f1;
4
+ color: #333;
5
+ }
6
+
7
+ article {
8
+ max-width: 800px;
9
+ margin: 0 auto;
10
+ padding: 16px;
11
+ }
12
+
13
+ h1, h2, h3, h4, h5, h6 {
14
+ color: #333;
15
+ }
16
+
17
+ a {
18
+ color: #0066cc;
19
+ }
20
+
21
+ a:hover {
22
+ color: #004999;
23
+ text-decoration: underline;
24
+ }
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html lang="{{ site.language_code }}" style="--bg: {{ bg_color }}">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{ page_title }} - {{ site.title }}</title>
7
+ <link rel="stylesheet" href="/assets/style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ </head>
10
+ <body class="bg-[--bg] text-black antialiased duration-200 ease-out dark:text-white">
11
+ <header class="mx-auto max-w-3xl px-8 py-4">
12
+ <nav class="flex items-center justify-between">
13
+ <a href="/" class="text-xl font-bold">{{ site.title }}</a>
14
+ <div class="flex space-x-4">
15
+ {% if site.params.social.x %}
16
+ <a href="{{ site.params.social.x }}" class="text-blue-500 hover:text-blue-600">X</a>
17
+ {% endif %}
18
+ {% if site.params.social.mastodon %}
19
+ <a href="{{ site.params.social.mastodon }}" class="text-purple-600 hover:text-purple-700">Mastodon</a>
20
+ {% endif %}
21
+ {% if site.params.social.bluesky %}
22
+ <a href="{{ site.params.social.bluesky }}" class="text-sky-600 hover:text-sky-700">Bluesky</a>
23
+ {% endif %}
24
+ {% if site.params.social.nostr %}
25
+ <a href="{{ site.params.social.nostr }}" class="text-yellow-600 hover:text-yellow-700">Nostr</a>
26
+ {% endif %}
27
+ </div>
28
+ </nav>
29
+ </header>
30
+
31
+ <main class="prose prose-neutral dark:prose-invert mx-auto min-h-[calc(100vh-9rem)] max-w-3xl px-8 pt-14 pb-16">
32
+ {{ content }}
33
+ </main>
34
+
35
+ <footer class="mx-auto max-w-3xl px-8 py-4 text-center text-sm text-gray-600 dark:text-gray-400">
36
+ <p>&copy; {{ "now" | date: "%Y" }} {{ site.title }}. Powered by <a href="https://github.com/timappledotcom/siru" class="text-blue-600 hover:text-blue-700">Siru</a>.</p>
37
+ </footer>
38
+ </body>
39
+ </html>
@@ -0,0 +1,17 @@
1
+ {% if site.params.bio %}
2
+ <div class="mb-12 -mt-2 flex items-center">
3
+ <div>
4
+ <div class="mt-3 mb-1 text-2xl font-medium text-black dark:text-white">{{ site.title }}</div>
5
+ <div class="break-words">{{ site.params.bio }}</div>
6
+ </div>
7
+ </div>
8
+ {% endif %}
9
+
10
+ {% for post in posts %}
11
+ <section class="relative my-10 first-of-type:mt-0 last-of-type:mb-0">
12
+ <h2 class="my-0">{{ post.title }}</h2>
13
+ <time class="text-xs antialiased opacity-60">{{ post.date | date: "%B %d, %Y" }}</time>
14
+ <div class="mt-2">{{ post.summary }}</div>
15
+ <a class="absolute inset-0 text-[0px]" href="{{ post.url }}">{{ post.title }}</a>
16
+ </section>
17
+ {% endfor %}
@@ -0,0 +1,13 @@
1
+ {% layout "default/baseof" %} {% block "contents" %}
2
+ <main>
3
+ <article>
4
+ <header>
5
+ <h1>{{ post.title }}</h1>
6
+ <time>{{ post.date | date: "%B %d, %Y" }}</time>
7
+ </header>
8
+ <section>{{ post.rendered_content }}</section>
9
+ <footer>Tags: {% for tag in post.tags %} <a href="/tags/{{ tag }}">{{ tag }}</a> {% unless forloop.last %}, {% endunless %}{% endfor %}
10
+ </footer>
11
+ </article>
12
+ </main>
13
+ {% endblock %}
@@ -0,0 +1,18 @@
1
+ <article>
2
+ <header class="mb-14">
3
+ <h1 class="my-0! pb-2.5">{{ post.title }}</h1>
4
+ <div class="text-xs antialiased opacity-60">
5
+ <time>{{ post.date | date: "%B %d, %Y" }}</time>
6
+ </div>
7
+ </header>
8
+
9
+ <section>{{ post.rendered_content }}</section>
10
+
11
+ {% if post.tags and post.tags.size > 0 %}
12
+ <footer class="mt-12 flex flex-wrap">
13
+ {% for tag in post.tags %}
14
+ <a class="mb-1.5 rounded-lg bg-black/[3%] px-5 py-1 no-underline hover:bg-black/[6%] ltr:mr-1.5 rtl:ml-1.5 dark:bg-white/[8%] dark:hover:bg-white/[12%]" href="/tags/{{ tag | downcase | replace: ' ', '-' }}">{{ tag }}</a>
15
+ {% endfor %}
16
+ </footer>
17
+ {% endif %}
18
+ </article>
@@ -0,0 +1,73 @@
1
+ body {
2
+ font-family: 'Helvetica Neue', Arial, sans-serif;
3
+ background-color: #faf8f1;
4
+ color: #333;
5
+ }
6
+
7
+ article {
8
+ max-width: 800px;
9
+ margin: 0 auto;
10
+ padding: 16px;
11
+ }
12
+
13
+ h1, h2, h3, h4, h5, h6 {
14
+ color: #333;
15
+ }
16
+
17
+ a {
18
+ color: #0066cc;
19
+ }
20
+
21
+ a:hover {
22
+ color: #004999;
23
+ text-decoration: underline;
24
+ }
25
+
26
+ /* Catppuccin Mocha Dark Theme Overrides */
27
+ .prose p {
28
+ margin-top: 1.25em !important;
29
+ margin-bottom: 1.25em !important;
30
+ color: #cdd6f4 !important;
31
+ }
32
+
33
+ .prose p:first-child {
34
+ margin-top: 0 !important;
35
+ }
36
+
37
+ .prose p:last-child {
38
+ margin-bottom: 0 !important;
39
+ }
40
+
41
+ /* Additional dark theme text styling */
42
+ .prose {
43
+ color: #cdd6f4;
44
+ }
45
+
46
+ .prose h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6 {
47
+ color: #cdd6f4;
48
+ }
49
+
50
+ .prose a {
51
+ color: #89b4fa;
52
+ }
53
+
54
+ .prose a:hover {
55
+ color: #b4befe;
56
+ }
57
+
58
+ .prose code {
59
+ color: #f38ba8;
60
+ background-color: #313244;
61
+ padding: 0.2em 0.4em;
62
+ border-radius: 0.25rem;
63
+ }
64
+
65
+ .prose pre {
66
+ background-color: #313244;
67
+ color: #cdd6f4;
68
+ }
69
+
70
+ .prose blockquote {
71
+ border-left-color: #585b70;
72
+ color: #a6adc8;
73
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="1.1 1 21.5 21.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M6.335 5.144c-1.654 -1.199 -4.335 -2.127 -4.335 .826c0 .59 .35 4.953 .556 5.661c.713 2.463 3.13 2.75 5.444 2.369c-4.045 .665 -4.889 3.208 -2.667 5.41c1.03 1.018 1.913 1.59 2.667 1.59c2 0 3.134 -2.769 3.5 -3.5c.333 -.667 .5 -1.167 .5 -1.5c0 .333 .167 .833 .5 1.5c.366 .731 1.5 3.5 3.5 3.5c.754 0 1.637 -.571 2.667 -1.59c2.222 -2.203 1.378 -4.746 -2.667 -5.41c2.314 .38 4.73 .094 5.444 -2.369c.206 -.708 .556 -5.072 .556 -5.661c0 -2.953 -2.68 -2.025 -4.335 -.826c-2.293 1.662 -4.76 5.048 -5.665 6.856c-.905 -1.808 -3.372 -5.194 -5.665 -6.856z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="3.5 3.5 25 25"><path d="M 15.9375 4.03125 C 12.917 4.0435 9.9179219 4.4269844 8.3574219 5.1464844 C 8.3574219 5.1464844 5 6.6748594 5 11.880859 C 5 18.077859 4.9955 25.860234 10.5625 27.365234 C 12.6945 27.938234 14.527953 28.061562 16.001953 27.976562 C 18.676953 27.825562 20 27.005859 20 27.005859 L 19.910156 25.029297 C 19.910156 25.029297 18.176297 25.640313 16.029297 25.570312 C 13.902297 25.495313 11.6615 25.335688 11.3125 22.679688 C 11.2805 22.432688 11.264625 22.182594 11.265625 21.933594 C 15.772625 23.052594 19.615828 22.420969 20.673828 22.292969 C 23.627828 21.933969 26.199344 20.081672 26.527344 18.388672 C 27.041344 15.720672 26.998047 11.880859 26.998047 11.880859 C 26.998047 6.6748594 23.646484 5.1464844 23.646484 5.1464844 C 22.000984 4.3779844 18.958 4.019 15.9375 4.03125 z M 12.705078 8.0019531 C 13.739953 8.0297031 14.762578 8.4927031 15.392578 9.4707031 L 16.001953 10.505859 L 16.609375 9.4707031 C 17.874375 7.5037031 20.709594 7.6264375 22.058594 9.1484375 C 23.302594 10.596438 23.025391 11.531 23.025391 18 L 23.025391 18.001953 L 20.578125 18.001953 L 20.578125 12.373047 C 20.578125 9.7380469 17.21875 9.6362812 17.21875 12.738281 L 17.21875 16 L 14.787109 16 L 14.787109 12.738281 C 14.787109 9.6362812 11.429688 9.7360938 11.429688 12.371094 L 11.429688 18 L 8.9765625 18 C 8.9765625 11.526 8.7043594 10.585438 9.9433594 9.1484375 C 10.622859 8.3824375 11.670203 7.9742031 12.705078 8.0019531 z"/></svg>
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 875 875">
3
+ <defs>
4
+ <style>
5
+ .cls-1 {
6
+ stroke: #000;
7
+ stroke-miterlimit: 10;
8
+ stroke-width: 6px;
9
+ }
10
+ </style>
11
+ </defs>
12
+ <path class="cls-1" d="m684.72,485.57c.22,12.59-11.93,51.47-38.67,81.3-26.74,29.83-56.02,20.85-58.42,20.16s-3.09-4.46-7.89-3.77-9.6,6.17-18.86,7.2-17.49,1.71-26.06-1.37c-4.46.69-5.14.71-7.2,2.24s-17.83,10.79-21.6,11.47c0,7.2-1.37,44.57,0,55.89s3.77,25.71,7.54,36c3.77,10.29,2.74,10.63,7.54,9.94s13.37.34,15.77,4.11c2.4,3.77,1.37,6.51,5.49,8.23s60.69,17.14,99.43,19.2c26.74.69,42.86,2.74,52.12,19.54,1.37,7.89,7.54,13.03,11.31,14.06s8.23,2.06,12,5.83,1.03,8.23,5.49,11.66c4.46,3.43,14.74,8.57,25.37,13.71,10.63,5.14,15.09,13.37,15.77,16.11s1.71,10.97,1.71,10.97c0,0-8.91,0-10.97-2.06s-2.74-5.83-2.74-5.83c0,0-6.17,1.03-7.54,3.43s.69,2.74-7.89.69-11.66-3.77-18.17-8.57c-6.51-4.8-16.46-17.14-25.03-16.8,4.11,8.23,5.83,8.23,10.63,10.97s8.23,5.83,8.23,5.83l-7.2,4.46s-4.46,2.06-14.74-.69-11.66-4.46-12.69-10.63,0-9.26-2.74-14.4-4.11-15.77-22.29-21.26c-18.17-5.49-66.52-21.26-100.12-24.69s-22.63-2.74-28.11-1.37-15.77,4.46-26.4-1.37c-10.63-5.83-16.8-13.71-17.49-20.23s-1.71-10.97,0-19.2,3.43-19.89,1.71-26.74-14.06-55.89-19.89-64.12c-13.03,1.03-50.74-.69-50.74-.69,0,0-2.4-.69-17.49,5.83s-36.48,13.76-46.77,19.93-14.4,9.7-16.12,13.13c.12,3-1.23,7.72-2.79,9.06s-12.48,2.42-12.48,2.42c0,0-5.85,5.86-8.25,9.97-6.86,9.6-55.2,125.14-66.52,149.83-13.54,32.57-9.77,27.43-37.71,27.43s-8.06.3-8.06.3c0,0-12.34,5.88-16.8,5.88s-18.86-2.4-26.4,0-16.46,9.26-23.31,10.29-4.95-1.34-8.38-3.74c-4-.21-14.27-.12-14.27-.12,0,0,1.74-6.51,7.91-10.88,8.23-5.83,25.37-16.11,34.63-21.26s17.49-7.89,23.31-9.26,18.51-6.17,30.51-9.94,19.54-8.23,29.83-31.54c10.29-23.31,50.4-111.43,51.43-116.23.63-2.96,3.73-6.48,4.8-15.09.66-5.35-2.49-13.04,1.71-22.63,10.97-25.03,21.6-20.23,26.4-20.23s17.14.34,26.4-1.37,15.43-2.74,24.69-7.89,11.31-8.91,11.31-8.91l-19.89-3.43s-18.51.69-25.03-4.46-15.43-15.77-15.43-15.77l-7.54-7.2,1.03,8.57s-5.14-8.91-6.51-10.29-8.57-6.51-11.31-11.31-7.54-25.03-7.54-25.03l-6.17,13.03-1.71-18.86-5.14,7.2-2.74-16.11-4.8,8.23-3.43-14.4-5.83,4.46-2.4-10.29-5.83-3.43s-14.06-9.26-16.46-9.6-4.46,3.43-4.46,3.43l1.37,12-12.2-6.27-7-11.9s2.36,4.01-9.62,7.53c-20.55,0-21.89-2.28-24.93-3.94-1.31-6.56-5.57-10.11-5.57-10.11h-20.57l-.34-6.86-7.89,3.09.69-10.29h-14.06l1.03-11.31h-8.91s3.09-9.26,25.71-22.97,25.03-16.46,46.29-17.14c21.26-.69,32.91,2.74,46.29,8.23s38.74,13.71,43.89,17.49c11.31-9.94,28.46-19.89,34.29-19.89,1.03-2.4,6.19-12.33,17.96-17.6,35.31-15.81,108.13-34,131.53-35.54,31.2-2.06,7.89-1.37,39.09,2.06,31.2,3.43,54.17,7.54,69.6,12.69,12.58,4.19,25.03,9.6,34.29,2.06,4.33-1.81,11.81-1.34,17.83-5.14,30.69-25.09,34.72-32.35,43.63-41.95s20.14-24.91,22.54-45.14,4.46-58.29-10.63-88.12-28.8-45.26-34.63-69.26c-5.83-24-8.23-61.03-6.17-73.03,2.06-12,5.14-22.29,6.86-30.51s9.94-14.74,19.89-16.46c9.94-1.71,17.83,1.37,22.29,4.8,4.46,3.43,11.65,6.28,13.37,10.29.34,1.71-1.37,6.51,8.23,8.23,9.6,1.71,16.05,4.16,16.05,4.16,0,0,15.64,4.29,3.11,7.73-12.69,2.06-20.52-.71-24.29,1.69s-7.21,10.08-9.61,11.1-7.2.34-12,4.11-9.6,6.86-12.69,14.4-5.49,15.77-3.43,26.74,8.57,31.54,14.4,43.2c5.83,11.66,20.23,40.8,24.34,47.66s15.77,29.49,16.8,53.83,1.03,44.23,0,54.86-10.84,51.65-35.53,85.94c-8.16,14.14-23.21,31.9-24.67,35.03-1.45,3.13-3.02,4.88-1.61,7.65,4.62,9.05,12.87,22.13,14.71,29.22,2.29,6.64,6.99,16.13,7.22,28.72Z"/>
13
+ </svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="4 4 40 40"><path d="M 12.5 6 C 8.9280619 6 6 8.9280619 6 12.5 L 6 35.5 C 6 39.071938 8.9280619 42 12.5 42 L 35.5 42 C 39.071938 42 42 39.071938 42 35.5 L 42 12.5 C 42 8.9280619 39.071938 6 35.5 6 L 12.5 6 z M 12.5 9 L 35.5 9 C 37.450062 9 39 10.549938 39 12.5 L 39 35.5 C 39 37.450062 37.450062 39 35.5 39 L 12.5 39 C 10.549938 39 9 37.450062 9 35.5 L 9 12.5 C 9 10.549938 10.549938 9 12.5 9 z M 13.828125 14 L 21.564453 25.056641 L 13.822266 34 L 15.865234 34 L 22.46875 26.351562 L 27.820312 34 L 34.257812 34 L 26.025391 22.234375 L 33.136719 14 L 31.136719 14 L 25.123047 20.943359 L 20.265625 14 L 13.828125 14 z M 16.935547 15.695312 L 19.498047 15.695312 L 31.150391 32.304688 L 28.587891 32.304688 L 16.935547 15.695312 z"/></svg>