diff --git a/dragon_fire.code-workspace b/dragon_fire.code-workspace
new file mode 100644
index 0000000..533b5a2
--- /dev/null
+++ b/dragon_fire.code-workspace
@@ -0,0 +1,11 @@
+{
+ "folders": [
+ {
+ "path": "."
+ },
+ {
+ "path": "../dragon_fire_content"
+ }
+ ],
+ "settings": {}
+}
\ No newline at end of file
diff --git a/www/fontawesome.php b/www/fontawesome.php
index 91b82d5..924e1f7 100644
--- a/www/fontawesome.php
+++ b/www/fontawesome.php
@@ -1,11 +1,16 @@
' ',
- 'image' => ' ',
- 'images' => ' ',
- 'folder' => ' ',
- 'rss' => ' '
+ 'bars' => ' ',
+ 'markdown' => ' ',
+ 'image' => ' ',
+ 'images' => ' ',
+ 'turn-up' => ' ',
+ 'rectangle-list' => ' ',
+ 'folder-tree' => ' ',
+ 'folder' => ' ',
+ 'folder-open' => ' ',
+ 'rss' => ' '
];
?>
\ No newline at end of file
diff --git a/www/mysql_adapter.php b/www/mysql_adapter.php
index 3d845b6..7a98c09 100644
--- a/www/mysql_adapter.php
+++ b/www/mysql_adapter.php
@@ -268,7 +268,7 @@ class MySQLAdapter {
];
$qry = "
- SELECT post_path, post_metadata
+ SELECT *
FROM posts
WHERE MATCH(post_tags) AGAINST (? IN BOOLEAN MODE)
";
@@ -386,7 +386,8 @@ class MySQLAdapter {
$post_data ??= ['found' => false];
$post_data['post_path'] = $post_path;
-
+ $post_data['parent_path'] = dirname($post_path);
+
$post_data = $this->_normalize_post_data($post_data);
if(!$post_data['found']) {
@@ -403,6 +404,19 @@ class MySQLAdapter {
return $post_data;
}
+ function get_markdown_for_id($id) {
+ $qry = "SELECT post_content
+ FROM posts
+ WHERE post_id = ? AND host = ?
+ ";
+
+ $post_data = $this->_exec($qry, "is", $id,
+ $this->SITE_CONFIG['HTTP_HOST']
+ )->fetch_assoc();
+
+ return $post_data['post_content'];
+ }
+
function get_subposts_by_path($path) {
global $sql;
diff --git a/www/post.php b/www/post.php
new file mode 100644
index 0000000..872b75f
--- /dev/null
+++ b/www/post.php
@@ -0,0 +1,200 @@
+
+ -1,
+ 'post_path' => '/404.md',
+ 'post_title' => '404 Page',
+ 'post_metadata' => [
+ 'type' => '404'
+ ]
+ ];
+ }
+
+ public static function _deduce_type($path) {
+ $ext = pathinfo($path, PATHINFO_EXTENSION);
+
+ if(preg_match("/\.(\w+)\.md$/", $path, $ext_match)) {
+ $ext = $ext_match[1];
+ }
+
+ $ext_mapping = [
+ '' => 'directory',
+ 'md' => 'text/markdown',
+ 'png' => 'image',
+ 'jpg' => 'image',
+ 'jpeg' => 'image'
+ ];
+
+ return $ext_mapping[$ext] ?? '?';
+ }
+
+ public static function _deduce_icon($type) {
+ $icon_mapping = [
+ '' => 'question',
+ 'text/markdown' => 'markdown',
+ 'blog' => 'markdown',
+ 'blog_list' => 'rectangle-list',
+ 'directory' => 'folder',
+ 'gallery' => 'images',
+ 'image' => 'image'
+ ];
+
+ return $icon_mapping[$type] ?? 'unknown';
+ }
+
+ function __construct($post_handler, $sql_row) {
+ $this->handler = $post_handler;
+
+ $this->content_html = null;
+ $this->content_markdown = null;
+
+ $sql_meta = null;
+
+ if(!isset($sql_row) or !$sql_row['found']) {
+ $sql_row = $this->_generate_404($sql_row);
+ $sql_meta = $sql_row['post_metadata'];
+ }
+
+ $sql_meta = $sql_row['post_metadata'];
+ if(is_string($sql_meta)) {
+ $sql_meta = json_decode($sql_meta, true);
+ }
+
+ unset($sql_meta['settings']);
+
+ $this->sql_row = $sql_row;
+ $this->sql_meta = $sql_meta ?? [];
+
+ $sql_settings = json_decode($sql_row['post_settings_cache'], true)
+ ?? $this->handler->get_settings_for_path($sql_row['post_path']);
+
+ $data = [
+ 'id' => $sql_row['post_id'],
+ 'path' => $sql_row['post_path'],
+ 'url' => 'https://' . $sql_row['host'] . $sql_row['post_path'],
+ 'created_at' => $sql_row['post_create_time'] ?? '',
+ 'updated_at' => $sql_row['post_update_time'] ?? '',
+ 'view_count' => $sql_row['post_access_count'] ?? 0
+ ];
+
+ $data['title'] = $sql_meta['title'] ?? $sql_row['title'];
+ unset($sql_meta['title']);
+
+ $data['tags'] = $sql_meta['tags'] ?? [];
+ unset($sql_meta['tags']);
+
+ $data['type'] = $sql_meta['type']
+ ?? self::_deduce_type($sql_row['post_path']);
+ unset($sql_meta['type']);
+
+ $data['icon'] = $sql_meta['icon']
+ ?? self::_deduce_icon($data['type']);
+ unset($sql_meta['icon']);
+
+ if(isset($sql_meta['media_url'])) {
+ $data['media_url'] = $sql_meta['media_url'];
+ $data['thumb_url'] = $sql_meta['thumb_url'] ?? $data['media_url'];
+
+ unset($sql_meta['media_url']);
+ unset($sql_meta['thumb_url']);
+ }
+
+ $data['banners'] = $sql_meta['banners']
+ ?? $sql_settings['banners']
+ ?? self::$default_banners;
+
+ unset($sql_meta['banners']);
+ unset($sql_settings['banners']);
+
+ $data['preview_image'] = $sql_meta['preview_image'] ?? $data['banners'][0]['src'] ?? null;
+ unset($sql_meta['preview_image']);
+
+ $data['brief'] = $sql_meta['brief']
+ ?? $data['title'];
+ unset($sql_meta['brief']);
+
+ $data['excerpt'] = $sql_meta['excerpt']
+ ?? substr($sql_row['post_content'], 0, 256);
+
+ $data['metadata'] = $sql_meta;
+ $data['settings'] = $sql_settings;
+
+ $this->data = $data;
+ }
+
+ public function __get($name) {
+ if($name == 'html') {
+ return $this->get_html();
+ }
+ if($name == 'markdown') {
+ return $this->get_markdown();
+ }
+ if($name == 'json') {
+ return $this->to_json();
+ }
+
+ return $this->data[$name];
+ }
+
+ public function get_html() {
+ $fn = self::$markdown_engine;
+ $this->content_html ??= $fn($this);
+
+ return $this->content_html;
+ }
+ public function get_markdown() {
+ $this->content_markdown ??=
+ $this->handler->get_markdown_for_id($this->data['id']);
+
+ return $this->content_markdown;
+ }
+
+ public function to_json($with_markdown = false, $with_html = false) {
+ $out_data = $this->data;
+
+ if($with_markdown) {
+ $out_data['markdown'] = $this->get_markdown();
+ }
+ if($with_html) {
+ $out_data['html'] = $this->get_html();
+ }
+
+ return json_encode($out_data);
+ }
+
+
+ public function get_parent_post() {
+ $parent_path = dirname($this->data['path']);
+ if($parent_path == '')
+ return null;
+
+ $this->parent_post ??= new PostData($this->handler,
+ $this->handler->get_post_by_path($parent_path));
+
+ return $this->parent_post;
+ }
+
+ public function get_child_posts() {
+ if(isset($this->child_posts))
+ return $this->child_posts;
+
+ $child_data = $this->handler->get_subposts_by_path($this->data['path']);
+
+ $this->child_posts = array_map(function($data) {
+ return new PostData($this->handler, $data);
+ }, $child_data);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/www/post_adapter.php b/www/post_adapter.php
index 65b4ced..05927e4 100644
--- a/www/post_adapter.php
+++ b/www/post_adapter.php
@@ -36,8 +36,10 @@ class PostHandler extends MySQLAdapter {
$icon_mapping = [
'' => 'question',
'text/markdown' => 'markdown',
+ 'blog' => 'markdown',
'directory' => 'folder',
'gallery' => 'images',
+ 'blog_list' => 'rectangle-list',
'image' => 'image'
];
@@ -97,6 +99,10 @@ class PostHandler extends MySQLAdapter {
}
function save_markdown_post($post_path, $post_data) {
+ if(basename($post_path) == "README.md") {
+ $post_path = dirname($post_path);
+ }
+
$frontmatter_post = YamlFrontMatter::parse($post_data);
$post_path = $this->_sanitize_path($post_path);
@@ -110,29 +116,18 @@ class PostHandler extends MySQLAdapter {
$post_metadata['tags'][]= 'type:' . $post_metadata['type'];
- if(basename($post_path) == "README.md") {
- $readme_metadata = [];
- if(isset($post_metadata['settings'])) {
- $readme_metadata['settings'] = $post_metadata['settings'];
- }
- if(isset($post_metadata['directory'])) {
- $readme_metadata = $post_metadata['directory'];
- }
-
- $this->update_or_create_post(dirname($post_path),
- $readme_metadata, $post_content);
- }
-
$this->update_or_create_post($post_path, $post_metadata, $post_content);
}
function handle_upload($post_path, $file_path) {
+ $post_path = $this->_sanitize_path($post_path);
$ext = pathinfo($post_path, PATHINFO_EXTENSION);
switch($ext) {
case "md":
$this->save_markdown_post($post_path, file_get_contents($file_path));
+ $this->make_post_directory(dirname($post_path));
move_uploaded_file($file_path, $this->data_directory . $post_path);
break;
default:
diff --git a/www/router.php b/www/router.php
index 18c4641..8e0d1e7 100644
--- a/www/router.php
+++ b/www/router.php
@@ -5,6 +5,9 @@ $data_time_start = microtime(true);
require_once 'vendor/autoload.php';
require_once 'post_adapter.php';
+
+require_once 'post.php';
+
require_once 'fontawesome.php';
require_once 'dergdown.php';
@@ -40,6 +43,10 @@ function dergdown_to_html($text) {
return $Parsedown->text($text);
}
+function post_to_html($post) {
+ return dergdown_to_html($post->markdown);
+}
+PostData::$markdown_engine = "post_to_html";
function deduce_user_agent() {
$real_agent=$_SERVER['HTTP_USER_AGENT'];
@@ -126,6 +133,25 @@ function render_twig($template, $args = []) {
echo $twig->render($template, $args);
}
+function try_render_ajax($SURI) {
+ global $adapter;
+
+ $match = null;
+ preg_match('/^\/ajax\/([^\/]+)(.*)$/', $SURI, $match);
+
+ if(!isset($match)) {
+ die();
+ }
+
+ $post = $adapter->get_post_by_path($match[2]);
+ $subposts = $adapter->get_subposts_by_path($match[2]);
+
+ echo render_twig('ajax/' . $match[1] . '.html', [
+ "post" => $post,
+ "subposts" => $subposts
+ ]);
+}
+
function try_render_post($SURI) {
global $adapter;
@@ -160,6 +186,7 @@ function try_render_post($SURI) {
break;
+ case 'blog':
case 'text/markdown':
echo render_twig('post_types/markdown.html', [
"post" => $post
@@ -185,6 +212,30 @@ function try_render_post($SURI) {
]);
break;
+ case 'blog_list':
+ if(preg_match('/^(.*[^\/])((?:#.*)?)$/', $SURI, $match)) {
+ header('Location: ' . $match[1] . '/' . $match[2]);
+
+ die();
+ }
+
+ $search_query = $post['post_metadata']['search_tags'] ??
+ ('+type:blog +path:' . $post['post_path'] . '/*');
+
+ $search_result = $adapter->perform_post_search($search_query);
+
+ $search_result = array_map(function($key) {
+ $post = new PostData($adapter, $key);
+ return $post->data;
+ }, $search_result['results']);
+
+ echo render_twig('post_types/blog_list.html', [
+ "post" => $post,
+ "subposts" => $adapter->get_subposts_by_path($SURI),
+ "blog_posts" => $search_result
+ ]);
+ break;
+
case 'image':
echo render_twig('post_types/image.html', [
"post" => $post,
@@ -233,7 +284,9 @@ function generate_website($SURI) {
} elseif(preg_match('/^\/api\/posts(.*)$/', $SURI, $match)) {
header('Content-Type: application/json');
- echo json_encode($adapter->get_post_by_path($match[1]));
+
+ $post = new PostData($adapter, $adapter->get_post_by_path($match[1]));
+ echo $post->to_json(with_markdown: true, with_html: true);
} elseif(preg_match('/^\/api\/subposts(.*)$/', $SURI, $match)) {
@@ -247,6 +300,8 @@ function generate_website($SURI) {
header('Content-Type: application/json');
echo json_encode($adapter->perform_post_search($_GET['search_query']));
}
+ } elseif(preg_match('/^\/ajax\//', $SURI)) {
+ try_render_ajax($SURI);
} elseif(preg_match('/^\/feed(?:\/(rss|atom)(.*))?$/', $SURI, $match)) {
$feed = $adapter->get_laminas_feed($match[2] ?? '/', $match[1] ?? 'rss');
@@ -255,7 +310,7 @@ function generate_website($SURI) {
header('Etag: W/"' . $SURI . '/' . strtotime($feed['feed_ts']) . '"');
echo $feed['feed'];
- } elseif(true) {
+ } else {
try_render_post($SURI);
}
}
diff --git a/www/secrets/.gitignore b/www/secrets/.gitignore
index f573c46..bb1f315 100644
--- a/www/secrets/.gitignore
+++ b/www/secrets/.gitignore
@@ -1,2 +1,3 @@
*.json
+*.yml
api_admin_key
\ No newline at end of file
diff --git a/www/static/.htaccess b/www/static/.htaccess
index 1c117e2..cf3ad7c 100644
--- a/www/static/.htaccess
+++ b/www/static/.htaccess
@@ -3,9 +3,9 @@ Allow from all
Options +Indexes
- Header set Cache-Control "max-age=315360, public"
+ Header set Cache-Control "max-age=60, public"
- Header set Cache-Control "max-age=315360, public"
+ Header set Cache-Control "max-age=60, public"
\ No newline at end of file
diff --git a/www/static/article_blop.css b/www/static/article_blop.css
new file mode 100644
index 0000000..1c46c37
--- /dev/null
+++ b/www/static/article_blop.css
@@ -0,0 +1,81 @@
+
+
+.article_blop {
+ position: relative;
+ overflow: clip;
+ z-index: 0;
+
+ background: var(--bg_2);
+
+ margin: 2rem;
+ padding: 0;
+
+ border-radius: 1rem;
+
+ box-shadow: 0px 5px 5px 0px #00000040;
+ transition: 0.3s;
+
+ min-height: 10rem;
+}
+
+.article_blop_bg {
+ position: absolute;
+ left: 0px;
+ right: 0;
+ top: 0;
+ bottom: 0;
+
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: cover;
+
+ opacity: 0.2;
+
+ z-index: -1;
+}
+
+.article_blop:hover {
+ box-shadow: 0px 8px 8px 0px #00000040;
+}
+
+.article_blop_content {
+ padding: 1rem;
+ padding-top: 5rem;
+}
+
+.article_blop_tags {
+ position: absolute;
+ top: 0.5rem;
+ right: 0.2rem;
+
+ width: 40%;
+ height: auto;
+
+ list-style: none;
+ display: flex;
+ flex-direction: row;
+ flex-flow: row wrap;
+
+ justify-content: right;
+}
+.article_blop_tags :first-child {
+ margin-left: auto;
+}
+.article_blop_tags li {
+ margin-right: 0.4rem;
+ margin-bottom: 0.4rem;
+
+ padding-left: 0.2rem;
+ padding-right: 0.2rem;
+
+ font-size: 0.8rem;
+
+ font-style: normal;
+ font-weight: bold;
+
+ background-color: var(--highlight_1);
+ border-radius: 0.3rem;
+ color: var(--bg_2);
+
+
+}
\ No newline at end of file
diff --git a/www/static/banner.js b/www/static/banner.js
index 1dc78c1..3da66de 100644
--- a/www/static/banner.js
+++ b/www/static/banner.js
@@ -61,6 +61,8 @@ class BannerHandler {
}
updateTranslation() {
+ this.bannerContainerDOM = document.getElementById("main_header")
+
const bannerTranslateMax = -this.bannerDOM.clientHeight + this.bannerContainerDOM.clientHeight
const bannerPercentageFrom = this.currentBannerData.from || 0;
@@ -120,7 +122,7 @@ class BannerHandler {
}
updateTick() {
- console.log("tick")
+
const nextPhase = this.getPhase() % 1;
@@ -150,11 +152,17 @@ class BannerHandler {
}
}
-var bannerHandler = new BannerHandler(
- document.getElementById("main_header"),
- document.getElementById("main_banner_img"),
- document.getElementById("main_banner_img_link"))
+let bannerHandler = null;
-bannerHandler.start()
+function startBanner() {
+ if(bannerHandler !== null) {
+ return;
+ }
-// addEventListener("resize", () => update_banner(banner, banner_container));
+ bannerHandler = new BannerHandler(
+ document.getElementById("main_header"),
+ document.getElementById("main_banner_img"),
+ document.getElementById("main_banner_img_link"))
+
+ bannerHandler.start()
+}
diff --git a/www/static/dergstyle.css b/www/static/dergstyle.css
index ccde5fa..2a4c1f9 100644
--- a/www/static/dergstyle.css
+++ b/www/static/dergstyle.css
@@ -6,9 +6,11 @@
padding: 0;
}
-svg {
+.fa-icn {
fill: var(--text_1);
padding-top: 0.1rem;
+ height: 1em;
+ vertical-align: -0.125em;
}
body {
@@ -16,6 +18,7 @@ body {
--bg_2: #2c2943;
--bg_3: #3f4148;
+ --highlight_0: #ee9015b1;
--highlight_1: #ee9015;
--highlight_2: #edd29e;
@@ -174,6 +177,35 @@ a:hover {
background: var(--bg_2);
}
+body::before {
+ content: '';
+
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+
+ width: 100%;
+ height: 100%;
+
+ background-image: url('/static/three-dots.svg');
+ background-repeat: no-repeat;
+ background-position: center;
+
+ opacity: 0;
+
+ z-index: 10;
+ pointer-events: none;
+
+ transition: opacity 0.2s;
+}
+body.htmx-request::before {
+ opacity: 1;
+
+ transition-delay: 0.5s;
+}
+
#post_file_bar {
position: sticky;
@@ -185,6 +217,7 @@ a:hover {
z-index: 5;
}
+
#post_file_titles {
display: flex;
flex-direction: row;
@@ -194,10 +227,11 @@ a:hover {
padding: 0px;
}
-#post_file_titles * {
- padding: 0.5rem;
+#post_file_titles > li {
+ padding: 0.2rem 0.8rem;
+
font-style: bold;
- font-size: 1.3rem;
+ font-size: 1.5rem;
background: var(--highlight_1);
}
@@ -208,6 +242,8 @@ a:hover {
padding-left: 0.5rem;
background: var(--highlight_1);
+
+ font-size: 1.1rem;
display: flex;
flex-direction: row;
@@ -223,7 +259,77 @@ a:hover {
padding-right: 0.2rem;
}
-#main_content_wrapper article {
+.navbar-expand {
+ background-color: var(--bg_3);
+
+ border: 0.15rem solid var(--highlight_1);
+ border-top: none;
+
+ border-radius: 0 0 0.2rem 0.2rem;
+ overflow: clip;
+
+ padding-bottom: 0.2rem;
+ padding-left: 0.3rem;
+
+ max-height: 80vh;
+ overflow-y: scroll;
+}
+
+.navbar-full-path {
+ width: 100%;
+ font-style: italic;
+ padding-left: 0.2rem;
+
+ display: flex;
+ flex-direction: row;
+ list-style-type: none;
+
+ overflow-x: scroll;
+ overflow-y: hidden;
+
+ white-space: nowrap;
+}
+.navbar-full-path li {
+ margin-left: 0.3rem;
+}
+
+.navbar-folder-list span, .navbar-folder-list label {
+ width: 1rem;
+ display: inline-block;
+ cursor: pointer;
+}
+.navbar-folder-list ul, .navbar-folder-list {
+ list-style: none;
+ padding-left: 0.4rem;
+ margin-left: 0.4rem;
+
+ border-left: 1px solid var(--text_border);
+}
+.navbar-folder-list a:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+}
+.folder-listing input {
+ display: none;
+}
+.folder-listing input + ul {
+ display: none;
+}
+.folder-listing input:checked + ul {
+ display: block;
+}
+
+#navbar-expand-label {
+ cursor: pointer;
+}
+#navbar-expander, .navbar-expand {
+ display: none;
+}
+
+#navbar-expander:checked + .navbar-expand {
+ display: block;
+}
+
+article {
background: var(--bg_3);
border-radius: 0rem 0rem 0.8rem 0.8rem;
@@ -232,7 +338,7 @@ a:hover {
padding: 0.75rem;
}
-#main_content_wrapper article img {
+article img {
display: block;
max-width: 100%;
diff --git a/www/static/htmx.min.js b/www/static/htmx.min.js
new file mode 100644
index 0000000..47eb70f
--- /dev/null
+++ b/www/static/htmx.min.js
@@ -0,0 +1 @@
+(function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var Q={onLoad:F,process:zt,on:de,off:ge,trigger:ce,ajax:Nr,find:C,findAll:f,closest:v,values:function(e,t){var r=dr(e,t||"post");return r.values},remove:_,addClass:z,removeClass:n,toggleClass:$,takeClass:W,defineExtension:Ur,removeExtension:Br,logAll:V,logNone:j,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"],selfRequestsOnly:false,ignoreTitle:false,scrollIntoViewOnBoost:true,triggerSpecsCache:null},parseInterval:d,_:t,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=Q.config.wsBinaryType;return t},version:"1.9.10"};var r={addTriggerHandler:Lt,bodyContains:se,canAccessLocalStorage:U,findThisElement:xe,filterValues:yr,hasAttribute:o,getAttributeValue:te,getClosestAttributeValue:ne,getClosestMatch:c,getExpressionVars:Hr,getHeaders:xr,getInputValues:dr,getInternalData:ae,getSwapSpecification:wr,getTriggerSpecs:it,getTarget:ye,makeFragment:l,mergeObjects:le,makeSettleInfo:T,oobSwap:Ee,querySelectorExt:ue,selectAndSwap:je,settleImmediately:nr,shouldCancel:ut,triggerEvent:ce,triggerErrorEvent:fe,withExtensions:R};var w=["get","post","put","delete","patch"];var i=w.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");var S=e("head"),q=e("title"),H=e("svg",true);function e(e,t=false){return new RegExp(`<${e}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${e}>`,t?"gim":"im")}function d(e){if(e==undefined){return undefined}let t=NaN;if(e.slice(-2)=="ms"){t=parseFloat(e.slice(0,-2))}else if(e.slice(-1)=="s"){t=parseFloat(e.slice(0,-1))*1e3}else if(e.slice(-1)=="m"){t=parseFloat(e.slice(0,-1))*1e3*60}else{t=parseFloat(e)}return isNaN(t)?undefined:t}function ee(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function te(e,t){return ee(e,t)||ee(e,"data-"+t)}function u(e){return e.parentElement}function re(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function L(e,t,r){var n=te(t,r);var i=te(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function ne(t,r){var n=null;c(t,function(e){return n=L(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function A(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function a(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=re().createDocumentFragment()}return i}function N(e){return/
"+n+" ",0);return i.querySelector("template").content}switch(r){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return a("",1);case"col":return a("",2);case"tr":return a("",2);case"td":case"th":return a("",3);case"script":case"style":return a(""+n+"
",1);default:return a(n,0)}}function ie(e){if(e){e()}}function I(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function k(e){return I(e,"Function")}function P(e){return I(e,"Object")}function ae(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function M(e){var t=[];if(e){for(var r=0;r=0}function se(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return re().body.contains(e.getRootNode().host)}else{return re().body.contains(e)}}function D(e){return e.trim().split(/\s+/)}function le(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function E(e){try{return JSON.parse(e)}catch(e){b(e);return null}}function U(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function B(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!/^\/$/.test(t)){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function t(e){return Tr(re().body,function(){return eval(e)})}function F(t){var e=Q.on("htmx:load",function(e){t(e.detail.elt)});return e}function V(){Q.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function j(){Q.logger=null}function C(e,t){if(t){return e.querySelector(t)}else{return C(re(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(re(),e)}}function _(e,t){e=g(e);if(t){setTimeout(function(){_(e);e=null},t)}else{e.parentElement.removeChild(e)}}function z(e,t,r){e=g(e);if(r){setTimeout(function(){z(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=g(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function $(e,t){e=g(e);e.classList.toggle(t)}function W(e,t){e=g(e);oe(e.parentElement.children,function(e){n(e,t)});z(e,t)}function v(e,t){e=g(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function s(e,t){return e.substring(0,t.length)===t}function G(e,t){return e.substring(e.length-t.length)===t}function J(e){var t=e.trim();if(s(t,"<")&&G(t,"/>")){return t.substring(1,t.length-2)}else{return t}}function Z(e,t){if(t.indexOf("closest ")===0){return[v(e,J(t.substr(8)))]}else if(t.indexOf("find ")===0){return[C(e,J(t.substr(5)))]}else if(t==="next"){return[e.nextElementSibling]}else if(t.indexOf("next ")===0){return[K(e,J(t.substr(5)))]}else if(t==="previous"){return[e.previousElementSibling]}else if(t.indexOf("previous ")===0){return[Y(e,J(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return re().querySelectorAll(J(t))}}var K=function(e,t){var r=re().querySelectorAll(t);for(var n=0;n=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ue(e,t){if(t){return Z(e,t)[0]}else{return Z(re().body,e)[0]}}function g(e){if(I(e,"String")){return C(e)}else{return e}}function ve(e,t,r){if(k(t)){return{target:re().body,event:e,listener:t}}else{return{target:g(e),event:t,listener:r}}}function de(t,r,n){jr(function(){var e=ve(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=k(r);return e?r:n}function ge(t,r,n){jr(function(){var e=ve(t,r,n);e.target.removeEventListener(e.event,e.listener)});return k(r)?r:n}var me=re().createElement("output");function pe(e,t){var r=ne(e,t);if(r){if(r==="this"){return[xe(e,t)]}else{var n=Z(e,r);if(n.length===0){b('The selector "'+r+'" on '+t+" returned no matches!");return[me]}else{return n}}}}function xe(e,t){return c(e,function(e){return te(e,t)!=null})}function ye(e){var t=ne(e,"hx-target");if(t){if(t==="this"){return xe(e,"hx-target")}else{return ue(e,t)}}else{var r=ae(e);if(r.boosted){return re().body}else{return e}}}function be(e){var t=Q.config.attributesToSettle;for(var r=0;r0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=re().querySelectorAll(t);if(r){oe(r,function(e){var t;var r=i.cloneNode(true);t=re().createDocumentFragment();t.appendChild(r);if(!Se(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!ce(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){Fe(o,e,e,t,a)}oe(a.elts,function(e){ce(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);fe(re().body,"htmx:oobErrorNoTarget",{content:i})}return e}function Ce(e,t,r){var n=ne(e,"hx-select-oob");if(n){var i=n.split(",");for(var a=0;a0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();we(e,i);s.tasks.push(function(){we(e,a)})}}})}function Oe(e){return function(){n(e,Q.config.addedClass);zt(e);Nt(e);qe(e);ce(e,"htmx:load")}}function qe(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function m(e,t,r,n){Te(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;z(i,Q.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Oe(i))}}}function He(e,t){var r=0;while(r-1){var t=e.replace(H,"");var r=t.match(q);if(r){return r[2]}}}function je(e,t,r,n,i,a){i.title=Ve(n);var o=l(n);if(o){Ce(r,o,i);o=Be(r,o,a);Re(o);return Fe(e,r,t,o,i)}}function _e(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=E(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!P(o)){o={value:o}}ce(r,a,o)}}}else{var s=n.split(",");for(var l=0;l0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=Tr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){fe(re().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(Qe(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function y(e,t){var r="";while(e.length>0&&!t.test(e[0])){r+=e.shift()}return r}function tt(e){var t;if(e.length>0&&Ze.test(e[0])){e.shift();t=y(e,Ke).trim();e.shift()}else{t=y(e,x)}return t}var rt="input, textarea, select";function nt(e,t,r){var n=[];var i=Ye(t);do{y(i,Je);var a=i.length;var o=y(i,/[,\[\s]/);if(o!==""){if(o==="every"){var s={trigger:"every"};y(i,Je);s.pollInterval=d(y(i,/[,\[\s]/));y(i,Je);var l=et(e,i,"event");if(l){s.eventFilter=l}n.push(s)}else if(o.indexOf("sse:")===0){n.push({trigger:"sse",sseEvent:o.substr(4)})}else{var u={trigger:o};var l=et(e,i,"event");if(l){u.eventFilter=l}while(i.length>0&&i[0]!==","){y(i,Je);var f=i.shift();if(f==="changed"){u.changed=true}else if(f==="once"){u.once=true}else if(f==="consume"){u.consume=true}else if(f==="delay"&&i[0]===":"){i.shift();u.delay=d(y(i,x))}else if(f==="from"&&i[0]===":"){i.shift();if(Ze.test(i[0])){var c=tt(i)}else{var c=y(i,x);if(c==="closest"||c==="find"||c==="next"||c==="previous"){i.shift();var h=tt(i);if(h.length>0){c+=" "+h}}}u.from=c}else if(f==="target"&&i[0]===":"){i.shift();u.target=tt(i)}else if(f==="throttle"&&i[0]===":"){i.shift();u.throttle=d(y(i,x))}else if(f==="queue"&&i[0]===":"){i.shift();u.queue=y(i,x)}else if(f==="root"&&i[0]===":"){i.shift();u[f]=tt(i)}else if(f==="threshold"&&i[0]===":"){i.shift();u[f]=y(i,x)}else{fe(e,"htmx:syntax:error",{token:i.shift()})}}n.push(u)}}if(i.length===a){fe(e,"htmx:syntax:error",{token:i.shift()})}y(i,Je)}while(i[0]===","&&i.shift());if(r){r[t]=n}return n}function it(e){var t=te(e,"hx-trigger");var r=[];if(t){var n=Q.config.triggerSpecsCache;r=n&&n[t]||nt(e,t,n)}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"], input[type="submit"]')){return[{trigger:"click"}]}else if(h(e,rt)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function at(e){ae(e).cancelled=true}function ot(e,t,r){var n=ae(e);n.timeout=setTimeout(function(){if(se(e)&&n.cancelled!==true){if(!ct(r,e,Wt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}ot(e,t,r)}},r.pollInterval)}function st(e){return location.hostname===e.hostname&&ee(e,"href")&&ee(e,"href").indexOf("#")!==0}function lt(t,r,e){if(t.tagName==="A"&&st(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=ee(t,"href")}else{var a=ee(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=ee(t,"action")}e.forEach(function(e){ht(t,function(e,t){if(v(e,Q.config.disableSelector)){p(e);return}he(n,i,e,t)},r,e,true)})}}function ut(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&v(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function ft(e,t){return ae(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function ct(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){fe(re().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function ht(a,o,e,s,l){var u=ae(a);var t;if(s.from){t=Z(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ae(e);t.lastValue=e.value})}oe(t,function(n){var i=function(e){if(!se(a)){n.removeEventListener(s.trigger,i);return}if(ft(a,e)){return}if(l||ut(e,a)){e.preventDefault()}if(ct(s,a,e)){return}var t=ae(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!h(e.target,s.target)){return}}if(s.once){if(u.triggeredOnce){return}else{u.triggeredOnce=true}}if(s.changed){var r=ae(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle>0){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay>0){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{ce(a,"htmx:trigger");o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var vt=false;var dt=null;function gt(){if(!dt){dt=function(){vt=true};window.addEventListener("scroll",dt);setInterval(function(){if(vt){vt=false;oe(re().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){mt(e)})}},200)}}function mt(t){if(!o(t,"data-hx-revealed")&&X(t)){t.setAttribute("data-hx-revealed","true");var e=ae(t);if(e.initHash){ce(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){ce(t,"revealed")},{once:true})}}}function pt(e,t,r){var n=D(r);for(var i=0;i=0){var t=wt(n);setTimeout(function(){xt(s,r,n+1)},t)}};t.onopen=function(e){n=0};ae(s).webSocket=t;t.addEventListener("message",function(e){if(yt(s)){return}var t=e.data;R(s,function(e){t=e.transformResponse(t,null,s)});var r=T(s);var n=l(t);var i=M(n.children);for(var a=0;a0){ce(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(ut(e,u)){e.preventDefault()}})}else{fe(u,"htmx:noWebSocketSourceError")}}function wt(e){var t=Q.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}b('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function St(e,t,r){var n=D(r);for(var i=0;i0){setTimeout(i,n)}else{i()}}function Ht(t,i,e){var a=false;oe(w,function(r){if(o(t,"hx-"+r)){var n=te(t,"hx-"+r);a=true;i.path=n;i.verb=r;e.forEach(function(e){Lt(t,e,i,function(e,t){if(v(e,Q.config.disableSelector)){p(e);return}he(r,n,e,t)})})}});return a}function Lt(n,e,t,r){if(e.sseEvent){Rt(n,r,e.sseEvent)}else if(e.trigger==="revealed"){gt();ht(n,r,t,e);mt(n)}else if(e.trigger==="intersect"){var i={};if(e.root){i.root=ue(n,e.root)}if(e.threshold){i.threshold=parseFloat(e.threshold)}var a=new IntersectionObserver(function(e){for(var t=0;t0){t.polling=true;ot(n,r,e)}else{ht(n,r,t,e)}}function At(e){if(Q.config.allowScriptTags&&(e.type==="text/javascript"||e.type==="module"||e.type==="")){var t=re().createElement("script");oe(e.attributes,function(e){t.setAttribute(e.name,e.value)});t.textContent=e.textContent;t.async=false;if(Q.config.inlineScriptNonce){t.nonce=Q.config.inlineScriptNonce}var r=e.parentElement;try{r.insertBefore(t,e)}catch(e){b(e)}finally{if(e.parentElement){e.parentElement.removeChild(e)}}}}function Nt(e){if(h(e,"script")){At(e)}oe(f(e,"script"),function(e){At(e)})}function It(e){var t=e.attributes;for(var r=0;r0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=Bt(o)}for(var l in r){Ft(e,l,r[l])}}}function jt(e){Ae(e);for(var t=0;tQ.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){fe(re().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Yt(e){if(!U()){return null}e=B(e);var t=E(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r=200&&this.status<400){ce(re().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Zt();var r=T(t);var n=Ve(this.response);if(n){var i=C("title");if(i){i.innerHTML=n}else{window.document.title=n}}Ue(t,e,r);nr(r.tasks);Jt=a;ce(re().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{fe(re().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function ar(e){er();e=e||location.pathname+location.search;var t=Yt(e);if(t){var r=l(t.content);var n=Zt();var i=T(n);Ue(n,r,i);nr(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Jt=e;ce(re().body,"htmx:historyRestore",{path:e,item:t})}else{if(Q.config.refreshOnHistoryMiss){window.location.reload(true)}else{ir(e)}}}function or(e){var t=pe(e,"hx-indicator");if(t==null){t=[e]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,Q.config.requestClass)});return t}function sr(e){var t=pe(e,"hx-disabled-elt");if(t==null){t=[]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.setAttribute("disabled","")});return t}function lr(e,t){oe(e,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,Q.config.requestClass)}});oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.removeAttribute("disabled")}})}function ur(e,t){for(var r=0;r=0}function wr(e,t){var r=t?t:ne(e,"hx-swap");var n={swapStyle:ae(e).boosted?"innerHTML":Q.config.defaultSwapStyle,swapDelay:Q.config.defaultSwapDelay,settleDelay:Q.config.defaultSettleDelay};if(Q.config.scrollIntoViewOnBoost&&ae(e).boosted&&!br(e)){n["show"]="top"}if(r){var i=D(r);if(i.length>0){for(var a=0;a0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}else if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}else if(o.indexOf("focus-scroll:")===0){var v=o.substr("focus-scroll:".length);n["focusScroll"]=v=="true"}else if(a==0){n["swapStyle"]=o}else{b("Unknown modifier in hx-swap: "+o)}}}}return n}function Sr(e){return ne(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&ee(e,"enctype")==="multipart/form-data"}function Er(t,r,n){var i=null;R(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(Sr(r)){return pr(n)}else{return mr(n)}}}function T(e){return{tasks:[],elts:[e]}}function Cr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ue(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ue(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:Q.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:Q.config.scrollBehavior})}}}function Rr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=te(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=Tr(e,function(){return Function("return ("+a+")")()},{})}else{s=E(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return Rr(u(e),t,r,n)}function Tr(e,t,r){if(Q.config.allowEval){return t()}else{fe(e,"htmx:evalDisallowedError");return r}}function Or(e,t){return Rr(e,"hx-vars",true,t)}function qr(e,t){return Rr(e,"hx-vals",false,t)}function Hr(e){return le(Or(e),qr(e))}function Lr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function Ar(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){fe(re().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function O(e,t){return t.test(e.getAllResponseHeaders())}function Nr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||I(r,"String")){return he(e,t,null,null,{targetOverride:g(r),returnPromise:true})}else{return he(e,t,g(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:g(r.target),swapOverride:r.swap,select:r.select,returnPromise:true})}}else{return he(e,t,null,null,{returnPromise:true})}}function Ir(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function kr(e,t,r){var n;var i;if(typeof URL==="function"){i=new URL(t,document.location.href);var a=document.location.origin;n=a===i.origin}else{i=t;n=s(t,document.location.origin)}if(Q.config.selfRequestsOnly){if(!n){return false}}return ce(e,"htmx:validateUrl",le({url:i,sameHost:n},r))}function he(t,r,n,i,a,e){var o=null;var s=null;a=a!=null?a:{};if(a.returnPromise&&typeof Promise!=="undefined"){var l=new Promise(function(e,t){o=e;s=t})}if(n==null){n=re().body}var M=a.handler||Mr;var X=a.select||null;if(!se(n)){ie(o);return l}var u=a.targetOverride||ye(n);if(u==null||u==me){fe(n,"htmx:targetError",{target:te(n,"hx-target")});ie(s);return l}var f=ae(n);var c=f.lastButtonClicked;if(c){var h=ee(c,"formaction");if(h!=null){r=h}var v=ee(c,"formmethod");if(v!=null){if(v.toLowerCase()!=="dialog"){t=v}}}var d=ne(n,"hx-confirm");if(e===undefined){var D=function(e){return he(t,r,n,i,a,!!e)};var U={target:u,elt:n,path:r,verb:t,triggeringEvent:i,etc:a,issueRequest:D,question:d};if(ce(n,"htmx:confirm",U)===false){ie(o);return l}}var g=n;var m=ne(n,"hx-sync");var p=null;var x=false;if(m){var B=m.split(":");var F=B[0].trim();if(F==="this"){g=xe(n,"hx-sync")}else{g=ue(n,F)}m=(B[1]||"drop").trim();f=ae(g);if(m==="drop"&&f.xhr&&f.abortable!==true){ie(o);return l}else if(m==="abort"){if(f.xhr){ie(o);return l}else{x=true}}else if(m==="replace"){ce(g,"htmx:abort")}else if(m.indexOf("queue")===0){var V=m.split(" ");p=(V[1]||"last").trim()}}if(f.xhr){if(f.abortable){ce(g,"htmx:abort")}else{if(p==null){if(i){var y=ae(i);if(y&&y.triggerSpec&&y.triggerSpec.queue){p=y.triggerSpec.queue}}if(p==null){p="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(p==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(p==="all"){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(p==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){he(t,r,n,i,a)})}ie(o);return l}}var b=new XMLHttpRequest;f.xhr=b;f.abortable=x;var w=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var j=ne(n,"hx-prompt");if(j){var S=prompt(j);if(S===null||!ce(n,"htmx:prompt",{prompt:S,target:u})){ie(o);w();return l}}if(d&&!e){if(!confirm(d)){ie(o);w();return l}}var E=xr(n,u,S);if(t!=="get"&&!Sr(n)){E["Content-Type"]="application/x-www-form-urlencoded"}if(a.headers){E=le(E,a.headers)}var _=dr(n,t);var C=_.errors;var R=_.values;if(a.values){R=le(R,a.values)}var z=Hr(n);var $=le(R,z);var T=yr($,n);if(Q.config.getCacheBusterParam&&t==="get"){T["org.htmx.cache-buster"]=ee(u,"id")||"true"}if(r==null||r===""){r=re().location.href}var O=Rr(n,"hx-request");var W=ae(n).boosted;var q=Q.config.methodsThatUseUrlParams.indexOf(t)>=0;var H={boosted:W,useUrlParams:q,parameters:T,unfilteredParameters:$,headers:E,target:u,verb:t,errors:C,withCredentials:a.credentials||O.credentials||Q.config.withCredentials,timeout:a.timeout||O.timeout||Q.config.timeout,path:r,triggeringEvent:i};if(!ce(n,"htmx:configRequest",H)){ie(o);w();return l}r=H.path;t=H.verb;E=H.headers;T=H.parameters;C=H.errors;q=H.useUrlParams;if(C&&C.length>0){ce(n,"htmx:validation:halted",H);ie(o);w();return l}var G=r.split("#");var J=G[0];var L=G[1];var A=r;if(q){A=J;var Z=Object.keys(T).length!==0;if(Z){if(A.indexOf("?")<0){A+="?"}else{A+="&"}A+=mr(T);if(L){A+="#"+L}}}if(!kr(n,A,H)){fe(n,"htmx:invalidPath",H);ie(s);return l}b.open(t.toUpperCase(),A,true);b.overrideMimeType("text/html");b.withCredentials=H.withCredentials;b.timeout=H.timeout;if(O.noHeaders){}else{for(var N in E){if(E.hasOwnProperty(N)){var K=E[N];Lr(b,N,K)}}}var I={xhr:b,target:u,requestConfig:H,etc:a,boosted:W,select:X,pathInfo:{requestPath:r,finalRequestPath:A,anchor:L}};b.onload=function(){try{var e=Ir(n);I.pathInfo.responsePath=Ar(b);M(n,I);lr(k,P);ce(n,"htmx:afterRequest",I);ce(n,"htmx:afterOnLoad",I);if(!se(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(se(r)){t=r}}if(t){ce(t,"htmx:afterRequest",I);ce(t,"htmx:afterOnLoad",I)}}ie(o);w()}catch(e){fe(n,"htmx:onLoadError",le({error:e},I));throw e}};b.onerror=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendError",I);ie(s);w()};b.onabort=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendAbort",I);ie(s);w()};b.ontimeout=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:timeout",I);ie(s);w()};if(!ce(n,"htmx:beforeRequest",I)){ie(o);w();return l}var k=or(n);var P=sr(n);oe(["loadstart","loadend","progress","abort"],function(t){oe([b,b.upload],function(e){e.addEventListener(t,function(e){ce(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});ce(n,"htmx:beforeSend",I);var Y=q?null:Er(b,n,T);b.send(Y);return l}function Pr(e,t){var r=t.xhr;var n=null;var i=null;if(O(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(O(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(O(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=ne(e,"hx-push-url");var l=ne(e,"hx-replace-url");var u=ae(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function Mr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;var t=u.requestConfig;var h=u.select;if(!ce(l,"htmx:beforeOnLoad",u))return;if(O(f,/HX-Trigger:/i)){_e(f,"HX-Trigger",l)}if(O(f,/HX-Location:/i)){er();var r=f.getResponseHeader("HX-Location");var v;if(r.indexOf("{")===0){v=E(r);r=v["path"];delete v["path"]}Nr("GET",r,v).then(function(){tr(r)});return}var n=O(f,/HX-Refresh:/i)&&"true"===f.getResponseHeader("HX-Refresh");if(O(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");n&&location.reload();return}if(n){location.reload();return}if(O(f,/HX-Retarget:/i)){if(f.getResponseHeader("HX-Retarget")==="this"){u.target=l}else{u.target=ue(l,f.getResponseHeader("HX-Retarget"))}}var d=Pr(l,u);var i=f.status>=200&&f.status<400&&f.status!==204;var g=f.response;var a=f.status>=400;var m=Q.config.ignoreTitle;var o=le({shouldSwap:i,serverResponse:g,isError:a,ignoreTitle:m},u);if(!ce(c,"htmx:beforeSwap",o))return;c=o.target;g=o.serverResponse;a=o.isError;m=o.ignoreTitle;u.target=c;u.failed=a;u.successful=!a;if(o.shouldSwap){if(f.status===286){at(l)}R(l,function(e){g=e.transformResponse(g,f,l)});if(d.type){er()}var s=e.swapOverride;if(O(f,/HX-Reswap:/i)){s=f.getResponseHeader("HX-Reswap")}var v=wr(l,s);if(v.hasOwnProperty("ignoreTitle")){m=v.ignoreTitle}c.classList.add(Q.config.swappingClass);var p=null;var x=null;var y=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(h){r=h}if(O(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}if(d.type){ce(re().body,"htmx:beforeHistoryUpdate",le({history:d},u));if(d.type==="push"){tr(d.path);ce(re().body,"htmx:pushedIntoHistory",{path:d.path})}else{rr(d.path);ce(re().body,"htmx:replacedInHistory",{path:d.path})}}var n=T(c);je(v.swapStyle,c,l,g,n,r);if(t.elt&&!se(t.elt)&&ee(t.elt,"id")){var i=document.getElementById(ee(t.elt,"id"));var a={preventScroll:v.focusScroll!==undefined?!v.focusScroll:!Q.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(Q.config.swappingClass);oe(n.elts,function(e){if(e.classList){e.classList.add(Q.config.settlingClass)}ce(e,"htmx:afterSwap",u)});if(O(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!se(l)){o=re().body}_e(f,"HX-Trigger-After-Swap",o)}var s=function(){oe(n.tasks,function(e){e.call()});oe(n.elts,function(e){if(e.classList){e.classList.remove(Q.config.settlingClass)}ce(e,"htmx:afterSettle",u)});if(u.pathInfo.anchor){var e=re().getElementById(u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title&&!m){var t=C("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}Cr(n.elts,v);if(O(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!se(l)){r=re().body}_e(f,"HX-Trigger-After-Settle",r)}ie(p)};if(v.settleDelay>0){setTimeout(s,v.settleDelay)}else{s()}}catch(e){fe(l,"htmx:swapError",u);ie(x);throw e}};var b=Q.config.globalViewTransitions;if(v.hasOwnProperty("transition")){b=v.transition}if(b&&ce(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var w=new Promise(function(e,t){p=e;x=t});var S=y;y=function(){document.startViewTransition(function(){S();return w})}}if(v.swapDelay>0){setTimeout(y,v.swapDelay)}else{y()}}if(a){fe(l,"htmx:responseError",le({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Xr={};function Dr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Ur(e,t){if(t.init){t.init(r)}Xr[e]=le(Dr(),t)}function Br(e){delete Xr[e]}function Fr(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=te(e,"hx-ext");if(t){oe(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Xr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Fr(u(e),r,n)}var Vr=false;re().addEventListener("DOMContentLoaded",function(){Vr=true});function jr(e){if(Vr||re().readyState==="complete"){e()}else{re().addEventListener("DOMContentLoaded",e)}}function _r(){if(Q.config.includeIndicatorStyles!==false){re().head.insertAdjacentHTML("beforeend","")}}function zr(){var e=re().querySelector('meta[name="htmx-config"]');if(e){return E(e.content)}else{return null}}function $r(){var e=zr();if(e){Q.config=le(Q.config,e)}}jr(function(){$r();_r();var e=re().body;zt(e);var t=re().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ae(t);if(r&&r.xhr){r.xhr.abort()}});const r=window.onpopstate?window.onpopstate.bind(window):null;window.onpopstate=function(e){if(e.state&&e.state.htmx){ar();oe(t,function(e){ce(e,"htmx:restored",{document:re(),triggerEvent:ce})})}else{if(r){r(e)}}};setTimeout(function(){ce(e,"htmx:load",{});e=null},0)});return Q}()});
\ No newline at end of file
diff --git a/www/static/three-dots.svg b/www/static/three-dots.svg
new file mode 100644
index 0000000..47092c2
--- /dev/null
+++ b/www/static/three-dots.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/www/templates/ajax/closed_folder_listing.html b/www/templates/ajax/closed_folder_listing.html
new file mode 100644
index 0000000..399894f
--- /dev/null
+++ b/www/templates/ajax/closed_folder_listing.html
@@ -0,0 +1,13 @@
+
+
+
+ {{ fa[post.post_metadata.icon] | raw }}
+
+
+
+ {{ post.post_metadata.title }}
+
+
\ No newline at end of file
diff --git a/www/templates/ajax/folder_listing.html b/www/templates/ajax/folder_listing.html
new file mode 100644
index 0000000..b90fb59
--- /dev/null
+++ b/www/templates/ajax/folder_listing.html
@@ -0,0 +1,4 @@
+
+{% for post in subposts %}
+{{ include('ajax/folder_listing_entry.html') }}
+{% endfor %}
\ No newline at end of file
diff --git a/www/templates/ajax/folder_listing_entry.html b/www/templates/ajax/folder_listing_entry.html
new file mode 100644
index 0000000..e47bf9b
--- /dev/null
+++ b/www/templates/ajax/folder_listing_entry.html
@@ -0,0 +1,26 @@
+
+
+
+ {% set folder_key = random() %}
+
+
+
+ {{ fa[post.post_metadata.icon] | raw }}
+
+
+
+ {{ post.post_metadata.title }}
+
+
+
+
+
\ No newline at end of file
diff --git a/www/templates/ajax/open_folder_listing.html b/www/templates/ajax/open_folder_listing.html
new file mode 100644
index 0000000..9bd6414
--- /dev/null
+++ b/www/templates/ajax/open_folder_listing.html
@@ -0,0 +1,20 @@
+
+
+
+
+ {{ fa[post.post_metadata.icon] | raw }}
+
+
+
+ {{ post.post_metadata.title }}
+
+
+
+ {% for post in subposts %}
+ {{ include('ajax/closed_folder_listing.html') }}
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/www/templates/fragments/article_blop.html b/www/templates/fragments/article_blop.html
new file mode 100644
index 0000000..0000271
--- /dev/null
+++ b/www/templates/fragments/article_blop.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+ {{post.title}}
+
+
+
+ {% for tag in post.tags %}
+ {{ tag }}
+ {% endfor %}
+
+
+
+ {{post.excerpt}}
+
+
+
+
\ No newline at end of file
diff --git a/www/templates/fragments/filepath_bar.html b/www/templates/fragments/filepath_bar.html
index 31b5265..314e019 100644
--- a/www/templates/fragments/filepath_bar.html
+++ b/www/templates/fragments/filepath_bar.html
@@ -17,17 +17,53 @@
{% endif %}
{% endfor %}
+
-
-
- raw
- api
-
-
+
+ {{ fa['bars'] | raw }}
+ style="padding-left: 0.3rem;" href="/feed/rss{{post.post_path}}">
{{ fa['rss']|raw }}
-
\ No newline at end of file
+
+
+
+ Full path:
+
+ {% set split_post = post.post_path |split('/') %}
+ {% for i in range(0, split_post|length - 1) %}
+
+ {% if i != 0 %}
+
+ / {{ split_post[i] }}
+
+ {% else %}
+ root
+ {% endif %}
+
+ {% endfor %}
+
+
+ Dev links:
+
raw
+
api
+
+
Folder browser:
+
+
+
+
+ {{ fa['turn-up'] | raw}}
+
+
+ ..
+
+
+ {% for post in subposts %}
+ {{ include('ajax/folder_listing_entry.html') }}
+ {% endfor %}
+
+
+
diff --git a/www/templates/pathed_content.html b/www/templates/pathed_content.html
index af5b566..90a0350 100644
--- a/www/templates/pathed_content.html
+++ b/www/templates/pathed_content.html
@@ -17,7 +17,7 @@
{{ include('fragments/filepath_bar.html') }}
-
+
{%block content_article %}
{%endblock%}
diff --git a/www/templates/post_types/blog_list.html b/www/templates/post_types/blog_list.html
new file mode 100644
index 0000000..1a104fd
--- /dev/null
+++ b/www/templates/post_types/blog_list.html
@@ -0,0 +1,20 @@
+
+
+{% extends "pathed_content.html" %}
+
+{% block extra_head %}
+
+
+{%endblock%}
+
+{%block content_article%}
+ {{ content_html|raw }}
+
+ {% if blog_posts|length > 0 %}
+ {% for post in blog_posts %}
+ {% include('fragments/article_blop.html') %}
+ {% endfor %}
+ {%else%}
+ How sad. There are no blog posts yet... What a real shame :c
+ {% endif %}
+{%endblock%}
diff --git a/www/templates/post_types/directory.html b/www/templates/post_types/directory.html
index ffacda0..e0babeb 100644
--- a/www/templates/post_types/directory.html
+++ b/www/templates/post_types/directory.html
@@ -38,6 +38,6 @@
This shouldn't happen, sorry!
{% endif %}
- {{ post.post_content|markdown_to_html }}
+ {{ content_html|raw }}
{%endblock%}
diff --git a/www/templates/root.html b/www/templates/root.html
index 01a87d6..0919f0e 100644
--- a/www/templates/root.html
+++ b/www/templates/root.html
@@ -2,14 +2,24 @@
{{og.site_name}} - {{og.title}}
+
+
+
+
+
+
+
+
+
+
{% block feed_links %}
{% endblock %}
@@ -38,11 +48,9 @@
{% endblock %}
-
-
+
+
{%if age_gate %}
@@ -59,10 +67,14 @@
{% endif %}
-
- full picture
+
+ full picture
+
+
+ startBanner();
+
{% block big_title %}{{og.site_name}}{%endblock%}
{% block second_title %}{% endblock %}