diff options
author | Andrew Godwin | 2022-11-13 16:14:38 -0700 |
---|---|---|
committer | Andrew Godwin | 2022-11-13 16:15:14 -0700 |
commit | 34b24a0dcb044cb755e201ad1a83253d0690e78e (patch) | |
tree | 51e6842d9e1392fafcd617cf4de0fa7e28397c87 | |
parent | 5a8b6bb3d022a532562ad5fa6d629cfc48c51b46 (diff) | |
download | takahe-34b24a0dcb044cb755e201ad1a83253d0690e78e.tar.gz takahe-34b24a0dcb044cb755e201ad1a83253d0690e78e.tar.bz2 takahe-34b24a0dcb044cb755e201ad1a83253d0690e78e.zip |
More UI!
-rw-r--r-- | activities/models/post.py | 8 | ||||
-rw-r--r-- | activities/templatetags/__init__.py | 0 | ||||
-rw-r--r-- | activities/templatetags/activity_tags.py | 33 | ||||
-rw-r--r-- | activities/views/home.py | 42 | ||||
-rw-r--r-- | activities/views/timelines.py | 70 | ||||
-rw-r--r-- | core/forms.py | 11 | ||||
-rw-r--r-- | core/views.py | 2 | ||||
-rw-r--r-- | requirements.txt | 1 | ||||
-rw-r--r-- | setup.cfg | 3 | ||||
-rw-r--r-- | static/css/style.css | 197 | ||||
-rwxr-xr-x | static/js/hyperscript.min.js | 1 | ||||
-rw-r--r-- | takahe/settings/base.py | 1 | ||||
-rw-r--r-- | takahe/settings/development.py | 1 | ||||
-rw-r--r-- | takahe/settings/production.py | 1 | ||||
-rw-r--r-- | takahe/urls.py | 3 | ||||
-rw-r--r-- | templates/activities/_home_menu.html | 6 | ||||
-rw-r--r-- | templates/activities/_post.html | 15 | ||||
-rw-r--r-- | templates/activities/federated.html | 21 | ||||
-rw-r--r-- | templates/activities/home.html | 31 | ||||
-rw-r--r-- | templates/auth/login.html | 17 | ||||
-rw-r--r-- | templates/base.html | 1 | ||||
-rw-r--r-- | templates/forms/_field.html | 13 | ||||
-rw-r--r-- | templates/identity/create.html | 18 | ||||
-rw-r--r-- | templates/index.html | 4 | ||||
-rw-r--r-- | users/views/auth.py | 5 | ||||
-rw-r--r-- | users/views/identity.py | 30 |
26 files changed, 397 insertions, 138 deletions
diff --git a/activities/models/post.py b/activities/models/post.py index ec5e629..75a4388 100644 --- a/activities/models/post.py +++ b/activities/models/post.py @@ -1,4 +1,4 @@ -from typing import Dict +from typing import Dict, Optional import urlman from django.db import models @@ -126,10 +126,14 @@ class Post(StatorModel): ### Local creation ### @classmethod - def create_local(cls, author: Identity, content: str) -> "Post": + def create_local( + cls, author: Identity, content: str, summary: Optional[str] = None + ) -> "Post": post = cls.objects.create( author=author, content=content, + summary=summary or None, + sensitive=bool(summary), local=True, ) post.object_uri = post.author.actor_uri + f"posts/{post.id}/" diff --git a/activities/templatetags/__init__.py b/activities/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/activities/templatetags/__init__.py diff --git a/activities/templatetags/activity_tags.py b/activities/templatetags/activity_tags.py new file mode 100644 index 0000000..cbbae57 --- /dev/null +++ b/activities/templatetags/activity_tags.py @@ -0,0 +1,33 @@ +import datetime + +from django import template +from django.utils import timezone + +register = template.Library() + + +@register.filter +def timedeltashort(value: datetime.datetime): + """ + A more compact version of timesince + """ + if not value: + return "" + # TODO: Handle things in the future properly + delta = timezone.now() - value + seconds = int(delta.total_seconds()) + days = delta.days + if seconds < 60: + text = f"{seconds:0n}s" + elif seconds < 60 * 60: + minutes = seconds // 60 + text = f"{minutes:0n}m" + elif seconds < 60 * 60 * 24: + hours = seconds // (60 * 60) + text = f"{hours:0n}h" + elif days < 365: + text = f"{days:0n}h" + else: + years = days // 365.25 + text = f"{years:0n}y" + return text diff --git a/activities/views/home.py b/activities/views/home.py deleted file mode 100644 index 867856d..0000000 --- a/activities/views/home.py +++ /dev/null @@ -1,42 +0,0 @@ -from django import forms -from django.shortcuts import redirect -from django.template.defaultfilters import linebreaks_filter -from django.utils.decorators import method_decorator -from django.views.generic import FormView - -from activities.models import Post, TimelineEvent -from core.forms import FormHelper -from users.decorators import identity_required - - -@method_decorator(identity_required, name="dispatch") -class Home(FormView): - - template_name = "activities/home.html" - - class form_class(forms.Form): - text = forms.CharField() - - helper = FormHelper(submit_text="Post") - - def get_context_data(self): - context = super().get_context_data() - context.update( - { - "timeline_posts": [ - te.subject_post - for te in TimelineEvent.objects.filter( - identity=self.request.identity, - type=TimelineEvent.Types.post, - ).order_by("-created")[:100] - ], - } - ) - return context - - def form_valid(self, form): - Post.create_local( - author=self.request.identity, - content=linebreaks_filter(form.cleaned_data["text"]), - ) - return redirect(".") diff --git a/activities/views/timelines.py b/activities/views/timelines.py new file mode 100644 index 0000000..76cf018 --- /dev/null +++ b/activities/views/timelines.py @@ -0,0 +1,70 @@ +from django import forms +from django.shortcuts import redirect +from django.template.defaultfilters import linebreaks_filter +from django.utils.decorators import method_decorator +from django.views.generic import FormView, TemplateView + +from activities.models import Post, TimelineEvent +from users.decorators import identity_required + + +@method_decorator(identity_required, name="dispatch") +class Home(FormView): + + template_name = "activities/home.html" + + class form_class(forms.Form): + text = forms.CharField( + widget=forms.Textarea( + attrs={ + "placeholder": "What's on your mind?", + }, + ) + ) + content_warning = forms.CharField( + required=False, + widget=forms.TextInput( + attrs={ + "placeholder": "Content Warning", + "class": "hidden", + }, + ), + ) + + def get_context_data(self): + context = super().get_context_data() + context["timeline_posts"] = [ + te.subject_post + for te in TimelineEvent.objects.filter( + identity=self.request.identity, + type=TimelineEvent.Types.post, + ) + .select_related("subject_post", "subject_post__author") + .order_by("-created")[:100] + ] + context["current_page"] = "home" + return context + + def form_valid(self, form): + Post.create_local( + author=self.request.identity, + content=linebreaks_filter(form.cleaned_data["text"]), + summary=form.cleaned_data.get("content_warning"), + ) + return redirect(".") + + +@method_decorator(identity_required, name="dispatch") +class Federated(TemplateView): + + template_name = "activities/federated.html" + + def get_context_data(self): + context = super().get_context_data() + context["timeline_posts"] = ( + Post.objects.filter(visibility=Post.Visibilities.public) + .select_related("author") + .order_by("-created")[:100] + ) + context["current_page"] = "federated" + return context diff --git a/core/forms.py b/core/forms.py deleted file mode 100644 index 8a4801d..0000000 --- a/core/forms.py +++ /dev/null @@ -1,11 +0,0 @@ -from crispy_forms.helper import FormHelper as BaseFormHelper -from crispy_forms.layout import Submit - - -class FormHelper(BaseFormHelper): - - submit_text = "Submit" - - def __init__(self, form=None, submit_text=None): - super().__init__(form) - self.add_input(Submit("submit", submit_text or "Submit")) diff --git a/core/views.py b/core/views.py index 205224c..30eaf90 100644 --- a/core/views.py +++ b/core/views.py @@ -1,6 +1,6 @@ from django.views.generic import TemplateView -from activities.views.home import Home +from activities.views.timelines import Home from users.models import Identity diff --git a/requirements.txt b/requirements.txt index 911b852..1c09acd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,6 @@ django~=4.1 pyld~=2.0.3 pillow~=9.3.0 urlman~=2.0.1 -django-crispy-forms~=1.14 cryptography~=38.0 httpx~=0.23 pyOpenSSL~=22.1.0 @@ -22,9 +22,6 @@ ignore_missing_imports = True [mypy-urlman.*] ignore_missing_imports = True -[mypy-crispy_forms.*] -ignore_missing_imports = True - [mypy-cryptography.*] ignore_missing_imports = True diff --git a/static/css/style.css b/static/css/style.css index 56c68ee..0611fb5 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -79,6 +79,7 @@ a { --color-bg-main: #26323c; --color-bg-menu: #2e3e4c; --color-bg-box: #1a2631; + --color-bg-error: rgb(87, 32, 32); --color-highlight: #449c8c; --color-text-duller: #5f6983; @@ -90,13 +91,13 @@ a { --color-button-main: #444b5d; --color-button-main-hover: #515d7c; --color-bg3: #444b5d; - --color-text-error: rgb(155, 111, 111); } body { background-color: var(--color-bg-main); color: var(--color-text-main); font-family: "Raleway", sans-serif; + font-size: 16px; } main { @@ -123,7 +124,7 @@ header .logo { } header .logo:hover { - border-bottom: 3px solid rgba(255, 255, 255, 0.2); + border-bottom: 3px solid rgba(255, 255, 255, 0.3); } header .logo img { @@ -201,6 +202,33 @@ nav a:hover { color: var(--color-text-main); } +/* Left-right columns */ + +.columns { + display: flex; +} + +.left-column { + flex-grow: 1; + width: 300px; + padding: 15px; +} + +.right-column { + width: 250px; + background: var(--color-bg-menu); +} + +.right-column h2 { + background: var(--color-highlight); + padding: 8px 10px; + font-weight: bold; + font-size: 90%; + text-transform: uppercase; +} + +/* Icon menus */ + .icon-menu { display: flex; flex-wrap: wrap; @@ -255,43 +283,111 @@ nav a:hover { /* Forms */ -form .control-group { - margin: 0 0 15px 0; +form { + padding: 20px 40px 20px 30px; } -form .asteriskField { - display: none; +.right-column form { + padding: 0; +} + +form h1 { + margin: 0 0 10px 0; +} + +form p { + color: var(--color-text-main); + margin: 10px 0 15px 0; +} + +form .field { + margin: 25px 0 25px 0; + background: var(--color-bg-box); + box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1); + padding: 10px 10px; +} + +.right-column form .field { + margin: 0; + background: none; + box-shadow: none; + padding: 0; } form label { + display: block; text-transform: uppercase; - font-size: 110%; - color: var(--color-text-dull); - letter-spacing: 0.05em; + font-size: 100%; + font-weight: bold; } -form label.requiredField::after { - content: " (required)"; +form label small { font-size: 80%; - color: var(--color-text-duller); + margin-left: 5px; + color: var(--color-text-dull); } -form .help-block { - color: var(--color-text-error); - padding: 4px 0 0 0; +.right-column form label { + margin: 5px 10px 5px 10px; +} + +form .help { + color: var(--color-text-dull); + font-size: 90%; + margin: 2px 0 6px 0; +} + +form .errorlist { + list-style-type: none; + margin: 0; + padding: 0; +} + +form .errorlist li { + color: var(--color-text-main); + background: var(--color-bg-error); + border-radius: 3px; + margin: 5px 0 8px 0; + padding: 3px 7px; +} + +form .errorlist li::before { + content: "\f071"; + font: var(--fa-font-solid); + margin-right: 7px; +} + +form .hidden { + display: none; } form input, -form select { +form select, +form textarea { width: 100%; - padding: 4px 6px; + padding: 5px 7px; background: var(--color-bg-main); border: 1px solid var(--color-input-border); border-radius: 3px; color: var(--color-text-main); } -form input:focus { +.right-column form.compose input, +.right-column form.compose textarea { + margin: 0 0 10px 0; + border: 0; + font-size: 95%; + border-radius: 0; + background-color: var(--color-bg-box); +} + +.right-column form.compose textarea { + height: 150px; +} + +form input:focus, +form select:focus, +form textarea:focus { outline: none; border: 1px solid var(--color-input-border-active); } @@ -311,6 +407,48 @@ form input[type=submit]:hover { background: var(--color-button-main-hover); } +form .buttons { + text-align: right; + margin: 25px 0 15px 0; +} + +.right-column form .buttons { + margin: 5px 10px 5px 0; +} + +form button, +form .button { + padding: 5px 10px; + margin: 0 0 0 5px; + border-radius: 5px; + border: 3px solid rgba(255, 255, 255, 0); + cursor: pointer; + font-weight: bold; + background-color: var(--color-highlight); + color: var(--color-text-main); + display: inline-block; +} + +form button.toggle, +form .button.toggle { + background: var(--color-bg-main); +} + +form button.toggle.enabled, +form .button.toggle.enabled { + background: var(--color-highlight); +} + +form button:hover, +form .button:hover { + border: 3px solid rgba(255, 255, 255, 0.3); +} + +.right-column form button, +.right-column form .button { + padding: 2px 6px; +} + /* Identities */ h1.identity { @@ -350,29 +488,26 @@ h1.identity small { overflow: hidden; } +.left-column .post { + background: var(--color-bg-box); + box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1); + padding: 10px; +} + .post .icon { height: 48px; width: auto; float: left; } -.post .author { - padding-left: 64px; -} - -.post .author a, -.post time a { - color: inherit; - text-decoration: none; -} - -.post .author small { - font-weight: normal; - color: var(--color-text-dull); +.post .handle { + display: block; + padding: 7px 0 10px 64px; } .post time { display: block; + float: right; padding-left: 64px; color: var(--color-text-duller); } diff --git a/static/js/hyperscript.min.js b/static/js/hyperscript.min.js new file mode 100755 index 0000000..4e22b3b --- /dev/null +++ b/static/js/hyperscript.min.js @@ -0,0 +1 @@ +(function(e,t){const r=t(e);if(typeof exports==="object"&&typeof exports["nodeName"]!=="string"){module.exports=r}else{e["_hyperscript"]=r;if("document"in e)e["_hyperscript"].browserInit()}})(typeof self!=="undefined"?self:this,(e=>{"use strict";const t={dynamicResolvers:[function(e,t){if(e==="Fixed"){return Number(t).toFixed()}else if(e.indexOf("Fixed:")===0){let r=e.split(":")[1];return Number(t).toFixed(parseInt(r))}}],String:function(e){if(e.toString){return e.toString()}else{return""+e}},Int:function(e){return parseInt(e)},Float:function(e){return parseFloat(e)},Number:function(e){return Number(e)},Date:function(e){return new Date(e)},Array:function(e){return Array.from(e)},JSON:function(e){return JSON.stringify(e)},Object:function(e){if(e instanceof String){e=e.toString()}if(typeof e==="string"){return JSON.parse(e)}else{return Object.assign({},e)}}};const r={attributes:"_, script, data-script",defaultTransition:"all 500ms ease-in",disableSelector:"[disable-scripting], [data-disable-scripting]",conversions:t};class n{static OP_TABLE={"+":"PLUS","-":"MINUS","*":"MULTIPLY","/":"DIVIDE",".":"PERIOD","..":"ELLIPSIS","\\":"BACKSLASH",":":"COLON","%":"PERCENT","|":"PIPE","!":"EXCLAMATION","?":"QUESTION","#":"POUND","&":"AMPERSAND",$:"DOLLAR",";":"SEMI",",":"COMMA","(":"L_PAREN",")":"R_PAREN","<":"L_ANG",">":"R_ANG","<=":"LTE_ANG",">=":"GTE_ANG","==":"EQ","===":"EQQ","!=":"NEQ","!==":"NEQQ","{":"L_BRACE","}":"R_BRACE","[":"L_BRACKET","]":"R_BRACKET","=":"EQUALS"};static isValidCSSClassChar(e){return n.isAlpha(e)||n.isNumeric(e)||e==="-"||e==="_"||e===":"}static isValidCSSIDChar(e){return n.isAlpha(e)||n.isNumeric(e)||e==="-"||e==="_"||e===":"}static isWhitespace(e){return e===" "||e==="\t"||n.isNewline(e)}static positionString(e){return"[Line: "+e.line+", Column: "+e.column+"]"}static isNewline(e){return e==="\r"||e==="\n"}static isNumeric(e){return e>="0"&&e<="9"}static isAlpha(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"}static isIdentifierChar(e,t){return e==="_"||e==="$"}static isReservedChar(e){return e==="`"||e==="^"}static isValidSingleQuoteStringStart(e){if(e.length>0){var t=e[e.length-1];if(t.type==="IDENTIFIER"||t.type==="CLASS_REF"||t.type==="ID_REF"){return false}if(t.op&&(t.value===">"||t.value===")")){return false}}return true}static tokenize(e,t){var r=[];var a=e;var o=0;var s=0;var u=1;var l="<START>";var c=0;function f(){return t&&c===0}while(o<a.length){if(S()==="-"&&q()==="-"&&(n.isWhitespace(N(2))||N(2)===""||N(2)==="-")||S()==="/"&&q()==="/"){h()}else if(S()==="/"&&q()==="*"){v()}else{if(n.isWhitespace(S())){r.push(C())}else if(!R()&&S()==="."&&(n.isAlpha(q())||q()==="{")){r.push(d())}else if(!R()&&S()==="#"&&(n.isAlpha(q())||q()==="{")){r.push(k())}else if(S()==="["&&q()==="@"){r.push(E())}else if(S()==="@"){r.push(T())}else if(S()==="*"&&n.isAlpha(q())){r.push(y())}else if(n.isAlpha(S())||!f()&&n.isIdentifierChar(S())){r.push(x())}else if(n.isNumeric(S())){r.push(g())}else if(!f()&&(S()==='"'||S()==="`")){r.push(w())}else if(!f()&&S()==="'"){if(n.isValidSingleQuoteStringStart(r)){r.push(w())}else{r.push(b())}}else if(n.OP_TABLE[S()]){if(l==="$"&&S()==="{"){c++}if(S()==="}"){c--}r.push(b())}else if(f()||n.isReservedChar(S())){r.push(p("RESERVED",I()))}else{if(o<a.length){throw Error("Unknown token: "+S()+" ")}}}}return new i(r,[],a);function m(e,t){var r=p(e,t);r.op=true;return r}function p(e,t){return{type:e,value:t||"",start:o,end:o+1,column:s,line:u}}function h(){while(S()&&!n.isNewline(S())){I()}I()}function v(){while(S()&&!(S()==="*"&&q()==="/")){I()}I();I()}function d(){var e=p("CLASS_REF");var t=I();if(S()==="{"){e.template=true;t+=I();while(S()&&S()!=="}"){t+=I()}if(S()!=="}"){throw Error("Unterminated class reference")}else{t+=I()}}else{while(n.isValidCSSClassChar(S())){t+=I()}}e.value=t;e.end=o;return e}function E(){var e=p("ATTRIBUTE_REF");var t=I();while(o<a.length&&S()!=="]"){t+=I()}if(S()==="]"){t+=I()}e.value=t;e.end=o;return e}function T(){var e=p("ATTRIBUTE_REF");var t=I();while(n.isValidCSSIDChar(S())){t+=I()}e.value=t;e.end=o;return e}function y(){var e=p("STYLE_REF");var t=I();while(n.isAlpha(S())||S()==="-"){t+=I()}e.value=t;e.end=o;return e}function k(){var e=p("ID_REF");var t=I();if(S()==="{"){e.template=true;t+=I();while(S()&&S()!=="}"){t+=I()}if(S()!=="}"){throw Error("Unterminated id reference")}else{I()}}else{while(n.isValidCSSIDChar(S())){t+=I()}}e.value=t;e.end=o;return e}function x(){var e=p("IDENTIFIER");var t=I();while(n.isAlpha(S())||n.isNumeric(S())||n.isIdentifierChar(S())){t+=I()}if(S()==="!"&&t==="beep"){t+=I()}e.value=t;e.end=o;return e}function g(){var e=p("NUMBER");var t=I();while(n.isNumeric(S())){t+=I()}if(S()==="."&&n.isNumeric(q())){t+=I()}while(n.isNumeric(S())){t+=I()}e.value=t;e.end=o;return e}function b(){var e=m();var t=I();while(S()&&n.OP_TABLE[t+S()]){t+=I()}e.type=n.OP_TABLE[t];e.value=t;e.end=o;return e}function w(){var e=p("STRING");var t=I();var r="";while(S()&&S()!==t){if(S()==="\\"){I();let e=I();if(e==="b"){r+="\b"}else if(e==="f"){r+="\f"}else if(e==="n"){r+="\n"}else if(e==="r"){r+="\r"}else if(e==="t"){r+="\t"}else if(e==="v"){r+="\v"}else{r+=e}}else{r+=I()}}if(S()!==t){throw Error("Unterminated string at "+n.positionString(e))}else{I()}e.value=r;e.end=o;e.template=t==="`";return e}function S(){return a.charAt(o)}function q(){return a.charAt(o+1)}function N(e=1){return a.charAt(o+e)}function I(){l=S();o++;s++;return l}function R(){return n.isAlpha(l)||n.isNumeric(l)||l===")"||l==='"'||l==="'"||l==="`"||l==="}"||l==="]"}function C(){var e=p("WHITESPACE");var t="";while(S()&&n.isWhitespace(S())){if(n.isNewline(S())){s=0;u++}t+=I()}e.value=t;e.end=o;return e}}tokenize(e,t){return n.tokenize(e,t)}}class i{constructor(e,t,r){this.tokens=e;this.consumed=t;this.source=r;this.consumeWhitespace()}get list(){return this.tokens}_lastConsumed=null;consumeWhitespace(){while(this.token(0,true).type==="WHITESPACE"){this.consumed.push(this.tokens.shift())}}raiseError(e,t){a.raiseParseError(e,t)}requireOpToken(e){var t=this.matchOpToken(e);if(t){return t}else{this.raiseError(this,"Expected '"+e+"' but found '"+this.currentToken().value+"'")}}matchAnyOpToken(e,t,r){for(var n=0;n<arguments.length;n++){var i=arguments[n];var a=this.matchOpToken(i);if(a){return a}}}matchAnyToken(e,t,r){for(var n=0;n<arguments.length;n++){var i=arguments[n];var a=this.matchToken(i);if(a){return a}}}matchOpToken(e){if(this.currentToken()&&this.currentToken().op&&this.currentToken().value===e){return this.consumeToken()}}requireTokenType(e,t,r,n){var i=this.matchTokenType(e,t,r,n);if(i){return i}else{this.raiseError(this,"Expected one of "+JSON.stringify([e,t,r]))}}matchTokenType(e,t,r,n){if(this.currentToken()&&this.currentToken().type&&[e,t,r,n].indexOf(this.currentToken().type)>=0){return this.consumeToken()}}requireToken(e,t){var r=this.matchToken(e,t);if(r){return r}else{this.raiseError(this,"Expected '"+e+"' but found '"+this.currentToken().value+"'")}}peekToken(e,t,r){return this.tokens[t]&&this.tokens[t].value===e&&this.tokens[t].type===r}matchToken(e,t){if(this.follows.indexOf(e)!==-1){return}t=t||"IDENTIFIER";if(this.currentToken()&&this.currentToken().value===e&&this.currentToken().type===t){return this.consumeToken()}}consumeToken(){var e=this.tokens.shift();this.consumed.push(e);this._lastConsumed=e;this.consumeWhitespace();return e}consumeUntil(e,t){var r=[];var n=this.token(0,true);while((t==null||n.type!==t)&&(e==null||n.value!==e)&&n.type!=="EOF"){var i=this.tokens.shift();this.consumed.push(i);r.push(n);n=this.token(0,true)}this.consumeWhitespace();return r}lastWhitespace(){if(this.consumed[this.consumed.length-1]&&this.consumed[this.consumed.length-1].type==="WHITESPACE"){return this.consumed[this.consumed.length-1].value}else{return""}}consumeUntilWhitespace(){return this.consumeUntil(null,"WHITESPACE")}hasMore(){return this.tokens.length>0}token(e,t){var r;var n=0;do{if(!t){while(this.tokens[n]&&this.tokens[n].type==="WHITESPACE"){n++}}r=this.tokens[n];e--;n++}while(e>-1);if(r){return r}else{return{type:"EOF",value:"<<<EOF>>>"}}}currentToken(){return this.token(0)}lastMatch(){return this._lastConsumed}static sourceFor=function(){return this.programSource.substring(this.startToken.start,this.endToken.end)};static lineFor=function(){return this.programSource.split("\n")[this.startToken.line-1]};follows=[];pushFollow(e){this.follows.push(e)}popFollow(){this.follows.pop()}clearFollows(){var e=this.follows;this.follows=[];return e}restoreFollows(e){this.follows=e}}class a{constructor(e){this.runtime=e;this.possessivesDisabled=false;this.addGrammarElement("feature",(function(e,t,r){if(r.matchOpToken("(")){var n=e.requireElement("feature",r);r.requireOpToken(")");return n}var i=e.FEATURES[r.currentToken().value||""];if(i){return i(e,t,r)}}));this.addGrammarElement("command",(function(e,t,r){if(r.matchOpToken("(")){const t=e.requireElement("command",r);r.requireOpToken(")");return t}var n=e.COMMANDS[r.currentToken().value||""];let i;if(n){i=n(e,t,r)}else if(r.currentToken().type==="IDENTIFIER"){i=e.parseElement("pseudoCommand",r)}if(i){return e.parseElement("indirectStatement",r,i)}return i}));this.addGrammarElement("commandList",(function(e,t,r){var n=e.parseElement("command",r);if(n){r.matchToken("then");const t=e.parseElement("commandList",r);if(t)n.next=t;return n}}));this.addGrammarElement("leaf",(function(e,t,r){var n=e.parseAnyOf(e.LEAF_EXPRESSIONS,r);if(n==null){return e.parseElement("symbol",r)}return n}));this.addGrammarElement("indirectExpression",(function(e,t,r,n){for(var i=0;i<e.INDIRECT_EXPRESSIONS.length;i++){var a=e.INDIRECT_EXPRESSIONS[i];n.endToken=r.lastMatch();var o=e.parseElement(a,r,n);if(o){return o}}return n}));this.addGrammarElement("indirectStatement",(function(e,t,r,n){if(r.matchToken("unless")){n.endToken=r.lastMatch();var i=e.requireElement("expression",r);var a={type:"unlessStatementModifier",args:[i],op:function(e,t){if(t){return this.next}else{return n}},execute:function(e){return t.unifiedExec(this,e)}};n.parent=a;return a}return n}));this.addGrammarElement("primaryExpression",(function(e,t,r){var n=e.parseElement("leaf",r);if(n){return e.parseElement("indirectExpression",r,n)}e.raiseParseError(r,"Unexpected value: "+r.currentToken().value)}))}use(e){e(this);return this}GRAMMAR={};COMMANDS={};FEATURES={};LEAF_EXPRESSIONS=[];INDIRECT_EXPRESSIONS=[];initElt(e,t,r){e.startToken=t;e.sourceFor=i.sourceFor;e.lineFor=i.lineFor;e.programSource=r.source}parseElement(e,t,r=undefined){var n=this.GRAMMAR[e];if(n){var i=t.currentToken();var a=n(this,this.runtime,t,r);if(a){this.initElt(a,i,t);a.endToken=a.endToken||t.lastMatch();var r=a.root;while(r!=null){this.initElt(r,i,t);r=r.root}}return a}}requireElement(e,t,r,n){var i=this.parseElement(e,t,n);if(!i)a.raiseParseError(t,r||"Expected "+e);return i}parseAnyOf(e,t){for(var r=0;r<e.length;r++){var n=e[r];var i=this.parseElement(n,t);if(i){return i}}}addGrammarElement(e,t){this.GRAMMAR[e]=t}addCommand(e,t){var r=e+"Command";var n=function(e,n,i){const a=t(e,n,i);if(a){a.type=r;a.execute=function(e){e.meta.command=a;return n.unifiedExec(this,e)};return a}};this.GRAMMAR[r]=n;this.COMMANDS[e]=n}addFeature(e,t){var r=e+"Feature";var n=function(n,i,a){var o=t(n,i,a);if(o){o.isFeature=true;o.keyword=e;o.type=r;return o}};this.GRAMMAR[r]=n;this.FEATURES[e]=n}addLeafExpression(e,t){this.LEAF_EXPRESSIONS.push(e);this.addGrammarElement(e,t)}addIndirectExpression(e,t){this.INDIRECT_EXPRESSIONS.push(e);this.addGrammarElement(e,t)}static createParserContext(e){var t=e.currentToken();var r=e.source;var n=r.split("\n");var i=t&&t.line?t.line-1:n.length-1;var a=n[i];var o=t&&t.line?t.column:a.length-1;return a+"\n"+" ".repeat(o)+"^^\n\n"}static raiseParseError(e,t){t=(t||"Unexpected Token : "+e.currentToken().value)+"\n\n"+a.createParserContext(e);var r=new Error(t);r["tokens"]=e;throw r}raiseParseError(e,t){a.raiseParseError(e,t)}parseHyperScript(e){var t=this.parseElement("hyperscript",e);if(e.hasMore())this.raiseParseError(e);if(t)return t}setParent(e,t){if(typeof e==="object"){e.parent=t;if(typeof t==="object"){t.children=t.children||new Set;t.children.add(e)}this.setParent(e.next,t)}}commandStart(e){return this.COMMANDS[e.value||""]}featureStart(e){return this.FEATURES[e.value||""]}commandBoundary(e){if(e.value=="end"||e.value=="then"||e.value=="else"||e.value=="otherwise"||e.value==")"||this.commandStart(e)||this.featureStart(e)||e.type=="EOF"){return true}return false}parseStringTemplate(e){var t=[""];do{t.push(e.lastWhitespace());if(e.currentToken().value==="$"){e.consumeToken();var r=e.matchOpToken("{");t.push(this.requireElement("expression",e));if(r){e.requireOpToken("}")}t.push("")}else if(e.currentToken().value==="\\"){e.consumeToken();e.consumeToken()}else{var n=e.consumeToken();t[t.length-1]+=n?n.value:""}}while(e.hasMore());t.push(e.lastWhitespace());return t}ensureTerminated(e){const t=this.runtime;var r={type:"implicitReturn",op:function(e){e.meta.returned=true;if(e.meta.resolve){e.meta.resolve()}return t.HALT},execute:function(e){}};var n=e;while(n.next){n=n.next}n.next=r}}class o{constructor(e,t){this.lexer=e??new n;this.parser=t??new a(this).use(h).use(v);this.parser.runtime=this}matchesSelector(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}makeEvent(t,r){var n;if(e.Event&&typeof e.Event==="function"){n=new Event(t,{bubbles:true,cancelable:true});n["detail"]=r}else{n=document.createEvent("CustomEvent");n.initCustomEvent(t,true,true,r)}return n}triggerEvent(e,t,r,n){r=r||{};r["sender"]=n;var i=this.makeEvent(t,r);var a=e.dispatchEvent(i);return a}isArrayLike(e){return Array.isArray(e)||typeof NodeList!=="undefined"&&(e instanceof NodeList||e instanceof HTMLCollection)}isIterable(e){return typeof e==="object"&&Symbol.iterator in e&&typeof e[Symbol.iterator]==="function"}shouldAutoIterate(e){return e!=null&&e[l]||this.isArrayLike(e)}forEach(e,t){if(e==null){}else if(this.isIterable(e)){for(const r of e){t(r)}}else if(this.isArrayLike(e)){for(var r=0;r<e.length;r++){t(e[r])}}else{t(e)}}implicitLoop(e,t){if(this.shouldAutoIterate(e)){for(const r of e)t(r)}else{t(e)}}wrapArrays(e){var t=[];for(var r=0;r<e.length;r++){var n=e[r];if(Array.isArray(n)){t.push(Promise.all(n))}else{t.push(n)}}return t}unwrapAsyncs(e){for(var t=0;t<e.length;t++){var r=e[t];if(r.asyncWrapper){e[t]=r.value}if(Array.isArray(r)){for(var n=0;n<r.length;n++){var i=r[n];if(i.asyncWrapper){r[n]=i.value}}}}}static HALT={};HALT=o.HALT;unifiedExec(e,t){while(true){try{var r=this.unifiedEval(e,t)}catch(n){if(t.meta.handlingFinally){console.error(" Exception in finally block: ",n);r=o.HALT}else{this.registerHyperTrace(t,n);if(t.meta.errorHandler&&!t.meta.handlingError){t.meta.handlingError=true;t.locals[t.meta.errorSymbol]=n;e=t.meta.errorHandler;continue}else{t.meta.currentException=n;r=o.HALT}}}if(r==null){console.error(e," did not return a next element to execute! context: ",t);return}else if(r.then){r.then((e=>{this.unifiedExec(e,t)})).catch((e=>{this.unifiedExec({op:function(){throw e}},t)}));return}else if(r===o.HALT){if(t.meta.finallyHandler&&!t.meta.handlingFinally){t.meta.handlingFinally=true;e=t.meta.finallyHandler}else{if(t.meta.onHalt){t.meta.onHalt()}if(t.meta.currentException){if(t.meta.reject){t.meta.reject(t.meta.currentException);return}else{throw t.meta.currentException}}else{return}}}else{e=r}}}unifiedEval(e,t){var r=[t];var n=false;var i=false;if(e.args){for(var a=0;a<e.args.length;a++){var o=e.args[a];if(o==null){r.push(null)}else if(Array.isArray(o)){var s=[];for(var u=0;u<o.length;u++){var l=o[u];var c=l?l.evaluate(t):null;if(c){if(c.then){n=true}else if(c.asyncWrapper){i=true}}s.push(c)}r.push(s)}else if(o.evaluate){var c=o.evaluate(t);if(c){if(c.then){n=true}else if(c.asyncWrapper){i=true}}r.push(c)}else{r.push(o)}}}if(n){return new Promise(((t,n)=>{r=this.wrapArrays(r);Promise.all(r).then((function(r){if(i){this.unwrapAsyncs(r)}try{var a=e.op.apply(e,r);t(a)}catch(e){n(e)}})).catch((function(e){n(e)}))}))}else{if(i){this.unwrapAsyncs(r)}return e.op.apply(e,r)}}_scriptAttrs=null;getScriptAttributes(){if(this._scriptAttrs==null){this._scriptAttrs=r.attributes.replace(/ /g,"").split(",")}return this._scriptAttrs}getScript(e){for(var t=0;t<this.getScriptAttributes().length;t++){var r=this.getScriptAttributes()[t];if(e.hasAttribute&&e.hasAttribute(r)){return e.getAttribute(r)}}if(e instanceof HTMLScriptElement&&e.type==="text/hyperscript"){return e.innerText}return null}hyperscriptFeaturesMap=new WeakMap;getHyperscriptFeatures(e){var t=this.hyperscriptFeaturesMap.get(e);if(typeof t==="undefined"){if(e){this.hyperscriptFeaturesMap.set(e,t={})}}return t}addFeatures(e,t){if(e){Object.assign(t.locals,this.getHyperscriptFeatures(e));this.addFeatures(e.parentElement,t)}}makeContext(e,t,r,n){return new s(e,t,r,n,this)}getScriptSelector(){return this.getScriptAttributes().map((function(e){return"["+e+"]"})).join(", ")}convertValue(e,r){var n=t.dynamicResolvers;for(var i=0;i<n.length;i++){var a=n[i];var o=a(r,e);if(o!==undefined){return o}}if(e==null){return null}var s=t[r];if(s){return s(e)}throw"Unknown conversion : "+r}parse(e){const t=this.lexer,r=this.parser;var n=t.tokenize(e);if(this.parser.commandStart(n.currentToken())){var i=r.requireElement("commandList",n);if(n.hasMore())r.raiseParseError(n);r.ensureTerminated(i);return i}else if(r.featureStart(n.currentToken())){var a=r.requireElement("hyperscript",n);if(n.hasMore())r.raiseParseError(n);return a}else{var o=r.requireElement("expression",n);if(n.hasMore())r.raiseParseError(n);return o}}evaluateNoPromise(e,t){let r=e.evaluate(t);if(r.next){throw new Error(i.sourceFor.call(e)+" returned a Promise in a context that they are not allowed.")}return r}evaluate(t,r,n){class i extends EventTarget{constructor(e){super();this.module=e}toString(){return this.module.id}}var a="document"in e?e.document.body:new i(n&&n.module);r=Object.assign(this.makeContext(a,null,a,null),r||{});var o=this.parse(t);if(o.execute){o.execute(r);return r.result}else if(o.apply){o.apply(a,a,n);return this.getHyperscriptFeatures(a)}else{return o.evaluate(r)}function s(){return{}}}processNode(e){var t=this.getScriptSelector();if(this.matchesSelector(e,t)){this.initElement(e,e)}if(e instanceof HTMLScriptElement&&e.type==="text/hyperscript"){this.initElement(e,document.body)}if(e.querySelectorAll){this.forEach(e.querySelectorAll(t+", [type='text/hyperscript']"),(e=>{this.initElement(e,e instanceof HTMLScriptElement&&e.type==="text/hyperscript"?document.body:e)}))}}initElement(e,t){if(e.closest&&e.closest(r.disableSelector)){return}var n=this.getInternalData(e);if(!n.initialized){var i=this.getScript(e);if(i){try{n.initialized=true;n.script=i;const r=this.lexer,s=this.parser;var a=r.tokenize(i);var o=s.parseHyperScript(a);if(!o)return;o.apply(t||e,e);setTimeout((()=>{this.triggerEvent(t||e,"load",{hyperscript:true})}),1)}catch(t){this.triggerEvent(e,"exception",{error:t});console.error("hyperscript errors were found on the following element:",e,"\n\n",t.message,t.stack)}}}}internalDataMap=new WeakMap;getInternalData(e){var t=this.internalDataMap.get(e);if(typeof t==="undefined"){this.internalDataMap.set(e,t={})}return t}typeCheck(e,t,r){if(e==null&&r){return true}var n=Object.prototype.toString.call(e).slice(8,-1);return n===t}getElementScope(e){var t=e.meta&&e.meta.owner;if(t){var r=this.getInternalData(t);var n="elementScope";if(e.meta.feature&&e.meta.feature.behavior){n=e.meta.feature.behavior+"Scope"}var i=c(r,n);return i}else{return{}}}isReservedWord(e){return["meta","it","result","locals","event","target","detail","sender","body"].includes(e)}isHyperscriptContext(e){return e instanceof s}resolveSymbol(t,r,n){if(t==="me"||t==="my"||t==="I"){return r.me}if(t==="it"||t==="its"||t==="result"){return r.result}if(t==="you"||t==="your"||t==="yourself"){return r.you}else{if(n==="global"){return e[t]}else if(n==="element"){var i=this.getElementScope(r);return i[t]}else if(n==="local"){return r.locals[t]}else{if(r.meta&&r.meta.context){var a=r.meta.context[t];if(typeof a!=="undefined"){return a}}if(this.isHyperscriptContext(r)&&!this.isReservedWord(t)){var o=r.locals[t]}else{var o=r[t]}if(typeof o!=="undefined"){return o}else{var i=this.getElementScope(r);o=i[t];if(typeof o!=="undefined"){return o}else{return e[t]}}}}}setSymbol(t,r,n,i){if(n==="global"){e[t]=i}else if(n==="element"){var a=this.getElementScope(r);a[t]=i}else if(n==="local"){r.locals[t]=i}else{if(this.isHyperscriptContext(r)&&!this.isReservedWord(t)&&typeof r.locals[t]!=="undefined"){r.locals[t]=i}else{var a=this.getElementScope(r);var o=a[t];if(typeof o!=="undefined"){a[t]=i}else{if(this.isHyperscriptContext(r)&&!this.isReservedWord(t)){r.locals[t]=i}else{r[t]=i}}}}}findNext(e,t){if(e){if(e.resolveNext){return e.resolveNext(t)}else if(e.next){return e.next}else{return this.findNext(e.parent,t)}}}flatGet(e,t,r){if(e!=null){var n=r(e,t);if(typeof n!=="undefined"){return n}if(this.shouldAutoIterate(e)){var i=[];for(var a of e){var o=r(a,t);i.push(o)}return i}}}resolveProperty(e,t){return this.flatGet(e,t,((e,t)=>e[t]))}resolveAttribute(e,t){return this.flatGet(e,t,((e,t)=>e.getAttribute&&e.getAttribute(t)))}resolveStyle(e,t){return this.flatGet(e,t,((e,t)=>e.style&&e.style[t]))}resolveComputedStyle(e,t){return this.flatGet(e,t,((e,t)=>getComputedStyle(e).getPropertyValue(t)))}assignToNamespace(t,r,n,i){let a;if(typeof document!=="undefined"&&t===document.body){a=e}else{a=this.getHyperscriptFeatures(t)}var o;while((o=r.shift())!==undefined){var s=a[o];if(s==null){s={};a[o]=s}a=s}a[n]=i}getHyperTrace(e,t){var r=[];var n=e;while(n.meta.caller){n=n.meta.caller}if(n.meta.traceMap){return n.meta.traceMap.get(t,r)}}registerHyperTrace(e,t){var r=[];var n=null;while(e!=null){r.push(e);n=e;e=e.meta.caller}if(n.meta.traceMap==null){n.meta.traceMap=new Map}if(!n.meta.traceMap.get(t)){var i={trace:r,print:function(e){e=e||console.error;e("hypertrace /// ");var t=0;for(var n=0;n<r.length;n++){t=Math.max(t,r[n].meta.feature.displayName.length)}for(var n=0;n<r.length;n++){var i=r[n];e(" ->",i.meta.feature.displayName.padEnd(t+2),"-",i.meta.owner)}}};n.meta.traceMap.set(t,i)}}escapeSelector(e){return e.replace(/:/g,(function(e){return"\\"+e}))}nullCheck(e,t){if(e==null){throw new Error("'"+t.sourceFor()+"' is null")}}isEmpty(e){return e==undefined||e.length=== |