Compare commits
	
		
			No commits in common. "93dc74a4cc66280c914c654608a6190c0bc1a9cd" and "9faa5fb1702cac6d87b26721f4e642e6ff705856" have entirely different histories.
		
	
	
		
			93dc74a4cc
			...
			9faa5fb170
		
	
		
					 93 changed files with 3589 additions and 2819 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -4,7 +4,6 @@ venv/
 | 
				
			||||||
scanners/ole/venv/
 | 
					scanners/ole/venv/
 | 
				
			||||||
tmp/
 | 
					tmp/
 | 
				
			||||||
temp/
 | 
					temp/
 | 
				
			||||||
node_modules
 | 
					 | 
				
			||||||
**/__pycache__
 | 
					**/__pycache__
 | 
				
			||||||
# Created by https://www.toptal.com/developers/gitignore/api/linux,go,vim,visualstudiocode,macos,windows
 | 
					# Created by https://www.toptal.com/developers/gitignore/api/linux,go,vim,visualstudiocode,macos,windows
 | 
				
			||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=linux,go,vim,visualstudiocode,macos,windows
 | 
					# Edit at https://www.toptal.com/developers/gitignore?templates=linux,go,vim,visualstudiocode,macos,windows
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -27,14 +27,13 @@ clean: ## Delete build artifacts
 | 
				
			||||||
	rm -rf storage/*
 | 
						rm -rf storage/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dev: ## Start templ-dev tailwind-dev and watch
 | 
					dev: ## Start templ-dev tailwind-dev and watch
 | 
				
			||||||
	make -j5 templ-dev tailwind-dev capa-dev ole-dev watch
 | 
						make -j3 templ-dev tailwind-dev watch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
templ-dev: ## Watch & Live rebuild of templ
 | 
					templ-dev: ## Watch & Live rebuild of templ
 | 
				
			||||||
	templ generate --watch --proxy="http://localhost:8080" --open-browser=false
 | 
						templ generate --watch --proxy="http://localhost:8080" --open-browser=false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tailwind-dev: ##Live rebuild of tailwind
 | 
					tailwind-dev: ##Live rebuild of tailwind
 | 
				
			||||||
	#tailwindcss -o server/web/assets/styles.css -i input.css --watch
 | 
						tailwindcss -o server/web/assets/styles.css -i input.css --watch
 | 
				
			||||||
	npx @tailwindcss/cli -o server/web/assets/styles.css -i input.css --watch
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
ole-dev: ##Live rebouild of ole-scanner
 | 
					ole-dev: ##Live rebouild of ole-scanner
 | 
				
			||||||
	. ./venv/bin/activate; \
 | 
						. ./venv/bin/activate; \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,8 +12,3 @@ these dependencies are required additionally to what is specified in go.mod and
 | 
				
			||||||
- python3 3.13
 | 
					- python3 3.13
 | 
				
			||||||
- python3-venv
 | 
					- python3-venv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
## TODO
 | 
					 | 
				
			||||||
ICAP - if someone wants to integrate (multiple) Antivirus scanners
 | 
					 | 
				
			||||||
CAPE - for dynamic sandbox analysis
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,5 +17,4 @@ services:
 | 
				
			||||||
      - "5001:5001"
 | 
					      - "5001:5001"
 | 
				
			||||||
    volumes:
 | 
					    volumes:
 | 
				
			||||||
      - "./storage/files:/mnt/storage/files"
 | 
					      - "./storage/files:/mnt/storage/files"
 | 
				
			||||||
#  db:
 | 
					
 | 
				
			||||||
#    image: 'postgres:latest'
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
										
									
									
									
								
							| 
						 | 
					@ -4,7 +4,7 @@ go 1.24.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/Oudwins/tailwind-merge-go v0.2.1
 | 
						github.com/Oudwins/tailwind-merge-go v0.2.1
 | 
				
			||||||
	github.com/a-h/templ v0.3.924
 | 
						github.com/a-h/templ v0.3.865
 | 
				
			||||||
	github.com/gabriel-vasile/mimetype v1.4.9
 | 
						github.com/gabriel-vasile/mimetype v1.4.9
 | 
				
			||||||
	github.com/gorilla/securecookie v1.1.2
 | 
						github.com/gorilla/securecookie v1.1.2
 | 
				
			||||||
	github.com/gorilla/sessions v1.4.0
 | 
						github.com/gorilla/sessions v1.4.0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
										
									
									
									
								
							| 
						 | 
					@ -2,8 +2,6 @@ github.com/Oudwins/tailwind-merge-go v0.2.1 h1:jxRaEqGtwwwF48UuFIQ8g8XT7YSualNuG
 | 
				
			||||||
github.com/Oudwins/tailwind-merge-go v0.2.1/go.mod h1:kkZodgOPvZQ8f7SIrlWkG/w1g9JTbtnptnePIh3V72U=
 | 
					github.com/Oudwins/tailwind-merge-go v0.2.1/go.mod h1:kkZodgOPvZQ8f7SIrlWkG/w1g9JTbtnptnePIh3V72U=
 | 
				
			||||||
github.com/a-h/templ v0.3.865 h1:nYn5EWm9EiXaDgWcMQaKiKvrydqgxDUtT1+4zU2C43A=
 | 
					github.com/a-h/templ v0.3.865 h1:nYn5EWm9EiXaDgWcMQaKiKvrydqgxDUtT1+4zU2C43A=
 | 
				
			||||||
github.com/a-h/templ v0.3.865/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
 | 
					github.com/a-h/templ v0.3.865/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
 | 
				
			||||||
github.com/a-h/templ v0.3.924 h1:t5gZqTneXqvehpNZsgtnlOscnBboNh9aASBH2MgV/0k=
 | 
					 | 
				
			||||||
github.com/a-h/templ v0.3.924/go.mod h1:FFAu4dI//ESmEN7PQkJ7E7QfnSEMdcnu7QrAY8Dn334=
 | 
					 | 
				
			||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
					github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1063
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										1063
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,6 +0,0 @@
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					 | 
				
			||||||
    "@tailwindcss/cli": "^4.1.11",
 | 
					 | 
				
			||||||
    "tailwindcss": "^4.1.11"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,4 @@
 | 
				
			||||||
from flask import Blueprint, request, abort
 | 
					from flask import Blueprint, request, abort
 | 
				
			||||||
from flask.json import jsonify
 | 
					 | 
				
			||||||
from werkzeug.utils import secure_filename
 | 
					from werkzeug.utils import secure_filename
 | 
				
			||||||
import capa.main
 | 
					import capa.main
 | 
				
			||||||
import capa.rules
 | 
					import capa.rules
 | 
				
			||||||
| 
						 | 
					@ -12,13 +11,9 @@ from pathlib import Path
 | 
				
			||||||
import config
 | 
					import config
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import capa.render.utils as rutils
 | 
					
 | 
				
			||||||
import capa.render.result_document as rd
 | 
					 | 
				
			||||||
import collections
 | 
					 | 
				
			||||||
from capa.render.default import find_subrule_matches
 | 
					 | 
				
			||||||
capa_bp = Blueprint('capa', __name__)
 | 
					capa_bp = Blueprint('capa', __name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This function is essentially a hacked up version of https://github.com/mandiant/capa/blob/master/capa/render/default.py
 | 
					 | 
				
			||||||
@capa_bp.route('/analyze', methods=['GET'])
 | 
					@capa_bp.route('/analyze', methods=['GET'])
 | 
				
			||||||
def analyze_capa():
 | 
					def analyze_capa():
 | 
				
			||||||
    file = secure_filename(request.args.get('file', ''))
 | 
					    file = secure_filename(request.args.get('file', ''))
 | 
				
			||||||
| 
						 | 
					@ -34,82 +29,6 @@ def analyze_capa():
 | 
				
			||||||
    capabilities = capa.capabilities.common.find_capabilities(rules, extractor, disable_progress=True)
 | 
					    capabilities = capa.capabilities.common.find_capabilities(rules, extractor, disable_progress=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    meta = capa.loader.collect_metadata([], filepath, FORMAT_AUTO, OS_AUTO, [capa.main.get_default_root()/ "rules"], extractor, capabilities)
 | 
					    meta = capa.loader.collect_metadata([], filepath, FORMAT_AUTO, OS_AUTO, [capa.main.get_default_root()/ "rules"], extractor, capabilities)
 | 
				
			||||||
    doc = rd.ResultDocument.from_capa(meta, rules, capabilities.matches)
 | 
					 | 
				
			||||||
    caps = {}
 | 
					 | 
				
			||||||
    tactics = {}
 | 
					 | 
				
			||||||
    maec = {}
 | 
					 | 
				
			||||||
    objectives = {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    subrule_matches = find_subrule_matches(doc)
 | 
					 | 
				
			||||||
    for rule in rutils.capability_rules(doc):
 | 
					 | 
				
			||||||
        if rule.meta.name in subrule_matches:
 | 
					 | 
				
			||||||
            # rules that are also matched by other rules should not get rendered by default.
 | 
					 | 
				
			||||||
            # this cuts down on the amount of output while giving approx the same detail.
 | 
					 | 
				
			||||||
            # see #224
 | 
					 | 
				
			||||||
            continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        count = len(rule.matches)
 | 
					 | 
				
			||||||
        if count == 1:
 | 
					 | 
				
			||||||
            capability = rule.meta.name
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            capability = rule.meta.name + f" ({count} matches)"
 | 
					 | 
				
			||||||
        caps[capability] = rule.meta.namespace
 | 
					 | 
				
			||||||
        for attack in rule.meta.attack:
 | 
					 | 
				
			||||||
            tactics[attack.tactic] = attack.technique + attack.subtechnique + attack.id.strip("[").strip("]")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    maec_categories = {
 | 
					 | 
				
			||||||
        "analysis_conclusion",
 | 
					 | 
				
			||||||
        "analysis_conclusion_ov",
 | 
					 | 
				
			||||||
        "malware_family",
 | 
					 | 
				
			||||||
        "malware_category",
 | 
					 | 
				
			||||||
        "malware_category_ov",
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for rule in rutils.maec_rules(doc):
 | 
					 | 
				
			||||||
        for maec_category in maec_categories:
 | 
					 | 
				
			||||||
            maec_value = getattr(rule.meta.maec, maec_category, None)
 | 
					 | 
				
			||||||
            if maec_value:
 | 
					 | 
				
			||||||
                maec[maec_category] = maec_value
 | 
					 | 
				
			||||||
    for rule in rutils.capability_rules(doc):
 | 
					 | 
				
			||||||
        for mbc in rule.meta.mbc:
 | 
					 | 
				
			||||||
            objectives[mbc.objective] = mbc.behavior + mbc.method + mbc.id.strip("[").strip("]")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return jsonify(capabilities=caps, tactics=tactics, maec=maec, objectives=objectives)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@capa_bp.route('/json', methods=['GET'])
 | 
					 | 
				
			||||||
def analyze_capa_json():
 | 
					 | 
				
			||||||
    file = secure_filename(request.args.get('file', ''))
 | 
					 | 
				
			||||||
    if file == '':
 | 
					 | 
				
			||||||
        abort(400)
 | 
					 | 
				
			||||||
    filepath = Path(path.join(config.Config.FILE_DIRECTORY, file))
 | 
					 | 
				
			||||||
    if not os.path.exists(filepath):
 | 
					 | 
				
			||||||
        print(f"Error: File not found at '{filepath}'")
 | 
					 | 
				
			||||||
        abort(400)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rules = capa.rules.get_rules([Path(config.Config.RULES)])
 | 
					 | 
				
			||||||
    extractor = capa.loader.get_extractor(filepath, FORMAT_AUTO, OS_AUTO, capa.main.BACKEND_VIV, [], should_save_workspace=False, disable_progress=True)
 | 
					 | 
				
			||||||
    capabilities = capa.capabilities.common.find_capabilities(rules, extractor, disable_progress=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    meta = capa.loader.collect_metadata([], filepath, FORMAT_AUTO, OS_AUTO, [capa.main.get_default_root()/ "rules"], extractor, capabilities)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return json.loads(capa.render.json.render(meta=meta, rules=rules, capabilities=capabilities.matches))
 | 
					    return json.loads(capa.render.json.render(meta=meta, rules=rules, capabilities=capabilities.matches))
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@capa_bp.route('/default', methods=['GET'])
 | 
					 | 
				
			||||||
def analyze_capa_default():
 | 
					 | 
				
			||||||
    file = secure_filename(request.args.get('file', ''))
 | 
					 | 
				
			||||||
    if file == '':
 | 
					 | 
				
			||||||
        abort(400)
 | 
					 | 
				
			||||||
    filepath = Path(path.join(config.Config.FILE_DIRECTORY, file))
 | 
					 | 
				
			||||||
    if not os.path.exists(filepath):
 | 
					 | 
				
			||||||
        print(f"Error: File not found at '{filepath}'")
 | 
					 | 
				
			||||||
        abort(400)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rules = capa.rules.get_rules([Path(config.Config.RULES)])
 | 
					 | 
				
			||||||
    extractor = capa.loader.get_extractor(filepath, FORMAT_AUTO, OS_AUTO, capa.main.BACKEND_VIV, [], should_save_workspace=False, disable_progress=True)
 | 
					 | 
				
			||||||
    capabilities = capa.capabilities.common.find_capabilities(rules, extractor, disable_progress=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    meta = capa.loader.collect_metadata([], filepath, FORMAT_AUTO, OS_AUTO, [capa.main.get_default_root()/ "rules"], extractor, capabilities)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return capa.render.default.render(meta=meta, rules=rules, capabilities=capabilities.matches)
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,9 +36,6 @@ func setDefaults() {
 | 
				
			||||||
	viper.SetDefault("web.key", "/etc/ssl/key/ssl-cert-snakeoil.key")
 | 
						viper.SetDefault("web.key", "/etc/ssl/key/ssl-cert-snakeoil.key")
 | 
				
			||||||
	viper.SetDefault("web.loghttp", true)
 | 
						viper.SetDefault("web.loghttp", true)
 | 
				
			||||||
	viper.SetDefault("web.maxfilesizemb", 100)
 | 
						viper.SetDefault("web.maxfilesizemb", 100)
 | 
				
			||||||
	viper.SetDefault("web.download.usermax", 5)
 | 
					 | 
				
			||||||
	viper.SetDefault("web.download.anonmax", 1)
 | 
					 | 
				
			||||||
	viper.SetDefault("web.download.disable", false)
 | 
					 | 
				
			||||||
	// Database
 | 
						// Database
 | 
				
			||||||
	viper.SetDefault("db.host", "localhost")
 | 
						viper.SetDefault("db.host", "localhost")
 | 
				
			||||||
	viper.SetDefault("db.port", 5432)
 | 
						viper.SetDefault("db.port", 5432)
 | 
				
			||||||
| 
						 | 
					@ -48,7 +45,6 @@ func setDefaults() {
 | 
				
			||||||
	viper.SetDefault("db.debug", false)
 | 
						viper.SetDefault("db.debug", false)
 | 
				
			||||||
	// Others
 | 
						// Others
 | 
				
			||||||
	viper.SetDefault("processing.oleurl", "http://localhost:5000")
 | 
						viper.SetDefault("processing.oleurl", "http://localhost:5000")
 | 
				
			||||||
	viper.SetDefault("processing.capaurl", "http://localhost:5001")
 | 
					 | 
				
			||||||
	viper.SetDefault("processing.maxmimesize", "100MB")
 | 
						viper.SetDefault("processing.maxmimesize", "100MB")
 | 
				
			||||||
	viper.SetDefault("processing.yararules", "./storage/rules")
 | 
						viper.SetDefault("processing.yararules", "./storage/rules")
 | 
				
			||||||
	viper.SetDefault("processing.yaracompiled", "./storage/output.yarc")
 | 
						viper.SetDefault("processing.yaracompiled", "./storage/output.yarc")
 | 
				
			||||||
| 
						 | 
					@ -57,7 +53,7 @@ func setDefaults() {
 | 
				
			||||||
	// UI Interface info
 | 
						// UI Interface info
 | 
				
			||||||
	viper.SetDefault("ui.name", "Scanfile")
 | 
						viper.SetDefault("ui.name", "Scanfile")
 | 
				
			||||||
	viper.SetDefault("ui.byurl", "https://www.jmbit.de")
 | 
						viper.SetDefault("ui.byurl", "https://www.jmbit.de")
 | 
				
			||||||
	viper.SetDefault("ui.byname", "Johannes Bülow")
 | 
						viper.SetDefault("ui.byurl", "Johannes Bülow")
 | 
				
			||||||
	viper.SetDefault("ui.source", "https://git.jmbit.de/jmb/scanfile")
 | 
						viper.SetDefault("ui.source", "https://git.jmbit.de/jmb/scanfile")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@ package database
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"log/slog"
 | 
						"log/slog"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.jmbit.de/jmb/scanfile/server/internal/sqlc"
 | 
						"git.jmbit.de/jmb/scanfile/server/internal/sqlc"
 | 
				
			||||||
| 
						 | 
					@ -78,63 +77,5 @@ func GetAllFiles() ([]sqlc.File, error) {
 | 
				
			||||||
		slog.Error("Error in GetAllProperties", "error", err)
 | 
							slog.Error("Error in GetAllProperties", "error", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return files, err
 | 
						return files, err
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
func InsertFileDiec(params sqlc.InsertFileDIECParams) error {
 | 
					 | 
				
			||||||
	query := sqlc.New(pool)
 | 
					 | 
				
			||||||
	err := query.InsertFileDIEC(context.Background(), params)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error from query in InsertFileDiec", "file-uuid", params.FileID.String(), "error", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
} 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func GetFileDiec(fileID pgtype.UUID) (Diec, error){
 | 
					 | 
				
			||||||
	var r Diec
 | 
					 | 
				
			||||||
	var data DiecData
 | 
					 | 
				
			||||||
	query := sqlc.New(pool)
 | 
					 | 
				
			||||||
	rawDiec, err := query.GetFileDIEC(context.Background(), fileID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error from query in GetFileDiec", "file-uuid", fileID.String(), "error", err)
 | 
					 | 
				
			||||||
		return r, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	r.ID = rawDiec.ID
 | 
					 | 
				
			||||||
	r.FileID = rawDiec.FileID
 | 
					 | 
				
			||||||
	err = json.Unmarshal(rawDiec.Data, &data)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error in GetFileDiec", "file-uuid", fileID.String(), "error", err)
 | 
					 | 
				
			||||||
		return r, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	r.Data = data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return r, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func InsertFileCapa(params sqlc.InsertFileCapaParams) error {
 | 
					 | 
				
			||||||
	query := sqlc.New(pool)
 | 
					 | 
				
			||||||
	err := query.InsertFileCapa(context.Background(), params)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error from Query in InsertFileCapa", "file-uuid", params.FileID.String(), "error", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func GetFileCapa(fileID pgtype.UUID) (CapaResult, error) {
 | 
					 | 
				
			||||||
	var r CapaResult
 | 
					 | 
				
			||||||
	var data CapaData
 | 
					 | 
				
			||||||
	query := sqlc.New(pool)
 | 
					 | 
				
			||||||
	rawResult, err := query.GetFileCapa(context.Background(), fileID)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error from Query in GetFileCapa", "file-uuid", fileID.String(), "error", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	r.ID = rawResult.ID
 | 
					 | 
				
			||||||
	r.FileID = rawResult.FileID
 | 
					 | 
				
			||||||
	err = json.Unmarshal(rawResult.Data, &data)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error in GetFileCapa", "file-uuid", fileID.String(), "error", err)
 | 
					 | 
				
			||||||
		return r, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return r, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,37 +0,0 @@
 | 
				
			||||||
package database
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "github.com/jackc/pgx/v5/pgtype"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type DiecData struct {
 | 
					 | 
				
			||||||
	Detects []struct {
 | 
					 | 
				
			||||||
		Filetype       string `json:"filetype"`
 | 
					 | 
				
			||||||
		Parentfilepart string `json:"parentfilepart"`
 | 
					 | 
				
			||||||
		Values         []struct {
 | 
					 | 
				
			||||||
			Info    string `json:"info"`
 | 
					 | 
				
			||||||
			Name    string `json:"name"`
 | 
					 | 
				
			||||||
			String  string `json:"string"`
 | 
					 | 
				
			||||||
			Type    string `json:"type"`
 | 
					 | 
				
			||||||
			Version string `json:"version"`
 | 
					 | 
				
			||||||
		} `json:"values"`
 | 
					 | 
				
			||||||
	} `json:"detects"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Diec struct {
 | 
					 | 
				
			||||||
	ID int64
 | 
					 | 
				
			||||||
	FileID pgtype.UUID
 | 
					 | 
				
			||||||
	Data DiecData
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type CapaResult struct {
 | 
					 | 
				
			||||||
	ID int64
 | 
					 | 
				
			||||||
	FileID pgtype.UUID
 | 
					 | 
				
			||||||
	Data CapaData
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type CapaData struct {
 | 
					 | 
				
			||||||
	Capabilities map[string]string `json:"capabilities"`
 | 
					 | 
				
			||||||
	Maec map[string]string `json:"maec"`
 | 
					 | 
				
			||||||
	Objectives map[string]string `json:"objectives"`
 | 
					 | 
				
			||||||
	Tactics map[string]string `json:"tactics"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -50,7 +50,6 @@ func FailProcessingJob(jobid int64, jobErr error) error {
 | 
				
			||||||
	var params sqlc.FailProcessingJobParams
 | 
						var params sqlc.FailProcessingJobParams
 | 
				
			||||||
	params.ID = jobid
 | 
						params.ID = jobid
 | 
				
			||||||
	params.Error.String = jobErr.Error()
 | 
						params.Error.String = jobErr.Error()
 | 
				
			||||||
	params.Error.Valid = true
 | 
					 | 
				
			||||||
	err := query.FailProcessingJob(context.Background(), params)
 | 
						err := query.FailProcessingJob(context.Background(), params)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		slog.Error("Unable to mark processing job as failed", "job-id", jobid, "error", err)
 | 
							slog.Error("Unable to mark processing job as failed", "job-id", jobid, "error", err)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,17 +13,3 @@ INSERT INTO diec (
 | 
				
			||||||
  file_id, data
 | 
					  file_id, data
 | 
				
			||||||
) VALUES ($1, $2);
 | 
					) VALUES ($1, $2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- name: GetFileDIEC :one
 | 
					 | 
				
			||||||
SELECT * FROM diec
 | 
					 | 
				
			||||||
WHERE file_id = $1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- name: InsertFileCapa :exec
 | 
					 | 
				
			||||||
INSERT INTO capa_results (
 | 
					 | 
				
			||||||
 file_id, data
 | 
					 | 
				
			||||||
) VALUES ($1, $2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- name: GetFileCapa :one
 | 
					 | 
				
			||||||
SELECT * FROM capa_results
 | 
					 | 
				
			||||||
WHERE file_id = $1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,25 @@
 | 
				
			||||||
 | 
					-- name: InsertFileMsofficeOleid :exec
 | 
				
			||||||
 | 
					INSERT INTO msoffice_oleid (
 | 
				
			||||||
 | 
					  file_id, data
 | 
				
			||||||
 | 
					) VALUES ($1, $2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: InsertFileMsofficeOlevba :exec
 | 
				
			||||||
 | 
					INSERT INTO msoffice_olevba (
 | 
				
			||||||
 | 
					  file_id, data
 | 
				
			||||||
 | 
					) VALUES ($1, $2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: InsertFileMsofficeMraptor :exec
 | 
				
			||||||
 | 
					INSERT INTO msoffice_mraptor (
 | 
				
			||||||
 | 
					  file_id, data
 | 
				
			||||||
 | 
					) VALUES ($1, $2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: GetMSOfficeData :one
 | 
				
			||||||
 | 
					SELECT t1.file_id, t1.data AS oleid, t2.data AS olevba, t3.data AS mraptor
 | 
				
			||||||
 | 
					 FROM msoffice_oleid as t1
 | 
				
			||||||
 | 
					 LEFT join msoffice_olevba AS t2 ON t2.file_id = t1.file_id
 | 
				
			||||||
 | 
					 LEFT JOIN msoffice_mraptor AS t3 ON t3.file_id = t1.file_id
 | 
				
			||||||
 | 
					 WHERE t1.file_id = $1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- name: InsertMSOfficeResults :exec
 | 
					-- name: InsertMSOfficeResults :exec
 | 
				
			||||||
INSERT INTO msoffice (
 | 
					INSERT INTO msoffice (
 | 
				
			||||||
  file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros,
 | 
					  file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,10 @@ SET completed = NOW(),
 | 
				
			||||||
  status = 'completed'
 | 
					  status = 'completed'
 | 
				
			||||||
WHERE id = $1;
 | 
					WHERE id = $1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- name: GetJobsForFile :many
 | 
				
			||||||
 | 
					SELECT * FROM processing_jobs
 | 
				
			||||||
 | 
					WHERE file_id = $1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- name: GetJob :one
 | 
					-- name: GetJob :one
 | 
				
			||||||
SELECT * FROM processing_jobs
 | 
					SELECT * FROM processing_jobs
 | 
				
			||||||
WHERE id = $1
 | 
					WHERE id = $1
 | 
				
			||||||
| 
						 | 
					@ -30,8 +34,3 @@ WHERE id = $2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- name: GetAllJobs :many
 | 
					-- name: GetAllJobs :many
 | 
				
			||||||
SELECT * FROM processing_jobs;
 | 
					SELECT * FROM processing_jobs;
 | 
				
			||||||
 | 
					 | 
				
			||||||
-- name: GetJobsForFile :many
 | 
					 | 
				
			||||||
SELECT * FROM processing_jobs
 | 
					 | 
				
			||||||
WHERE file_id = $1
 | 
					 | 
				
			||||||
ORDER BY created DESC;
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,32 +0,0 @@
 | 
				
			||||||
-- CreateUser :exec
 | 
					 | 
				
			||||||
INSERT INTO users (
 | 
					 | 
				
			||||||
  user_name, display_name, pw_hash, email_address
 | 
					 | 
				
			||||||
) VALUES ($1, $2, $3, $4);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- DeleteUser :exec
 | 
					 | 
				
			||||||
DELETE FROM users
 | 
					 | 
				
			||||||
WHERE id = $1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- UpdateUserPW :exec
 | 
					 | 
				
			||||||
UPDATE users 
 | 
					 | 
				
			||||||
SET pw_hash = $2
 | 
					 | 
				
			||||||
WHERE id = $1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- UpdateUserName :exec
 | 
					 | 
				
			||||||
UPDATE users
 | 
					 | 
				
			||||||
SET user_name = $2
 | 
					 | 
				
			||||||
WHERE id = $1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- UpdateUserDisplayName :exec
 | 
					 | 
				
			||||||
UPDATE users
 | 
					 | 
				
			||||||
SET display_name = $2
 | 
					 | 
				
			||||||
WHERE id = $1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- GetUser :one
 | 
					 | 
				
			||||||
SELECT * FROM users 
 | 
					 | 
				
			||||||
WHERE id = $1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- GetUserByName :one
 | 
					 | 
				
			||||||
SELECT * FROM users
 | 
					 | 
				
			||||||
WHERE user_name = $1;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -2,17 +2,6 @@
 | 
				
			||||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
 | 
					CREATE EXTENSION IF NOT EXISTS "pgcrypto";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Tables
 | 
					-- Tables
 | 
				
			||||||
 | 
					 | 
				
			||||||
CREATE TABLE IF NOT EXISTS users (
 | 
					 | 
				
			||||||
  id BIGSERIAL PRIMARY KEY,
 | 
					 | 
				
			||||||
  user_name TEXT NOT NULL UNIQUE,
 | 
					 | 
				
			||||||
  display_name TEXT NOT NULL,
 | 
					 | 
				
			||||||
  pw_hash BYTEA NOT NULL,
 | 
					 | 
				
			||||||
  email_address TEXT NOT NULL,
 | 
					 | 
				
			||||||
  enabled BOOLEAN NOT NULL DEFAULT TRUE,
 | 
					 | 
				
			||||||
  created TIMESTAMP DEFAULT NOW() NOT NULL
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CREATE TABLE IF NOT EXISTS files (
 | 
					CREATE TABLE IF NOT EXISTS files (
 | 
				
			||||||
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 | 
					  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 | 
				
			||||||
  name TEXT NOT NULL,
 | 
					  name TEXT NOT NULL,
 | 
				
			||||||
| 
						 | 
					@ -20,8 +9,6 @@ CREATE TABLE IF NOT EXISTS files (
 | 
				
			||||||
  mimetype TEXT NOT NULL,
 | 
					  mimetype TEXT NOT NULL,
 | 
				
			||||||
  size BIGINT NOT NULL,
 | 
					  size BIGINT NOT NULL,
 | 
				
			||||||
  blake2 BYTEA NOT NULL UNIQUE,
 | 
					  blake2 BYTEA NOT NULL UNIQUE,
 | 
				
			||||||
  score DECIMAL,
 | 
					 | 
				
			||||||
  creator BIGINT REFERENCES users (id),
 | 
					 | 
				
			||||||
  created TIMESTAMP DEFAULT NOW() NOT NULL,
 | 
					  created TIMESTAMP DEFAULT NOW() NOT NULL,
 | 
				
			||||||
  updated TIMESTAMP DEFAULT NOW() NOT NULL
 | 
					  updated TIMESTAMP DEFAULT NOW() NOT NULL
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
| 
						 | 
					@ -29,7 +16,7 @@ CREATE TABLE IF NOT EXISTS files (
 | 
				
			||||||
CREATE TABLE IF NOT EXISTS processing_jobs (
 | 
					CREATE TABLE IF NOT EXISTS processing_jobs (
 | 
				
			||||||
  id BIGSERIAL PRIMARY KEY,
 | 
					  id BIGSERIAL PRIMARY KEY,
 | 
				
			||||||
  file_id UUID REFERENCES files (id) ON DELETE CASCADE,
 | 
					  file_id UUID REFERENCES files (id) ON DELETE CASCADE,
 | 
				
			||||||
  created TIMESTAMP DEFAULT NOW() NOT NULL,
 | 
					  created TIMESTAMP DEFAULT NOW(),
 | 
				
			||||||
  started TIMESTAMP,
 | 
					  started TIMESTAMP,
 | 
				
			||||||
  completed TIMESTAMP,
 | 
					  completed TIMESTAMP,
 | 
				
			||||||
  status TEXT,
 | 
					  status TEXT,
 | 
				
			||||||
| 
						 | 
					@ -41,8 +28,7 @@ CREATE TABLE IF NOT EXISTS processing_jobs (
 | 
				
			||||||
CREATE TABLE IF NOT EXISTS diec (
 | 
					CREATE TABLE IF NOT EXISTS diec (
 | 
				
			||||||
  id BIGSERIAL PRIMARY KEY,
 | 
					  id BIGSERIAL PRIMARY KEY,
 | 
				
			||||||
  file_id UUID REFERENCES files (id) ON DELETE CASCADE,
 | 
					  file_id UUID REFERENCES files (id) ON DELETE CASCADE,
 | 
				
			||||||
  data JSONB,
 | 
					  data JSONB
 | 
				
			||||||
  created TIMESTAMP DEFAULT NOW() NOT NULL
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CREATE TABLE IF NOT EXISTS msoffice (
 | 
					CREATE TABLE IF NOT EXISTS msoffice (
 | 
				
			||||||
| 
						 | 
					@ -60,8 +46,7 @@ CREATE TABLE IF NOT EXISTS msoffice (
 | 
				
			||||||
  nb_macros INTEGER,
 | 
					  nb_macros INTEGER,
 | 
				
			||||||
  nb_suspicious INTEGER,
 | 
					  nb_suspicious INTEGER,
 | 
				
			||||||
  olevba_results TEXT[][],
 | 
					  olevba_results TEXT[][],
 | 
				
			||||||
  macros TEXT[][],
 | 
					  macros TEXT[][]
 | 
				
			||||||
  created TIMESTAMP DEFAULT NOW() NOT NULL
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,32 +57,23 @@ CREATE TABLE IF NOT EXISTS file_properties (
 | 
				
			||||||
  md5 BYTEA,
 | 
					  md5 BYTEA,
 | 
				
			||||||
  libmagic_mime TEXT,
 | 
					  libmagic_mime TEXT,
 | 
				
			||||||
  libmagic_extension TEXT,
 | 
					  libmagic_extension TEXT,
 | 
				
			||||||
  libmagic_apple TEXT,
 | 
					  libmagic_apple TEXT
 | 
				
			||||||
  created TIMESTAMP DEFAULT NOW() NOT NULL
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CREATE TABLE IF NOT EXISTS yara_results (
 | 
					CREATE TABLE IF NOT EXISTS yara_results (
 | 
				
			||||||
  id BIGSERIAL PRIMARY KEY,
 | 
					  id BIGSERIAL PRIMARY KEY,
 | 
				
			||||||
  file_id UUID REFERENCES files (id) ON DELETE CASCADE,
 | 
					  file_id UUID REFERENCES files (id) ON DELETE CASCADE,
 | 
				
			||||||
  matched TEXT[],
 | 
					  matched TEXT[]
 | 
				
			||||||
  created TIMESTAMP DEFAULT NOW() NOT NULL
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CREATE TABLE IF NOT EXISTS capa_results (
 | 
					 | 
				
			||||||
  id BIGSERIAL PRIMARY KEY,
 | 
					 | 
				
			||||||
  file_id UUID REFERENCES files (id) ON DELETE CASCADE,
 | 
					 | 
				
			||||||
  data JSONB,
 | 
					 | 
				
			||||||
  type TEXT DEFAULT 'default' NOT NULL,
 | 
					 | 
				
			||||||
  created TIMESTAMP DEFAULT NOW() NOT NULL
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Indices
 | 
					-- Indices
 | 
				
			||||||
-- Since tables will be heavily accessed by file_id, there should be indices for them
 | 
					-- Since tables will be heavily accessed by file_id, there should be indices for them
 | 
				
			||||||
CREATE INDEX idx_diec_file_id ON diec (file_id);
 | 
					CREATE INDEX idx_diec_file_id ON diec (file_id);
 | 
				
			||||||
CREATE INDEX idx_processing_jobs_file_id ON processing_jobs (file_id);
 | 
					CREATE INDEX idx_processing_jobs_file_id ON processing_jobs (file_id);
 | 
				
			||||||
 | 
					CREATE INDEX idx_msoffice_oleid_file_id ON msoffice_oleid (file_id);
 | 
				
			||||||
 | 
					CREATE INDEX idx_msoffice_olevba_file_id ON msoffice_olevba (file_id);
 | 
				
			||||||
 | 
					CREATE INDEX idx_msoffice_mraptor_file_id ON msoffice_mraptor (file_id);
 | 
				
			||||||
CREATE INDEX idx_msoffice_results_file_id ON msoffice (file_id);
 | 
					CREATE INDEX idx_msoffice_results_file_id ON msoffice (file_id);
 | 
				
			||||||
CREATE INDEX idx_file_properties_file_id ON file_properties (file_id);
 | 
					CREATE INDEX idx_file_properties_file_id ON file_properties (file_id);
 | 
				
			||||||
CREATE INDEX idx_file_id ON files (id);
 | 
					CREATE INDEX idx_file_id ON files (id);
 | 
				
			||||||
CREATE INDEX idx_yara_results_file_id ON yara_results (file_id);
 | 
					CREATE INDEX idx_yara_results_file_id ON yara_results (file_id);
 | 
				
			||||||
CREATE INDEX idx_user_name ON users (user_name);
 | 
					 | 
				
			||||||
CREATE INDEX idx_capa_results_file_id ON capa_results (file_id);
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,2 +1,8 @@
 | 
				
			||||||
package database
 | 
					package database
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type User struct {
 | 
				
			||||||
 | 
						Id     int64
 | 
				
			||||||
 | 
						Name   string `xorm:"not null unique"`
 | 
				
			||||||
 | 
						PwHash string //Password hash
 | 
				
			||||||
 | 
						Role   int64  `xorm:"default 0"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,23 +43,6 @@ func BasicProcessing(job sqlc.ProcessingJob) error {
 | 
				
			||||||
		slog.Error("Error inserting basic file properties into database", "file-uuid", job.FileID.String(), "error", err)
 | 
							slog.Error("Error inserting basic file properties into database", "file-uuid", job.FileID.String(), "error", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	diec, err := DiecScan(job.FileID.String())
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		database.FailProcessingJob(job.ID, err)
 | 
					 | 
				
			||||||
		slog.Error("Error processing file", "file-uuid", job.FileID.String(), "error", err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	slog.Debug("Diec result", "file-uuid", job.FileID.String(), "diec", diec)
 | 
					 | 
				
			||||||
	err = database.InsertFileDiec(sqlc.InsertFileDIECParams{
 | 
					 | 
				
			||||||
		FileID: job.FileID,
 | 
					 | 
				
			||||||
		Data: diec,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		database.FailProcessingJob(job.ID, err)
 | 
					 | 
				
			||||||
		slog.Error("Error inserting detect-it-easy results into database", "file-uuid", job.FileID.String(), "error", err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	database.FinishProcessingJob(job.ID)
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,63 +0,0 @@
 | 
				
			||||||
package capa
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"log/slog"
 | 
					 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.jmbit.de/jmb/scanfile/server/internal/database"
 | 
					 | 
				
			||||||
	"git.jmbit.de/jmb/scanfile/server/internal/sqlc"
 | 
					 | 
				
			||||||
	"github.com/jackc/pgx/v5/pgtype"
 | 
					 | 
				
			||||||
	"github.com/spf13/viper"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func CapaProcessing(job sqlc.ProcessingJob) error {
 | 
					 | 
				
			||||||
	database.StartProcessingJob(job.ID)
 | 
					 | 
				
			||||||
	capaBytes, err := CapaScan(job.FileID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		database.FailProcessingJob(job.ID, err)
 | 
					 | 
				
			||||||
		slog.Error("Error processing file", "file-uuid", job.FileID.String(), "error", err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var params sqlc.InsertFileCapaParams
 | 
					 | 
				
			||||||
	params.FileID = job.FileID
 | 
					 | 
				
			||||||
	params.Data = capaBytes
 | 
					 | 
				
			||||||
	err = database.InsertFileCapa(params)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		database.FailProcessingJob(job.ID, err)
 | 
					 | 
				
			||||||
		slog.Error("Error processing file CAPA data", "file-uuid", job.FileID.String(), "error", err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	database.FinishProcessingJob(job.ID)
 | 
					 | 
				
			||||||
  return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func CapaScan(fileID pgtype.UUID) ([]byte, error) {
 | 
					 | 
				
			||||||
	var by []byte
 | 
					 | 
				
			||||||
	slog.Debug("Started Capa scan", "file-uuid", fileID.String())
 | 
					 | 
				
			||||||
	capaUrl, err := url.Parse(viper.GetString("processing.capaurl"))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error in CapaScan parsing URL for ole service", "file-uuid", fileID.String(), "error", err)
 | 
					 | 
				
			||||||
		return by, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	capaUrl.Path = "/capa/analyze"
 | 
					 | 
				
			||||||
	capaUrl.RawQuery = fmt.Sprintf("file=%s", fileID.String())
 | 
					 | 
				
			||||||
	capaResp, err := http.Get(capaUrl.String())
 | 
					 | 
				
			||||||
	slog.Debug("CAPA scan request", "file-uuid", fileID.String(), "url", capaUrl.String(), "status-code", capaResp.StatusCode)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error in CapaScan getting capa result from service", "file-uuid", fileID.String(), "error", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer capaResp.Body.Close()
 | 
					 | 
				
			||||||
	body, err := io.ReadAll(capaResp.Body)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error in CapaScan parsing body", "file-uuid", fileID.String(), "error", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	slog.Debug("CapaScan", "file-uuid", fileID.String(), "data", body)
 | 
					 | 
				
			||||||
	return body, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -56,6 +56,5 @@ func MSOfficeProcessing(job sqlc.ProcessingJob) error {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	database.FinishProcessingJob(job.ID)
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,7 @@ type oleidResponse struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func OleIDScan(fileID pgtype.UUID) (oleidResponse, error) {
 | 
					func OleIDScan(fileID pgtype.UUID) (oleidResponse, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	slog.Debug("Starting OleID scan", "file-uuid", fileID.String())
 | 
						slog.Debug("Starting OleID scan", "file-uuid", fileID.String())
 | 
				
			||||||
	oleidUrl, err := url.Parse(viper.GetString("processing.oleurl"))
 | 
						oleidUrl, err := url.Parse(viper.GetString("processing.oleurl"))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,6 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.jmbit.de/jmb/scanfile/server/internal/database"
 | 
						"git.jmbit.de/jmb/scanfile/server/internal/database"
 | 
				
			||||||
	"git.jmbit.de/jmb/scanfile/server/internal/processing/basic"
 | 
						"git.jmbit.de/jmb/scanfile/server/internal/processing/basic"
 | 
				
			||||||
	"git.jmbit.de/jmb/scanfile/server/internal/processing/capa"
 | 
					 | 
				
			||||||
	"git.jmbit.de/jmb/scanfile/server/internal/processing/msoffice"
 | 
						"git.jmbit.de/jmb/scanfile/server/internal/processing/msoffice"
 | 
				
			||||||
	"git.jmbit.de/jmb/scanfile/server/internal/processing/yara"
 | 
						"git.jmbit.de/jmb/scanfile/server/internal/processing/yara"
 | 
				
			||||||
	"github.com/jackc/pgx/v5/pgtype"
 | 
						"github.com/jackc/pgx/v5/pgtype"
 | 
				
			||||||
| 
						 | 
					@ -33,12 +32,12 @@ func Submit(ctx context.Context, file pgtype.UUID) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go basic.BasicProcessing(job)
 | 
						go basic.BasicProcessing(job)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//yaraJob, err := database.NewProcessingJob(ctx, file, TypeYARA)
 | 
						yaraJob, err := database.NewProcessingJob(ctx, file, TypeYARA)
 | 
				
			||||||
	//if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
	//	slog.Error("Could not submit processing job", "error", err, "file-uuid", file, "type", TypeBasic)
 | 
							slog.Error("Could not submit processing job", "error", err, "file-uuid", file, "type", TypeBasic)
 | 
				
			||||||
	//	return err
 | 
							return err
 | 
				
			||||||
	//}
 | 
						}
 | 
				
			||||||
	//go yara.YaraProcessing(yaraJob)
 | 
						go yara.YaraProcessing(yaraJob)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mimeType, err := database.GetFileMime(file)
 | 
						mimeType, err := database.GetFileMime(file)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -53,20 +52,6 @@ func Submit(ctx context.Context, file pgtype.UUID) error {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		go msoffice.MSOfficeProcessing(officeJob)
 | 
							go msoffice.MSOfficeProcessing(officeJob)
 | 
				
			||||||
	case TypeELF:
 | 
					 | 
				
			||||||
	  capaJob, err := database.NewProcessingJob(ctx, file, TypeELF)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			slog.Error("Could not submit processing job", "error", err, "file-uuid", file, "type", TypeCAPA)
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	  go capa.CapaProcessing(capaJob)
 | 
					 | 
				
			||||||
	case TypePE:
 | 
					 | 
				
			||||||
	  capaJob, err := database.NewProcessingJob(ctx, file, TypeELF)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			slog.Error("Could not submit processing job", "error", err, "file-uuid", file, "type", TypeCAPA)
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	  go capa.CapaProcessing(capaJob)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,9 +28,6 @@ const TypeOther = "Other"
 | 
				
			||||||
// Yara Scan (can be done for all filetypes)
 | 
					// Yara Scan (can be done for all filetypes)
 | 
				
			||||||
const TypeYARA = "Yara"
 | 
					const TypeYARA = "Yara"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CAPA Scan
 | 
					 | 
				
			||||||
const TypeCAPA = "Capa"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var MSOfficeMime = []string{
 | 
					var MSOfficeMime = []string{
 | 
				
			||||||
	"application/msword",
 | 
						"application/msword",
 | 
				
			||||||
	"application/vnd.ms-excel",
 | 
						"application/vnd.ms-excel",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,19 +8,10 @@ import (
 | 
				
			||||||
	"github.com/jackc/pgx/v5/pgtype"
 | 
						"github.com/jackc/pgx/v5/pgtype"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CapaResult struct {
 | 
					 | 
				
			||||||
	ID      int64
 | 
					 | 
				
			||||||
	FileID  pgtype.UUID
 | 
					 | 
				
			||||||
	Data    []byte
 | 
					 | 
				
			||||||
	Type    string
 | 
					 | 
				
			||||||
	Created pgtype.Timestamp
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Diec struct {
 | 
					type Diec struct {
 | 
				
			||||||
	ID      int64
 | 
						ID     int64
 | 
				
			||||||
	FileID  pgtype.UUID
 | 
						FileID pgtype.UUID
 | 
				
			||||||
	Data    []byte
 | 
						Data   []byte
 | 
				
			||||||
	Created pgtype.Timestamp
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type File struct {
 | 
					type File struct {
 | 
				
			||||||
| 
						 | 
					@ -30,8 +21,6 @@ type File struct {
 | 
				
			||||||
	Mimetype    string
 | 
						Mimetype    string
 | 
				
			||||||
	Size        int64
 | 
						Size        int64
 | 
				
			||||||
	Blake2      []byte
 | 
						Blake2      []byte
 | 
				
			||||||
	Score       pgtype.Numeric
 | 
					 | 
				
			||||||
	Creator     pgtype.Int8
 | 
					 | 
				
			||||||
	Created     pgtype.Timestamp
 | 
						Created     pgtype.Timestamp
 | 
				
			||||||
	Updated     pgtype.Timestamp
 | 
						Updated     pgtype.Timestamp
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -44,7 +33,6 @@ type FileProperty struct {
 | 
				
			||||||
	LibmagicMime      pgtype.Text
 | 
						LibmagicMime      pgtype.Text
 | 
				
			||||||
	LibmagicExtension pgtype.Text
 | 
						LibmagicExtension pgtype.Text
 | 
				
			||||||
	LibmagicApple     pgtype.Text
 | 
						LibmagicApple     pgtype.Text
 | 
				
			||||||
	Created           pgtype.Timestamp
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Msoffice struct {
 | 
					type Msoffice struct {
 | 
				
			||||||
| 
						 | 
					@ -63,7 +51,6 @@ type Msoffice struct {
 | 
				
			||||||
	NbSuspicious    pgtype.Int4
 | 
						NbSuspicious    pgtype.Int4
 | 
				
			||||||
	OlevbaResults   [][]string
 | 
						OlevbaResults   [][]string
 | 
				
			||||||
	Macros          [][]string
 | 
						Macros          [][]string
 | 
				
			||||||
	Created         pgtype.Timestamp
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ProcessingJob struct {
 | 
					type ProcessingJob struct {
 | 
				
			||||||
| 
						 | 
					@ -78,19 +65,8 @@ type ProcessingJob struct {
 | 
				
			||||||
	Messages  []string
 | 
						Messages  []string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type User struct {
 | 
					 | 
				
			||||||
	ID           int64
 | 
					 | 
				
			||||||
	UserName     string
 | 
					 | 
				
			||||||
	DisplayName  string
 | 
					 | 
				
			||||||
	PwHash       []byte
 | 
					 | 
				
			||||||
	EmailAddress string
 | 
					 | 
				
			||||||
	Enabled      bool
 | 
					 | 
				
			||||||
	Created      pgtype.Timestamp
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type YaraResult struct {
 | 
					type YaraResult struct {
 | 
				
			||||||
	ID      int64
 | 
						ID      int64
 | 
				
			||||||
	FileID  pgtype.UUID
 | 
						FileID  pgtype.UUID
 | 
				
			||||||
	Matched []string
 | 
						Matched []string
 | 
				
			||||||
	Created pgtype.Timestamp
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,43 +11,8 @@ import (
 | 
				
			||||||
	"github.com/jackc/pgx/v5/pgtype"
 | 
						"github.com/jackc/pgx/v5/pgtype"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getFileCapa = `-- name: GetFileCapa :one
 | 
					 | 
				
			||||||
SELECT id, file_id, data, type, created FROM capa_results
 | 
					 | 
				
			||||||
WHERE file_id = $1
 | 
					 | 
				
			||||||
`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (q *Queries) GetFileCapa(ctx context.Context, fileID pgtype.UUID) (CapaResult, error) {
 | 
					 | 
				
			||||||
	row := q.db.QueryRow(ctx, getFileCapa, fileID)
 | 
					 | 
				
			||||||
	var i CapaResult
 | 
					 | 
				
			||||||
	err := row.Scan(
 | 
					 | 
				
			||||||
		&i.ID,
 | 
					 | 
				
			||||||
		&i.FileID,
 | 
					 | 
				
			||||||
		&i.Data,
 | 
					 | 
				
			||||||
		&i.Type,
 | 
					 | 
				
			||||||
		&i.Created,
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	return i, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const getFileDIEC = `-- name: GetFileDIEC :one
 | 
					 | 
				
			||||||
SELECT id, file_id, data, created FROM diec
 | 
					 | 
				
			||||||
WHERE file_id = $1
 | 
					 | 
				
			||||||
`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (q *Queries) GetFileDIEC(ctx context.Context, fileID pgtype.UUID) (Diec, error) {
 | 
					 | 
				
			||||||
	row := q.db.QueryRow(ctx, getFileDIEC, fileID)
 | 
					 | 
				
			||||||
	var i Diec
 | 
					 | 
				
			||||||
	err := row.Scan(
 | 
					 | 
				
			||||||
		&i.ID,
 | 
					 | 
				
			||||||
		&i.FileID,
 | 
					 | 
				
			||||||
		&i.Data,
 | 
					 | 
				
			||||||
		&i.Created,
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	return i, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const getFileProperties = `-- name: GetFileProperties :one
 | 
					const getFileProperties = `-- name: GetFileProperties :one
 | 
				
			||||||
SELECT id, file_id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple, created FROM file_properties
 | 
					SELECT id, file_id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple FROM file_properties
 | 
				
			||||||
WHERE file_id = $1
 | 
					WHERE file_id = $1
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,27 +27,10 @@ func (q *Queries) GetFileProperties(ctx context.Context, fileID pgtype.UUID) (Fi
 | 
				
			||||||
		&i.LibmagicMime,
 | 
							&i.LibmagicMime,
 | 
				
			||||||
		&i.LibmagicExtension,
 | 
							&i.LibmagicExtension,
 | 
				
			||||||
		&i.LibmagicApple,
 | 
							&i.LibmagicApple,
 | 
				
			||||||
		&i.Created,
 | 
					 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const insertFileCapa = `-- name: InsertFileCapa :exec
 | 
					 | 
				
			||||||
INSERT INTO capa_results (
 | 
					 | 
				
			||||||
 file_id, data
 | 
					 | 
				
			||||||
) VALUES ($1, $2)
 | 
					 | 
				
			||||||
`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type InsertFileCapaParams struct {
 | 
					 | 
				
			||||||
	FileID pgtype.UUID
 | 
					 | 
				
			||||||
	Data   []byte
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (q *Queries) InsertFileCapa(ctx context.Context, arg InsertFileCapaParams) error {
 | 
					 | 
				
			||||||
	_, err := q.db.Exec(ctx, insertFileCapa, arg.FileID, arg.Data)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const insertFileDIEC = `-- name: InsertFileDIEC :exec
 | 
					const insertFileDIEC = `-- name: InsertFileDIEC :exec
 | 
				
			||||||
INSERT INTO diec (
 | 
					INSERT INTO diec (
 | 
				
			||||||
  file_id, data
 | 
					  file_id, data
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ INSERT INTO files (
 | 
				
			||||||
  $1,$2,$3,$4,$5
 | 
					  $1,$2,$3,$4,$5
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
ON CONFLICT DO NOTHING -- Handle this in application code
 | 
					ON CONFLICT DO NOTHING -- Handle this in application code
 | 
				
			||||||
RETURNING id, name, description, mimetype, size, blake2, score, creator, created, updated
 | 
					RETURNING id, name, description, mimetype, size, blake2, created, updated
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CreateFileParams struct {
 | 
					type CreateFileParams struct {
 | 
				
			||||||
| 
						 | 
					@ -45,8 +45,6 @@ func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) (File, e
 | 
				
			||||||
		&i.Mimetype,
 | 
							&i.Mimetype,
 | 
				
			||||||
		&i.Size,
 | 
							&i.Size,
 | 
				
			||||||
		&i.Blake2,
 | 
							&i.Blake2,
 | 
				
			||||||
		&i.Score,
 | 
					 | 
				
			||||||
		&i.Creator,
 | 
					 | 
				
			||||||
		&i.Created,
 | 
							&i.Created,
 | 
				
			||||||
		&i.Updated,
 | 
							&i.Updated,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
| 
						 | 
					@ -65,7 +63,7 @@ func (q *Queries) DeleteFile(ctx context.Context, id pgtype.UUID) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getAllFiles = `-- name: GetAllFiles :many
 | 
					const getAllFiles = `-- name: GetAllFiles :many
 | 
				
			||||||
SELECT id, name, description, mimetype, size, blake2, score, creator, created, updated FROM files
 | 
					SELECT id, name, description, mimetype, size, blake2, created, updated FROM files
 | 
				
			||||||
ORDER BY created DESC
 | 
					ORDER BY created DESC
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,8 +83,6 @@ func (q *Queries) GetAllFiles(ctx context.Context) ([]File, error) {
 | 
				
			||||||
			&i.Mimetype,
 | 
								&i.Mimetype,
 | 
				
			||||||
			&i.Size,
 | 
								&i.Size,
 | 
				
			||||||
			&i.Blake2,
 | 
								&i.Blake2,
 | 
				
			||||||
			&i.Score,
 | 
					 | 
				
			||||||
			&i.Creator,
 | 
					 | 
				
			||||||
			&i.Created,
 | 
								&i.Created,
 | 
				
			||||||
			&i.Updated,
 | 
								&i.Updated,
 | 
				
			||||||
		); err != nil {
 | 
							); err != nil {
 | 
				
			||||||
| 
						 | 
					@ -101,7 +97,7 @@ func (q *Queries) GetAllFiles(ctx context.Context) ([]File, error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getFileByBlake2 = `-- name: GetFileByBlake2 :one
 | 
					const getFileByBlake2 = `-- name: GetFileByBlake2 :one
 | 
				
			||||||
SELECT id, name, description, mimetype, size, blake2, score, creator, created, updated
 | 
					SELECT id, name, description, mimetype, size, blake2, created, updated
 | 
				
			||||||
FROM files
 | 
					FROM files
 | 
				
			||||||
WHERE blake2 = $1
 | 
					WHERE blake2 = $1
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
| 
						 | 
					@ -116,8 +112,6 @@ func (q *Queries) GetFileByBlake2(ctx context.Context, blake2 []byte) (File, err
 | 
				
			||||||
		&i.Mimetype,
 | 
							&i.Mimetype,
 | 
				
			||||||
		&i.Size,
 | 
							&i.Size,
 | 
				
			||||||
		&i.Blake2,
 | 
							&i.Blake2,
 | 
				
			||||||
		&i.Score,
 | 
					 | 
				
			||||||
		&i.Creator,
 | 
					 | 
				
			||||||
		&i.Created,
 | 
							&i.Created,
 | 
				
			||||||
		&i.Updated,
 | 
							&i.Updated,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
| 
						 | 
					@ -125,7 +119,7 @@ func (q *Queries) GetFileByBlake2(ctx context.Context, blake2 []byte) (File, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getFileByUUID = `-- name: GetFileByUUID :one
 | 
					const getFileByUUID = `-- name: GetFileByUUID :one
 | 
				
			||||||
SELECT id, name, description, mimetype, size, blake2, score, creator, created, updated 
 | 
					SELECT id, name, description, mimetype, size, blake2, created, updated 
 | 
				
			||||||
FROM files 
 | 
					FROM files 
 | 
				
			||||||
WHERE id = $1
 | 
					WHERE id = $1
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
| 
						 | 
					@ -140,8 +134,6 @@ func (q *Queries) GetFileByUUID(ctx context.Context, id pgtype.UUID) (File, erro
 | 
				
			||||||
		&i.Mimetype,
 | 
							&i.Mimetype,
 | 
				
			||||||
		&i.Size,
 | 
							&i.Size,
 | 
				
			||||||
		&i.Blake2,
 | 
							&i.Blake2,
 | 
				
			||||||
		&i.Score,
 | 
					 | 
				
			||||||
		&i.Creator,
 | 
					 | 
				
			||||||
		&i.Created,
 | 
							&i.Created,
 | 
				
			||||||
		&i.Updated,
 | 
							&i.Updated,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,8 +11,35 @@ import (
 | 
				
			||||||
	"github.com/jackc/pgx/v5/pgtype"
 | 
						"github.com/jackc/pgx/v5/pgtype"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getMSOfficeData = `-- name: GetMSOfficeData :one
 | 
				
			||||||
 | 
					SELECT t1.file_id, t1.data AS oleid, t2.data AS olevba, t3.data AS mraptor
 | 
				
			||||||
 | 
					 FROM msoffice_oleid as t1
 | 
				
			||||||
 | 
					 LEFT join msoffice_olevba AS t2 ON t2.file_id = t1.file_id
 | 
				
			||||||
 | 
					 LEFT JOIN msoffice_mraptor AS t3 ON t3.file_id = t1.file_id
 | 
				
			||||||
 | 
					 WHERE t1.file_id = $1
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetMSOfficeDataRow struct {
 | 
				
			||||||
 | 
						FileID  pgtype.UUID
 | 
				
			||||||
 | 
						Oleid   []byte
 | 
				
			||||||
 | 
						Olevba  []byte
 | 
				
			||||||
 | 
						Mraptor []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) GetMSOfficeData(ctx context.Context, dollar_1 pgtype.UUID) (GetMSOfficeDataRow, error) {
 | 
				
			||||||
 | 
						row := q.db.QueryRow(ctx, getMSOfficeData, dollar_1)
 | 
				
			||||||
 | 
						var i GetMSOfficeDataRow
 | 
				
			||||||
 | 
						err := row.Scan(
 | 
				
			||||||
 | 
							&i.FileID,
 | 
				
			||||||
 | 
							&i.Oleid,
 | 
				
			||||||
 | 
							&i.Olevba,
 | 
				
			||||||
 | 
							&i.Mraptor,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						return i, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getMSOfficeResults = `-- name: GetMSOfficeResults :one
 | 
					const getMSOfficeResults = `-- name: GetMSOfficeResults :one
 | 
				
			||||||
SELECT id, file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros, vba_stomping, nb_autoexec, nb_iocs, nb_macros, nb_suspicious, olevba_results, macros, created FROM msoffice
 | 
					SELECT id, file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros, vba_stomping, nb_autoexec, nb_iocs, nb_macros, nb_suspicious, olevba_results, macros FROM msoffice
 | 
				
			||||||
WHERE file_id = $1
 | 
					WHERE file_id = $1
 | 
				
			||||||
LIMIT 1
 | 
					LIMIT 1
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
| 
						 | 
					@ -36,11 +63,58 @@ func (q *Queries) GetMSOfficeResults(ctx context.Context, fileID pgtype.UUID) (M
 | 
				
			||||||
		&i.NbSuspicious,
 | 
							&i.NbSuspicious,
 | 
				
			||||||
		&i.OlevbaResults,
 | 
							&i.OlevbaResults,
 | 
				
			||||||
		&i.Macros,
 | 
							&i.Macros,
 | 
				
			||||||
		&i.Created,
 | 
					 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const insertFileMsofficeMraptor = `-- name: InsertFileMsofficeMraptor :exec
 | 
				
			||||||
 | 
					INSERT INTO msoffice_mraptor (
 | 
				
			||||||
 | 
					  file_id, data
 | 
				
			||||||
 | 
					) VALUES ($1, $2)
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InsertFileMsofficeMraptorParams struct {
 | 
				
			||||||
 | 
						Column1 pgtype.UUID
 | 
				
			||||||
 | 
						Column2 []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) InsertFileMsofficeMraptor(ctx context.Context, arg InsertFileMsofficeMraptorParams) error {
 | 
				
			||||||
 | 
						_, err := q.db.Exec(ctx, insertFileMsofficeMraptor, arg.Column1, arg.Column2)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const insertFileMsofficeOleid = `-- name: InsertFileMsofficeOleid :exec
 | 
				
			||||||
 | 
					INSERT INTO msoffice_oleid (
 | 
				
			||||||
 | 
					  file_id, data
 | 
				
			||||||
 | 
					) VALUES ($1, $2)
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InsertFileMsofficeOleidParams struct {
 | 
				
			||||||
 | 
						Column1 pgtype.UUID
 | 
				
			||||||
 | 
						Column2 []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) InsertFileMsofficeOleid(ctx context.Context, arg InsertFileMsofficeOleidParams) error {
 | 
				
			||||||
 | 
						_, err := q.db.Exec(ctx, insertFileMsofficeOleid, arg.Column1, arg.Column2)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const insertFileMsofficeOlevba = `-- name: InsertFileMsofficeOlevba :exec
 | 
				
			||||||
 | 
					INSERT INTO msoffice_olevba (
 | 
				
			||||||
 | 
					  file_id, data
 | 
				
			||||||
 | 
					) VALUES ($1, $2)
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InsertFileMsofficeOlevbaParams struct {
 | 
				
			||||||
 | 
						Column1 pgtype.UUID
 | 
				
			||||||
 | 
						Column2 []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *Queries) InsertFileMsofficeOlevba(ctx context.Context, arg InsertFileMsofficeOlevbaParams) error {
 | 
				
			||||||
 | 
						_, err := q.db.Exec(ctx, insertFileMsofficeOlevba, arg.Column1, arg.Column2)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const insertMSOfficeResults = `-- name: InsertMSOfficeResults :exec
 | 
					const insertMSOfficeResults = `-- name: InsertMSOfficeResults :exec
 | 
				
			||||||
INSERT INTO msoffice (
 | 
					INSERT INTO msoffice (
 | 
				
			||||||
  file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros,
 | 
					  file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,7 +125,6 @@ func (q *Queries) GetJob(ctx context.Context, id int64) (ProcessingJob, error) {
 | 
				
			||||||
const getJobsForFile = `-- name: GetJobsForFile :many
 | 
					const getJobsForFile = `-- name: GetJobsForFile :many
 | 
				
			||||||
SELECT id, file_id, created, started, completed, status, job_type, error, messages FROM processing_jobs
 | 
					SELECT id, file_id, created, started, completed, status, job_type, error, messages FROM processing_jobs
 | 
				
			||||||
WHERE file_id = $1
 | 
					WHERE file_id = $1
 | 
				
			||||||
ORDER BY created DESC
 | 
					 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q *Queries) GetJobsForFile(ctx context.Context, fileID pgtype.UUID) ([]ProcessingJob, error) {
 | 
					func (q *Queries) GetJobsForFile(ctx context.Context, fileID pgtype.UUID) ([]ProcessingJob, error) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ func (q *Queries) DeleteYaraResults(ctx context.Context, id int64) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getYaraResults = `-- name: GetYaraResults :one
 | 
					const getYaraResults = `-- name: GetYaraResults :one
 | 
				
			||||||
SELECT id, file_id, matched, created FROM yara_results
 | 
					SELECT id, file_id, matched FROM yara_results
 | 
				
			||||||
WHERE file_id = $1
 | 
					WHERE file_id = $1
 | 
				
			||||||
LIMIT 1
 | 
					LIMIT 1
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
| 
						 | 
					@ -30,12 +30,7 @@ LIMIT 1
 | 
				
			||||||
func (q *Queries) GetYaraResults(ctx context.Context, fileID pgtype.UUID) (YaraResult, error) {
 | 
					func (q *Queries) GetYaraResults(ctx context.Context, fileID pgtype.UUID) (YaraResult, error) {
 | 
				
			||||||
	row := q.db.QueryRow(ctx, getYaraResults, fileID)
 | 
						row := q.db.QueryRow(ctx, getYaraResults, fileID)
 | 
				
			||||||
	var i YaraResult
 | 
						var i YaraResult
 | 
				
			||||||
	err := row.Scan(
 | 
						err := row.Scan(&i.ID, &i.FileID, &i.Matched)
 | 
				
			||||||
		&i.ID,
 | 
					 | 
				
			||||||
		&i.FileID,
 | 
					 | 
				
			||||||
		&i.Matched,
 | 
					 | 
				
			||||||
		&i.Created,
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +38,7 @@ const insertYaraResults = `-- name: InsertYaraResults :one
 | 
				
			||||||
INSERT INTO yara_results (
 | 
					INSERT INTO yara_results (
 | 
				
			||||||
 file_id, matched
 | 
					 file_id, matched
 | 
				
			||||||
) VALUES ($1, $2)
 | 
					) VALUES ($1, $2)
 | 
				
			||||||
RETURNING id, file_id, matched, created
 | 
					RETURNING id, file_id, matched
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type InsertYaraResultsParams struct {
 | 
					type InsertYaraResultsParams struct {
 | 
				
			||||||
| 
						 | 
					@ -54,11 +49,6 @@ type InsertYaraResultsParams struct {
 | 
				
			||||||
func (q *Queries) InsertYaraResults(ctx context.Context, arg InsertYaraResultsParams) (YaraResult, error) {
 | 
					func (q *Queries) InsertYaraResults(ctx context.Context, arg InsertYaraResultsParams) (YaraResult, error) {
 | 
				
			||||||
	row := q.db.QueryRow(ctx, insertYaraResults, arg.FileID, arg.Matched)
 | 
						row := q.db.QueryRow(ctx, insertYaraResults, arg.FileID, arg.Matched)
 | 
				
			||||||
	var i YaraResult
 | 
						var i YaraResult
 | 
				
			||||||
	err := row.Scan(
 | 
						err := row.Scan(&i.ID, &i.FileID, &i.Matched)
 | 
				
			||||||
		&i.ID,
 | 
					 | 
				
			||||||
		&i.FileID,
 | 
					 | 
				
			||||||
		&i.Matched,
 | 
					 | 
				
			||||||
		&i.Created,
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	return i, err
 | 
						return i, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
package web
 | 
					package web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
package web
 | 
					package web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -67,7 +67,7 @@ templ NavBar(title string) {
 | 
				
			||||||
    <div class="container mx-auto flex justify-between items-center">
 | 
					    <div class="container mx-auto flex justify-between items-center">
 | 
				
			||||||
      <!-- Logo or Brand Name -->
 | 
					      <!-- Logo or Brand Name -->
 | 
				
			||||||
      <a href="/" class="text-white text-lg font-bold">
 | 
					      <a href="/" class="text-white text-lg font-bold">
 | 
				
			||||||
        Scanfile
 | 
					        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
      <!-- Navigation Links -->
 | 
					      <!-- Navigation Links -->
 | 
				
			||||||
      <div class="flex space-x-4">
 | 
					      <div class="flex space-x-4">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
package web
 | 
					package web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
| 
						 | 
					@ -79,12 +79,8 @@ func Base(title string) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var4 templ.SafeURL
 | 
							var templ_7745c5c3_Var4 templ.SafeURL = templ.URL(viper.GetString("ui.byurl"))
 | 
				
			||||||
		templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(viper.GetString("ui.byurl")))
 | 
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
			return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/base.templ`, Line: 27, Col: 90}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -105,12 +101,8 @@ func Base(title string) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var6 templ.SafeURL
 | 
							var templ_7745c5c3_Var6 templ.SafeURL = templ.URL(viper.GetString("ui.source"))
 | 
				
			||||||
		templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(viper.GetString("ui.source")))
 | 
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var6)))
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
			return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/base.templ`, Line: 28, Col: 59}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -143,7 +135,7 @@ func NavBar(title string) templ.Component {
 | 
				
			||||||
			templ_7745c5c3_Var7 = templ.NopComponent
 | 
								templ_7745c5c3_Var7 = templ.NopComponent
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx = templ.ClearChildren(ctx)
 | 
							ctx = templ.ClearChildren(ctx)
 | 
				
			||||||
		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<nav class=\"bg-blue-600 p-4 shadow-lg\"><div class=\"container mx-auto flex justify-between items-center\"><!-- Logo or Brand Name --><a href=\"/\" class=\"text-white text-lg font-bold\">Scanfile</a><!-- Navigation Links --><div class=\"flex space-x-4\"><a href=\"/\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">Home</a> <a href=\"/about\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">About</a> <a href=\"/login\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">Login</a></div></div></nav>")
 | 
							templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<nav class=\"bg-blue-600 p-4 shadow-lg\"><div class=\"container mx-auto flex justify-between items-center\"><!-- Logo or Brand Name --><a href=\"/\" class=\"text-white text-lg font-bold\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-search\"><circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line></svg></a><!-- Navigation Links --><div class=\"flex space-x-4\"><a href=\"/\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">Home</a> <a href=\"/about\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">About</a> <a href=\"/login\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">Login</a></div></div></nav>")
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
package web
 | 
					package web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
| 
						 | 
					@ -253,12 +253,8 @@ func FileList(files []sqlc.File) templ.Component {
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							var templ_7745c5c3_Var13 templ.SafeURL
 | 
												var templ_7745c5c3_Var13 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
 | 
				
			||||||
							templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
 | 
												_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var13)))
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 33, Col: 78}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
| 
						 | 
					@ -305,12 +301,8 @@ func FileList(files []sqlc.File) templ.Component {
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							var templ_7745c5c3_Var16 templ.SafeURL
 | 
												var templ_7745c5c3_Var16 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
 | 
				
			||||||
							templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
 | 
												_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var16)))
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 38, Col: 78}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
| 
						 | 
					@ -357,12 +349,8 @@ func FileList(files []sqlc.File) templ.Component {
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							var templ_7745c5c3_Var19 templ.SafeURL
 | 
												var templ_7745c5c3_Var19 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
 | 
				
			||||||
							templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
 | 
												_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var19)))
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 43, Col: 78}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
| 
						 | 
					@ -409,12 +397,8 @@ func FileList(files []sqlc.File) templ.Component {
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							var templ_7745c5c3_Var22 templ.SafeURL
 | 
												var templ_7745c5c3_Var22 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
 | 
				
			||||||
							templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
 | 
												_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var22)))
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 48, Col: 78}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
| 
						 | 
					@ -461,12 +445,8 @@ func FileList(files []sqlc.File) templ.Component {
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							var templ_7745c5c3_Var25 templ.SafeURL
 | 
												var templ_7745c5c3_Var25 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
 | 
				
			||||||
							templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
 | 
												_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var25)))
 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 53, Col: 78}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
												if templ_7745c5c3_Err != nil {
 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
													return templ_7745c5c3_Err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,13 +25,7 @@ func FileViewWebHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
		http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
							http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	diec, err := database.GetFileDiec(file.ID) 
 | 
						component := FileView(file, fileProperties)
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		slog.Error("Error getting Detect-It-Easy in FileViewWebHandler", "error", err, "file-uuid", r.PathValue("uuid"))
 | 
					 | 
				
			||||||
		http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	component := FileView(file, fileProperties, diec)
 | 
					 | 
				
			||||||
	err = component.Render(r.Context(), w)
 | 
						err = component.Render(r.Context(), w)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		slog.Error("Error rendering in FileViewWebHandler", "error", err)
 | 
							slog.Error("Error rendering in FileViewWebHandler", "error", err)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,9 +6,8 @@ import "git.jmbit.de/jmb/scanfile/server/web/templui/components/modal"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/internal/processing"
 | 
					import "git.jmbit.de/jmb/scanfile/server/internal/processing"
 | 
				
			||||||
import "fmt"
 | 
					import "fmt"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
 | 
					import "git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/internal/database"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
templ FileView(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Diec) {
 | 
					templ FileView(file sqlc.File, fileProperties sqlc.FileProperty) {
 | 
				
			||||||
  @Base(file.Name) {
 | 
					  @Base(file.Name) {
 | 
				
			||||||
    <div class="flex space-x-4 pb-4">
 | 
					    <div class="flex space-x-4 pb-4">
 | 
				
			||||||
      <h1 class="text-4xl">{file.Name}</h1>
 | 
					      <h1 class="text-4xl">{file.Name}</h1>
 | 
				
			||||||
| 
						 | 
					@ -16,11 +15,12 @@ templ FileView(file sqlc.File, fileProperties sqlc.FileProperty, diec database.D
 | 
				
			||||||
      @FileViewDownloadModal(file.ID.String())
 | 
					      @FileViewDownloadModal(file.ID.String())
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="grid grid-cols-2 gap-4">
 | 
					    <div class="grid grid-cols-2 gap-4">
 | 
				
			||||||
    @FileViewGenericTable(file, fileProperties, diec)
 | 
					    @FileViewGenericTable(file, fileProperties)
 | 
				
			||||||
    if processing.TypeFromMime(file.Mimetype) == processing.TypeMSOffice {
 | 
					    if processing.TypeFromMime(file.Mimetype) == processing.TypeMSOffice {
 | 
				
			||||||
      @FileViewMsofficeLoader(file.ID.String())
 | 
					      @FileViewMsofficeLoader(file.ID.String())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,9 +5,8 @@ import "git.jmbit.de/jmb/scanfile/server/web/templui/components/table"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
 | 
					import "git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
 | 
				
			||||||
import "encoding/hex"
 | 
					import "encoding/hex"
 | 
				
			||||||
import "fmt"
 | 
					import "fmt"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/internal/database"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
templ FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Diec) {
 | 
					templ FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) {
 | 
				
			||||||
    <div class="w-full">
 | 
					    <div class="w-full">
 | 
				
			||||||
      <h2 class="text-3xl">Generic Information</h2>
 | 
					      <h2 class="text-3xl">Generic Information</h2>
 | 
				
			||||||
      @table.Table() {
 | 
					      @table.Table() {
 | 
				
			||||||
| 
						 | 
					@ -72,7 +71,7 @@ templ FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, die
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if fileProperties.LibmagicApple.Valid && fileProperties.LibmagicApple.String != "UNKNUNKN" {
 | 
					        if fileProperties.LibmagicApple.Valid {
 | 
				
			||||||
          @table.Row() {
 | 
					          @table.Row() {
 | 
				
			||||||
            @table.Cell() {
 | 
					            @table.Cell() {
 | 
				
			||||||
              Apple Filetype
 | 
					              Apple Filetype
 | 
				
			||||||
| 
						 | 
					@ -91,65 +90,17 @@ templ FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, die
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    @DiecInfo(diec)
 | 
					 | 
				
			||||||
    @OtherServices(hex.EncodeToString(fileProperties.Sha256))
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
templ DiecInfo(diec database.Diec) {
 | 
					    <p class="p-1">Look for this file on other services</p>
 | 
				
			||||||
    <h3 class="text-2xl">Detect-It-Easy information</h3>
 | 
					 | 
				
			||||||
      @table.Table() {
 | 
					 | 
				
			||||||
        @table.Header() {
 | 
					 | 
				
			||||||
          @table.Head() {
 | 
					 | 
				
			||||||
            Info
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          @table.Head() {
 | 
					 | 
				
			||||||
            Name
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          @table.Head() {
 | 
					 | 
				
			||||||
            Type
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          @table.Head() {
 | 
					 | 
				
			||||||
            Details
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          @table.Head() {
 | 
					 | 
				
			||||||
            Version
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        @table.Body() {
 | 
					 | 
				
			||||||
          for _, row := range diec.Data.Detects[0].Values {
 | 
					 | 
				
			||||||
            @table.Row() {
 | 
					 | 
				
			||||||
              @table.Cell() {
 | 
					 | 
				
			||||||
                {row.Info}
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              @table.Cell() {
 | 
					 | 
				
			||||||
                {row.Name}
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              @table.Cell() {
 | 
					 | 
				
			||||||
                {row.Type}
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              @table.Cell() {
 | 
					 | 
				
			||||||
                {row.String}
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              @table.Cell() {
 | 
					 | 
				
			||||||
                {row.Version}
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
templ OtherServices(sha256 string) {
 | 
					 | 
				
			||||||
    <h3 class="text-2xl">Look for this file on other Services</h3>
 | 
					 | 
				
			||||||
    <div class="flex space-x-4 pb-4">
 | 
					    <div class="flex space-x-4 pb-4">
 | 
				
			||||||
       @button.Button(button.Props{
 | 
					       @button.Button(button.Props{
 | 
				
			||||||
         Variant: button.VariantOutline,
 | 
					         Variant: button.VariantOutline,
 | 
				
			||||||
         Href: fmt.Sprintf("https://www.virustotal.com/gui/file/%s", sha256),
 | 
					         Href: fmt.Sprintf("https://www.virustotal.com/gui/file/%s", hex.EncodeToString(fileProperties.Sha256)),
 | 
				
			||||||
         }) {VirusTotal}
 | 
					         }) {VirusTotal}
 | 
				
			||||||
       @button.Button(button.Props{
 | 
					       @button.Button(button.Props{
 | 
				
			||||||
         Variant: button.VariantOutline,
 | 
					         Variant: button.VariantOutline,
 | 
				
			||||||
         Href: fmt.Sprintf("https://bazaar.abuse.ch/sample/%s", sha256),
 | 
					         Href: fmt.Sprintf("https://bazaar.abuse.ch/sample/%s", hex.EncodeToString(fileProperties.Sha256)),
 | 
				
			||||||
         }) {Malware Bazaar}
 | 
					         }) {Malware Bazaar}
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
package web
 | 
					package web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
| 
						 | 
					@ -13,9 +13,8 @@ import "git.jmbit.de/jmb/scanfile/server/web/templui/components/table"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
 | 
					import "git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
 | 
				
			||||||
import "encoding/hex"
 | 
					import "encoding/hex"
 | 
				
			||||||
import "fmt"
 | 
					import "fmt"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/internal/database"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Diec) templ.Component {
 | 
					func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) templ.Component {
 | 
				
			||||||
	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
						return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
				
			||||||
		templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
							templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
				
			||||||
		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
 | 
							if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
 | 
				
			||||||
| 
						 | 
					@ -105,7 +104,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
					var templ_7745c5c3_Var6 string
 | 
										var templ_7745c5c3_Var6 string
 | 
				
			||||||
					templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(file.Size)
 | 
										templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(file.Size)
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
						return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 19, Col: 22}
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 18, Col: 22}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -184,7 +183,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
					var templ_7745c5c3_Var10 string
 | 
										var templ_7745c5c3_Var10 string
 | 
				
			||||||
					templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(file.Mimetype)
 | 
										templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(file.Mimetype)
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
						return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 27, Col: 26}
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 26, Col: 26}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -259,7 +258,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
					var templ_7745c5c3_Var14 string
 | 
										var templ_7745c5c3_Var14 string
 | 
				
			||||||
					templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(file.Blake2))
 | 
										templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(file.Blake2))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
						return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 36, Col: 44}
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 35, Col: 44}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -334,7 +333,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
					var templ_7745c5c3_Var18 string
 | 
										var templ_7745c5c3_Var18 string
 | 
				
			||||||
					templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(fileProperties.Sha256))
 | 
										templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(fileProperties.Sha256))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
						return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 44, Col: 54}
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 43, Col: 54}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -409,7 +408,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
					var templ_7745c5c3_Var22 string
 | 
										var templ_7745c5c3_Var22 string
 | 
				
			||||||
					templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(fileProperties.Md5))
 | 
										templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(fileProperties.Md5))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
						return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 52, Col: 51}
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 51, Col: 51}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -485,7 +484,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
						var templ_7745c5c3_Var26 string
 | 
											var templ_7745c5c3_Var26 string
 | 
				
			||||||
						templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicMime.String)
 | 
											templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicMime.String)
 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
											if templ_7745c5c3_Err != nil {
 | 
				
			||||||
							return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 61, Col: 49}
 | 
												return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 60, Col: 49}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
 | 
											_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
											if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -562,7 +561,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
						var templ_7745c5c3_Var30 string
 | 
											var templ_7745c5c3_Var30 string
 | 
				
			||||||
						templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicExtension.String)
 | 
											templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicExtension.String)
 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
											if templ_7745c5c3_Err != nil {
 | 
				
			||||||
							return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 71, Col: 54}
 | 
												return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 70, Col: 54}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
 | 
											_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
											if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -585,7 +584,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if fileProperties.LibmagicApple.Valid && fileProperties.LibmagicApple.String != "UNKNUNKN" {
 | 
								if fileProperties.LibmagicApple.Valid {
 | 
				
			||||||
				templ_7745c5c3_Var31 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
									templ_7745c5c3_Var31 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
				
			||||||
					templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
										templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
				
			||||||
					templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
										templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
				
			||||||
| 
						 | 
					@ -639,7 +638,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
						var templ_7745c5c3_Var34 string
 | 
											var templ_7745c5c3_Var34 string
 | 
				
			||||||
						templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicApple.String)
 | 
											templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicApple.String)
 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
											if templ_7745c5c3_Err != nil {
 | 
				
			||||||
							return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 81, Col: 50}
 | 
												return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 80, Col: 50}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
 | 
											_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
											if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -715,7 +714,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
					var templ_7745c5c3_Var38 string
 | 
										var templ_7745c5c3_Var38 string
 | 
				
			||||||
					templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(file.Created.Time.String())
 | 
										templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(file.Created.Time.String())
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
						return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 90, Col: 39}
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 89, Col: 39}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -739,44 +738,32 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = DiecInfo(diec).Render(ctx, templ_7745c5c3_Buffer)
 | 
							templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<p class=\"p-1\">Look for this file on other services</p><div class=\"flex space-x-4 pb-4\">")
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = OtherServices(hex.EncodeToString(fileProperties.Sha256)).Render(ctx, templ_7745c5c3_Buffer)
 | 
							templ_7745c5c3_Var39 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
								templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
				
			||||||
		}
 | 
								if !templ_7745c5c3_IsBuffer {
 | 
				
			||||||
		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "</div>")
 | 
									defer func() {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
										templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
										if templ_7745c5c3_Err == nil {
 | 
				
			||||||
		}
 | 
											templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
				
			||||||
		return nil
 | 
										}
 | 
				
			||||||
	})
 | 
									}()
 | 
				
			||||||
}
 | 
								}
 | 
				
			||||||
 | 
								ctx = templ.InitializeContext(ctx)
 | 
				
			||||||
func DiecInfo(diec database.Diec) templ.Component {
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "VirusTotal")
 | 
				
			||||||
	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
		templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
 | 
								}
 | 
				
			||||||
			return templ_7745c5c3_CtxErr
 | 
								return nil
 | 
				
			||||||
		}
 | 
							})
 | 
				
			||||||
		templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
							templ_7745c5c3_Err = button.Button(button.Props{
 | 
				
			||||||
		if !templ_7745c5c3_IsBuffer {
 | 
								Variant: button.VariantOutline,
 | 
				
			||||||
			defer func() {
 | 
								Href:    fmt.Sprintf("https://www.virustotal.com/gui/file/%s", hex.EncodeToString(fileProperties.Sha256)),
 | 
				
			||||||
				templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
							}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var39), templ_7745c5c3_Buffer)
 | 
				
			||||||
				if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
					templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
		templ_7745c5c3_Var39 := templ.GetChildren(ctx)
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Var39 == nil {
 | 
					 | 
				
			||||||
			templ_7745c5c3_Var39 = templ.NopComponent
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ctx = templ.ClearChildren(ctx)
 | 
					 | 
				
			||||||
		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<h3 class=\"text-2xl\">Detect-It-Easy information</h3>")
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -792,391 +779,7 @@ func DiecInfo(diec database.Diec) templ.Component {
 | 
				
			||||||
				}()
 | 
									}()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ctx = templ.InitializeContext(ctx)
 | 
								ctx = templ.InitializeContext(ctx)
 | 
				
			||||||
			templ_7745c5c3_Var41 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "Malware Bazaar")
 | 
				
			||||||
				templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
				templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
				if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
					defer func() {
 | 
					 | 
				
			||||||
						templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
							templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}()
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
				templ_7745c5c3_Var42 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
					templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
					templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
					if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
						defer func() {
 | 
					 | 
				
			||||||
							templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
								templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}()
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
					templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "Info")
 | 
					 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
						return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					return nil
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var42), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " ")
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				templ_7745c5c3_Var43 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
					templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
					templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
					if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
						defer func() {
 | 
					 | 
				
			||||||
							templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
								templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}()
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
					templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "Name")
 | 
					 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
						return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					return nil
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var43), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " ")
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				templ_7745c5c3_Var44 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
					templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
					templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
					if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
						defer func() {
 | 
					 | 
				
			||||||
							templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
								templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}()
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
					templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "Type")
 | 
					 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
						return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					return nil
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var44), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " ")
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				templ_7745c5c3_Var45 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
					templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
					templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
					if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
						defer func() {
 | 
					 | 
				
			||||||
							templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
								templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}()
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
					templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "Details")
 | 
					 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
						return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					return nil
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var45), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, " ")
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				templ_7745c5c3_Var46 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
					templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
					templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
					if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
						defer func() {
 | 
					 | 
				
			||||||
							templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
								templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}()
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
					templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "Version")
 | 
					 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
						return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					return nil
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var46), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return nil
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
			templ_7745c5c3_Err = table.Header().Render(templ.WithChildren(ctx, templ_7745c5c3_Var41), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, " ")
 | 
					 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			templ_7745c5c3_Var47 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
				templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
				templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
				if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
					defer func() {
 | 
					 | 
				
			||||||
						templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
							templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}()
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
				for _, row := range diec.Data.Detects[0].Values {
 | 
					 | 
				
			||||||
					templ_7745c5c3_Var48 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
						templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
						templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
						if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
							defer func() {
 | 
					 | 
				
			||||||
								templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
								if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
									templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
							}()
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
						templ_7745c5c3_Var49 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
							templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
							templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
							if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
								defer func() {
 | 
					 | 
				
			||||||
									templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
									if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
										templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}()
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
							var templ_7745c5c3_Var50 string
 | 
					 | 
				
			||||||
							templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(row.Info)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 123, Col: 25}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							return nil
 | 
					 | 
				
			||||||
						})
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var49), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, " ")
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						templ_7745c5c3_Var51 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
							templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
							templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
							if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
								defer func() {
 | 
					 | 
				
			||||||
									templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
									if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
										templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}()
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
							var templ_7745c5c3_Var52 string
 | 
					 | 
				
			||||||
							templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(row.Name)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 126, Col: 25}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							return nil
 | 
					 | 
				
			||||||
						})
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var51), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, " ")
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						templ_7745c5c3_Var53 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
							templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
							templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
							if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
								defer func() {
 | 
					 | 
				
			||||||
									templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
									if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
										templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}()
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
							var templ_7745c5c3_Var54 string
 | 
					 | 
				
			||||||
							templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(row.Type)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 129, Col: 25}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							return nil
 | 
					 | 
				
			||||||
						})
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var53), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, " ")
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						templ_7745c5c3_Var55 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
							templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
							templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
							if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
								defer func() {
 | 
					 | 
				
			||||||
									templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
									if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
										templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}()
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
							var templ_7745c5c3_Var56 string
 | 
					 | 
				
			||||||
							templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinStringErrs(row.String)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 132, Col: 27}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							return nil
 | 
					 | 
				
			||||||
						})
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var55), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " ")
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						templ_7745c5c3_Var57 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
							templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
							templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
							if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
								defer func() {
 | 
					 | 
				
			||||||
									templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
									if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
										templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}()
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
							var templ_7745c5c3_Var58 string
 | 
					 | 
				
			||||||
							templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(row.Version)
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 135, Col: 28}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))
 | 
					 | 
				
			||||||
							if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
								return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							return nil
 | 
					 | 
				
			||||||
						})
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var57), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
						if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
							return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						return nil
 | 
					 | 
				
			||||||
					})
 | 
					 | 
				
			||||||
					templ_7745c5c3_Err = table.Row().Render(templ.WithChildren(ctx, templ_7745c5c3_Var48), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
					if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
						return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return nil
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
			templ_7745c5c3_Err = table.Body().Render(templ.WithChildren(ctx, templ_7745c5c3_Var47), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		templ_7745c5c3_Err = table.Table().Render(templ.WithChildren(ctx, templ_7745c5c3_Var40), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func OtherServices(sha256 string) templ.Component {
 | 
					 | 
				
			||||||
	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
		templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
 | 
					 | 
				
			||||||
			return templ_7745c5c3_CtxErr
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
		if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
			defer func() {
 | 
					 | 
				
			||||||
				templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
					templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
		templ_7745c5c3_Var59 := templ.GetChildren(ctx)
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Var59 == nil {
 | 
					 | 
				
			||||||
			templ_7745c5c3_Var59 = templ.NopComponent
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ctx = templ.ClearChildren(ctx)
 | 
					 | 
				
			||||||
		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<h3 class=\"text-2xl\">Look for this file on other Services</h3><div class=\"flex space-x-4 pb-4\">")
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		templ_7745c5c3_Var60 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
					 | 
				
			||||||
			templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
			templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
			if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
				defer func() {
 | 
					 | 
				
			||||||
					templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
					if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "VirusTotal")
 | 
					 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -1184,37 +787,12 @@ func OtherServices(sha256 string) templ.Component {
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		templ_7745c5c3_Err = button.Button(button.Props{
 | 
							templ_7745c5c3_Err = button.Button(button.Props{
 | 
				
			||||||
			Variant: button.VariantOutline,
 | 
								Variant: button.VariantOutline,
 | 
				
			||||||
			Href:    fmt.Sprintf("https://www.virustotal.com/gui/file/%s", sha256),
 | 
								Href:    fmt.Sprintf("https://bazaar.abuse.ch/sample/%s", hex.EncodeToString(fileProperties.Sha256)),
 | 
				
			||||||
		}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var60), templ_7745c5c3_Buffer)
 | 
							}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var40), templ_7745c5c3_Buffer)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Var61 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
							templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "</div></div>")
 | 
				
			||||||
			templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
					 | 
				
			||||||
			templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
 | 
					 | 
				
			||||||
			if !templ_7745c5c3_IsBuffer {
 | 
					 | 
				
			||||||
				defer func() {
 | 
					 | 
				
			||||||
					templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
					if templ_7745c5c3_Err == nil {
 | 
					 | 
				
			||||||
						templ_7745c5c3_Err = templ_7745c5c3_BufErr
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			ctx = templ.InitializeContext(ctx)
 | 
					 | 
				
			||||||
			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "Malware Bazaar")
 | 
					 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		templ_7745c5c3_Err = button.Button(button.Props{
 | 
					 | 
				
			||||||
			Variant: button.VariantOutline,
 | 
					 | 
				
			||||||
			Href:    fmt.Sprintf("https://bazaar.abuse.ch/sample/%s", sha256),
 | 
					 | 
				
			||||||
		}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var61), templ_7745c5c3_Buffer)
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</div>")
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
package web
 | 
					package web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
| 
						 | 
					@ -66,12 +66,8 @@ func FileViewMsofficeLoader(fileid string) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var3 templ.SafeURL
 | 
							var templ_7745c5c3_Var3 templ.SafeURL = templ.URL(fmt.Sprintf("/files/%s/msoffice", fileid))
 | 
				
			||||||
		templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(fmt.Sprintf("/files/%s/msoffice", fileid)))
 | 
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3)))
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
			return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewMsoffice.templ`, Line: 18, Col: 79}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
 | 
					 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
package web
 | 
					package web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
| 
						 | 
					@ -14,9 +14,8 @@ import "git.jmbit.de/jmb/scanfile/server/web/templui/components/modal"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/internal/processing"
 | 
					import "git.jmbit.de/jmb/scanfile/server/internal/processing"
 | 
				
			||||||
import "fmt"
 | 
					import "fmt"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
 | 
					import "git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
 | 
				
			||||||
import "git.jmbit.de/jmb/scanfile/server/internal/database"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func FileView(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Diec) templ.Component {
 | 
					func FileView(file sqlc.File, fileProperties sqlc.FileProperty) templ.Component {
 | 
				
			||||||
	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
						return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
				
			||||||
		templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
							templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
				
			||||||
		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
 | 
							if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
 | 
				
			||||||
| 
						 | 
					@ -56,7 +55,7 @@ func FileView(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Di
 | 
				
			||||||
			var templ_7745c5c3_Var3 string
 | 
								var templ_7745c5c3_Var3 string
 | 
				
			||||||
			templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(file.Name)
 | 
								templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(file.Name)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileView.templ`, Line: 14, Col: 37}
 | 
									return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileView.templ`, Line: 13, Col: 37}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -78,7 +77,7 @@ func FileView(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Di
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = FileViewGenericTable(file, fileProperties, diec).Render(ctx, templ_7745c5c3_Buffer)
 | 
								templ_7745c5c3_Err = FileViewGenericTable(file, fileProperties).Render(ctx, templ_7745c5c3_Buffer)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
package web
 | 
					package web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component accordion - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component accordion - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package accordion
 | 
					package accordion
 | 
				
			||||||
| 
						 | 
					@ -64,10 +64,11 @@ func Accordion(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"divide-y rounded-md divide-border border",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"divide-y rounded-md divide-border border",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -158,11 +159,12 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var6 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var6 = []any{
 | 
				
			||||||
			"group",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"open:[&>summary_svg]:rotate-180",
 | 
									"group",
 | 
				
			||||||
			p.Class,
 | 
									"open:[&>summary_svg]:rotate-180",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -253,13 +255,14 @@ func Trigger(props ...TriggerProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var10 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var10 = []any{
 | 
				
			||||||
			"flex w-full items-center justify-between py-4 px-5",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"text-left font-medium cursor-pointer",
 | 
									"flex w-full items-center justify-between py-4 px-5",
 | 
				
			||||||
			"transition-all hover:underline",
 | 
									"text-left font-medium cursor-pointer",
 | 
				
			||||||
			"list-none [&::-webkit-details-marker]:hidden",
 | 
									"transition-all hover:underline",
 | 
				
			||||||
			p.Class,
 | 
									"list-none [&::-webkit-details-marker]:hidden",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -361,10 +364,11 @@ func Content(props ...ContentProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var14 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var14 = []any{
 | 
				
			||||||
			"px-5 pb-4 pt-0",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"px-5 pb-4 pt-0",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component alert - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component alert - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package alert
 | 
					package alert
 | 
				
			||||||
| 
						 | 
					@ -63,14 +63,15 @@ func Alert(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative w-full p-4",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
 | 
									"relative w-full p-4",
 | 
				
			||||||
			"[&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11",
 | 
									"[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
 | 
				
			||||||
			"rounded-lg border",
 | 
									"[&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11",
 | 
				
			||||||
			variantClasses(p.Variant),
 | 
									"rounded-lg border",
 | 
				
			||||||
			p.Class,
 | 
									variantClasses(p.Variant),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -161,10 +162,11 @@ func Title(props ...TitleProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var6 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var6 = []any{
 | 
				
			||||||
			"mb-1 font-medium leading-none tracking-tight",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"mb-1 font-medium leading-none tracking-tight",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -255,10 +257,11 @@ func Description(props ...DescriptionProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var10 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var10 = []any{
 | 
				
			||||||
			"[&_p]:leading-relaxed text-sm",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"[&_p]:leading-relaxed text-sm",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component aspectratio - version: main installed by templui v0.71.0
 | 
					// templui component aspectratio - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package aspectratio
 | 
					package aspectratio
 | 
				
			||||||
| 
						 | 
					@ -54,11 +54,12 @@ func AspectRatio(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative w-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			ratioClass(p.Ratio),
 | 
									"relative w-full",
 | 
				
			||||||
			p.Class,
 | 
									ratioClass(p.Ratio),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component aspectratio - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component aspectratio - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package aspectratio
 | 
					package aspectratio
 | 
				
			||||||
| 
						 | 
					@ -54,11 +54,12 @@ func AspectRatio(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative w-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			ratioClass(p.Ratio),
 | 
									"relative w-full",
 | 
				
			||||||
			p.Class,
 | 
									ratioClass(p.Ratio),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component avatar - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component avatar - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package avatar
 | 
					package avatar
 | 
				
			||||||
| 
						 | 
					@ -85,13 +85,14 @@ func Avatar(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"inline-flex items-center justify-center",
 | 
								utils.TwMerge(
 | 
				
			||||||
			SizeClasses(p.Size),
 | 
									"inline-flex items-center justify-center",
 | 
				
			||||||
			"rounded-full bg-muted",
 | 
									SizeClasses(p.Size),
 | 
				
			||||||
			utils.If(p.InGroup, "ring-2 ring-background"),
 | 
									"rounded-full bg-muted",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.InGroup, "ring-2 ring-background"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -182,11 +183,12 @@ func Image(props ...ImageProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var6 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var6 = []any{
 | 
				
			||||||
			"w-full h-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"rounded-full object-cover",
 | 
									"w-full h-full",
 | 
				
			||||||
			p.Class,
 | 
									"rounded-full object-cover",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -301,10 +303,11 @@ func Fallback(props ...FallbackProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var12 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var12 = []any{
 | 
				
			||||||
			"font-medium text-muted-foreground",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"font-medium text-muted-foreground",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -395,11 +398,12 @@ func Group(props ...GroupProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var16 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var16 = []any{
 | 
				
			||||||
			"flex items-center -space-x-3",
 | 
								utils.TwMerge(
 | 
				
			||||||
			groupSpacingClasses(p.Spacing),
 | 
									"flex items-center -space-x-3",
 | 
				
			||||||
			p.Class,
 | 
									groupSpacingClasses(p.Spacing),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -490,12 +494,13 @@ func GroupOverflow(count int, props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var20 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var20 = []any{
 | 
				
			||||||
			"inline-flex items-center justify-center",
 | 
								utils.TwMerge(
 | 
				
			||||||
			SizeClasses(p.Size),
 | 
									"inline-flex items-center justify-center",
 | 
				
			||||||
			"rounded-full bg-muted ring-2 ring-background",
 | 
									SizeClasses(p.Size),
 | 
				
			||||||
			p.Class,
 | 
									"rounded-full bg-muted ring-2 ring-background",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component badge - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component badge - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package badge
 | 
					package badge
 | 
				
			||||||
| 
						 | 
					@ -53,14 +53,15 @@ func Badge(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
									"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none",
 | 
				
			||||||
			"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
 | 
									"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
				
			||||||
			"transition-[color,box-shadow] overflow-hidden",
 | 
									"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
 | 
				
			||||||
			p.variantClasses(),
 | 
									"transition-[color,box-shadow] overflow-hidden",
 | 
				
			||||||
			p.Class,
 | 
									p.variantClasses(),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component breadcrumb - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component breadcrumb - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package breadcrumb
 | 
					package breadcrumb
 | 
				
			||||||
| 
						 | 
					@ -73,10 +73,11 @@ func Breadcrumb(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"flex",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -167,10 +168,11 @@ func List(props ...ListProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var6 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var6 = []any{
 | 
				
			||||||
			"flex items-center flex-wrap gap-1 text-sm",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex items-center flex-wrap gap-1 text-sm",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -261,10 +263,11 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var10 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var10 = []any{
 | 
				
			||||||
			"flex items-center",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex items-center",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -355,10 +358,11 @@ func Link(props ...LinkProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var14 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var14 = []any{
 | 
				
			||||||
			"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -392,12 +396,8 @@ func Link(props ...LinkProps) templ.Component {
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var templ_7745c5c3_Var16 templ.SafeURL
 | 
								var templ_7745c5c3_Var16 templ.SafeURL = templ.SafeURL(p.Href)
 | 
				
			||||||
			templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Href))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var16)))
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
				return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 116, Col: 31}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
 | 
					 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -468,10 +468,11 @@ func Separator(props ...SeparatorProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var19 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var19 = []any{
 | 
				
			||||||
			"mx-2 text-muted-foreground",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"mx-2 text-muted-foreground",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var19...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var19...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -569,10 +570,11 @@ func Page(props ...ItemProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var23 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var23 = []any{
 | 
				
			||||||
			"font-medium text-foreground flex items-center gap-1.5",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"font-medium text-foreground flex items-center gap-1.5",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var23...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var23...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
// templui component button - version: v0.85.0 installed by templui v0.85.0
 | 
					// templui component button - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
package button
 | 
					package button
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
| 
						 | 
					@ -111,7 +111,7 @@ templ Button(props ...Props) {
 | 
				
			||||||
func (b Props) variantClasses() string {
 | 
					func (b Props) variantClasses() string {
 | 
				
			||||||
	switch b.Variant {
 | 
						switch b.Variant {
 | 
				
			||||||
	case VariantDestructive:
 | 
						case VariantDestructive:
 | 
				
			||||||
		return "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
 | 
							return "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
 | 
				
			||||||
	case VariantOutline:
 | 
						case VariantOutline:
 | 
				
			||||||
		return "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
 | 
							return "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
 | 
				
			||||||
	case VariantSecondary:
 | 
						case VariantSecondary:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component button - version: v0.85.0 installed by templui v0.85.0
 | 
					// templui component button - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package button
 | 
					package button
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,17 +83,18 @@ func Button(props ...Props) templ.Component {
 | 
				
			||||||
			p.Type = TypeButton
 | 
								p.Type = TypeButton
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if p.Href != "" && !p.Disabled {
 | 
							if p.Href != "" && !p.Disabled {
 | 
				
			||||||
			var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
								var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
				"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all",
 | 
									utils.TwMerge(
 | 
				
			||||||
				"disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
 | 
										"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all",
 | 
				
			||||||
				"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
										"disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
 | 
				
			||||||
				"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
 | 
										"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
				
			||||||
				"cursor-pointer",
 | 
										"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
 | 
				
			||||||
				p.variantClasses(),
 | 
										"cursor-pointer",
 | 
				
			||||||
				p.sizeClasses(),
 | 
										p.variantClasses(),
 | 
				
			||||||
				p.modifierClasses(),
 | 
										p.sizeClasses(),
 | 
				
			||||||
				p.Class,
 | 
										p.modifierClasses(),
 | 
				
			||||||
			),
 | 
										p.Class,
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
								templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -126,12 +127,8 @@ func Button(props ...Props) templ.Component {
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var templ_7745c5c3_Var4 templ.SafeURL
 | 
								var templ_7745c5c3_Var4 templ.SafeURL = templ.SafeURL(p.Href)
 | 
				
			||||||
			templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Href))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
				return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 61, Col: 31}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
 | 
					 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -192,17 +189,18 @@ func Button(props ...Props) templ.Component {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			var templ_7745c5c3_Var7 = []any{utils.TwMerge(
 | 
								var templ_7745c5c3_Var7 = []any{
 | 
				
			||||||
				"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all",
 | 
									utils.TwMerge(
 | 
				
			||||||
				"disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
 | 
										"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all",
 | 
				
			||||||
				"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
										"disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
 | 
				
			||||||
				"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
 | 
										"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
				
			||||||
				"cursor-pointer",
 | 
										"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
 | 
				
			||||||
				p.variantClasses(),
 | 
										"cursor-pointer",
 | 
				
			||||||
				p.sizeClasses(),
 | 
										p.variantClasses(),
 | 
				
			||||||
				p.modifierClasses(),
 | 
										p.sizeClasses(),
 | 
				
			||||||
				p.Class,
 | 
										p.modifierClasses(),
 | 
				
			||||||
			),
 | 
										p.Class,
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
 | 
								templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -297,7 +295,7 @@ func Button(props ...Props) templ.Component {
 | 
				
			||||||
func (b Props) variantClasses() string {
 | 
					func (b Props) variantClasses() string {
 | 
				
			||||||
	switch b.Variant {
 | 
						switch b.Variant {
 | 
				
			||||||
	case VariantDestructive:
 | 
						case VariantDestructive:
 | 
				
			||||||
		return "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
 | 
							return "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
 | 
				
			||||||
	case VariantOutline:
 | 
						case VariantOutline:
 | 
				
			||||||
		return "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
 | 
							return "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
 | 
				
			||||||
	case VariantSecondary:
 | 
						case VariantSecondary:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component calendar - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component calendar - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package calendar
 | 
					package calendar
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component card - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component card - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package card
 | 
					package card
 | 
				
			||||||
| 
						 | 
					@ -73,10 +73,11 @@ func Card(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"w-full rounded-lg border bg-card text-card-foreground shadow-xs",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"w-full rounded-lg border bg-card text-card-foreground shadow-xs",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -167,10 +168,11 @@ func Header(props ...HeaderProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var6 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var6 = []any{
 | 
				
			||||||
			"flex flex-col space-y-1.5 p-6 pb-0",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex flex-col space-y-1.5 p-6 pb-0",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -261,10 +263,11 @@ func Title(props ...TitleProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var10 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var10 = []any{
 | 
				
			||||||
			"text-lg font-semibold leading-none tracking-tight",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"text-lg font-semibold leading-none tracking-tight",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -355,10 +358,11 @@ func Description(props ...DescriptionProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var14 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var14 = []any{
 | 
				
			||||||
			"text-sm text-muted-foreground",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"text-sm text-muted-foreground",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -449,10 +453,11 @@ func Content(props ...ContentProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var18 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var18 = []any{
 | 
				
			||||||
			"p-6",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"p-6",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -543,10 +548,11 @@ func Footer(props ...FooterProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var22 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var22 = []any{
 | 
				
			||||||
			"flex items-center p-6 pt-0",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex items-center p-6 pt-0",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component carousel - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component carousel - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package carousel
 | 
					package carousel
 | 
				
			||||||
| 
						 | 
					@ -82,10 +82,11 @@ func Carousel(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"carousel-component relative overflow-hidden w-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"carousel-component relative overflow-hidden w-full",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -220,10 +221,11 @@ func Content(props ...ContentProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var9 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var9 = []any{
 | 
				
			||||||
			"carousel-track flex h-full w-full transition-transform duration-500 ease-in-out",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"carousel-track flex h-full w-full transition-transform duration-500 ease-in-out",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -314,10 +316,11 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var13 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var13 = []any{
 | 
				
			||||||
			"carousel-item flex-shrink-0 w-full h-full relative",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"carousel-item flex-shrink-0 w-full h-full relative",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var13...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var13...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -408,10 +411,11 @@ func Previous(props ...PreviousProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var17 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var17 = []any{
 | 
				
			||||||
			"carousel-prev absolute left-2 top-1/2 transform -translate-y-1/2 p-2 rounded-full bg-black/20 text-white hover:bg-black/40 focus:outline-none",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"carousel-prev absolute left-2 top-1/2 transform -translate-y-1/2 p-2 rounded-full bg-black/20 text-white hover:bg-black/40 focus:outline-none",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -502,10 +506,11 @@ func Next(props ...NextProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var21 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var21 = []any{
 | 
				
			||||||
			"carousel-next absolute right-2 top-1/2 transform -translate-y-1/2 p-2 rounded-full bg-black/20 text-white hover:bg-black/40 focus:outline-none",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"carousel-next absolute right-2 top-1/2 transform -translate-y-1/2 p-2 rounded-full bg-black/20 text-white hover:bg-black/40 focus:outline-none",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var21...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var21...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -596,10 +601,11 @@ func Indicators(props ...IndicatorsProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var25 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var25 = []any{
 | 
				
			||||||
			"absolute bottom-4 left-1/2 transform -translate-x-1/2 flex gap-2",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"absolute bottom-4 left-1/2 transform -translate-x-1/2 flex gap-2",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var25...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var25...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -654,10 +660,11 @@ func Indicators(props ...IndicatorsProps) templ.Component {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for i := 0; i < p.Count; i++ {
 | 
							for i := 0; i < p.Count; i++ {
 | 
				
			||||||
			var templ_7745c5c3_Var28 = []any{utils.TwMerge(
 | 
								var templ_7745c5c3_Var28 = []any{
 | 
				
			||||||
				"carousel-indicator w-3 h-3 rounded-full bg-white/50 hover:bg-white/80 focus:outline-none transition-colors",
 | 
									utils.TwMerge(
 | 
				
			||||||
				utils.If(i == 0, "bg-white"),
 | 
										"carousel-indicator w-3 h-3 rounded-full bg-white/50 hover:bg-white/80 focus:outline-none transition-colors",
 | 
				
			||||||
			),
 | 
										utils.If(i == 0, "bg-white"),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var28...)
 | 
								templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var28...)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component chart - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component chart - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package chart
 | 
					package chart
 | 
				
			||||||
| 
						 | 
					@ -106,9 +106,10 @@ func Chart(props ...Props) templ.Component {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		canvasId := p.ID + "-canvas"
 | 
							canvasId := p.ID + "-canvas"
 | 
				
			||||||
		dataId := p.ID + "-data"
 | 
							dataId := p.ID + "-data"
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"chart-container relative",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class),
 | 
									"chart-container relative",
 | 
				
			||||||
 | 
									p.Class),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component checkbox - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component checkbox - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package checkbox
 | 
					package checkbox
 | 
				
			||||||
| 
						 | 
					@ -56,15 +56,16 @@ func Checkbox(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative size-4 overflow-hidden peer",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"before:absolute before:inset-0 before:content['']",
 | 
									"relative size-4 overflow-hidden peer",
 | 
				
			||||||
			"appearance-none rounded-sm border-2 border-primary bg-background",
 | 
									"before:absolute before:inset-0 before:content['']",
 | 
				
			||||||
			"cursor-pointer transition-colors",
 | 
									"appearance-none rounded-sm border-2 border-primary bg-background",
 | 
				
			||||||
			"checked:before:bg-primary",
 | 
									"cursor-pointer transition-colors",
 | 
				
			||||||
			"disabled:cursor-not-allowed disabled:opacity-50",
 | 
									"checked:before:bg-primary",
 | 
				
			||||||
			p.Class,
 | 
									"disabled:cursor-not-allowed disabled:opacity-50",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -174,11 +175,12 @@ func Checkbox(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var7 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var7 = []any{
 | 
				
			||||||
			"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"size-3 text-primary-foreground pointer-events-none opacity-0",
 | 
									"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
 | 
				
			||||||
			"peer-checked:opacity-100",
 | 
									"size-3 text-primary-foreground pointer-events-none opacity-0",
 | 
				
			||||||
		),
 | 
									"peer-checked:opacity-100",
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component checkboxcard - version: main installed by templui v0.71.0
 | 
					// templui component checkboxcard - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package checkboxcard
 | 
					package checkboxcard
 | 
				
			||||||
| 
						 | 
					@ -70,11 +70,12 @@ func CheckboxCard(props ...Props) templ.Component {
 | 
				
			||||||
			p.ID = utils.RandomID()
 | 
								p.ID = utils.RandomID()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		inputId := p.ID + "-input"
 | 
							inputId := p.ID + "-input"
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.If(p.Disabled, "opacity-60"),
 | 
									"relative",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.Disabled, "opacity-60"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -201,16 +202,17 @@ func CheckboxCard(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var8 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var8 = []any{
 | 
				
			||||||
			"block w-full rounded-lg border overflow-hidden h-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"bg-card text-card-foreground p-4 flex flex-col",
 | 
									"block w-full rounded-lg border overflow-hidden h-full",
 | 
				
			||||||
			"cursor-pointer",
 | 
									"bg-card text-card-foreground p-4 flex flex-col",
 | 
				
			||||||
			"hover:border-primary/50",
 | 
									"cursor-pointer",
 | 
				
			||||||
			"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
 | 
									"hover:border-primary/50",
 | 
				
			||||||
			utils.If(p.Disabled, "cursor-not-allowed"),
 | 
									"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
 | 
				
			||||||
			"transition-all duration-200",
 | 
									utils.If(p.Disabled, "cursor-not-allowed"),
 | 
				
			||||||
			p.Class,
 | 
									"transition-all duration-200",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -283,10 +285,11 @@ func Header(props ...HeaderProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var12 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var12 = []any{
 | 
				
			||||||
			"flex items-center justify-between mb-2",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex items-center justify-between mb-2",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -377,10 +380,11 @@ func Description(props ...DescriptionProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var16 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var16 = []any{
 | 
				
			||||||
			"text-sm text-muted-foreground",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"text-sm text-muted-foreground",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -471,10 +475,11 @@ func Footer(props ...FooterProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var20 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var20 = []any{
 | 
				
			||||||
			"mt-auto pt-4 w-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"mt-auto pt-4 w-full",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component checkboxcard - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component checkboxcard - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package checkboxcard
 | 
					package checkboxcard
 | 
				
			||||||
| 
						 | 
					@ -70,11 +70,12 @@ func CheckboxCard(props ...Props) templ.Component {
 | 
				
			||||||
			p.ID = utils.RandomID()
 | 
								p.ID = utils.RandomID()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		inputId := p.ID + "-input"
 | 
							inputId := p.ID + "-input"
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.If(p.Disabled, "opacity-60"),
 | 
									"relative",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.Disabled, "opacity-60"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -201,16 +202,17 @@ func CheckboxCard(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var8 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var8 = []any{
 | 
				
			||||||
			"block w-full rounded-lg border overflow-hidden h-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"bg-card text-card-foreground p-4 flex flex-col",
 | 
									"block w-full rounded-lg border overflow-hidden h-full",
 | 
				
			||||||
			"cursor-pointer",
 | 
									"bg-card text-card-foreground p-4 flex flex-col",
 | 
				
			||||||
			"hover:border-primary/50",
 | 
									"cursor-pointer",
 | 
				
			||||||
			"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
 | 
									"hover:border-primary/50",
 | 
				
			||||||
			utils.If(p.Disabled, "cursor-not-allowed"),
 | 
									"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
 | 
				
			||||||
			"transition-all duration-200",
 | 
									utils.If(p.Disabled, "cursor-not-allowed"),
 | 
				
			||||||
			p.Class,
 | 
									"transition-all duration-200",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -283,10 +285,11 @@ func Header(props ...HeaderProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var12 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var12 = []any{
 | 
				
			||||||
			"flex items-center justify-between mb-2",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex items-center justify-between mb-2",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -377,10 +380,11 @@ func Description(props ...DescriptionProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var16 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var16 = []any{
 | 
				
			||||||
			"text-sm text-muted-foreground",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"text-sm text-muted-foreground",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -471,10 +475,11 @@ func Footer(props ...FooterProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var20 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var20 = []any{
 | 
				
			||||||
			"mt-auto pt-4 w-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"mt-auto pt-4 w-full",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component code - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component code - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package code
 | 
					package code
 | 
				
			||||||
| 
						 | 
					@ -108,15 +108,16 @@ func Code(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var5 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var5 = []any{
 | 
				
			||||||
			"language-"+p.Language,
 | 
								utils.TwMerge(
 | 
				
			||||||
			"overflow-y-auto! rounded-md block text-sm max-h-[501px]",
 | 
									"language-"+p.Language,
 | 
				
			||||||
			utils.If(p.Size == SizeSm, "max-h-[250px]"),
 | 
									"overflow-y-auto! rounded-md block text-sm max-h-[501px]",
 | 
				
			||||||
			utils.If(p.Size == SizeLg, "max-h-[1000px]"),
 | 
									utils.If(p.Size == SizeSm, "max-h-[250px]"),
 | 
				
			||||||
			utils.If(p.Size == SizeFull, "max-h-full"),
 | 
									utils.If(p.Size == SizeLg, "max-h-[1000px]"),
 | 
				
			||||||
			"hljs-target",
 | 
									utils.If(p.Size == SizeFull, "max-h-full"),
 | 
				
			||||||
			p.CodeClass,
 | 
									"hljs-target",
 | 
				
			||||||
		),
 | 
									p.CodeClass,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component datepicker - version: main installed by templui v0.71.0
 | 
					// templui component datepicker - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package datepicker
 | 
					package datepicker
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component datepicker - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component datepicker - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package datepicker
 | 
					package datepicker
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component drawer - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component drawer - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package drawer
 | 
					package drawer
 | 
				
			||||||
| 
						 | 
					@ -245,14 +245,15 @@ func Content(props ...ContentProps) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var8 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var8 = []any{
 | 
				
			||||||
			"fixed z-50 templui-drawer-content hidden",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"fixed z-50 templui-drawer-content hidden",
 | 
				
			||||||
			utils.If(p.Position == PositionRight, "inset-y-0 right-0 w-3/4 md:w-1/2 lg:w-1/3"),
 | 
									p.Class,
 | 
				
			||||||
			utils.If(p.Position == PositionLeft, "inset-y-0 left-0 w-3/4 md:w-1/2 lg:w-1/3"),
 | 
									utils.If(p.Position == PositionRight, "inset-y-0 right-0 w-3/4 md:w-1/2 lg:w-1/3"),
 | 
				
			||||||
			utils.If(p.Position == PositionTop, "inset-x-0 top-0 h-auto sm:h-1/2"),
 | 
									utils.If(p.Position == PositionLeft, "inset-y-0 left-0 w-3/4 md:w-1/2 lg:w-1/3"),
 | 
				
			||||||
			utils.If(p.Position == PositionBottom, "inset-x-0 bottom-0 h-auto sm:h-1/2"),
 | 
									utils.If(p.Position == PositionTop, "inset-x-0 top-0 h-auto sm:h-1/2"),
 | 
				
			||||||
		),
 | 
									utils.If(p.Position == PositionBottom, "inset-x-0 bottom-0 h-auto sm:h-1/2"),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -309,13 +310,14 @@ func Content(props ...ContentProps) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var12 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var12 = []any{
 | 
				
			||||||
			"h-full overflow-y-auto bg-background p-6 shadow-lg",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.If(p.Position == PositionRight, "border-l"),
 | 
									"h-full overflow-y-auto bg-background p-6 shadow-lg",
 | 
				
			||||||
			utils.If(p.Position == PositionLeft, "border-r"),
 | 
									utils.If(p.Position == PositionRight, "border-l"),
 | 
				
			||||||
			utils.If(p.Position == PositionBottom, "border-t"),
 | 
									utils.If(p.Position == PositionLeft, "border-r"),
 | 
				
			||||||
			utils.If(p.Position == PositionTop, "border-b"),
 | 
									utils.If(p.Position == PositionBottom, "border-t"),
 | 
				
			||||||
		),
 | 
									utils.If(p.Position == PositionTop, "border-b"),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -735,13 +737,14 @@ func Close(props ...CloseProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var31 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var31 = []any{
 | 
				
			||||||
			"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
 | 
									"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background",
 | 
				
			||||||
			"disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent",
 | 
									"transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
 | 
				
			||||||
			"hover:text-accent-foreground h-10 px-4 py-2",
 | 
									"disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent",
 | 
				
			||||||
			p.Class,
 | 
									"hover:text-accent-foreground h-10 px-4 py-2",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var31...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var31...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component dropdown - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component dropdown - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package dropdown
 | 
					package dropdown
 | 
				
			||||||
| 
						 | 
					@ -519,12 +519,13 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
			p.ID = utils.RandomID()
 | 
								p.ID = utils.RandomID()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if p.Href != "" {
 | 
							if p.Href != "" {
 | 
				
			||||||
			var templ_7745c5c3_Var17 = []any{utils.TwMerge(
 | 
								var templ_7745c5c3_Var17 = []any{
 | 
				
			||||||
				"flex text-left items-center px-2 py-1.5 text-sm rounded-sm",
 | 
									utils.TwMerge(
 | 
				
			||||||
				utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
 | 
										"flex text-left items-center px-2 py-1.5 text-sm rounded-sm",
 | 
				
			||||||
				utils.If(p.Disabled, "opacity-50 pointer-events-none"),
 | 
										utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
 | 
				
			||||||
				p.Class,
 | 
										utils.If(p.Disabled, "opacity-50 pointer-events-none"),
 | 
				
			||||||
			),
 | 
										p.Class,
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
 | 
								templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -552,12 +553,8 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
									if templ_7745c5c3_Err != nil {
 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
										return templ_7745c5c3_Err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				var templ_7745c5c3_Var19 templ.SafeURL
 | 
									var templ_7745c5c3_Var19 templ.SafeURL = templ.SafeURL(p.Href)
 | 
				
			||||||
				templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Href))
 | 
									_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var19)))
 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
					 | 
				
			||||||
					return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/dropdown/dropdown.templ`, Line: 216, Col: 32}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
 | 
					 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
									if templ_7745c5c3_Err != nil {
 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
										return templ_7745c5c3_Err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					@ -625,12 +622,13 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			var templ_7745c5c3_Var22 = []any{utils.TwMerge(
 | 
								var templ_7745c5c3_Var22 = []any{
 | 
				
			||||||
				"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
 | 
									utils.TwMerge(
 | 
				
			||||||
				utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
 | 
										"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
 | 
				
			||||||
				utils.If(p.Disabled, "opacity-50 pointer-events-none"),
 | 
										utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
 | 
				
			||||||
				p.Class,
 | 
										utils.If(p.Disabled, "opacity-50 pointer-events-none"),
 | 
				
			||||||
			),
 | 
										p.Class,
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...)
 | 
								templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -1009,11 +1007,12 @@ func SubTrigger(props ...SubTriggerProps) templ.Component {
 | 
				
			||||||
				}()
 | 
									}()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ctx = templ.InitializeContext(ctx)
 | 
								ctx = templ.InitializeContext(ctx)
 | 
				
			||||||
			var templ_7745c5c3_Var39 = []any{utils.TwMerge(
 | 
								var templ_7745c5c3_Var39 = []any{
 | 
				
			||||||
				"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
 | 
									utils.TwMerge(
 | 
				
			||||||
				"focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default",
 | 
										"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
 | 
				
			||||||
				p.Class,
 | 
										"focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default",
 | 
				
			||||||
			),
 | 
										p.Class,
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var39...)
 | 
								templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var39...)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component form - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component form - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package form
 | 
					package form
 | 
				
			||||||
| 
						 | 
					@ -400,11 +400,12 @@ func Message(props ...MessageProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var16 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var16 = []any{
 | 
				
			||||||
			"text-[0.8rem] font-medium",
 | 
								utils.TwMerge(
 | 
				
			||||||
			messageVariantClass(p.Variant),
 | 
									"text-[0.8rem] font-medium",
 | 
				
			||||||
			p.Class,
 | 
									messageVariantClass(p.Variant),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component input - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component input - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package input
 | 
					package input
 | 
				
			||||||
| 
						 | 
					@ -82,27 +82,28 @@ func Input(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			// Base styles
 | 
								utils.TwMerge(
 | 
				
			||||||
			"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
 | 
									// Base styles
 | 
				
			||||||
			// Dark mode background
 | 
									"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
 | 
				
			||||||
			"dark:bg-input/30",
 | 
									// Dark mode background
 | 
				
			||||||
			// Selection styles
 | 
									"dark:bg-input/30",
 | 
				
			||||||
			"selection:bg-primary selection:text-primary-foreground",
 | 
									// Selection styles
 | 
				
			||||||
			// Placeholder
 | 
									"selection:bg-primary selection:text-primary-foreground",
 | 
				
			||||||
			"placeholder:text-muted-foreground",
 | 
									// Placeholder
 | 
				
			||||||
			// File input styles
 | 
									"placeholder:text-muted-foreground",
 | 
				
			||||||
			"file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground",
 | 
									// File input styles
 | 
				
			||||||
			// Focus styles
 | 
									"file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground",
 | 
				
			||||||
			"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
									// Focus styles
 | 
				
			||||||
			// Disabled styles
 | 
									"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
				
			||||||
			"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
 | 
									// Disabled styles
 | 
				
			||||||
			// Error/Invalid styles
 | 
									"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
 | 
				
			||||||
			"aria-invalid:ring-destructive/20 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40",
 | 
									// Error/Invalid styles
 | 
				
			||||||
			utils.If(p.HasError, "border-destructive ring-destructive/20 dark:ring-destructive/40"),
 | 
									"aria-invalid:ring-destructive/20 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40",
 | 
				
			||||||
			utils.If(p.Type == TypePassword && !p.NoTogglePassword, "pr-8"),
 | 
									utils.If(p.HasError, "border-destructive ring-destructive/20 dark:ring-destructive/40"),
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.Type == TypePassword && !p.NoTogglePassword, "pr-8"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component inputotp - version: main installed by templui v0.71.0
 | 
					// templui component inputotp - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package inputotp
 | 
					package inputotp
 | 
				
			||||||
| 
						 | 
					@ -76,10 +76,11 @@ func InputOTP(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"flex flex-row items-center gap-2 w-fit",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex flex-row items-center gap-2 w-fit",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -241,10 +242,11 @@ func Group(props ...GroupProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var9 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var9 = []any{
 | 
				
			||||||
			"flex gap-2",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex gap-2",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -373,15 +375,16 @@ func Slot(props ...SlotProps) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var14 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var14 = []any{
 | 
				
			||||||
			"w-10 h-12 text-center",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"rounded-md border border-input bg-background text-sm",
 | 
									"w-10 h-12 text-center",
 | 
				
			||||||
			"file:border-0 file:bg-transparent file:text-sm file:font-medium",
 | 
									"rounded-md border border-input bg-background text-sm",
 | 
				
			||||||
			"placeholder:text-muted-foreground",
 | 
									"file:border-0 file:bg-transparent file:text-sm file:font-medium",
 | 
				
			||||||
			"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
 | 
									"placeholder:text-muted-foreground",
 | 
				
			||||||
			"disabled:cursor-not-allowed disabled:opacity-50",
 | 
									"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
 | 
				
			||||||
			p.Class,
 | 
									"disabled:cursor-not-allowed disabled:opacity-50",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -500,10 +503,11 @@ func Separator(props ...SeparatorProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var20 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var20 = []any{
 | 
				
			||||||
			"flex items-center text-muted-foreground text-xl",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex items-center text-muted-foreground text-xl",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component inputotp - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component inputotp - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package inputotp
 | 
					package inputotp
 | 
				
			||||||
| 
						 | 
					@ -73,10 +73,11 @@ func InputOTP(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"flex flex-row items-center gap-2 w-fit",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex flex-row items-center gap-2 w-fit",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -244,10 +245,11 @@ func Group(props ...GroupProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var9 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var9 = []any{
 | 
				
			||||||
			"flex gap-2",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex gap-2",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -376,24 +378,25 @@ func Slot(props ...SlotProps) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var14 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var14 = []any{
 | 
				
			||||||
			// Base styles - keeping the specific OTP dimensions
 | 
								utils.TwMerge(
 | 
				
			||||||
			"w-10 h-12 text-center rounded-md border border-input bg-transparent text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
 | 
									// Base styles - keeping the specific OTP dimensions
 | 
				
			||||||
			// Dark mode background
 | 
									"w-10 h-12 text-center rounded-md border border-input bg-transparent text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
 | 
				
			||||||
			"dark:bg-input/30",
 | 
									// Dark mode background
 | 
				
			||||||
			// Selection styles
 | 
									"dark:bg-input/30",
 | 
				
			||||||
			"selection:bg-primary selection:text-primary-foreground",
 | 
									// Selection styles
 | 
				
			||||||
			// Placeholder
 | 
									"selection:bg-primary selection:text-primary-foreground",
 | 
				
			||||||
			"placeholder:text-muted-foreground",
 | 
									// Placeholder
 | 
				
			||||||
			// Focus styles
 | 
									"placeholder:text-muted-foreground",
 | 
				
			||||||
			"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
									// Focus styles
 | 
				
			||||||
			// Disabled styles
 | 
									"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
				
			||||||
			"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
 | 
									// Disabled styles
 | 
				
			||||||
			// Error/Invalid styles
 | 
									"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
 | 
				
			||||||
			"aria-invalid:ring-destructive/20 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40",
 | 
									// Error/Invalid styles
 | 
				
			||||||
			utils.If(p.HasError, "border-destructive ring-destructive/20 dark:ring-destructive/40"),
 | 
									"aria-invalid:ring-destructive/20 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.HasError, "border-destructive ring-destructive/20 dark:ring-destructive/40"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -518,10 +521,11 @@ func Separator(props ...SeparatorProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var20 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var20 = []any{
 | 
				
			||||||
			"flex items-center text-muted-foreground text-xl",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex items-center text-muted-foreground text-xl",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component label - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component label - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package label
 | 
					package label
 | 
				
			||||||
| 
						 | 
					@ -45,11 +45,12 @@ func Label(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"text-sm font-medium leading-none inline-block",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.If(len(p.Error) > 0, "text-destructive"),
 | 
									"text-sm font-medium leading-none inline-block",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(len(p.Error) > 0, "text-destructive"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component modal - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component modal - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package modal
 | 
					package modal
 | 
				
			||||||
| 
						 | 
					@ -138,11 +138,12 @@ func Modal(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var4 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var4 = []any{
 | 
				
			||||||
			"modal-content relative bg-background rounded-lg border text-left overflow-hidden shadow-xl transform transition-all sm:my-8 w-full scale-95 opacity-0", // Base classes + transition start
 | 
								utils.TwMerge(
 | 
				
			||||||
			"duration-300 ease-out", // Enter duration
 | 
									"modal-content relative bg-background rounded-lg border text-left overflow-hidden shadow-xl transform transition-all sm:my-8 w-full scale-95 opacity-0", // Base classes + transition start
 | 
				
			||||||
			p.Class,
 | 
									"duration-300 ease-out", // Enter duration
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -215,11 +216,12 @@ func Trigger(props ...TriggerProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var8 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var8 = []any{
 | 
				
			||||||
			"group",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.IfElse(p.Disabled, "cursor-not-allowed opacity-50", "cursor-pointer"),
 | 
									"group",
 | 
				
			||||||
			p.Class,
 | 
									utils.IfElse(p.Disabled, "cursor-not-allowed opacity-50", "cursor-pointer"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component pagination - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component pagination - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package pagination
 | 
					package pagination
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component popover - version: main installed by templui v0.71.0
 | 
					// templui component popover - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package popover
 | 
					package popover
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component popover - version: main installed by templui v0.71.0
 | 
					// templui component popover - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package popover
 | 
					package popover
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component popover - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component popover - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package popover
 | 
					package popover
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component progress - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component progress - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package progress
 | 
					package progress
 | 
				
			||||||
| 
						 | 
					@ -192,12 +192,13 @@ func Progress(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var9 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var9 = []any{
 | 
				
			||||||
			"h-full rounded-full transition-all",
 | 
								utils.TwMerge(
 | 
				
			||||||
			sizeClasses(p.Size),
 | 
									"h-full rounded-full transition-all",
 | 
				
			||||||
			variantClasses(p.Variant),
 | 
									sizeClasses(p.Size),
 | 
				
			||||||
			p.BarClass,
 | 
									variantClasses(p.Variant),
 | 
				
			||||||
		),
 | 
									p.BarClass,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component radio - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component radio - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package radio
 | 
					package radio
 | 
				
			||||||
| 
						 | 
					@ -48,20 +48,21 @@ func Radio(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative h-4 w-4",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"before:absolute before:left-1/2 before:top-1/2",
 | 
									"relative h-4 w-4",
 | 
				
			||||||
			"before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2",
 | 
									"before:absolute before:left-1/2 before:top-1/2",
 | 
				
			||||||
			"appearance-none rounded-full",
 | 
									"before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2",
 | 
				
			||||||
			"border-2 border-primary",
 | 
									"appearance-none rounded-full",
 | 
				
			||||||
			"before:content[''] before:rounded-full before:bg-background",
 | 
									"border-2 border-primary",
 | 
				
			||||||
			"checked:border-primary checked:bg-primary",
 | 
									"before:content[''] before:rounded-full before:bg-background",
 | 
				
			||||||
			"checked:before:visible",
 | 
									"checked:border-primary checked:bg-primary",
 | 
				
			||||||
			"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
 | 
									"checked:before:visible",
 | 
				
			||||||
			"focus-visible:ring-offset-2 focus-visible:ring-offset-background",
 | 
									"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
 | 
				
			||||||
			"disabled:cursor-not-allowed",
 | 
									"focus-visible:ring-offset-2 focus-visible:ring-offset-background",
 | 
				
			||||||
			p.Class,
 | 
									"disabled:cursor-not-allowed",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component radiocard - version: main installed by templui v0.71.0
 | 
					// templui component radiocard - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package radiocard
 | 
					package radiocard
 | 
				
			||||||
| 
						 | 
					@ -69,11 +69,12 @@ func RadioCard(props ...Props) templ.Component {
 | 
				
			||||||
		if p.ID == "" {
 | 
							if p.ID == "" {
 | 
				
			||||||
			p.ID = utils.RandomID()
 | 
								p.ID = utils.RandomID()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.If(p.Disabled, "opacity-60"),
 | 
									"relative",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.Disabled, "opacity-60"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -190,16 +191,17 @@ func RadioCard(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var8 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var8 = []any{
 | 
				
			||||||
			"block w-full rounded-lg border overflow-hidden h-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"bg-card text-card-foreground p-4 flex flex-col",
 | 
									"block w-full rounded-lg border overflow-hidden h-full",
 | 
				
			||||||
			"cursor-pointer",
 | 
									"bg-card text-card-foreground p-4 flex flex-col",
 | 
				
			||||||
			"hover:border-primary/50",
 | 
									"cursor-pointer",
 | 
				
			||||||
			"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
 | 
									"hover:border-primary/50",
 | 
				
			||||||
			utils.If(p.Disabled, "cursor-not-allowed"),
 | 
									"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
 | 
				
			||||||
			"transition-all duration-200",
 | 
									utils.If(p.Disabled, "cursor-not-allowed"),
 | 
				
			||||||
			p.Class,
 | 
									"transition-all duration-200",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component radiocard - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component radiocard - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package radiocard
 | 
					package radiocard
 | 
				
			||||||
| 
						 | 
					@ -69,11 +69,12 @@ func RadioCard(props ...Props) templ.Component {
 | 
				
			||||||
		if p.ID == "" {
 | 
							if p.ID == "" {
 | 
				
			||||||
			p.ID = utils.RandomID()
 | 
								p.ID = utils.RandomID()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"relative",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.If(p.Disabled, "opacity-60"),
 | 
									"relative",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.Disabled, "opacity-60"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -190,16 +191,17 @@ func RadioCard(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var8 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var8 = []any{
 | 
				
			||||||
			"block w-full rounded-lg border overflow-hidden h-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"bg-card text-card-foreground p-4 flex flex-col",
 | 
									"block w-full rounded-lg border overflow-hidden h-full",
 | 
				
			||||||
			"cursor-pointer",
 | 
									"bg-card text-card-foreground p-4 flex flex-col",
 | 
				
			||||||
			"hover:border-primary/50",
 | 
									"cursor-pointer",
 | 
				
			||||||
			"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
 | 
									"hover:border-primary/50",
 | 
				
			||||||
			utils.If(p.Disabled, "cursor-not-allowed"),
 | 
									"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
 | 
				
			||||||
			"transition-all duration-200",
 | 
									utils.If(p.Disabled, "cursor-not-allowed"),
 | 
				
			||||||
			p.Class,
 | 
									"transition-all duration-200",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component rating - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component rating - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package rating
 | 
					package rating
 | 
				
			||||||
| 
						 | 
					@ -76,10 +76,11 @@ func Rating(props ...Props) templ.Component {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		p.setDefaults()
 | 
							p.setDefaults()
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"flex flex-col items-start gap-1",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"flex flex-col items-start gap-1",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -368,13 +369,14 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		p.setDefaults()
 | 
							p.setDefaults()
 | 
				
			||||||
		var templ_7745c5c3_Var17 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var17 = []any{
 | 
				
			||||||
			"relative",
 | 
								utils.TwMerge(
 | 
				
			||||||
			colorClass(p.Style),
 | 
									"relative",
 | 
				
			||||||
			"transition-opacity",
 | 
									colorClass(p.Style),
 | 
				
			||||||
			"cursor-pointer", // Default cursor
 | 
									"transition-opacity",
 | 
				
			||||||
			p.Class,
 | 
									"cursor-pointer", // Default cursor
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component selectbox - version: main installed by templui v0.71.0
 | 
					// templui component selectbox - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package selectbox
 | 
					package selectbox
 | 
				
			||||||
| 
						 | 
					@ -705,14 +705,15 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var26 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var26 = []any{
 | 
				
			||||||
			"select-item relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 px-2 text-sm font-light outline-none",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"hover:bg-accent hover:text-accent-foreground",
 | 
									"select-item relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 px-2 text-sm font-light outline-none",
 | 
				
			||||||
			"focus:bg-accent focus:text-accent-foreground",
 | 
									"hover:bg-accent hover:text-accent-foreground",
 | 
				
			||||||
			utils.If(p.Selected, "bg-accent text-accent-foreground"),
 | 
									"focus:bg-accent focus:text-accent-foreground",
 | 
				
			||||||
			utils.If(p.Disabled, "pointer-events-none opacity-50"),
 | 
									utils.If(p.Selected, "bg-accent text-accent-foreground"),
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.Disabled, "pointer-events-none opacity-50"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var26...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var26...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -813,10 +814,11 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var32 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var32 = []any{
 | 
				
			||||||
			"select-check absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.IfElse(p.Selected, "opacity-100", "opacity-0"),
 | 
									"select-check absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
 | 
				
			||||||
		),
 | 
									utils.IfElse(p.Selected, "opacity-100", "opacity-0"),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var32...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var32...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component selectbox - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component selectbox - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package selectbox
 | 
					package selectbox
 | 
				
			||||||
| 
						 | 
					@ -752,14 +752,15 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var25 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var25 = []any{
 | 
				
			||||||
			"select-item relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 px-2 text-sm font-light outline-none",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"hover:bg-accent hover:text-accent-foreground",
 | 
									"select-item relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 px-2 text-sm font-light outline-none",
 | 
				
			||||||
			"focus:bg-accent focus:text-accent-foreground",
 | 
									"hover:bg-accent hover:text-accent-foreground",
 | 
				
			||||||
			utils.If(p.Selected, "bg-accent text-accent-foreground"),
 | 
									"focus:bg-accent focus:text-accent-foreground",
 | 
				
			||||||
			utils.If(p.Disabled, "pointer-events-none opacity-50"),
 | 
									utils.If(p.Selected, "bg-accent text-accent-foreground"),
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.Disabled, "pointer-events-none opacity-50"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var25...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var25...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -860,10 +861,11 @@ func Item(props ...ItemProps) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var31 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var31 = []any{
 | 
				
			||||||
			"select-check absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.IfElse(p.Selected, "opacity-100", "opacity-0"),
 | 
									"select-check absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
 | 
				
			||||||
		),
 | 
									utils.IfElse(p.Selected, "opacity-100", "opacity-0"),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var31...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var31...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component separator - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component separator - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package separator
 | 
					package separator
 | 
				
			||||||
| 
						 | 
					@ -115,10 +115,11 @@ func Separator(props ...Props) templ.Component {
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var templ_7745c5c3_Var5 = []any{utils.TwMerge(
 | 
								var templ_7745c5c3_Var5 = []any{
 | 
				
			||||||
				"absolute w-full border-t h-[1px]",
 | 
									utils.TwMerge(
 | 
				
			||||||
				decorationClasses(p.Decoration),
 | 
										"absolute w-full border-t h-[1px]",
 | 
				
			||||||
			),
 | 
										decorationClasses(p.Decoration),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
 | 
								templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -203,10 +204,11 @@ func Separator(props ...Props) templ.Component {
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var templ_7745c5c3_Var10 = []any{utils.TwMerge(
 | 
								var templ_7745c5c3_Var10 = []any{
 | 
				
			||||||
				"absolute h-full border-l w-[1px]",
 | 
									utils.TwMerge(
 | 
				
			||||||
				decorationClasses(p.Decoration),
 | 
										"absolute h-full border-l w-[1px]",
 | 
				
			||||||
			),
 | 
										decorationClasses(p.Decoration),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
								templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component skeleton - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component skeleton - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package skeleton
 | 
					package skeleton
 | 
				
			||||||
| 
						 | 
					@ -43,10 +43,11 @@ func Skeleton(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"animate-pulse rounded bg-muted",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"animate-pulse rounded bg-muted",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component slider - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component slider - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package slider
 | 
					package slider
 | 
				
			||||||
| 
						 | 
					@ -158,18 +158,19 @@ func Input(props ...InputProps) templ.Component {
 | 
				
			||||||
		if p.ID == "" {
 | 
							if p.ID == "" {
 | 
				
			||||||
			p.ID = utils.RandomID()
 | 
								p.ID = utils.RandomID()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var6 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var6 = []any{
 | 
				
			||||||
			"w-full h-2 rounded-full bg-secondary appearance-none cursor-pointer",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
 | 
									"w-full h-2 rounded-full bg-secondary appearance-none cursor-pointer",
 | 
				
			||||||
			"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
 | 
									"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
 | 
				
			||||||
			"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary",
 | 
									"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
 | 
				
			||||||
			"[&::-webkit-slider-thumb]:hover:bg-primary/90",
 | 
									"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary",
 | 
				
			||||||
			"[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:border-0",
 | 
									"[&::-webkit-slider-thumb]:hover:bg-primary/90",
 | 
				
			||||||
			"[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-primary",
 | 
									"[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:border-0",
 | 
				
			||||||
			"[&::-moz-range-thumb]:hover:bg-primary/90",
 | 
									"[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-primary",
 | 
				
			||||||
			"disabled:opacity-50 disabled:cursor-not-allowed",
 | 
									"[&::-moz-range-thumb]:hover:bg-primary/90",
 | 
				
			||||||
			p.Class,
 | 
									"disabled:opacity-50 disabled:cursor-not-allowed",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component spinner - version: main installed by templui v0.71.0
 | 
					// templui component spinner - version: main installed by templui v0.71.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package spinner
 | 
					package spinner
 | 
				
			||||||
| 
						 | 
					@ -53,10 +53,11 @@ func Spinner(props ...Props) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			"inline-flex flex-col items-center justify-center",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"inline-flex flex-col items-center justify-center",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -110,21 +111,22 @@ func Spinner(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var5 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var5 = []any{
 | 
				
			||||||
			"animate-spin rounded-full",
 | 
								utils.TwMerge(
 | 
				
			||||||
			sizeClass(p.Size),
 | 
									"animate-spin rounded-full",
 | 
				
			||||||
			borderSizeClass(p.Size),
 | 
									sizeClass(p.Size),
 | 
				
			||||||
			utils.IfElse(
 | 
									borderSizeClass(p.Size),
 | 
				
			||||||
				p.Color == "",
 | 
									utils.IfElse(
 | 
				
			||||||
				"border-primary border-b-transparent",
 | 
										p.Color == "",
 | 
				
			||||||
				"border-current border-b-transparent",
 | 
										"border-primary border-b-transparent",
 | 
				
			||||||
 | 
										"border-current border-b-transparent",
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
 | 
									utils.IfElse(
 | 
				
			||||||
 | 
										p.Color != "",
 | 
				
			||||||
 | 
										p.Color,
 | 
				
			||||||
 | 
										"",
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			),
 | 
								),
 | 
				
			||||||
			utils.IfElse(
 | 
					 | 
				
			||||||
				p.Color != "",
 | 
					 | 
				
			||||||
				p.Color,
 | 
					 | 
				
			||||||
				"",
 | 
					 | 
				
			||||||
			),
 | 
					 | 
				
			||||||
		),
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component table - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component table - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package table
 | 
					package table
 | 
				
			||||||
| 
						 | 
					@ -450,11 +450,12 @@ func Row(props ...RowProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var18 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var18 = []any{
 | 
				
			||||||
			"border-b transition-colors hover:bg-muted/50",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.If(p.Selected, "data-[state=selected]:bg-muted"),
 | 
									"border-b transition-colors hover:bg-muted/50",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.Selected, "data-[state=selected]:bg-muted"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -545,11 +546,12 @@ func Head(props ...HeadProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var22 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var22 = []any{
 | 
				
			||||||
			"h-10 px-2 text-left align-middle font-medium text-muted-foreground",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
 | 
									"h-10 px-2 text-left align-middle font-medium text-muted-foreground",
 | 
				
			||||||
			p.Class,
 | 
									"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -640,11 +642,12 @@ func Cell(props ...CellProps) templ.Component {
 | 
				
			||||||
		if len(props) > 0 {
 | 
							if len(props) > 0 {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var26 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var26 = []any{
 | 
				
			||||||
			"p-2 align-middle",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
 | 
									"p-2 align-middle",
 | 
				
			||||||
			p.Class,
 | 
									"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var26...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var26...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component tabs - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component tabs - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package tabs
 | 
					package tabs
 | 
				
			||||||
| 
						 | 
					@ -179,10 +179,11 @@ func List(props ...ListProps) templ.Component {
 | 
				
			||||||
			p = props[0]
 | 
								p = props[0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		tabsID := IDFromContext(ctx)
 | 
							tabsID := IDFromContext(ctx)
 | 
				
			||||||
		var templ_7745c5c3_Var7 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var7 = []any{
 | 
				
			||||||
			"relative flex items-center justify-center h-10 p-1 rounded-lg select-none bg-muted text-muted-foreground",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"relative flex items-center justify-center h-10 p-1 rounded-lg select-none bg-muted text-muted-foreground",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -296,10 +297,11 @@ func Trigger(props ...TriggerProps) templ.Component {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var12 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var12 = []any{
 | 
				
			||||||
			"relative z-20 flex-1 inline-flex items-center justify-center h-8 px-3 text-sm font-medium transition-all rounded-md cursor-pointer whitespace-nowrap hover:text-foreground",
 | 
								utils.TwMerge(
 | 
				
			||||||
			p.Class,
 | 
									"relative z-20 flex-1 inline-flex items-center justify-center h-8 px-3 text-sm font-medium transition-all rounded-md cursor-pointer whitespace-nowrap hover:text-foreground",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					@ -439,11 +441,12 @@ func Content(props ...ContentProps) templ.Component {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var19 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var19 = []any{
 | 
				
			||||||
			"relative",
 | 
								utils.TwMerge(
 | 
				
			||||||
			utils.If(!p.IsActive, "hidden"),
 | 
									"relative",
 | 
				
			||||||
			p.Class,
 | 
									utils.If(!p.IsActive, "hidden"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var19...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var19...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component tagsinput - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component tagsinput - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package tagsinput
 | 
					package tagsinput
 | 
				
			||||||
| 
						 | 
					@ -49,21 +49,22 @@ func TagsInput(p Props) templ.Component {
 | 
				
			||||||
			templ_7745c5c3_Var1 = templ.NopComponent
 | 
								templ_7745c5c3_Var1 = templ.NopComponent
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx = templ.ClearChildren(ctx)
 | 
							ctx = templ.ClearChildren(ctx)
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			// Base styles
 | 
								utils.TwMerge(
 | 
				
			||||||
			"flex items-center flex-wrap gap-2 p-2 rounded-md border border-input bg-transparent shadow-xs transition-[color,box-shadow] outline-none",
 | 
									// Base styles
 | 
				
			||||||
			// Dark mode background
 | 
									"flex items-center flex-wrap gap-2 p-2 rounded-md border border-input bg-transparent shadow-xs transition-[color,box-shadow] outline-none",
 | 
				
			||||||
			"dark:bg-input/30",
 | 
									// Dark mode background
 | 
				
			||||||
			// Focus styles
 | 
									"dark:bg-input/30",
 | 
				
			||||||
			"focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]",
 | 
									// Focus styles
 | 
				
			||||||
			// Disabled styles
 | 
									"focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]",
 | 
				
			||||||
			utils.If(p.Disabled, "opacity-50 cursor-not-allowed"),
 | 
									// Disabled styles
 | 
				
			||||||
			// Width
 | 
									utils.If(p.Disabled, "opacity-50 cursor-not-allowed"),
 | 
				
			||||||
			"w-full",
 | 
									// Width
 | 
				
			||||||
			// Error/Invalid styles
 | 
									"w-full",
 | 
				
			||||||
			utils.If(p.HasError, "border-destructive ring-destructive/20 dark:ring-destructive/40"),
 | 
									// Error/Invalid styles
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.HasError, "border-destructive ring-destructive/20 dark:ring-destructive/40"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component textarea - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component textarea - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package textarea
 | 
					package textarea
 | 
				
			||||||
| 
						 | 
					@ -58,27 +58,28 @@ func Textarea(props ...Props) templ.Component {
 | 
				
			||||||
		if p.ID == "" {
 | 
							if p.ID == "" {
 | 
				
			||||||
			p.ID = utils.RandomID()
 | 
								p.ID = utils.RandomID()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var2 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var2 = []any{
 | 
				
			||||||
			// Base styles
 | 
								utils.TwMerge(
 | 
				
			||||||
			"flex w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
 | 
									// Base styles
 | 
				
			||||||
			"min-h-[80px]", // Default min-height
 | 
									"flex w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
 | 
				
			||||||
			// Dark mode background
 | 
									"min-h-[80px]", // Default min-height
 | 
				
			||||||
			"dark:bg-input/30",
 | 
									// Dark mode background
 | 
				
			||||||
			// Selection styles
 | 
									"dark:bg-input/30",
 | 
				
			||||||
			"selection:bg-primary selection:text-primary-foreground",
 | 
									// Selection styles
 | 
				
			||||||
			// Placeholder
 | 
									"selection:bg-primary selection:text-primary-foreground",
 | 
				
			||||||
			"placeholder:text-muted-foreground",
 | 
									// Placeholder
 | 
				
			||||||
			// Focus styles
 | 
									"placeholder:text-muted-foreground",
 | 
				
			||||||
			"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
									// Focus styles
 | 
				
			||||||
			// Disabled styles
 | 
									"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
 | 
				
			||||||
			"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
 | 
									// Disabled styles
 | 
				
			||||||
			// Error/Invalid styles
 | 
									"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
 | 
				
			||||||
			"aria-invalid:ring-destructive/20 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40",
 | 
									// Error/Invalid styles
 | 
				
			||||||
			utils.If(p.HasError, "border-destructive ring-destructive/20 dark:ring-destructive/40"),
 | 
									"aria-invalid:ring-destructive/20 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40",
 | 
				
			||||||
			// Add overflow-hidden only if auto-resizing to prevent scrollbar flicker
 | 
									utils.If(p.HasError, "border-destructive ring-destructive/20 dark:ring-destructive/40"),
 | 
				
			||||||
			utils.If(p.AutoResize, "overflow-hidden resize-none"),
 | 
									// Add overflow-hidden only if auto-resizing to prevent scrollbar flicker
 | 
				
			||||||
			p.Class,
 | 
									utils.If(p.AutoResize, "overflow-hidden resize-none"),
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component toast - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component toast - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package toast
 | 
					package toast
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component toggle - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component toggle - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package toggle
 | 
					package toggle
 | 
				
			||||||
| 
						 | 
					@ -183,20 +183,21 @@ func Toggle(props ...Props) templ.Component {
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var9 = []any{utils.TwMerge(
 | 
							var templ_7745c5c3_Var9 = []any{
 | 
				
			||||||
			"relative h-6 w-10",
 | 
								utils.TwMerge(
 | 
				
			||||||
			"after:absolute after:left-0.5 after:top-0.5",
 | 
									"relative h-6 w-10",
 | 
				
			||||||
			"after:h-5 after:w-5",
 | 
									"after:absolute after:left-0.5 after:top-0.5",
 | 
				
			||||||
			"rounded-full bg-neutral-200",
 | 
									"after:h-5 after:w-5",
 | 
				
			||||||
			"after:rounded-full after:bg-muted-foreground",
 | 
									"rounded-full bg-neutral-200",
 | 
				
			||||||
			"after:content-['']",
 | 
									"after:rounded-full after:bg-muted-foreground",
 | 
				
			||||||
			"after:transition-all",
 | 
									"after:content-['']",
 | 
				
			||||||
			"peer-checked:bg-primary",
 | 
									"after:transition-all",
 | 
				
			||||||
			"peer-checked:after:translate-x-[16px]",
 | 
									"peer-checked:bg-primary",
 | 
				
			||||||
			"peer-checked:after:bg-secondary",
 | 
									"peer-checked:after:translate-x-[16px]",
 | 
				
			||||||
			"peer-disabled:opacity-50",
 | 
									"peer-checked:after:bg-secondary",
 | 
				
			||||||
			p.Class,
 | 
									"peer-disabled:opacity-50",
 | 
				
			||||||
		),
 | 
									p.Class,
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
							templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.924
 | 
					// templ: version: v0.3.865
 | 
				
			||||||
// templui component tooltip - version: v0.84.0 installed by templui v0.84.0
 | 
					// templui component tooltip - version: v0.84.0 installed by templui v0.84.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package tooltip
 | 
					package tooltip
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue