Add new templates and tests for improved functionality

- Created index.html template for the homepage with service cards and partner logos.
- Added page_from_md.html template for rendering pages from markdown.
- Developed services.html template detailing various services offered.
- Implemented tests for link handling in markdown, ensuring external links open in new tabs and internal links function correctly.
- Enhanced markdown parser tests to validate heading extraction, content rendering, and link safety.
- Introduced utility tests for template rendering, HTML minification, and JavaScript minification.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-02 13:05:43 +02:00
parent 559a6e4c56
commit 9f0a216c5e
79 changed files with 4700 additions and 0 deletions
+6
View File
@@ -3,6 +3,7 @@
# vscode settings # vscode settings
.vscode/ .vscode/
v5.code-workspace
# python virtual environment # python virtual environment
.venv/ .venv/
@@ -10,3 +11,8 @@
# python cache # python cache
__pycache__/ __pycache__/
*.pyc *.pyc
#pytest cache
.pytest_cache/
.mypy_cache/
.coverage
+105
View File
@@ -0,0 +1,105 @@
# Nutzungsbedingungen AllYouCanGET
## Impressum
gemäß §5 Telemediengesetz bzw. § 5 Abs. 1 E-Commerce-Gesetz bzw. Art. 3 des Bundesgesetzes gegen den unlauteren Wettbewerb (UWG)
```text
All You Can GET
c/o Sinn Consulting
Im Dornäcker 16
CH-8967 Widen
georg AT allucanget DOT biz
```
_Aktualisiert am: 22.10.2025_
Willkommen auf der Website von **AllYouCanGET Sinn Consulting**, mit Sitz in Widen, Schweiz.
Durch den Zugriff auf diese Website erklärst du dich mit den folgenden Nutzungsbedingungen einverstanden.
Wenn du mit diesen Bedingungen nicht einverstanden bist, wird gebeten, die Website nicht zu nutzen.
---
## 1. Geltungsbereich
Diese Nutzungsbedingungen regeln den Zugriff auf und die Nutzung der von **AllYouCanGET Sinn Consulting** (nachfolgend „AllYouCanGET“ oder „das Unternehmen“) betriebenen Website.
Sie gelten für alle Besucherinnen und Besucher, Nutzerinnen und Nutzer dieser Website.
Für die Inanspruchnahme von Dienstleistungen des Unternehmens gelten die separaten **Allgemeinen Geschäftsbedingungen (AGB)**.
---
## 2. Zweck der Website
Die Website dient der Information über die Dienstleistungen, Philosophie und Angebote von AllYouCanGET in den Bereichen
**Business Consulting, Creative Development, Digital Marketing, Coaching und Technische Services**.
AllYouCanGET behält sich das Recht vor, Inhalte der Website jederzeit ohne Vorankündigung zu ändern, zu ergänzen oder zu entfernen.
---
## 3. Urheberrecht und geistiges Eigentum
Alle Inhalte dieser Website insbesondere Texte, Grafiken, Logos, Bilder, Design-Elemente und herunterladbare Materialien sind urheberrechtlich und durch andere Schutzrechte geschützt.
Sofern nicht anders angegeben, liegen alle Rechte bei **AllYouCanGET Sinn Consulting**.
Das Anzeigen, Herunterladen oder Ausdrucken von Inhalten ist nur für den **privaten, nicht kommerziellen Gebrauch** erlaubt, sofern alle Urheberrechts- und Eigentumshinweise bestehen bleiben.
Eine Vervielfältigung, Verbreitung, Bearbeitung oder Veröffentlichung von Inhalten zu kommerziellen Zwecken ist ohne ausdrückliche schriftliche Zustimmung von AllYouCanGET untersagt.
---
## 4. Nutzung der Website
Die Website darf nur zu rechtmässigen Zwecken und in einer Weise genutzt werden, die den Betrieb oder die Sicherheit der Website nicht beeinträchtigt.
Automatisierte Zugriffe (z. B. durch Bots oder Crawler) sind nur im Rahmen der in der Datei `robots.txt` festgelegten Regeln erlaubt.
AllYouCanGET behält sich das Recht vor, den Zugriff auf die Website jederzeit einzuschränken oder zu sperren.
---
## 5. Externe Links und Inhalte Dritter
Diese Website kann Links zu externen Websites Dritter enthalten.
AllYouCanGET hat keinen Einfluss auf deren Inhalte und übernimmt keinerlei Verantwortung oder Haftung für deren Richtigkeit, Rechtmässigkeit oder Verfügbarkeit.
Der Zugriff auf solche externen Seiten erfolgt auf eigenes Risiko der Nutzerin oder des Nutzers.
---
## 6. Vertraulichkeit und Datenschutz
AllYouCanGET behandelt personenbezogene Daten, die über diese Website übermittelt werden (z. B. über Kontaktformulare oder Newsletter-Anmeldungen), **vertraulich** und gemäss den geltenden Schweizer Datenschutzbestimmungen.
Die Daten werden ausschliesslich für den angegebenen Zweck verwendet.
Weitere Informationen finden sich in der separaten **Datenschutzerklärung**.
Nicht personenbezogene Informationen oder Materialien, die über die Website übermittelt werden (z. B. Feedback, Ideen, Konzepte), gelten als **nicht vertraulich**.
AllYouCanGET darf solche Informationen frei verwenden, sofern nichts anderes schriftlich vereinbart wurde.
---
## 7. Haftungsausschluss
AllYouCanGET ist bemüht, die Inhalte dieser Website sorgfältig und aktuell zu halten.
Dennoch wird keine Gewähr für die Richtigkeit, Vollständigkeit oder Verfügbarkeit der bereitgestellten Informationen übernommen.
AllYouCanGET haftet ausschliesslich für Schäden, die durch **vorsätzliches oder grobfahrlässiges Verhalten** verursacht werden.
Eine Haftung für **indirekte oder Folgeschäden**, insbesondere Datenverluste oder entgangenen Gewinn, ist ausgeschlossen.
---
## 8. Änderungen der Website und Nutzungsbedingungen
AllYouCanGET kann die Inhalte der Website sowie diese Nutzungsbedingungen jederzeit und ohne Vorankündigung ändern oder aktualisieren.
Es gilt stets die zum Zeitpunkt des Zugriffs auf der Website veröffentlichte Fassung.
---
## 9. Anwendbares Recht und Gerichtsstand
Diese Nutzungsbedingungen unterstehen ausschliesslich dem **schweizerischen Recht**.
Gerichtsstand für alle Streitigkeiten im Zusammenhang mit der Nutzung dieser Website ist **Widen, Schweiz**.
---
**AllYouCanGET Sinn Consulting**
Widen, Schweiz
[https://www.allyoucanget.ch](https://www.allyoucanget.biz)
+89
View File
@@ -0,0 +1,89 @@
# **Allgemeine Geschäftsbedingungen (AGB)**
**AllYouCanGET Sinn Consulting**
Widen, Schweiz
---
## **1. Geltungsbereich**
Diese Allgemeinen Geschäftsbedingungen (AGB) gelten für sämtliche Dienstleistungen der **AllYouCanGET Sinn Consulting** (nachfolgend „das Unternehmen“).
Sie finden Anwendung auf Verträge mit **Privatpersonen (B2C)** sowie **Unternehmen (B2B)**. Mit der Beauftragung des Unternehmens anerkennt der Kunde diese AGB in vollem Umfang.
---
## **2. Leistungen**
Das Unternehmen erbringt Dienstleistungen in den Bereichen **Business Consulting, Creative Development, Digital Marketing, Coaching und Technische Services**.
Art, Umfang und Ziel der jeweiligen Dienstleistung werden individuell schriftlich oder elektronisch vereinbart.
---
## **3. Angebote und Vertragsabschluss**
Alle Angebote des Unternehmens sind **unverbindlich**, bis sie schriftlich bestätigt werden.
Änderungen, Ergänzungen oder Zusatzleistungen bedürfen ebenfalls der **schriftlichen Bestätigung** durch das Unternehmen.
---
## **4. Preise und Zahlungsbedingungen**
Sofern nicht anders vereinbart, verstehen sich alle Preise in **Schweizer Franken (CHF)**, exklusive Mehrwertsteuer (sofern anwendbar).
Die Rechnungsstellung erfolgt **nach Abschluss der Dienstleistung**.
Rechnungen sind innerhalb von **30 Tagen** ab Rechnungsdatum ohne Abzug zu bezahlen.
Bei Zahlungsverzug behält sich das Unternehmen das Recht vor, **Mahngebühren** und **Verzugszinsen** zu erheben.
---
## **5. Annullierung und Rückerstattung**
Annullierungen durch den Kunden müssen **schriftlich** erfolgen.
- **Bis 7 Tage vor Leistungserbringung:** Rückerstattung von 50 % des vereinbarten Honorars.
- **Weniger als 7 Tage vor Leistungserbringung:** keine Rückerstattung möglich.
Das Unternehmen behält sich vor, Dienstleistungen aus wichtigen Gründen (z. B. Krankheit, unvorhergesehene Ereignisse) zu verschieben oder abzusagen. In diesem Fall wird ein neuer Termin vereinbart oder bereits geleistete Zahlungen werden zurückerstattet.
---
## **6. Haftung**
Das Unternehmen haftet ausschliesslich für **vorsätzliches oder grobfahrlässiges Verhalten**.
Eine Haftung für leichte Fahrlässigkeit, **indirekte Schäden**, **Folgeschäden**, **entgangenen Gewinn** oder **Datenverlust** ist ausdrücklich ausgeschlossen.
Der Kunde bleibt für die Umsetzung und die Entscheidungen, die aus der Beratung resultieren, selbst verantwortlich.
---
## **7. Urheberrecht und Nutzungsrechte**
Alle vom Unternehmen erstellten Unterlagen, Konzepte, Designs und Materialien bleiben bis zur **vollständigen Bezahlung** Eigentum des Unternehmens.
Sofern nicht anders vereinbart, verbleiben sämtliche **Urheber- und Nutzungsrechte** beim Unternehmen.
Eine Weitergabe, Vervielfältigung oder Nutzung der Materialien zu anderen Zwecken ist ohne vorherige schriftliche Zustimmung nicht gestattet.
---
## **8. Vertraulichkeit**
Das Unternehmen verpflichtet sich, alle im Rahmen der Zusammenarbeit erhaltenen Informationen und Daten des Kunden **vertraulich** zu behandeln.
Diese Pflicht besteht auch nach Beendigung der Geschäftsbeziehung fort.
Der Kunde verpflichtet sich ebenso, vertrauliche Informationen über das Unternehmen nicht an Dritte weiterzugeben.
---
## **9. Datenschutz**
Personenbezogene Daten werden ausschliesslich zur **Erbringung und Verwaltung der Dienstleistungen** verwendet.
Eine Weitergabe an Dritte erfolgt nur mit ausdrücklicher Zustimmung des Kunden oder wenn eine gesetzliche Verpflichtung besteht.
---
## **10. Anwendbares Recht und Gerichtsstand**
Diese AGB sowie alle Vertragsbeziehungen zwischen dem Unternehmen und dem Kunden unterstehen ausschliesslich dem **schweizerischen Recht**.
Gerichtsstand ist **Widen, Schweiz**.
---
**AllYouCanGET Sinn Consulting**
Widen, Schweiz
_(Gültig ab 01.01.2025)_
+234
View File
@@ -0,0 +1,234 @@
# Our Coaching Areas
Comprehensive coaching programs tailored to your professional and personal growth
## ![Career Advice](img/coaching-career.svg) Career Advice
Navigate your career path with expert guidance tailored to your industry and location.
### IT Career
- Career paths in software development
- Technical vs management track
- Transitioning between specialties
### Switzerland Specifics
- Work culture and expectations
- Salary negotiations
- Work permits and regulations
### Germany Specifics
- Job market trends
- Industry hubs and opportunities
### Remote Work
- Building a remote work routine
- Communication strategies
### Freelancing
- Setting up as independent contractor
- Client acquisition and retention
- Pricing strategies and negotiation
### Startups
- Evaluating startup opportunities
- Equity considerations
- Growth expectations
### Corporates
- Navigating corporate structures
- Internal mobility
- Building influence
### Consulting
- Types of consulting roles
- Client management
- Balancing multiple projects
## ![Personal Development](img/coaching-personal.svg) Personal Development
Discover your values, strengths, and purpose to create a fulfilling life and career.
### Values
- Value identification exercises
- Aligning career with personal values
- Identity Workshop
### Ikigai
- Finding purpose through passion
- Mission, vocation, and profession
- Practical discovery exercises
### Strengths
- Assessment tools and frameworks
- Leveraging strengths professionally
### Weaknesses
- Growth mindset approaches
- Strategic improvement planning
### Vision
- Creating personal vision statements
- Long-term life planning
- Visualization techniques
### Goals
- SMART goal framework
- Balancing short and long-term objectives
### Agile Self Organization
- Personal Kanban implementation
- Quarterly planning and review cycles
- Agile methods for personal productivity
## ![Leadership Coaching](img/coaching-leadership.svg) Leadership Coaching
Develop essential leadership skills to inspire teams and drive organizational success.
### Leadership Styles
- Management vs Leadership
- Situational leadership approaches
- Transformational vs transactional
### Communication
- Active listening techniques
- Delivering difficult messages
- Cross-cultural communication
### Feedback
- Structured feedback frameworks
- Creating feedback culture
- Growth-oriented approaches
### Delegation
- RACI and DACI models
- Identifying tasks to delegate
- Building team capacity
### Decision Making
- OODA loop, DECIDE model
- Data-driven decisions
- Managing decision paralysis
### Conflict Management
- Conflict resolution models
- Mediation techniques
- Transforming conflict to opportunity
### Motivation
- Intrinsic vs extrinsic motivation
- SCARF and Drive frameworks
- Tailoring to individual needs
### Empathy & Compassion
- Building empathetic leadership
- Compassion without compromising
### Trust
- Trust-building exercises
- Trust in remote teams
- Rebuilding broken trust
### Psychological Safety
- Assessment techniques
- Creating safety in teams
- Connection to innovation
### Team Building
- Tuckman's team formation
- Remote team activities
- Cross-functional dynamics
### Agile Project Management
- Project roles and responsibilities
- Agile hierarchies
- Balancing agility with governance
## ![Technical Coaching](img/coaching-technical.svg) Technical Coaching
Master technical skills and best practices in software development and IT infrastructure.
### Software and Web Development
#### Scalability
- Horizontal vs vertical scaling
- Distributed systems principles
- Load balancing strategies
#### Browser
- Developer tools mastery
- Performance optimization
- Extension development
### Operating Systems
#### Linux
- Debian, Ubuntu
- RedHat, Fedora, CentOS
- Arch, Manjaro
- SUSE, openSUSE
#### Windows
- Windows 10 & 11
- Windows Server 2019
- Windows Server 2022
#### macOS
- macOS basics
- System administration
- Shell commands
### Development Tools
#### Git
- Advanced git workflows
- Git hooks and automation
- Collaboration strategies
#### Docker
- Container optimization
- Docker Compose
- Kubernetes orchestration
#### Visual Studio Code
- Extension ecosystem
- Customization and settings
- Productivity optimization
## Ready to Accelerate Your Growth?
Let's work together to unlock your full potential
+81
View File
@@ -0,0 +1,81 @@
# Terms of Use AllYouCanGET
## ![IT Consulting](img/it-consulting.svg) Impressum
gemäß §5 Telemediengesetz bzw. § 5 Abs. 1 E-Commerce-Gesetz bzw. Art. 3 des Bundesgesetzes gegen den unlauteren Wettbewerb (UWG):
All You Can GET, c/o Sinn Consulting, Im Dornäcker 16, CH-8967 Widen - georg AT allucanget DOT biz
## Welcome
Welcome to the website of **AllYouCanGET Sinn Consulting**, based in Widen, Switzerland.
By accessing or using this website, you agree to be bound by the following Terms of Use.
If you do not agree, please refrain from using this site.
## 1. Scope of Application
These Terms of Use govern the access to and use of the website operated by **AllYouCanGET Sinn Consulting** (hereinafter “AllYouCanGET” or “the Company”).
They apply to all visitors, users, and other persons who access the website.
Separate agreements apply to consulting and service contracts concluded with clients. For such services, the **General Terms and Conditions (GTC)** of AllYouCanGET apply.
## 2. Purpose of the Website
This website serves to provide information about the Companys services, philosophy, and current offerings in the areas of **business consulting, creative development, digital marketing, coaching, and technical services**.
AllYouCanGET reserves the right to update, modify, or remove website content at any time without prior notice.
## 3. Intellectual Property and Copyright
All content on this website — including text, graphics, logos, images, design elements, and downloadable materials — is protected by copyright and other intellectual property rights.
Unless otherwise stated, all rights belong to **AllYouCanGET Sinn Consulting**.
You may view, download, and print website content **for personal and non-commercial use only**, provided that all copyright and proprietary notices remain intact.
Any reproduction, distribution, modification, or publication of website content for commercial purposes is prohibited without prior written permission from AllYouCanGET.
## 4. Use of the Website
Users agree to use this website responsibly and only for lawful purposes.
Any use that could impair or disrupt the functionality of the website or violate applicable laws is prohibited.
Automated access (e.g., by bots or crawlers) is only permitted within the limits defined by the sites `robots.txt` file.
AllYouCanGET reserves the right to restrict or block access to the website at its sole discretion.
## 5. External Links and Third-Party Content
This website may contain links to external websites operated by third parties.
AllYouCanGET has no control over the content of these websites and assumes no responsibility or liability for their accuracy, legality, or reliability.
Access to linked websites is at the users own risk.
## 6. Confidentiality and Data Protection
AllYouCanGET treats personal data provided via this website (e.g., through contact forms or newsletter subscriptions) as **strictly confidential**.
Data is processed solely for the stated purpose and in accordance with applicable Swiss data protection regulations.
Please refer to our **Privacy Policy** for detailed information on how personal data is handled.
Any non-personal information or material sent to AllYouCanGET via the website (e.g., feedback, ideas, or concepts) is deemed non-confidential, and AllYouCanGET may use such information freely, unless otherwise agreed in writing.
## 7. Disclaimer
AllYouCanGET strives to ensure that the information on this website is accurate and up to date.
However, no guarantee is given for the completeness, correctness, or availability of the information provided.
AllYouCanGET assumes no liability for any damages arising from the use of or inability to use the website or its contents, unless caused by gross negligence or intent.
Liability for indirect or consequential damages, including data loss or lost profits, is excluded.
## 8. Changes to the Website and Terms
AllYouCanGET may change, suspend, or discontinue any part of this website, or update these Terms of Use at any time without prior notice.
The current version published on the website applies.
## 9. Applicable Law and Jurisdiction
These Terms of Use are governed exclusively by **Swiss law**.
The exclusive place of jurisdiction is **Widen, Switzerland**.
---
## Last Update
Effective from 01.01.2025
+122
View File
@@ -0,0 +1,122 @@
# Streamline operations, optimize performance, and drive innovation with AllYouCanGET
Streamline operations, optimize performance, and drive innovation with AllYouCanGET
## ![IT Consulting](img/it-consulting.svg) IT Consulting
Strategic technology solutions to drive your digital transformation
### ✓ IT Strategy & Planning
A strategic view on business goals helps to align technology roadmaps accordingly
We develop comprehensive IT strategies that align with your business goals and drive digital transformation
### ✓ Technology Assessment
We evaluate existing IT infrastructure and identify improvement areas
A thorough assessment of your current technology landscape to identify strengths, weaknesses, and opportunities for improvement
### ✓ Enterprise Architecture
We design and implement scalable IT architectures that align with business objectives
Our enterprise architecture services help you design and implement scalable IT architectures that align with your business objectives
### ✓ Cybersecurity
Protect your digital assets! We guide you through comprehensive security strategies
Our cybersecurity services help you protect your digital assets and ensure compliance with industry standards
## ![Management Consulting](img/management-consulting.svg) Management Consulting
Optimize operations and accelerate business growth
### ✓ Strategy Development
We develop comprehensive strategies to drive business success
Tailored strategies that align with your business goals and drive growth
### ✓ Process Optimization
We improve efficiency by streamlining operations and reducing costs
Our process optimization services help you identify bottlenecks, eliminate waste, and enhance productivity
### ✓ Change Management
We implement effective change management strategies to ensure smooth transitions
Our change management services help you navigate organizational change and ensure successful adoption of new initiatives
### ✓ Financial Analysis
We provide data-driven insights for informed financial decision-making
Our financial analysis services help you make informed decisions based on data-driven insights
## ![Infrastructure Services](img/infrastructure.svg) Infrastructure Services
Build robust foundations for your business success
### ✓ Cloud Solutions
Build scalable and flexible cloud infrastructures tailored to your needs
We design and implement scalable and flexible cloud infrastructures that meet your business needs
### ✓ Network Design
We design and implement robust network architectures to ensure seamless connectivity
Our network design services help you create robust network architectures that ensure seamless connectivity and optimal performance
### ✓ System Integration
We integrate diverse systems and applications to streamline processes and enhance data flow
Our system integration services help you connect disparate systems and applications to streamline processes and enhance data flow
### ✓ Security Implementation
We implement comprehensive security measures to protect your infrastructure
Our security implementation services help you safeguard your infrastructure against cyber threats and ensure compliance with industry standards
## Our Partners
We collaborate with leading technology providers to deliver the best solutions for your business.
###
![IBM](img/partner/ibm.svg)
![Microsoft](img/partner/microsoft.svg)
![AWS](img/partner/aws.svg)
![Google](img/partner/google.svg)
![Oracle](img/partner/oracle.svg)
![Informatica](img/partner/informatica.svg)
![SAP](img/partner/sap.svg)
![Salesforce](img/partner/salesforce.svg)
## Projects
### Open Mic Odyssey
Website for a documentary film project about three best friends embarking on an outrageous adventure.
[Open Mic Odyssey](https://openmicodyssey.com)
### Bobby Ludlam
A landing page for a stand-up comedian, artist and entrepeneur.
[Bobby Ludlam](https://bobbyludlam.com)
### William Montgomery
Wordpress-based website for a stand-up comedian.
[William Montgomery](https://williamfmontgomery.com)
+55
View File
@@ -0,0 +1,55 @@
# Our Services
Comprehensive solutions to transform your business
## ![IT Consulting](img/it-consulting.svg) IT Consulting
Comprehensive IT solutions to drive digital transformation and optimize your technology infrastructure.
### ![IT Strategy & Planning](img/management-consulting.svg) IT Strategy & Planning
Develop technology roadmaps aligned with business objectives
### ![Infrastructure Management](img/infrastructure.svg) Infrastructure Management
Design and implement robust IT infrastructure solutions
### ![Cybersecurity](img/security.svg) Cybersecurity
Protect your assets with advanced security measures
## ![Management Consulting](img/barchart.svg) Management Consulting
Strategic business solutions to improve efficiency and drive growth.
### ![Process Optimization](img/management-consulting.svg) Process Optimization
Streamline operations and improve business efficiency
### ![Change Management](img/people.svg) Change Management
Guide organizational transformation effectively
### ![Financial Analysis](img/barchart.svg) Financial Analysis
Data-driven financial planning and optimization
## ![Infrastructure Services](img/infrastructure.svg) Infrastructure Services
Build robust foundations for your business success
### ![Cloud Solutions](img/cloud.svg) Cloud Solutions
Leverage cloud technology for scalable solutions
### ![Network Design](img/network.svg) Network Design
Create secure and efficient network architectures
### ![System Integration](img/system-integration.svg) System Integration
Seamlessly integrate systems for optimal performance
## Need Customized Solutions?
Let's discuss how we can help transform your business
+56
View File
@@ -0,0 +1,56 @@
# General Terms and Conditions (GTC)
## 1. Scope of Application
These General Terms and Conditions (GTC) apply to all services provided by **AllYouCanGET Sinn Consulting** (hereinafter “the Company”) to its clients, whether private individuals or businesses. By commissioning the Company, the client accepts these GTC in full.
## 2. Services
The Company provides services in the areas of **business consulting, creative development, digital marketing, coaching, and technical services**. The specific scope, content, and objectives of a service are agreed upon individually in writing or electronically.
## 3. Offers and Agreements
All offers are non-binding until confirmed by the Company in writing. Agreements, changes, or additional services are valid only with written confirmation.
## 4. Prices and Payment Terms
Unless otherwise agreed, prices are stated in Swiss francs (CHF) and exclude VAT (if applicable).
Invoices are issued after completion of the agreed service and are payable within **30 days** from the invoice date without deductions.
In case of late payment, the Company reserves the right to charge reminder fees and default interest.
## 5. Cancellations and Refunds
Cancellations by the client must be made in writing.
- **Up to 7 days before the service date:** partial refund (50%) of the agreed amount.
- **Less than 7 days before the service date:** no refund possible.
The Company reserves the right to cancel or postpone services for important reasons (e.g. illness, unforeseen events), in which case a new date will be arranged or any payments already made will be refunded.
## 6. Liability
The Company is liable only for **intentional or grossly negligent actions**. Liability for slight negligence, indirect or consequential damages, lost profits, or data loss is excluded.
The client remains responsible for the decisions and results derived from the consulting services.
## 7. Intellectual Property
All materials, concepts, designs, and documentation created by the Company remain the property of the Company until full payment has been received.
Unless otherwise agreed, the Company retains all copyrights and usage rights to its materials, which may not be copied, shared, or used for other purposes without prior written consent.
## 8. Confidentiality
The Company treats all information and data provided by clients as **strictly confidential**. This obligation continues after the business relationship ends. The client likewise undertakes to maintain confidentiality regarding all information obtained about the Company.
## 9. Data Protection
Personal data is collected and processed solely for the purpose of providing and managing services. Data is not shared with third parties without consent, except where legally required.
## 10. Applicable Law and Jurisdiction
These GTC and all contractual relationships between the Company and the client are governed exclusively by **Swiss law**.
The exclusive place of jurisdiction is **Widen, Switzerland**.
---
## Last Update
Effective from 01.01.2025
+94
View File
@@ -0,0 +1,94 @@
# Web Services AllYouCanGET
Reliable, secure, and fully managed hosting solutions tailored for your business
## ![Web Hosting](img/security.svg) Managed Hosting Solutions
Enjoy peace of mind with our fully managed hosting services. We handle maintenance, updates, backups, and security — so you can focus on your business.
### Managed CMS Hosting (PHP-based)
Ideal for WordPress and similar CMS platforms.
- Daily backups
- System and plugin updates
- Security screening and monitoring
- Starting from **25 CHF / month (incl. VAT)**
### Managed Application Hosting
(Node.js / Python)
Perfect for modern web applications and APIs.
- Daily backups
- Framework and dependency updates
- Security screening and optimization
- Starting from **25 CHF / month (incl. VAT)**
### Managed Docker Hosting
Flexible and containerized environments for developers.
- Daily backups
- Security screening and resource monitoring
- Starting from **25 CHF / month (incl. VAT)**
## ![Web Packages](img/infrastructure.svg) Hosting Packages
Simple, transparent, and scalable hosting plans with Swiss reliability.
### Basic Hosting
- **2 GB Diskspace**
- **1 Domain**
- **Unlimited Emails**
- **1 GB RAM**
- **SSH Access**
- **10 CHF / month (incl. VAT)**
### Standard Hosting
- **5 GB Diskspace**
- **1 Domain**
- **Unlimited Emails**
- **2 GB RAM**
- **SSH Access**
- **25 CHF / month (incl. VAT)**
### Premium Hosting
- **10 GB Diskspace**
- **1 Domain**
- **Unlimited Emails**
- **4 GB RAM**
- **SSH Access**
- **50 CHF / month (incl. VAT)**
## ![Why Choose Us](img/people.svg) Why Choose AllYouCanGET?
### Reliable Swiss Hosting
- Swiss data protection and hosting standards
- 24/7 monitoring and proactive security
- Daily backups included in all plans
- Scalable resources for growing businesses
- Expert technical support from experienced professionals
### Seamless Migration
- Free migration assistance for new customers
- Minimal downtime during transition
- Comprehensive support throughout the migration process
### Custom Solutions
- Tailored hosting environments to fit your needs
- Flexible resource allocation and scaling options
- Expert advice on architecture and optimization
- Integration with third-party services and tools
- Performance tuning for optimal speed and reliability
## Ready to Get Started?
Lets set up your hosting today — secure, managed, and built for growth.
+92
View File
@@ -0,0 +1,92 @@
{
"index.html": {
"name": "Home",
"url": "index.html",
"active": "False",
"page_title": "Transform Your Business",
"page_subtitle": "with expert IT & Management Consulting",
"page_cta": "See all Services",
"page_cta_url": "services.html",
"meta": {
"title": "AllYouCanGET - IT & Management Consulting",
"description": "AllYouCanGET is an expert IT & Management Consulting firm helping businesses transform their operations and drive growth through technology and strategy solutions.",
"keywords": "IT consulting services, Management consulting solutions, Digital transformation, Strategic technology solutions, IT strategy and planning, Technology assessment, Enterprise architecture consulting, Cybersecurity services, Infrastructure services, Cloud solutions, Network design and implementation, System integration, Security implementation, Streamline operations, Optimize business performance, Process optimization, Change management, Strategy development, Financial analysis, Business growth acceleration, Operations consulting, Expert consulting team, Business innovation, AllYouCanGET consulting",
"og_description": "Transform your business with expert IT and Management consulting. We streamline operations, optimize performance, and drive innovation."
}
},
"services.html": {
"name": "Services",
"url": "services.html",
"active": "False",
"page_title": "AllYouCanGET Services",
"page_subtitle": "IT & Management Consulting",
"page_cta": "Get Started",
"page_cta_url": "#contact-form",
"meta": {
"title": "Our Services - IT & Management Consulting | AllYouCanGET",
"description": "AllYouCanGET offers IT consulting services and management consulting solutions to help businesses drive digital transformation and optimize operations. Our expert consulting team provides strategic technology solutions to streamline operations, optimize business performance, and accelerate business growth. Contact us for a free consultation.",
"keywords": "IT consulting services, Management consulting solutions, Digital transformation, Strategic technology solutions, IT strategy and planning, Technology assessment, Enterprise architecture consulting, Cybersecurity services, Infrastructure services, Cloud solutions, Network design and implementation, System integration, Security implementation, Streamline operations, Optimize business performance, Process optimization, Change management, Strategy development, Financial analysis, Business growth acceleration, Operations consulting, Expert consulting team, Business innovation, AllYouCanGET consulting",
"og_description": "Explore our expert IT, Management, and Infrastructure consulting services designed to drive growth and efficiency for your business."
}
},
"webservices.html": {
"name": "Web Services",
"url": "webservices.html",
"active": "False",
"page_title": "Web Services Solutions",
"page_subtitle": "Scalable and Secure Web Services",
"page_cta": "Learn More",
"page_cta_url": "#contact-form",
"meta": {
"title": "Web Services - Scalable and Secure Solutions | AllYouCanGET",
"description": "AllYouCanGET provides scalable and secure web services solutions to help businesses enhance their online presence and improve customer engagement. Our expert team delivers customized web services tailored to your business needs. Contact us for more information.",
"keywords": "Web services solutions, Scalable web services, Secure web services, Online presence enhancement, Customer engagement, Customized web services, Business web solutions, IT consulting, Management consulting, AllYouCanGET consulting",
"og_description": "Discover our scalable and secure web services solutions designed to enhance your online presence and engage customers effectively."
}
},
"coaching.html": {
"name": "Coaching",
"url": "coaching.html",
"active": "False",
"page_title": "Professional Coaching Services",
"page_subtitle": "Unlock Your Potential Through Expert Mentoring",
"page_cta": "Start Your Journey",
"page_cta_url": "#contact-form",
"meta": {
"title": "Professional Coaching Services | AllYouCanGET",
"description": "AllYouCanGET offers professional coaching services in Career Advice, Personal Development, Leadership, and Technical Skills—helping individuals unlock their potential and achieve their personal and professional goals through expert mentoring and guidance.",
"keywords": "Coaching, Mentoring, Career Advice, Personal Development, Leadership Coaching, Technical Coaching, Software Development, IT Career, Switzerland, Germany, Remote Work, Freelancing, Startups, Corporates, Consulting, Agile, Leadership, Technical Skills, Professional coaching, Career coaching, Executive coaching, Team coaching, Business coaching",
"og_description": "Transform your career with AllYouCanGET's professional coaching services. Contact us for a free consultation."
}
},
"imprint.html": {
"name": "Imprint",
"url": "imprint.html",
"active": "False",
"page_title": "AllYouCanGET Imprint",
"page_subtitle": "IT & Management Consulting",
"page_cta": "Contact Us",
"page_cta_url": "#contact-form",
"meta": {
"title": "Imprint | AllYouCanGET",
"description": "Legal imprint and contact information for AllYouCanGET - Sinn Consulting. Find our company details, address, and legal disclosures as required by law.",
"keywords": "Imprint, Legal Notice, AllYouCanGET, Sinn Consulting, Impressum, contact information, legal disclosure, company details",
"og_description": "Official imprint and legal information for AllYouCanGET - Sinn Consulting. Includes company details and contact information."
}
},
"terms_and_conditions.html": {
"name": "Terms",
"url": "terms_and_conditions.html",
"active": "False",
"page_title": "Terms and Conditions",
"page_subtitle": "AllYouCanGET Consulting Services",
"page_cta": "Contact Us",
"page_cta_url": "#contact-form",
"meta": {
"title": "Terms and Conditions | AllYouCanGET",
"description": "Read the terms and conditions for using AllYouCanGET consulting services. Understand your rights and obligations when engaging with our IT and management consulting solutions.",
"keywords": "Terms and Conditions, AllYouCanGET, Consulting Services, IT Consulting, Management Consulting, Legal Terms, User Agreement, Service Agreement",
"og_description": "Review the terms and conditions for AllYouCanGET consulting services. Know your rights and responsibilities."
}
}
}
+83
View File
@@ -0,0 +1,83 @@
## Canonicalization and security headers
## ------------------------------------
## Enable rewrite engine
RewriteEngine On
## 1) Canonical host: redirect www -> apex (always to HTTPS)
RewriteCond %{HTTP_HOST} ^www\.allucanget\.biz$ [NC]
RewriteRule ^ https://allucanget.biz%{REQUEST_URI} [R=301,L]
## 2) Force HTTPS (works for direct HTTPS and when behind proxies setting X-Forwarded-Proto)
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
## 3) Security headers
<IfModule mod_headers.c>
# HSTS: one year, include subdomains (enable after HTTPS is configured everywhere)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS
# Clickjacking protection (also enforced via CSP frame-ancestors)
Header set X-Frame-Options "SAMEORIGIN"
# MIME sniffing protection
Header set X-Content-Type-Options "nosniff"
# Referrer policy
Header set Referrer-Policy "strict-origin-when-cross-origin"
# Lock down powerful features not in use
Header set Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=()"
# Content Security Policy tuned for local assets + jsdelivr Tailwind CDN
Header set Content-Security-Policy "object-src 'none'; frame-ancestors 'self'; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; upgrade-insecure-requests; block-all-mixed-content"
Header set Content-Security-Policy "default-src *.allucanget.biz; base-uri 'self'; script-src 'self' 'unsafe-inline' https://contact.allucanget.biz https://cdn.jsdelivr.net https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://contact.allucanget.biz https://cdn.jsdelivr.net https://static.cloudflareinsights.com; img-src 'self' data: https:; form-action https://contact.allucanget.biz; connect-src 'self' https://contact.allucanget.biz;"
</IfModule>
# ------------------------------------------------------------------
# Redirect the root URL ("/") to the canonical file "index.html"
# ------------------------------------------------------------------
RewriteRule ^$ /index.html [L]
# ------------------------------------------------------------------
# Internally rewrite clean URLs like "/about" → "about.html"
# ------------------------------------------------------------------
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ $1.html [L]
# ensure charset encoding is UTF-8 for all content
AddDefaultCharset UTF-8
# BEGIN cPanel-generated php ini directives, do not edit
# Manual editing of this file may result in unexpected behavior.
# To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
# For more information, read our documentation (https://go.cpanel.net/EA4ModifyINI)
<IfModule php5_module>
php_flag asp_tags Off
php_flag display_errors Off
php_value max_execution_time 30
php_value max_input_time 60
php_value max_input_vars 1000
php_value memory_limit 64M
php_value post_max_size 16M
php_value session.gc_maxlifetime 1440
php_value session.save_path "/var/cpanel/php/sessions/ea-php56"
php_value upload_max_filesize 16M
php_flag zlib.output_compression Off
</IfModule>
<IfModule lsapi_module>
php_flag asp_tags Off
php_flag display_errors Off
php_value max_execution_time 30
php_value max_input_time 60
php_value max_input_vars 1000
php_value memory_limit 64M
php_value post_max_size 16M
php_value session.gc_maxlifetime 1440
php_value session.save_path "/var/cpanel/php/sessions/ea-php56"
php_value upload_max_filesize 16M
php_flag zlib.output_compression Off
</IfModule>
# END cPanel-generated php ini directives, do not edit
File diff suppressed because one or more lines are too long
+565
View File
@@ -0,0 +1,565 @@
/* Color Palette and Typography */
/* Global Styles */
:root {
--primary: #10263d;
--secondary: #1b3c52;
--tertiary: #2f74ad;
--quaternary: #a3523f;
--quinary: #d9834d;
--white: #ffffff;
--black: var(--primary);
--black-translucent: rgba(16, 38, 61, 0.55);
--black-translucent-hover: rgba(16, 38, 61, 0.75);
--color-background: var(--primary);
--color-text: var(--primary);
--color-text-inverse: var(--white);
--color-link: #1f5f96;
--color-link-hover: #174875;
--color-link-inverse: var(--secondary);
--color-background-inverse: var(--white);
--color-muted: #e8eef6;
--color-muted-hover-bg: #2b5677;
--header-start: #0b8f69;
--header-end: #083f76;
--hero-start: #087f5d;
--hero-end: #062f5c;
--color-gray-50: oklch(98.5% 0.002 247.839);
--color-gray-dark: var(--primary);
--color-gray-medium-dark: var(--secondary);
--color-border-faint: rgba(255, 255, 255, 0.72);
--color-input-border: #a8b6c7;
--bg-inverse: var(--secondary);
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
width: 100%;
overflow-x: hidden;
}
body {
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
line-height: 1.3;
color: var(--color-text);
margin: 0;
padding: 0;
width: 100%;
overflow-x: hidden;
}
a {
color: var(--color-link);
text-decoration: underline;
}
a:hover {
color: var(--color-link-hover);
text-decoration: underline;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
outline: 2px solid var(--quinary);
outline-offset: 2px;
}
svg {
max-width: 64px;
max-height: 64px;
}
img,
video,
iframe {
max-width: 100%;
height: auto;
}
iframe {
width: 100%;
min-height: 440px;
display: block;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin-bottom: 0.2rem;
}
h2 img {
display: inline;
max-height: 1.5em;
min-height: 1.5em;
vertical-align: middle;
/* position left of text */
}
h3 img {
display: inline;
max-height: 1.2em;
min-height: 1.2em;
vertical-align: middle;
/* position left of text */
}
#header {
/*background-color: var(--color-gray-medium-dark);*/
background: linear-gradient(120deg, var(--header-start), var(--header-end));
color: var(--white);
padding: 1rem 1rem 2rem 1rem;
text-align: center;
}
#page-title {
width: 100%;
}
.page-title-header {
font-size: clamp(1.6rem, 4.5vw, 2.5rem);
line-height: 1.2;
font-weight: bold;
margin-bottom: 1rem;
}
.page-subtitle {
font-size: clamp(1rem, 3.4vw, 1.5rem);
line-height: 1.2;
margin: 0;
padding: 0;
}
.header-cta {
margin-top: 1rem;
padding-inline: 1.5rem;
}
.header-cta-buttons {
display: flex;
justify-content: center;
align-items: center;
gap: 0.75rem;
flex-wrap: wrap;
}
#site-navigation {
color: var(--white);
width: 100%;
position: relative;
z-index: 50;
}
#site-navigation-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
min-height: 80px;
display: flex;
align-items: center;
position: relative;
}
#site-navigation-content {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
#site-navigation-bar {
display: flex;
align-items: center;
width: 100%;
justify-content: space-between;
min-width: 0;
}
#site-navigation-brand {
flex-shrink: 0;
min-width: 0;
}
a.site-home-link {
display: flex;
align-items: center;
color: var(--white);
text-decoration: none;
font-size: 1.5rem;
font-weight: bold;
gap: 0.75rem;
transition: opacity 0.2s ease;
min-width: 0;
}
a.site-home-link:hover {
opacity: 0.9;
}
.nav-logo {
height: 50px;
width: auto;
object-fit: contain;
}
.nav-text {
font-size: 1.5rem;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.hamburger-menu {
display: none;
flex-direction: column;
justify-content: space-around;
width: 30px;
height: 30px;
background: transparent;
border: none;
cursor: pointer;
padding: 0;
z-index: 1001;
}
.hamburger-line {
width: 30px;
height: 3px;
background: var(--white);
border-radius: 2px;
transition: all 0.3s ease;
transform-origin: center;
}
.nav-menu {
display: flex;
}
#site-nav-links {
display: flex;
gap: 0.5rem;
align-items: center;
margin: 0;
padding: 0;
list-style: none;
}
a.site-nav-link {
color: var(--color-muted);
text-decoration: none;
font-weight: 600;
font-size: 1rem;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
transition: all 0.2s ease;
position: relative;
}
a.site-nav-link:hover {
color: var(--white);
background-color: var(--color-muted-hover-bg);
}
a.site-nav-link.active {
color: var(--white);
background-color: rgba(255, 255, 255, 0.2);
}
#main-content {
padding-top: 0;
}
#main {
background-color: var(--white);
min-height: 100vh;
margin: 0 auto;
padding: 0;
box-sizing: border-box;
border: 0 solid;
}
.bigbutton {
border-radius: 0.5rem;
padding: 0.5rem 1rem;
background: linear-gradient(135deg, var(--quaternary), var(--quinary));
color: var(--white);
margin-top: 0.5rem;
border: 1px solid var(--color-border-faint);
}
.bigbutton:hover {
background: linear-gradient(135deg, #934332, #c86f3a);
color: var(--white);
border-color: var(--white);
}
.bigbutton a {
color: var(--white);
font-weight: bold;
font-size: 1.2rem;
text-decoration: none;
}
.bigbutton a:hover {
color: var(--white);
font-weight: bold;
text-decoration: none;
border-color: var(--white);
}
.bigbutton a span:last-of-type {
margin-left: 0.5rem;
}
#hero {
background: linear-gradient(
to right,
var(--hero-start),
var(--hero-end)
);
color: var(--white);
padding: 4rem 0;
}
#hero .container {
text-align: left;
}
#hero h1 {
font-size: clamp(1.35rem, 4vw, 2rem);
line-height: 1.2;
font-weight: bold;
margin-bottom: 1rem;
text-align: center;
}
#hero p {
font-size: clamp(1rem, 3vw, 1.5rem);
margin: 0;
padding: 0;
}
.section {
background-color: var(--white);
padding-block: 3rem;
}
.section:nth-last-child(4) {
min-height: 300px;
height: auto;
text-align: center;
}
.section:nth-last-child(5) {
min-height: 300px;
height: auto;
text-align: center;
}
.section-container {
padding-inline: 1rem;
margin-inline: auto;
}
.section h2 {
font-size: clamp(1.3rem, 4vw, 2.25rem);
font-weight: bold;
margin-bottom: 2rem;
}
.section-content {
font-size: clamp(1rem, 2.3vw, 1.125rem);
color: var(--color-text);
margin-bottom: 1rem;
overflow-wrap: anywhere;
}
.section-content hr {
max-width: 80%;
margin: 3rem auto 1rem auto;
}
.section-cards {
display: grid;
gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
}
.section-card {
background-color: var(--white);
border-radius: 0.5rem;
padding: 1.5rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s ease;
}
.section-card:hover {
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.2);
}
.section-card-title {
font-size: 1.25rem;
margin-bottom: 1rem;
font-weight: bold;
}
.section-card-detail {
background-color: var(--color-background-inverse);
border-radius: 0.375rem;
padding: 0.75rem;
}
img[src*="img/partner/"] {
max-width: 200px;
max-height: 100px;
margin: 0 auto;
display: block;
margin: 2rem auto;
}
img[src*="img/partner/"].hidden {
max-width: 200px;
max-height: 100px;
display: none;
}
#call-to-action {
background: linear-gradient(120deg, #0a8e67, #073b70);
color: var(--white);
margin-top: 0;
padding: 3rem 0;
text-align: center;
}
#cta-container {
max-width: 800px;
padding: 0 1.5rem;
text-align: center;
}
#cta-container iframe {
max-width: 100%;
height: auto;
min-height: 520px;
}
#contact-form {
display: block;
max-width: 600px;
max-height: 600px;
margin: 0 auto;
scroll-behavior: auto;
}
#contact-form input,
#contact-form textarea {
width: 100%;
padding: 0.5rem;
margin-bottom: 1rem;
border: 1px solid var(--color-input-border);
border-radius: 0.25rem;
}
#contact-form textarea {
height: 150px;
}
#footer {
background-color: var(--color-background);
color: var(--quaternary);
padding: 2rem 0;
text-align: center;
display: block;
}
.footer-link {
color: var(--quinary);
text-decoration: underline;
}
#services {
display: block;
}
.container {
margin: 0 auto;
width: min(100%, 1200px);
max-width: 100%;
padding-inline: 1rem;
}
@media screen and (max-width: 640px) {
#header {
padding: 0;
padding-bottom: 1.5rem;
}
h1, h1.page-title-header, #hero h1 {
font-size: 1.4rem;
}
.page-subtitle {
font-size: 1rem;
}
.section h2 {
font-size: 1.3rem;
}
.section-content {
font-size: 1rem;
}
#page-title {
margin: 0.5rem auto;
padding: 0.5rem;
}
#hero {
padding: 1.5rem 0;
}
.container {
width: 100%;
max-width: 100%;
padding: 0 0.9rem;
}
}
@media screen and (max-width: 768px) {
#site-navigation-container {
padding: 0 1rem;
min-height: 60px;
}
#site-navigation-bar {
gap: 0.75rem;
}
a.site-home-link {
font-size: 1.25rem;
gap: 0.5rem;
max-width: calc(100% - 44px);
}
.nav-logo {
height: 35px;
}
.nav-text {
font-size: 1.25rem;
}
.hamburger-menu {
display: flex;
}
.nav-menu {
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: var(--color-gray-dark);
transform: translateY(-100%);
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
border-top: 1px solid rgba(255, 255, 255, 0.1);
z-index: 1000;
width: 100%;
max-height: calc(100vh - 60px);
overflow-y: auto;
}
.nav-menu.open {
transform: translateY(0);
opacity: 1;
visibility: visible;
}
#site-nav-links {
flex-direction: column;
width: 100%;
padding: 1rem 0;
}
a.site-nav-link {
width: 100%;
text-align: center;
padding: 1rem;
margin: 0.25rem 0;
border-radius: 0;
}
a.site-nav-link:hover {
background-color: var(--color-muted-hover-bg);
}
/* Hamburger animation */
.hamburger-menu.open .hamburger-line:nth-child(1) {
transform: rotate(45deg) translate(6px, 6px);
}
.hamburger-menu.open .hamburger-line:nth-child(2) {
opacity: 0;
}
.hamburger-menu.open .hamburger-line:nth-child(3) {
transform: rotate(-45deg) translate(6px, -6px);
}
}
@media screen and (max-width: 420px) {
.nav-text {
display: none;
}
a.site-home-link {
max-width: calc(100% - 40px);
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

+1
View File
@@ -0,0 +1 @@
google-site-verification: google8753946d6666aa9a.html
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

+13
View File
@@ -0,0 +1,13 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="12" x2="12" y1="20" y2="10"></line>
<line x1="18" x2="18" y1="20" y2="4"></line>
<line x1="6" x2="6" y1="20" y2="16"></line>
</svg>

After

Width:  |  Height:  |  Size: 378 B

+10
View File
@@ -0,0 +1,10 @@
<svg
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M6 16.326A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 .5 8.973"/>
<path d="m13 12-3 5h4l-3 5"/>
</svg>

After

Width:  |  Height:  |  Size: 327 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>

After

Width:  |  Height:  |  Size: 372 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>

After

Width:  |  Height:  |  Size: 462 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>

After

Width:  |  Height:  |  Size: 390 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
</svg>

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
</svg>

After

Width:  |  Height:  |  Size: 362 B

+14
View File
@@ -0,0 +1,14 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect>
<rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect>
<line x1="6" x2="6.01" y1="6" y2="6"></line>
<line x1="6" x2="6.01" y1="18" y2="18"></line>
</svg>

After

Width:  |  Height:  |  Size: 465 B

+11
View File
@@ -0,0 +1,11 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 412 B

+12
View File
@@ -0,0 +1,12 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"></polyline>
<polyline points="16 7 22 7 22 13"></polyline>
</svg>

After

Width:  |  Height:  |  Size: 338 B

+13
View File
@@ -0,0 +1,13 @@
<svg
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect x="16" y="16" width="6" height="6" rx="1"/>
<rect x="2" y="16" width="6" height="6" rx="1"/>
<rect x="9" y="2" width="6" height="6" rx="1"/>
<path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3"/>
<path d="M12 12V8"/>
</svg>

After

Width:  |  Height:  |  Size: 462 B

+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 304 182" style="enable-background:new 0 0 304 182;" xml:space="preserve"><script xmlns=""/>
<style type="text/css">
.st0{fill:#252F3E;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FF9900;}
</style>
<g>
<path class="st0" d="M86.4,66.4c0,3.7,0.4,6.7,1.1,8.9c0.8,2.2,1.8,4.6,3.2,7.2c0.5,0.8,0.7,1.6,0.7,2.3c0,1-0.6,2-1.9,3l-6.3,4.2 c-0.9,0.6-1.8,0.9-2.6,0.9c-1,0-2-0.5-3-1.4C76.2,90,75,88.4,74,86.8c-1-1.7-2-3.6-3.1-5.9c-7.8,9.2-17.6,13.8-29.4,13.8 c-8.4,0-15.1-2.4-20-7.2c-4.9-4.8-7.4-11.2-7.4-19.2c0-8.5,3-15.4,9.1-20.6c6.1-5.2,14.2-7.8,24.5-7.8c3.4,0,6.9,0.3,10.6,0.8 c3.7,0.5,7.5,1.3,11.5,2.2v-7.3c0-7.6-1.6-12.9-4.7-16c-3.2-3.1-8.6-4.6-16.3-4.6c-3.5,0-7.1,0.4-10.8,1.3c-3.7,0.9-7.3,2-10.8,3.4 c-1.6,0.7-2.8,1.1-3.5,1.3c-0.7,0.2-1.2,0.3-1.6,0.3c-1.4,0-2.1-1-2.1-3.1v-4.9c0-1.6,0.2-2.8,0.7-3.5c0.5-0.7,1.4-1.4,2.8-2.1 c3.5-1.8,7.7-3.3,12.6-4.5c4.9-1.3,10.1-1.9,15.6-1.9c11.9,0,20.6,2.7,26.2,8.1c5.5,5.4,8.3,13.6,8.3,24.6V66.4z M45.8,81.6 c3.3,0,6.7-0.6,10.3-1.8c3.6-1.2,6.8-3.4,9.5-6.4c1.6-1.9,2.8-4,3.4-6.4c0.6-2.4,1-5.3,1-8.7v-4.2c-2.9-0.7-6-1.3-9.2-1.7 c-3.2-0.4-6.3-0.6-9.4-0.6c-6.7,0-11.6,1.3-14.9,4c-3.3,2.7-4.9,6.5-4.9,11.5c0,4.7,1.2,8.2,3.7,10.6 C37.7,80.4,41.2,81.6,45.8,81.6z M126.1,92.4c-1.8,0-3-0.3-3.8-1c-0.8-0.6-1.5-2-2.1-3.9L96.7,10.2c-0.6-2-0.9-3.3-0.9-4 c0-1.6,0.8-2.5,2.4-2.5h9.8c1.9,0,3.2,0.3,3.9,1c0.8,0.6,1.4,2,2,3.9l16.8,66.2l15.6-66.2c0.5-2,1.1-3.3,1.9-3.9c0.8-0.6,2.2-1,4-1 h8c1.9,0,3.2,0.3,4,1c0.8,0.6,1.5,2,1.9,3.9l15.8,67l17.3-67c0.6-2,1.3-3.3,2-3.9c0.8-0.6,2.1-1,3.9-1h9.3c1.6,0,2.5,0.8,2.5,2.5 c0,0.5-0.1,1-0.2,1.6c-0.1,0.6-0.3,1.4-0.7,2.5l-24.1,77.3c-0.6,2-1.3,3.3-2.1,3.9c-0.8,0.6-2.1,1-3.8,1h-8.6c-1.9,0-3.2-0.3-4-1 c-0.8-0.7-1.5-2-1.9-4L156,23l-15.4,64.4c-0.5,2-1.1,3.3-1.9,4c-0.8,0.7-2.2,1-4,1H126.1z M254.6,95.1c-5.2,0-10.4-0.6-15.4-1.8 c-5-1.2-8.9-2.5-11.5-4c-1.6-0.9-2.7-1.9-3.1-2.8c-0.4-0.9-0.6-1.9-0.6-2.8v-5.1c0-2.1,0.8-3.1,2.3-3.1c0.6,0,1.2,0.1,1.8,0.3 c0.6,0.2,1.5,0.6,2.5,1c3.4,1.5,7.1,2.7,11,3.5c4,0.8,7.9,1.2,11.9,1.2c6.3,0,11.2-1.1,14.6-3.3c3.4-2.2,5.2-5.4,5.2-9.5 c0-2.8-0.9-5.1-2.7-7c-1.8-1.9-5.2-3.6-10.1-5.2L246,52c-7.3-2.3-12.7-5.7-16-10.2c-3.3-4.4-5-9.3-5-14.5c0-4.2,0.9-7.9,2.7-11.1 c1.8-3.2,4.2-6,7.2-8.2c3-2.3,6.4-4,10.4-5.2c4-1.2,8.2-1.7,12.6-1.7c2.2,0,4.5,0.1,6.7,0.4c2.3,0.3,4.4,0.7,6.5,1.1 c2,0.5,3.9,1,5.7,1.6c1.8,0.6,3.2,1.2,4.2,1.8c1.4,0.8,2.4,1.6,3,2.5c0.6,0.8,0.9,1.9,0.9,3.3v4.7c0,2.1-0.8,3.2-2.3,3.2 c-0.8,0-2.1-0.4-3.8-1.2c-5.7-2.6-12.1-3.9-19.2-3.9c-5.7,0-10.2,0.9-13.3,2.8c-3.1,1.9-4.7,4.8-4.7,8.9c0,2.8,1,5.2,3,7.1 c2,1.9,5.7,3.8,11,5.5l14.2,4.5c7.2,2.3,12.4,5.5,15.5,9.6c3.1,4.1,4.6,8.8,4.6,14c0,4.3-0.9,8.2-2.6,11.6 c-1.8,3.4-4.2,6.4-7.3,8.8c-3.1,2.5-6.8,4.3-11.1,5.6C264.4,94.4,259.7,95.1,254.6,95.1z"/>
<g>
<path class="st1" d="M273.5,143.7c-32.9,24.3-80.7,37.2-121.8,37.2c-57.6,0-109.5-21.3-148.7-56.7c-3.1-2.8-0.3-6.6,3.4-4.4 c42.4,24.6,94.7,39.5,148.8,39.5c36.5,0,76.6-7.6,113.5-23.2C274.2,133.6,278.9,139.7,273.5,143.7z"/>
<path class="st1" d="M287.2,128.1c-4.2-5.4-27.8-2.6-38.5-1.3c-3.2,0.4-3.7-2.4-0.8-4.5c18.8-13.2,49.7-9.4,53.3-5 c3.6,4.5-1,35.4-18.6,50.2c-2.7,2.3-5.3,1.1-4.1-1.9C282.5,155.7,291.4,133.4,287.2,128.1z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

+2
View File
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 272 92" width="272" height="92"><script xmlns=""/><path fill="#EA4335" d="M115.75 47.18c0 12.77-9.99 22.18-22.25 22.18s-22.25-9.41-22.25-22.18C71.25 34.32 81.24 25 93.5 25s22.25 9.32 22.25 22.18zm-9.74 0c0-7.98-5.79-13.44-12.51-13.44S80.99 39.2 80.99 47.18c0 7.9 5.79 13.44 12.51 13.44s12.51-5.55 12.51-13.44z"/><path fill="#FBBC05" d="M163.75 47.18c0 12.77-9.99 22.18-22.25 22.18s-22.25-9.41-22.25-22.18c0-12.85 9.99-22.18 22.25-22.18s22.25 9.32 22.25 22.18zm-9.74 0c0-7.98-5.79-13.44-12.51-13.44s-12.51 5.46-12.51 13.44c0 7.9 5.79 13.44 12.51 13.44s12.51-5.55 12.51-13.44z"/><path fill="#4285F4" d="M209.75 26.34v39.82c0 16.38-9.66 23.07-21.08 23.07-10.75 0-17.22-7.19-19.66-13.07l8.48-3.53c1.51 3.61 5.21 7.87 11.17 7.87 7.31 0 11.84-4.51 11.84-13v-3.19h-.34c-2.18 2.69-6.38 5.04-11.68 5.04-11.09 0-21.25-9.66-21.25-22.09 0-12.52 10.16-22.26 21.25-22.26 5.29 0 9.49 2.35 11.68 4.96h.34v-3.61h9.25zm-8.56 20.92c0-7.81-5.21-13.52-11.84-13.52-6.72 0-12.35 5.71-12.35 13.52 0 7.73 5.63 13.36 12.35 13.36 6.63 0 11.84-5.63 11.84-13.36z"/><path fill="#34A853" d="M225 3v65h-9.5V3h9.5z"/><path fill="#EA4335" d="M262.02 54.48l7.56 5.04c-2.44 3.61-8.32 9.83-18.48 9.83-12.6 0-22.01-9.74-22.01-22.18 0-13.19 9.49-22.18 20.92-22.18 11.51 0 17.14 9.16 18.98 14.11l1.01 2.52-29.65 12.28c2.27 4.45 5.8 6.72 10.75 6.72 4.96 0 8.4-2.44 10.92-6.14zm-23.27-7.98l19.82-8.23c-1.09-2.77-4.37-4.7-8.23-4.7-4.95 0-11.84 4.37-11.59 12.93z"/><path fill="#4285F4" d="M35.29 41.41V32H67c.31 1.64.47 3.58.47 5.68 0 7.06-1.93 15.79-8.15 22.01-6.05 6.3-13.78 9.66-24.02 9.66C16.32 69.35.36 53.89.36 34.91.36 15.93 16.32.47 35.3.47c10.5 0 17.98 4.12 23.6 9.49l-6.64 6.64c-4.03-3.78-9.49-6.72-16.97-6.72-13.86 0-24.7 11.17-24.7 25.03 0 13.86 10.84 25.03 24.7 25.03 8.99 0 14.11-3.61 17.39-6.89 2.66-2.66 4.41-6.46 5.1-11.65l-22.49.01z"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB

+40
View File
@@ -0,0 +1,40 @@
<svg version="1.2" baseProfile="tiny-ps" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1607 401" width="1607" height="401">
<title>logo-informatica-svg</title>
<style>
tspan { white-space:pre }
.shp0 { fill: #ff4d00 }
.shp1 { fill: #ff7d00 }
.shp2 { fill: #001aff }
.shp3 { fill: #e23400 }
.shp4 { fill: #373737 }
</style>
<g id="logo-informatica">
<g id="Logo/Informatica">
<g id="Group-32">
<g id="Layer">
<path id="Fill-1" class="shp0" d="M218.7 205.64L267.31 213.77L300.25 249.32L295.83 300.43L177.19 233.21L218.7 205.64Z" />
<path id="Fill-2" class="shp1" d="M394.43 200.52L295.83 300.44L197.21 0.69L394.43 200.52Z" />
<path id="Fill-3" class="shp2" d="M328.73 200.52L177.19 233.21L181.35 159.45L328.73 200.52Z" />
<path id="Fill-4" class="shp3" d="M0 200.53L73.06 216.86L121.39 248.63L124.91 280.61L105.3 307.22L0 200.53Z" />
<path id="Fill-5" class="shp0" d="M186.55 11.51L121.38 248.63L0 200.53L186.55 11.51Z" />
<path id="Fill-6" class="shp1" d="M121.39 248.63L283.58 312.85L197.21 400.36L105.3 307.22L121.39 248.63Z" />
<path id="Fill-7" class="shp4" d="M525.69 257.51L507.24 257.51L507.24 106.29L525.69 95.39L525.69 257.51Z" />
<path id="Fill-8" class="shp4" d="M1351.23 122.81L1332.26 122.81L1332.26 107.95L1332.26 102.75L1351.23 102.75L1351.23 122.81Z" />
<g id="Group-31">
<path id="Fill-9" fill-rule="evenodd" class="shp4" d="M638.75 153.75C645.9 161.89 649.68 173.34 649.68 186.9L649.68 257.51L631.64 257.51L631.64 191C631.64 170.62 621.17 158.44 603.64 158.44C585.71 158.44 573.18 172.36 573.18 192.3L573.18 257.51L555.15 257.51L555.15 143.33L573.18 143.33L573.18 159.87C581.6 147.3 593.33 140.94 608.13 140.94C620.8 140.94 631.39 145.36 638.75 153.75Z" />
<path id="Fill-11" fill-rule="evenodd" class="shp4" d="M849.57 200.09L849.57 200.52C849.57 216.32 843.88 231.19 833.55 242.37C822.99 253.81 808.62 260.11 793.13 260.11C761.82 260.11 737.29 234.12 737.29 200.96L737.29 200.52C737.29 184.7 742.94 169.85 753.21 158.68C763.72 147.24 778.04 140.94 793.53 140.94C824.95 140.94 849.57 166.93 849.57 200.09ZM793.13 158.01C771.81 158.01 755.73 176.1 755.73 200.09L755.73 200.52C755.73 224.25 772.34 242.83 793.53 242.83C814.96 242.83 831.13 224.82 831.13 200.96L831.13 200.52C831.13 176.69 814.43 158.01 793.13 158.01Z" />
<path id="Fill-13" fill-rule="evenodd" class="shp4" d="M931.47 141.38L932.59 141.43L932.59 160.93L930.21 160.93C905.51 160.93 889.55 181.34 889.55 211.77L889.55 257.51L871.52 257.51L871.52 143.32L889.55 143.32L889.55 168.41C898.64 150.63 914.01 140.61 931.47 141.38Z" />
<path id="Fill-15" fill-rule="evenodd" class="shp4" d="M1112.3 187.11L1112.3 257.51L1094.27 257.51L1094.27 191C1094.27 170.32 1084.74 158.44 1068.1 158.44C1060.43 158.44 1053.48 161.51 1048.51 167.08C1043.14 173.11 1040.3 181.69 1040.3 191.87L1040.3 257.51L1022.26 257.51L1022.26 190.57C1022.26 170.45 1012.55 158.44 996.29 158.44C979.95 158.44 968.08 172.77 968.08 192.52L968.08 257.51L950.05 257.51L950.05 143.33L968.08 143.33L968.08 159.43C974.47 150.22 984.04 140.94 1000.99 140.94C1016.06 140.94 1028.07 148.4 1034.99 162C1044.26 147.83 1056.38 140.94 1071.97 140.94C1096.85 140.94 1112.3 158.63 1112.3 187.11Z" />
<path id="Fill-17" fill-rule="evenodd" class="shp4" d="M1276.51 160.39L1276.51 224.54C1276.51 236.26 1281.93 241.96 1293.1 241.96C1298.35 241.96 1302.63 240.86 1307.87 238.19L1309.55 237.33L1309.55 254.22L1308.95 254.56C1302.87 257.9 1296.67 259.46 1289.42 259.46C1277.86 259.46 1258.47 255.2 1258.47 226.69L1258.47 160.39L1238.84 160.39L1238.84 143.32L1258.47 143.32L1258.47 114.23L1276.51 103.57L1276.51 143.32L1310.38 143.32L1310.38 160.39L1276.51 160.39Z" />
<path id="Fill-19" fill-rule="evenodd" class="shp4" d="M1460.95 225.64L1472.59 237.23L1471.89 238.06C1463.21 248.32 1450.37 260.11 1427.96 260.11C1412.9 260.11 1398.9 253.85 1388.53 242.5C1378.35 231.36 1372.74 216.61 1372.74 200.96L1372.74 200.52C1372.74 184.76 1378.35 169.9 1388.53 158.68C1398.9 147.24 1412.9 140.94 1427.96 140.94C1450.19 140.94 1462.67 151.79 1471.05 161.23L1471.75 162.02L1459.79 175.45L1458.92 174.5C1451.22 165.93 1442.12 158.01 1427.76 158.01C1407.25 158.01 1391.18 176.49 1391.18 200.09L1391.18 200.52C1391.18 224.25 1407.69 242.82 1428.77 242.82C1440.26 242.82 1450.52 237.51 1460.14 226.56L1460.95 225.64Z" />
<path id="Fill-21" fill-rule="evenodd" class="shp4" d="M1180.9 140.94C1196.12 140.94 1207.86 145.21 1215.8 153.64C1223.19 161.47 1226.94 173.6 1226.94 187.98L1226.94 257.51L1209.72 257.51L1209.72 242.87C1202.85 251.18 1191.02 259.89 1172.53 259.89C1152.39 259.89 1132.01 247.52 1132.01 223.88L1132.01 223.45C1132.01 200.8 1148.85 187.82 1178.25 187.82L1209.72 187.82C1209.72 167.01 1198.65 158.01 1179.27 158.01C1166.21 158.01 1156.41 161.91 1147.74 166.11L1146.57 166.68L1141.11 150.81L1142.05 150.36C1151.68 145.7 1163.82 140.94 1180.9 140.94ZM1179.88 202.51C1155.38 202.51 1150.24 213.54 1150.24 222.8L1150.24 223.24C1150.24 233.4 1158.17 244.34 1175.6 244.34C1195.05 244.34 1209.72 231.82 1209.72 215.23L1209.72 202.51L1179.88 202.51Z" />
<path id="Fill-23" fill-rule="evenodd" class="shp4" d="M700.68 143.32L734.54 143.32L734.54 160.38L700.68 160.38L700.68 257.51L682.64 257.51L682.64 160.38L663.01 160.38L663.01 143.32L682.64 143.32L682.64 131.82C682.64 119.06 685.93 108.85 692.14 102.26C697.7 96.36 705.82 93.24 715.61 93.24C722.84 93.24 727.98 94.08 733.35 96.13L733.72 96.27L733.72 113.18L732.61 112.85C726.56 111.02 722.59 110.09 717.65 110.09C704.84 110.09 700.68 116.25 700.68 132.68L700.68 143.32Z" />
<path id="Fill-25" class="shp4" d="M1350.76 257.51L1332.73 257.51L1332.73 155.47L1332.73 143.32L1350.76 143.32L1350.76 257.51Z" />
<path id="Fill-27" fill-rule="evenodd" class="shp4" d="M1532.62 140.94C1547.83 140.94 1559.58 145.21 1567.52 153.64C1574.91 161.47 1578.66 173.6 1578.66 187.99L1578.66 257.53L1561.43 257.53L1561.44 242.88C1554.56 251.19 1542.74 259.9 1524.25 259.9C1504.1 259.9 1483.71 247.53 1483.71 223.89L1483.71 223.46C1483.71 200.81 1500.56 187.83 1529.96 187.83L1561.44 187.83C1561.44 167.02 1550.37 158.01 1530.98 158.01C1517.93 158.01 1508.12 161.91 1499.45 166.12L1498.29 166.68L1492.81 150.81L1493.76 150.36C1503.39 145.7 1515.53 140.94 1532.62 140.94ZM1531.59 202.52C1507.09 202.52 1501.95 213.55 1501.95 222.81L1501.95 223.25C1501.95 233.41 1509.88 244.35 1527.31 244.35C1546.77 244.35 1561.44 231.84 1561.44 215.24L1561.44 202.52L1531.59 202.52Z" />
<path id="Fill-29" fill-rule="evenodd" class="shp4" d="M1586.67 147.9C1587.58 146.18 1588.86 144.82 1590.48 143.83C1592.11 142.84 1593.87 142.34 1595.76 142.34C1597.65 142.34 1599.39 142.84 1601.02 143.83C1602.64 144.82 1603.91 146.18 1604.83 147.9C1605.75 149.62 1606.2 151.48 1606.2 153.49C1606.2 155.46 1605.76 157.3 1604.88 159.01C1604 160.72 1602.74 162.1 1601.12 163.14C1599.49 164.18 1597.71 164.7 1595.76 164.7C1593.82 164.7 1592.04 164.19 1590.42 163.15C1588.78 162.12 1587.53 160.75 1586.63 159.03C1585.74 157.32 1585.29 155.48 1585.29 153.49C1585.29 151.48 1585.75 149.62 1586.67 147.9ZM1588.16 158.25C1588.95 159.7 1590.02 160.85 1591.37 161.67C1592.73 162.5 1594.18 162.9 1595.76 162.9C1597.34 162.9 1598.81 162.49 1600.16 161.64C1601.52 160.8 1602.58 159.66 1603.35 158.22C1604.12 156.78 1604.51 155.2 1604.51 153.49C1604.51 151.79 1604.12 150.22 1603.35 148.78C1602.58 147.34 1601.52 146.21 1600.16 145.38C1598.81 144.55 1597.34 144.14 1595.76 144.14C1594.18 144.14 1592.72 144.54 1591.36 145.36C1590.01 146.19 1588.93 147.32 1588.16 148.77C1587.38 150.23 1586.99 151.8 1586.99 153.49C1586.99 155.2 1587.38 156.78 1588.16 158.25ZM1593.59 154.62L1593.59 159.66L1591.51 159.66L1591.51 146.98L1595.58 146.98C1597.08 146.98 1598.25 147.31 1599.08 147.96C1599.91 148.62 1600.32 149.56 1600.32 150.81C1600.32 152.03 1599.7 152.97 1598.44 153.61C1599.63 154.12 1600.24 155.13 1600.26 156.67L1600.26 157.57C1600.26 158.43 1600.34 159.05 1600.5 159.43L1600.5 159.66L1598.37 159.66C1598.23 159.31 1598.16 158.66 1598.16 157.75C1598.16 156.83 1598.14 156.28 1598.11 156.11C1597.95 155.16 1597.32 154.65 1596.18 154.62L1593.59 154.62ZM1593.59 152.71L1595.89 152.71C1596.6 152.69 1597.17 152.51 1597.6 152.19C1598.04 151.86 1598.24 151.43 1598.24 150.89C1598.24 150.16 1598.06 149.65 1597.67 149.35C1597.29 149.05 1596.6 148.9 1595.63 148.9L1593.59 148.9L1593.59 152.71Z" />
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 337.6 72"><script xmlns=""/>
<path fill="#737373" d="M140.4,14.4v43.2h-7.5V23.7h-0.1l-13.4,33.9h-5l-13.7-33.9h-0.1v33.9h-6.9V14.4h10.8l12.4,32h0.2l13.1-32H140.4 z M146.6,17.7c0-1.2,0.4-2.2,1.3-3c0.9-0.8,1.9-1.2,3.1-1.2c1.3,0,2.4,0.4,3.2,1.2s1.3,1.8,1.3,3c0,1.2-0.4,2.2-1.3,3 c-0.9,0.8-1.9,1.2-3.2,1.2s-2.3-0.4-3.1-1.2C147.1,19.8,146.6,18.8,146.6,17.7z M154.7,26.6v31h-7.3v-31H154.7z M176.8,52.3 c1.1,0,2.3-0.2,3.6-0.8c1.3-0.5,2.5-1.2,3.6-2v6.8c-1.2,0.7-2.5,1.2-4,1.5c-1.5,0.3-3.1,0.5-4.9,0.5c-4.6,0-8.3-1.4-11.1-4.3 c-2.9-2.9-4.3-6.6-4.3-11c0-5,1.5-9.1,4.4-12.3c2.9-3.2,7-4.8,12.4-4.8c1.4,0,2.8,0.2,4.1,0.5c1.4,0.3,2.5,0.8,3.3,1.2v7 c-1.1-0.8-2.3-1.5-3.4-1.9c-1.2-0.4-2.4-0.7-3.6-0.7c-2.9,0-5.2,0.9-7,2.8s-2.6,4.4-2.6,7.6c0,3.1,0.9,5.6,2.6,7.3 C171.6,51.4,173.9,52.3,176.8,52.3z M204.7,26.1c0.6,0,1.1,0,1.6,0.1s0.9,0.2,1.2,0.3v7.4c-0.4-0.3-0.9-0.6-1.7-0.8 s-1.6-0.4-2.7-0.4c-1.8,0-3.3,0.8-4.5,2.3s-1.9,3.8-1.9,7v15.6h-7.3v-31h7.3v4.9h0.1c0.7-1.7,1.7-3,3-4 C201.2,26.6,202.8,26.1,204.7,26.1z M207.9,42.6c0-5.1,1.5-9.2,4.3-12.2c2.9-3,6.9-4.5,12-4.5c4.8,0,8.6,1.4,11.3,4.3 s4.1,6.8,4.1,11.7c0,5-1.5,9-4.3,12c-2.9,3-6.8,4.5-11.8,4.5c-4.8,0-8.6-1.4-11.4-4.2C209.3,51.3,207.9,47.4,207.9,42.6z M215.5,42.3c0,3.2,0.7,5.7,2.2,7.4s3.6,2.6,6.3,2.6c2.6,0,4.7-0.8,6.1-2.6c1.4-1.7,2.1-4.2,2.1-7.6c0-3.3-0.7-5.8-2.1-7.6 c-1.4-1.7-3.5-2.6-6-2.6c-2.7,0-4.7,0.9-6.2,2.7C216.2,36.5,215.5,39,215.5,42.3z M250.5,34.8c0,1,0.3,1.9,1,2.5 c0.7,0.6,2.1,1.3,4.4,2.2c2.9,1.2,5,2.5,6.1,3.9c1.2,1.5,1.8,3.2,1.8,5.3c0,2.9-1.1,5.2-3.4,7c-2.2,1.8-5.3,2.6-9.1,2.6 c-1.3,0-2.7-0.2-4.3-0.5c-1.6-0.3-2.9-0.7-4-1.2v-7.2c1.3,0.9,2.8,1.7,4.3,2.2c1.5,0.5,2.9,0.8,4.2,0.8c1.6,0,2.9-0.2,3.6-0.7 c0.8-0.5,1.2-1.2,1.2-2.3c0-1-0.4-1.8-1.2-2.6c-0.8-0.7-2.4-1.5-4.6-2.4c-2.7-1.1-4.6-2.4-5.7-3.8s-1.7-3.2-1.7-5.4 c0-2.8,1.1-5.1,3.3-6.9c2.2-1.8,5.1-2.7,8.6-2.7c1.1,0,2.3,0.1,3.6,0.4s2.5,0.6,3.4,0.9V34c-1-0.6-2.1-1.2-3.4-1.7 c-1.3-0.5-2.6-0.7-3.8-0.7c-1.4,0-2.5,0.3-3.2,0.8C250.9,33.1,250.5,33.8,250.5,34.8z M266.9,42.6c0-5.1,1.5-9.2,4.3-12.2 c2.9-3,6.9-4.5,12-4.5c4.8,0,8.6,1.4,11.3,4.3s4.1,6.8,4.1,11.7c0,5-1.5,9-4.3,12c-2.9,3-6.8,4.5-11.8,4.5c-4.8,0-8.6-1.4-11.4-4.2 C268.4,51.3,266.9,47.4,266.9,42.6z M274.5,42.3c0,3.2,0.7,5.7,2.2,7.4s3.6,2.6,6.3,2.6c2.6,0,4.7-0.8,6.1-2.6 c1.4-1.7,2.1-4.2,2.1-7.6c0-3.3-0.7-5.8-2.1-7.6c-1.4-1.7-3.5-2.6-6-2.6c-2.7,0-4.7,0.9-6.2,2.7C275.3,36.5,274.5,39,274.5,42.3z M322.9,32.6h-10.9v25h-7.4v-25h-5.2v-6h5.2v-4.3c0-3.2,1.1-5.9,3.2-8s4.8-3.1,8.1-3.1c0.9,0,1.7,0.1,2.4,0.1s1.3,0.2,1.8,0.4v6.3 c-0.2-0.1-0.7-0.3-1.3-0.5c-0.6-0.2-1.3-0.3-2.1-0.3c-1.5,0-2.7,0.5-3.5,1.4c-0.8,0.9-1.2,2.4-1.2,4.2v3.7h10.9v-7l7.3-2.2v9.2h7.4 v6h-7.4v14.5c0,1.9,0.4,3.2,1,4c0.7,0.8,1.8,1.2,3.3,1.2c0.4,0,0.9-0.1,1.5-0.3c0.6-0.2,1.1-0.4,1.5-0.7v6c-0.5,0.3-1.2,0.5-2.3,0.7 c-1.1,0.2-2.1,0.3-3.2,0.3c-3.1,0-5.4-0.8-6.9-2.4c-1.5-1.6-2.3-4.1-2.3-7.4L322.9,32.6L322.9,32.6z"/>
<rect fill="#F25022" width="34.2" height="34.2"/>
<rect x="37.8" fill="#7FBA00" width="34.2" height="34.2"/>
<rect y="37.8" fill="#00A4EF" width="34.2" height="34.2"/>
<rect x="37.8" y="37.8" fill="#FFB900" width="34.2" height="34.2"/>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 231 30" preserveAspectRatio="xMinYMid"><script xmlns=""/><path d="M99.61,19.52h15.24l-8.05-13L92,30H85.27l18-28.17a4.29,4.29,0,0,1,7-.05L128.32,30h-6.73l-3.17-5.25H103l-3.36-5.23m69.93,5.23V0.28h-5.72V27.16a2.76,2.76,0,0,0,.85,2,2.89,2.89,0,0,0,2.08.87h26l3.39-5.25H169.54M75,20.38A10,10,0,0,0,75,.28H50V30h5.71V5.54H74.65a4.81,4.81,0,0,1,0,9.62H58.54L75.6,30h8.29L72.43,20.38H75M14.88,30H32.15a14.86,14.86,0,0,0,0-29.71H14.88a14.86,14.86,0,1,0,0,29.71m16.88-5.23H15.26a9.62,9.62,0,0,1,0-19.23h16.5a9.62,9.62,0,1,1,0,19.23M140.25,30h17.63l3.34-5.23H140.64a9.62,9.62,0,1,1,0-19.23h16.75l3.38-5.25H140.25a14.86,14.86,0,1,0,0,29.71m69.87-5.23a9.62,9.62,0,0,1-9.26-7h24.42l3.36-5.24H200.86a9.61,9.61,0,0,1,9.26-7h16.76l3.35-5.25h-20.5a14.86,14.86,0,0,0,0,29.71h17.63l3.35-5.23h-20.6" transform="translate(-0.02 0)" style="fill:#C74634"/></svg>

After

Width:  |  Height:  |  Size: 892 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.9 KiB

+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="743.36707" height="368.43945"><script xmlns=""/>
<g transform="translate(-446.7987,535.9143)">
<path d="M 446.79872,-168.02763 L 822.11906,-168.02763 L 1190.1658,-535.9143 L 446.79872,-535.9143 L 446.79872,-168.02763" style="fill:#014185;fill-rule:nonzero;stroke:none"/>
<path d="M 887.58191,-466.77099 L 814.84541,-466.78553 L 814.84541,-292.77073 L 750.83729,-466.78553 L 688.2839,-466.78553 L 633.00416,-321.25434 C 627.18524,-357.91354 589.36226,-370.58424 558.81293,-380.06908 C 539.90144,-386.4408 518.08049,-395.80926 519.53522,-406.05056 C 519.53522,-414.54618 529.71833,-422.34353 551.53928,-421.17975 C 566.08658,-420.43784 579.17915,-419.23041 605.36429,-406.74883 L 631.54943,-451.07445 C 606.81902,-463.06142 574.81496,-470.64057 548.62982,-470.66966 L 548.62982,-470.66966 C 516.62576,-470.66966 490.44062,-460.60293 474.43859,-443.91718 C 464.25548,-432.30843 456.98183,-417.57202 456.98183,-401.2354 C 456.98183,-378.75982 465.71021,-362.81598 481.71224,-350.11619 C 497.71427,-339.42392 515.17103,-332.45577 532.62779,-327.34966 C 552.99401,-321.05068 568.99604,-315.59544 568.99604,-303.89942 C 568.99604,-299.57887 567.54131,-295.6511 564.63185,-292.49433 C 558.81293,-287.27185 551.53928,-285.29342 539.90144,-285.04611 C 519.53522,-284.66789 504.98792,-287.91193 480.25751,-302.3574 L 456.98183,-257.47898 C 481.71224,-243.57176 510.80684,-235.39618 539.90144,-235.39618 L 544.26563,-235.42527 C 568.99604,-235.89079 590.81699,-243.23717 606.81902,-256.5916 C 608.27375,-257.37715 608.27375,-258.10452 609.72848,-258.83188 L 602.45483,-239.29486 L 669.37241,-239.29486 L 679.55552,-273.16097 C 691.19336,-269.26229 704.28593,-266.99292 718.83323,-266.99292 C 733.38053,-266.99292 745.01837,-269.18956 756.65621,-272.88457 L 768.29405,-239.29486 L 875.94407,-239.29486 L 875.94407,-309.54377 L 900.67448,-309.54377 C 957.40895,-309.54377 990.86774,-338.65292 990.86774,-387.47365 C 990.86774,-441.82237 958.86368,-466.77099 887.58191,-466.77099 z M 718.83323,-317.79209 C 710.10485,-317.79209 702.8312,-319.30501 695.55755,-321.95261 L 718.83323,-395.15463 L 718.83323,-395.15463 L 742.10891,-321.71986 C 734.83526,-319.21772 727.56161,-317.79209 718.83323,-317.79209 z M 891.9461,-359.89197 L 875.94407,-359.89197 L 875.94407,-418.91037 L 891.9461,-418.91037 C 913.76705,-418.91037 931.22381,-411.76765 931.22381,-389.69939 C 931.22381,-367.0056 913.76705,-359.89197 891.9461,-359.89197" style="fill:#FFF;fill-rule:evenodd;stroke:none"/>
<path d="M 913.76705,-191.53607 C 913.76705,-202.78113 922.49543,-211.34949 932.67854,-211.34949 C 942.86165,-211.34949 951.59003,-202.78113 951.59003,-191.53607 C 951.59003,-179.86914 942.86165,-171.4608 932.67854,-171.4608 C 922.49543,-171.4608 913.76705,-179.86914 913.76705,-191.53607 z M 932.67854,-167.47484 C 945.77111,-167.47484 957.40895,-177.67249 957.40895,-191.53607 C 957.40895,-205.19599 945.77111,-215.23362 932.67854,-215.23362 C 919.58597,-215.23362 907.94813,-205.19599 907.94813,-191.53607 C 907.94813,-177.67249 919.58597,-167.47484 932.67854,-167.47484 z M 928.31435,-189.54309 L 932.67854,-189.54309 L 939.95219,-177.67249 L 944.31638,-177.67249 L 937.04273,-189.77585 C 939.95219,-190.27046 944.31638,-192.40891 944.31638,-197.2968 C 944.31638,-202.78113 939.95219,-205.19599 934.13327,-205.19599 L 923.95016,-205.19599 L 923.95016,-177.67249 L 928.31435,-177.67249 L 928.31435,-189.54309 z M 928.31435,-193.09263 L 928.31435,-201.69009 L 934.13327,-201.69009 C 935.588,-201.69009 939.95219,-201.02091 939.95219,-197.54411 C 939.95219,-193.36903 935.588,-193.09263 932.67854,-193.09263 L 928.31435,-193.09263" style="fill:#014185;fill-rule:nonzero;stroke:none"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

+14
View File
@@ -0,0 +1,14 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path>
<circle cx="9" cy="7" r="4"></circle>
<path d="M22 21v-2a4 4 0 0 0-3-3.87"></path>
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
</svg>

After

Width:  |  Height:  |  Size: 435 B

+10
View File
@@ -0,0 +1,10 @@
<svg
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="18" height="11" x="3" y="11" rx="2" ry="2"></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg>

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

+9
View File
@@ -0,0 +1,9 @@
<svg
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 699 B

+1
View File
@@ -0,0 +1 @@
dummy image content
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
document.getElementById('contact-form').addEventListener('submit', function(event) { event.preventDefault(); const formData = new FormData(event.target); fetch(event.target.action, { method: event.target.method, body: formData, }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log('Success:', data); }) .catch((error) => { console.error('Error:', error); }); });
+1
View File
@@ -0,0 +1 @@
function HumansNotBots(replacement_method, strAT, strDOT) { if (document.getElementsByTagName) { if (strAT == null || strDOT == null) { strAT = "AT"; strDOT = "DOT"; } var disguisedForm = "([a-zA-Z0-9._%+-]+)\\s" + strAT + "\\s([a-zA-Z0-9.-]+)\\s" + strDOT + "\\s(co.uk|[a-zA-Z]{2,4})"; var htmlbody = document.getElementsByTagName("body")[0]; if (replacement_method == "innerhtml") HumansNotBots_innerhtml(htmlbody, disguisedForm); else if (replacement_method == "dom") HumansNotBots_dom(htmlbody, disguisedForm); } } function HumansNotBots_innerhtml(htmlbody, disguisedForm) { var matchexp = new RegExp(disguisedForm, "g"); var replacement = '<a href="mailto:$1@$2.$3">$1@$2.$3</a>'; var newInnerHTML = htmlbody.innerHTML.replace(matchexp, replacement); htmlbody.innerHTML = newInnerHTML; } function HumansNotBots_dom(element, disguisedForm) { if (element) { if (element.hasChildNodes()) { var child = element.firstChild; while (child) { HumansNotBots_dom(child, disguisedForm); child = child.nextSibling; } } else if (element.nodeValue) { var matchexp = new RegExp(disguisedForm, "g"); var disguisedEmailAddresses = element.nodeValue.match(matchexp); if (disguisedEmailAddresses !== null) { var unprocessedText = element.nodeValue; var newParentsChildren = new Array(); for (var i = 0; i < disguisedEmailAddresses.length; i++) { var disguisedEmailAddress = disguisedEmailAddresses[i]; var textBefore = unprocessedText.substring( 0, unprocessedText.search(new RegExp(disguisedEmailAddress)) ); if (textBefore) { newParentsChildren.push(document.createTextNode(textBefore)); } var matchexp1 = new RegExp(disguisedForm); var realEmailAddress = disguisedEmailAddress.replace( matchexp1, "$1@$2.$3" ); var a = document.createElement("a"); a.setAttribute("href", "mailto:" + realEmailAddress); a.appendChild(document.createTextNode(realEmailAddress)); newParentsChildren.push(a); unprocessedText = unprocessedText.substring( textBefore.length + disguisedEmailAddress.length ); } if (unprocessedText) { newParentsChildren.push(document.createTextNode(unprocessedText)); } var parent = element.parentNode; var child = newParentsChildren.shift(); while (child) { parent.insertBefore(child, element); child = newParentsChildren.shift(); } parent.removeChild(element); } } } }
+1
View File
@@ -0,0 +1 @@
document.addEventListener("DOMContentLoaded", function () { const hamburger = document.querySelector(".hamburger-menu"); const navMenu = document.querySelector(".nav-menu"); if (!hamburger || !navMenu) { return; } hamburger.addEventListener("click", function () { hamburger.classList.toggle("open"); navMenu.classList.toggle("open"); }); document.addEventListener("click", function (event) { if (!hamburger.contains(event.target) && !navMenu.contains(event.target)) { hamburger.classList.remove("open"); navMenu.classList.remove("open"); } }); navMenu.addEventListener("click", function (event) { if (event.target.tagName === "A") { hamburger.classList.remove("open"); navMenu.classList.remove("open"); } }); });
+1
View File
@@ -0,0 +1 @@
function partnerRotate(interval = 3000) { const partners = document.querySelectorAll("img[src*='img/partner/']"); for (let i = 1; i < partners.length; i++) { partners[i].classList.add("hidden"); } let currentIndex = 0; const totalPartners = partners.length; setInterval(() => { partners[currentIndex].classList.add("hidden"); currentIndex = (currentIndex + 1) % totalPartners; partners[currentIndex].classList.remove("hidden"); }, interval); } window.onload = function () { partnerRotate(5000); };
+20
View File
@@ -0,0 +1,20 @@
; cPanel-generated php ini directives, do not edit
; Manual editing of this file may result in unexpected behavior.
; To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
; For more information, read our documentation (https://go.cpanel.net/EA4ModifyINI)
allow_url_fopen = On
allow_url_include = Off
asp_tags = Off
display_errors = Off
enable_dl = Off
file_uploads = On
max_execution_time = 30
max_input_time = 60
max_input_vars = 1000
memory_limit = 64M
post_max_size = 16M
session.gc_maxlifetime = 1440
session.save_path = "/var/cpanel/php/sessions/ea-php56"
upload_max_filesize = 16M
zlib.output_compression = Off
+2
View File
@@ -0,0 +1,2 @@
User-agent: *
Disallow:
File diff suppressed because one or more lines are too long
+122
View File
@@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://allucanget.biz/css/styles.css" />
<title>Email Signature - AllYouCanGET</title>
<style>
body {
margin: 0;
padding: 20px;
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
line-height: 1.4;
color: #333333;
background: transparent;
}
.signature-container {
max-width: 600px;
display: flex;
align-items: center;
gap: 20px;
padding: 20px;
background: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.logo-section {
flex-shrink: 0;
}
.logo {
height: 60px;
width: auto;
object-fit: contain;
}
.contact-info {
flex: 1;
}
.name {
font-size: 18px;
font-weight: bold;
color: #101828;
margin-bottom: 8px;
}
.position {
font-size: 14px;
color: #6b7280;
margin-bottom: 12px;
font-weight: 500;
}
.contact-details {
font-size: 14px;
line-height: 1.5;
}
.contact-item {
margin-bottom: 4px;
}
.contact-link {
color: #0a0a0a;
text-decoration: none;
transition: color 0.2s ease;
}
.contact-link:hover {
color: #2563eb;
}
.address {
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid #e5e7eb;
font-size: 13px;
color: #6b7280;
line-height: 1.4;
}
.address-line {
margin-bottom: 2px;
}
</style>
</head>
<body>
<div class="signature-container">
<div class="logo-section">
<img src="https://allucanget.biz/img/Logo-AllYouCanGet-204x100.png" alt="AllYouCanGET" class="logo" />
</div>
<div class="contact-info">
<div class="name">Georg Sinn</div>
<div class="position">IT & Management Consulting</div>
<div class="contact-details">
<div class="contact-item">
<a href="tel:+41799236402" class="contact-link">+41-79-9236402</a>
</div>
<div class="contact-item">
<a href="mailto:georg@allucanget.biz" class="contact-link">georg@allucanget.biz</a>
</div>
<div class="contact-item">
<a href="https://allucanget.biz" class="contact-link">allucanget.biz</a>
</div>
</div>
<div class="address">
<div class="address-line">All You Can GET</div>
<div class="address-line">c/o Sinn Consulting</div>
<div class="address-line">Im Dornäcker 16</div>
<div class="address-line">8967 Widen</div>
<div class="address-line">Switzerland</div>
</div>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
View File
+398
View File
@@ -0,0 +1,398 @@
"""
Markdown parser for converting Markdown files into structured component data.
This module reads Markdown files and returns a structured representation that maps
heading levels to component types:
- H1 (#) -> page title / hero
- H2 (##) -> major sections
- H3 (###) -> cards or subsections within sections
- Lists -> converted to component-compatible format
"""
import os
import re
import textwrap
import markdown
from bs4 import BeautifulSoup
from markdown.treeprocessors import Treeprocessor
from markdown.preprocessors import Preprocessor
from markdown.extensions import Extension
from typing import Dict, List, Any, Optional, cast
from lib.types import PageData, Section, Card, Detail, ParserState
class HeadingCollector(Treeprocessor):
"""
Custom Markdown tree processor that collects headings and their content.
"""
def __init__(self, md: Any) -> None:
super().__init__(md)
self.headings: List[Dict[str, Any]] = []
self.current_content: List[str] = []
self.main_intro: str = ''
def run(self, root: Any) -> Any:
"""Process the element tree and collect headings with content."""
self.headings = []
self.main_intro = ''
collecting_intro = False
for element in root:
if element.tag == 'h1':
collecting_intro = True
elif collecting_intro and element.tag in ['h2', 'h3', 'h4', 'h5', 'h6']:
collecting_intro = False
elif collecting_intro:
intro_text = self._extract_text(element)
if intro_text:
if self.main_intro:
self.main_intro += '\n\n' + intro_text
else:
self.main_intro = intro_text
self._process_element(element)
return root
def _process_element(self, element: Any) -> None:
"""Recursively process elements to extract heading structure."""
if element.tag in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']:
# Convert heading tag to level (e.g., 'h2' -> 2)
level = int(element.tag[1])
text = self._extract_text(element)
self.headings.append({
'level': level if level > 1 else 2, # Treat H1 as level 2 for sectioning
'text': text,
'tag': element.tag,
'element': element,
})
elif element.tag in ['ul', 'ol']:
# Extract list items
items: List[str] = []
for li in element:
items.append(self._extract_text(li))
self.headings.append({
'type': element.tag,
'items': items,
'element': element,
})
else:
# Process children
for child in element:
self._process_element(child)
def _extract_text(self, element: Any) -> str:
"""Extract all text from an element and its children."""
if element.text:
text = element.text
else:
text = ''
for child in element:
text += self._extract_text(child)
if child.tail:
text += child.tail
return text.strip()
class DedentPreprocessor(Preprocessor):
"""Normalize leading indentation so headings aren't treated as code blocks."""
def run(self, lines: List[str]) -> List[str]:
text = '\n'.join(lines)
dedented = textwrap.dedent(text)
return dedented.split('\n')
class HeadingExtension(Extension):
"""Markdown extension to collect headings."""
def extendMarkdown(self, md: Any) -> None:
md.preprocessors.register(
DedentPreprocessor(md), 'dedent_preprocessor', 27)
md.treeprocessors.register(
HeadingCollector(md), 'heading_collector', 5)
def parse_markdown_file(file_path: str) -> PageData:
"""
Parse a Markdown file and return a structured representation.
Args:
file_path (str): Path to the Markdown file to parse.
Returns:
dict: A nested dictionary representing the page structure.
Raises:
FileNotFoundError: If the file does not exist.
IOError: If there is an error reading the file.
"""
if not os.path.exists(file_path):
raise FileNotFoundError(f"Markdown file not found: {file_path}")
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Parse the content to extract structure
return build_component_structure(content, file_path)
def get_markdown_files(docs_dir: str = 'docs/en') -> List[str]:
"""Return Markdown filenames from the given docs directory."""
if not os.path.exists(docs_dir):
return []
return [f for f in os.listdir(docs_dir) if f.endswith('.md')]
def markdown_filename_to_html_filename(md_filename: str) -> str:
"""Convert a Markdown filename to its HTML counterpart."""
return md_filename.replace('.md', '.html').lower()
def build_component_structure(
markdown_content: str, file_path: str) -> PageData:
"""
Build a nested component structure from Markdown content.
This function parses Markdown headings and content into a hierarchical structure
suitable for rendering with component templates.
"""
lines = markdown_content.split('\n')
page: PageData = {
'title': None,
'sections': [],
}
current_section: Optional[Section] = None
current_card: Optional[Card] = None
current_detail: Optional[Detail] = None
content_buffer: List[str] = []
detail_buffer: List[str] = []
# Move local state into a dict so module-level helpers can operate on it
state: ParserState = {
'page': page,
'current_section': current_section,
'current_card': current_card,
'current_detail': current_detail,
'content_buffer': content_buffer,
'detail_buffer': detail_buffer,
}
for line in lines:
process_line_with_state(line, state)
# Rehydrate locals from state
current_section = state['current_section']
current_card = state['current_card']
current_detail = state['current_detail']
content_buffer = state['content_buffer']
detail_buffer = state['detail_buffer']
# Flush remaining content
flush_detail_buffer(state)
# Flush content buffer to card or section as appropriate
if current_card is not None and content_buffer:
current_card['content'] = markdown_to_html_lines(
'\n'.join(content_buffer).strip())
elif current_section is not None and content_buffer:
current_section['content'] = markdown_to_html_lines(
'\n'.join(content_buffer).strip())
if page['title'] is None:
filename = os.path.basename(file_path)
page['title'] = os.path.splitext(filename)[0].replace('_', ' ').title()
return page
def flush_detail_buffer(state: ParserState) -> None:
"""Flush the detail buffer into the current detail entry."""
current_detail = state['current_detail']
detail_buffer = state['detail_buffer']
if current_detail is not None and detail_buffer:
current_detail['content'] = markdown_to_html_lines(
'\n'.join(detail_buffer).strip())
state['detail_buffer'] = []
def flush_content_buffer_to_card(state: ParserState) -> None:
"""Flush the content buffer into the current card."""
current_card = state['current_card']
content_buffer = state['content_buffer']
if current_card is not None and content_buffer:
current_card['content'] = markdown_to_html_lines(
'\n'.join(content_buffer).strip())
def flush_content_buffer_to_section(state: ParserState) -> None:
"""Flush the content buffer into the current section."""
current_section = state['current_section']
content_buffer = state['content_buffer']
if current_section is not None and content_buffer:
current_section['content'] = markdown_to_html_lines(
'\n'.join(content_buffer).strip())
def start_section(title: str, state: ParserState) -> None:
"""Start a new section with the given title."""
if state['current_card'] is not None:
flush_content_buffer_to_card(state)
state['content_buffer'] = []
state['current_card'] = None
if state['current_section'] is not None:
flush_content_buffer_to_section(state)
section = cast(Section, {
'title': title,
'content': '',
'cards': []
})
sections = state['page'].get('sections', [])
sections.append(section)
state['page']['sections'] = sections
state['current_section'] = section
state['content_buffer'] = []
state['current_card'] = None
def start_card(title: str, state: ParserState) -> None:
"""Start a new card within the current section."""
if state['current_section'] is None:
return
if state['current_card'] is None:
flush_content_buffer_to_section(state)
else:
flush_content_buffer_to_card(state)
card = cast(Card, {
'title': title,
'content': ''
})
state['current_section']['cards'].append(card)
state['current_card'] = card
state['content_buffer'] = []
def start_detail(title: str, state: ParserState) -> None:
"""Start a new detail within the current card."""
if state['current_card'] is None:
return
if state['current_detail'] is not None and state['detail_buffer']:
state['current_detail']['content'] = markdown_to_html_lines(
'\n'.join(state['detail_buffer']).strip())
state['detail_buffer'] = []
detail = cast(Detail, {
'title': title,
'content': ''
})
if 'details' not in state['current_card']:
state['current_card']['details'] = []
state['current_card']['details'].append(detail)
state['current_detail'] = detail
def process_line_with_state(line: str, state: ParserState) -> None:
"""Process a single markdown line, updating the provided state dict."""
if line.startswith('# '):
# H1 - page title
state['page']['title'] = line[2:].strip()
# intro content before sections
if state['current_section'] is not None and state['content_buffer']:
flush_content_buffer_to_section(state)
state['current_section'] = None
elif line.startswith('## '):
# H2 - major section
flush_detail_buffer(state)
title = line[3:].strip()
title = check_image_in_title(title)
start_section(title, state)
elif line.startswith('### '):
# H3 - card or subsection
flush_detail_buffer(state)
title = line[4:].strip()
title = check_image_in_title(title)
start_card(title, state)
elif line.startswith('#### '):
# H4 - detail inside a card
if state['current_card'] is not None:
title = line[5:].strip()
title = check_image_in_title(title)
start_detail(title, state)
else:
state['content_buffer'].append(line)
elif line.strip():
if state['current_detail'] is not None:
state['detail_buffer'].append(line)
else:
state['content_buffer'].append(line)
def check_image_in_title(title: str) -> str:
"""
Check if there is an image in the title, preserve original title text and create HTML img tag with alt text and src.
"""
img_pattern = r'!\[([^\]]*)\]\(([^)]+)\)'
match = re.search(img_pattern, title)
if match:
alt_text = match.group(1).strip()
src = match.group(2).strip()
img_tag = f'<img src="{src}" alt="{alt_text}"/>'
title = re.sub(img_pattern, img_tag, title).strip()
return title
def markdown_to_html_lines(text: str) -> str:
"""
Convert Markdown text to HTML.
"""
if not text:
return ''
md = markdown.Markdown()
html = md.convert(text)
def _is_unsafe(href: str) -> bool:
lower = href.strip().lower()
return lower.startswith('javascript:') or lower.startswith(
'data:') or lower.startswith('vbscript:')
soup = BeautifulSoup(html, 'html.parser')
for anchor in soup.find_all('a'):
href = anchor.get('href')
if isinstance(href, (list, tuple)):
href = href[0]
href = (href or '').strip()
if not href:
continue
if _is_unsafe(href):
anchor['href'] = '#unsafe'
anchor.attrs.pop('target', None)
anchor.attrs.pop('rel', None)
continue
if href.startswith('http://') or href.startswith('https://'):
anchor['target'] = '_blank'
anchor['rel'] = 'noopener noreferrer'
for image in soup.find_all('img'):
src = image.get('src') or ''
if isinstance(src, (list, tuple)):
src = src[0]
src = src.strip()
if not src:
image.decompose()
continue
alt = image.get('alt')
if isinstance(alt, (list, tuple)):
alt = alt[0]
alt_text = (alt or '').strip()
# Determine final src for relative paths
if not (src.startswith('http://') or src.startswith('https://')
or src.startswith('/') or src.startswith('img/')):
filename = os.path.basename(src)
src = f'img/{filename}' if filename else src
image['src'] = src
if not alt_text:
alt_text = os.path.splitext(os.path.basename(src))[
0].replace('-', ' ').replace('_', ' ').strip()
image['alt'] = alt_text
return str(soup)
+54
View File
@@ -0,0 +1,54 @@
from typing import TypedDict, List, Dict, Optional
class Detail(TypedDict):
title: str
content: str
class Card(TypedDict, total=False):
title: str
content: str
details: List[Detail]
class Section(TypedDict):
title: str
content: str
cards: List[Card]
class PageData(TypedDict):
title: Optional[str]
sections: List[Section]
class PageMeta(TypedDict, total=False):
title: str
description: str
keywords: str
og_description: str
favicon: str
twitter_image: str
og_image: str
class PageEntry(TypedDict, total=False):
page_title: str
page_subtitle: str
page_cta: str
page_cta_url: str
meta: PageMeta
active: bool
PagesDict = Dict[str, PageEntry]
class ParserState(TypedDict):
page: PageData
current_section: Optional[Section]
current_card: Optional[Card]
current_detail: Optional[Detail]
content_buffer: List[str]
detail_buffer: List[str]
+126
View File
@@ -0,0 +1,126 @@
import os
import re
from typing import Dict, List, Any
from jinja2 import Environment, FileSystemLoader
from lib.types import PagesDict
DEFAULT_TEMPLATE_DIR = 'templates'
DEFAULT_OUTPUT_DIR = 'html'
def get_template_files(template_dir: str = DEFAULT_TEMPLATE_DIR) -> List[str]:
"""Return template filenames from the provided template directory."""
if not os.path.exists(template_dir):
return []
return [
name
for name in os.listdir(template_dir)
if name.endswith('.html') and not name.startswith('_')
]
def get_css_files(output_dir: str = DEFAULT_OUTPUT_DIR) -> List[str]:
"""Return CSS file paths contained in the output directory's css folder."""
css_dir = os.path.join(output_dir, 'css')
if not os.path.exists(css_dir):
return []
return [
os.path.join(css_dir, name)
for name in os.listdir(css_dir)
if name.endswith('.css')
]
def get_js_files(output_dir: str = DEFAULT_OUTPUT_DIR) -> List[str]:
"""Return JavaScript file paths contained in the output directory's js folder."""
js_dir = os.path.join(output_dir, 'js')
if not os.path.exists(js_dir):
return []
return [
os.path.join(js_dir, name)
for name in os.listdir(js_dir)
if name.endswith('.js')
]
def render_template(
template_name: str,
context: Dict[str, Any],
template_dir: str = DEFAULT_TEMPLATE_DIR) -> str:
"""Render a Jinja2 template with the provided context."""
env = Environment(loader=FileSystemLoader(template_dir))
template = env.get_template(template_name)
return template.render(context)
def set_active_page_by_url(pages: PagesDict, page_url: str) -> None:
"""Mutate navigation dictionary to mark the active page."""
for key, value in pages.items():
# value is a PageEntry TypedDict
value['active'] = key == page_url
def minify_js(js: str) -> str:
"""Minify JavaScript by removing comments and redundant whitespace."""
js = re.sub(r'//.*?\n|/\*.*?\*/', '', js, flags=re.DOTALL)
js = re.sub(r'\s+', ' ', js)
js = re.sub(r';\s+', ';\n', js)
js = re.sub(r'\n+', ' ', js)
return js.strip()
def minify_css(css: str) -> str:
"""Minify CSS by removing comments and redundant whitespace."""
css = re.sub(r'/\*.*?\*/', '', css, flags=re.DOTALL)
css = re.sub(r'\s+', ' ', css)
css = re.sub(r';\s+', ';\n', css)
css = re.sub(r'\s+([\{\s])', r'\1', css)
css = re.sub(r'\s+}', '}', css)
css = re.sub(r'\n+', ' ', css)
return css.strip()
def minify_html(html: str) -> str:
"""Minify HTML by removing comments and redundant whitespace."""
html = re.sub(r'<!--.*?-->', '', html, flags=re.DOTALL)
html = re.sub(r'\s+', ' ', html)
html = re.sub(r'>\s+<', '><', html)
html = re.sub(r'<\s+', '<', html)
html = re.sub(r'\s+</', '</', html)
return html.strip()
def css_minifier(output_dir: str = DEFAULT_OUTPUT_DIR) -> None:
"""Minify all CSS files within the output directory."""
for css_path in get_css_files(output_dir):
with open(css_path, 'r', encoding='utf-8') as handle:
content = handle.read()
minified = minify_css(content)
with open(css_path, 'w', encoding='utf-8') as handle:
handle.write(minified)
def js_minifier(output_dir: str = DEFAULT_OUTPUT_DIR) -> None:
"""Minify all JavaScript files within the output directory."""
for js_path in get_js_files(output_dir):
with open(js_path, 'r', encoding='utf-8') as handle:
content = handle.read()
minified = minify_js(content)
with open(js_path, 'w', encoding='utf-8') as handle:
handle.write(minified)
__all__ = [
'DEFAULT_OUTPUT_DIR',
'DEFAULT_TEMPLATE_DIR',
'get_template_files',
'get_css_files',
'get_js_files',
'render_template',
'set_active_page_by_url',
'minify_js',
'minify_css',
'minify_html',
'css_minifier',
'js_minifier',
]
+189
View File
@@ -0,0 +1,189 @@
import json
import os
from typing import Any, Dict
from lib.markdown_parser import (
parse_markdown_file,
get_markdown_files,
markdown_filename_to_html_filename,
)
from lib.utils import (
get_template_files,
render_template,
set_active_page_by_url,
minify_html,
js_minifier,
)
from lib.types import PagesDict
TEMPLATE_DIR = 'templates'
OUTPUT_DIR = 'html'
PAGES_JSON = 'docs/pages.json'
# Load json data for navigation and pages if needed
with open(PAGES_JSON, 'r') as f:
PAGES = json.load(f)
# Ensure output directory exists
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
def get_pages() -> PagesDict:
"""Load and return pages data from the pages.json file.
Returns:
dict: Pages dictionary structured as follows:
{
"page.html": {
"name": str,
"url": str,
"active": str,
"page_title": str,
"page_subtitle": str,
"page_cta": str,
"page_cta_url": str,
"meta": {
"title": str,
"description": str,
"keywords": str,
"og_description": str,
}
},
{...}
}
"""
# Set a default favicon for all pages
favicon = 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png'
with open(PAGES_JSON, 'r', encoding='utf-8') as f:
pages = json.load(f)
# Update the meta information for each page
for page in pages.values():
page['meta']['favicon'] = favicon
page['meta']['og_image'] = favicon
page['meta']['twitter_image'] = favicon
return pages
def process_markdown_file(
md_file_path: str,
output_html_path: str,
pages: PagesDict,
template_dir: str = TEMPLATE_DIR,
):
"""
Process a single Markdown file and render it using the page_from_md template.
Args:
md_file_path (str): Full path to the Markdown file.
output_html_path (str): Full path to write the output HTML.
pages (dict): Pages dictionary for context.
"""
try:
# Parse the Markdown file
page_data = parse_markdown_file(md_file_path)
# Get the HTML filename to determine active nav
html_filename = os.path.basename(output_html_path)
set_active_page_by_url(pages, html_filename)
# Build default meta data for the page
default_meta: Dict[str, Any] = {
'title': page_data.get('title', ''),
'description': 'Explore our comprehensive services and coaching programs.',
'keywords': 'consulting, coaching, services',
'og_description': page_data.get('title', ''),
'favicon': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
'twitter_image': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
'og_image': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
}
page = pages.get(html_filename, {})
meta = page.get('meta', default_meta)
page_title = page.get('page_title', page_data.get('title', ''))
page_subtitle = page.get('page_subtitle', '')
# Build context for rendering
context: Dict[str, Any] = {
'nav_pages': pages,
'page': page_data,
'page_title': page_title,
'page_subtitle': page_subtitle,
'meta': meta,
'page_url': html_filename,
'page_cta': page.get('page_cta', 'Get Started'),
'page_cta_url': page.get('page_cta_url', '#contact-form'),
}
# Render the template and write the output
output = render_template(
'page_from_md.html', context, template_dir=template_dir)
html = minify_html(output)
os.makedirs(os.path.dirname(output_html_path), exist_ok=True)
with open(output_html_path, 'w', encoding='utf-8') as f:
f.write(html)
print(f'Processed Markdown: {md_file_path} -> {output_html_path}')
except Exception as e:
print(f'Error processing Markdown file {md_file_path}: {e}')
def main():
"""Main function to render templates with navigation context."""
# Get all pages with their details
pages = get_pages()
if not pages:
print("No pages found to render.")
return
# Get navigation pages
templates = get_template_files(TEMPLATE_DIR)
if not templates:
print("No templates found to render.")
return
print(f'Found {len(templates)} templates to process.')
# # Process each template
# for template_name in templates:
# # Skip templates that are not in the pages dictionary
# if template_name not in pages:
# print(f'Skipping template: {template_name}')
# continue
# print(f'Processing template: {template_name}')
# # Set the active page based on the template name
# set_active_page_by_url(pages, template_name)
# page_details: PageEntry = pages[template_name]
# context = {
# 'nav_pages': pages,
# 'page_title': page_details.get('page_title', ''),
# 'page_subtitle': page_details.get('page_subtitle', ''),
# 'page_cta': page_details.get('page_cta', ''),
# 'page_cta_url': page_details.get('page_cta_url', ''),
# 'meta': page_details.get('meta', {}),
# }
# output = render_template(
# template_name, context, template_dir=TEMPLATE_DIR)
# html = minify_html(output)
# with open(f'{OUTPUT_DIR}/{template_name}', 'w', encoding='utf-8') as f:
# f.write(html)
# Process Markdown files from docs/en/
print("\nProcessing Markdown files...")
markdown_files = get_markdown_files()
for md_file in markdown_files:
md_path = os.path.join('docs/en', md_file)
html_filename = markdown_filename_to_html_filename(md_file)
html_path = os.path.join(OUTPUT_DIR, html_filename)
process_markdown_file(md_path, html_path, pages,
template_dir=TEMPLATE_DIR)
# Minify all CSS and JS files in the output directory.
print("\nMinifying CSS and JS files...")
# css_minifier()
js_minifier(OUTPUT_DIR)
print("Build complete!")
if __name__ == '__main__':
main()
+10
View File
@@ -0,0 +1,10 @@
jinja2
lib
markdown
pytest
beautifulsoup4
pytest
pytest-cov
autopep8
mypy
flake8
+17
View File
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
{% include "_head.html" %}
<body>
{% include "_header.html" %}
<div id="main-content">
<div id="main">
{% block content %}{% endblock %} {%include
"_footer.html" %}
</div>
</div>
{% block scripts %}
<script src="js/nav.js" defer></script>
{% endblock %}
<script src="js/partner.js" defer></script>
</body>
</html>
+9
View File
@@ -0,0 +1,9 @@
<div id="footer">
<div class="container">
<p>
&copy; 2025
<a href="imprint.html" class="footer-link">AllYouCanGET</a>
&nbsp;|&nbsp; All rights reserved.
</p>
</div>
</div>
+35
View File
@@ -0,0 +1,35 @@
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="{{ meta.description }}" />
<meta name="keywords" content="{{ meta.keywords }}" />
<!-- SEO and Social Sharing Meta Tags -->
<meta name="robots" content="index, follow" />
<link rel="canonical" href="https://allucanget.biz/{{ page_url }}" />
<meta name="theme-color" content="#111827" />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://allucanget.biz/{{ page_url }}" />
<meta property="og:title" content="{{ meta.title }}" />
<meta property="og:description" content="{{ meta.og_description }}" />
<meta property="og:image" content="{{ meta.favicon }}" />
<meta property="og:site_name" content="AllYouCanGET" />
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:url" content="https://allucanget.biz/{{ page_url }}" />
<meta name="twitter:title" content="{{ meta.title }}" />
<meta name="twitter:description" content="{{ meta.description }}" />
<meta name="twitter:image" content="{{ meta.favicon }}" />
<link rel="stylesheet" href="css/styles.css" />
<link
rel="icon"
href="img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png"
type="image/x-icon"
/>
<title>{{ page_title }}</title>
</head>
+56
View File
@@ -0,0 +1,56 @@
<div id="header">
<nav id="site-navigation">
<div id="site-navigation-container">
<div id="site-navigation-content">
<div id="site-navigation-bar">
<div id="site-navigation-brand">
<a href="index.html" class="site-home-link">
<img src="img/Logo-AllYouCanGet-204x100.png" alt="AllYouCanGET" class="nav-logo" />
<span class="nav-text">AllYouCanGET</span>
</a>
</div>
<button class="hamburger-menu" aria-label="Toggle navigation">
<span class="hamburger-line"></span>
<span class="hamburger-line"></span>
<span class="hamburger-line"></span>
</button>
<div class="nav-menu">
<div id="site-nav-links">
{% for key, page in nav_pages.items() %} {% if page.active %}
<a href="{{ page.url }}" class="site-nav-link active"
>{{ page.name }}</a
>
{% else %}
<a href="{{ page.url }}" class="site-nav-link">{{ page.name }}</a>
{% endif %} {% endfor %}
</div>
</div>
</div>
</div>
</div>
</nav>
<div id="page-title">
<h2 class="page-title-header">{{ page_title }}</h2>
<h3 class="page-subtitle">{{ page_subtitle }}</h3>
</div>
{% if page_cta_url %}
<div class="header-cta">
<div class="header-cta-buttons">
<button class="bigbutton">
<a href="{{ page_cta_url }}">
<span>{{ page_cta }}</span>
<span></span>
</a>
</button>
{% if page_cta_url == 'services.html' %}
<button class="bigbutton">
<a href="#contact-form">
<span>Contact Us</span>
<span></span>
</a>
</button>
{% endif %}
</div>
</div>
{% endif %}
</div>
+22
View File
@@ -0,0 +1,22 @@
<nav id="site-navigation">
<div id="site-navigation-container">
<div id="site-navigation-content">
<div id="site-navigation-bar">
<div id="site-navigation-brand">
<a href="index.html" class="site-home-link">AllYouCanGET</a>
</div>
<div class="nav-toggle hidden md:block">
<div id="site-nav-links">
{% for key, page in nav_pages.items() %} {% if page.active %}
<a href="{{ page.url }}" class="site-nav-link active"
>{{ page.name }}</a
>
{% else %}
<a href="{{ page.url }}" class="site-nav-link">{{ page.name }}</a>
{% endif %} {% endfor %}
</div>
</div>
</div>
</div>
</div>
</nav>
+498
View File
@@ -0,0 +1,498 @@
{% extends "_base.html" %} {% block content %}
<div class="bg-gray-50 py-12">
<div class="container mx-auto px-6">
<h1 class="text-4xl font-bold text-center mb-4">Our Coaching Areas</h1>
<p class="text-xl text-gray-600 text-center mb-12">
Comprehensive coaching programs tailored to your professional and personal
growth
</p>
<!-- Career Advice Section -->
<div class="mb-16">
<div class="flex items-center mb-8">
<img
src="img/coaching-career.svg"
alt="Career advice icon"
class="w-8 h-8 mr-4"
width="24"
height="24"
/>
<h2 class="text-3xl font-bold">Career Advice</h2>
</div>
<p class="text-lg text-gray-600 mb-8">
Navigate your career path with expert guidance tailored to your industry
and location.
</p>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">IT Career</h3>
<ul class="text-gray-600 space-y-2">
<li>• Career paths in software development</li>
<li>• Technical vs management track</li>
<li>• Transitioning between specialties</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Switzerland Specifics</h3>
<ul class="text-gray-600 space-y-2">
<li>• Work culture and expectations</li>
<li>• Salary negotiations</li>
<li>• Work permits and regulations</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Germany Specifics</h3>
<ul class="text-gray-600 space-y-2">
<li>• Job market trends</li>
<li>• Industry hubs and opportunities</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Remote Work</h3>
<ul class="text-gray-600 space-y-2">
<li>• Building a remote work routine</li>
<li>• Communication strategies</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Freelancing</h3>
<ul class="text-gray-600 space-y-2">
<li>• Setting up as independent contractor</li>
<li>• Client acquisition and retention</li>
<li>• Pricing strategies and negotiation</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Startups</h3>
<ul class="text-gray-600 space-y-2">
<li>• Evaluating startup opportunities</li>
<li>• Equity considerations</li>
<li>• Growth expectations</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Corporates</h3>
<ul class="text-gray-600 space-y-2">
<li>• Navigating corporate structures</li>
<li>• Internal mobility</li>
<li>• Building influence</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Consulting</h3>
<ul class="text-gray-600 space-y-2">
<li>• Types of consulting roles</li>
<li>• Client management</li>
<li>• Balancing multiple projects</li>
</ul>
</div>
</div>
</div>
<!-- Personal Development Section -->
<div class="mb-16">
<div class="flex items-center mb-8">
<img
src="img/coaching-personal.svg"
alt="Personal development icon"
class="w-8 h-8 mr-4"
width="24"
height="24"
/>
<h2 class="text-3xl font-bold">Personal Development</h2>
</div>
<p class="text-lg text-gray-600 mb-8">
Discover your values, strengths, and purpose to create a fulfilling life
and career.
</p>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Values</h3>
<ul class="text-gray-600 space-y-2">
<li>• Value identification exercises</li>
<li>• Aligning career with personal values</li>
<li>• Identity Workshop</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Ikigai</h3>
<ul class="text-gray-600 space-y-2">
<li>• Finding purpose through passion</li>
<li>• Mission, vocation, and profession</li>
<li>• Practical discovery exercises</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Strengths</h3>
<ul class="text-gray-600 space-y-2">
<li>• Assessment tools and frameworks</li>
<li>• Leveraging strengths professionally</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Weaknesses</h3>
<ul class="text-gray-600 space-y-2">
<li>• Growth mindset approaches</li>
<li>• Strategic improvement planning</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Vision</h3>
<ul class="text-gray-600 space-y-2">
<li>• Creating personal vision statements</li>
<li>• Long-term life planning</li>
<li>• Visualization techniques</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Goals</h3>
<ul class="text-gray-600 space-y-2">
<li>• SMART goal framework</li>
<li>• Balancing short and long-term objectives</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Agile Self Organization</h3>
<ul class="text-gray-600 space-y-2">
<li>• Personal Kanban implementation</li>
<li>• Quarterly planning and review cycles</li>
<li>• Agile methods for personal productivity</li>
</ul>
</div>
</div>
</div>
<!-- Leadership Coaching Section -->
<div class="mb-16">
<div class="flex items-center mb-8">
<img
src="img/coaching-leadership.svg"
alt="Leadership coaching icon"
class="w-8 h-8 mr-4"
width="24"
height="24"
/>
<h2 class="text-3xl font-bold">Leadership Coaching</h2>
</div>
<p class="text-lg text-gray-600 mb-8">
Develop essential leadership skills to inspire teams and drive
organizational success.
</p>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Leadership Styles</h3>
<ul class="text-gray-600 space-y-2">
<li>• Management vs Leadership</li>
<li>• Situational leadership approaches</li>
<li>• Transformational vs transactional</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Communication</h3>
<ul class="text-gray-600 space-y-2">
<li>• Active listening techniques</li>
<li>• Delivering difficult messages</li>
<li>• Cross-cultural communication</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Feedback</h3>
<ul class="text-gray-600 space-y-2">
<li>• Structured feedback frameworks</li>
<li>• Creating feedback culture</li>
<li>• Growth-oriented approaches</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Delegation</h3>
<ul class="text-gray-600 space-y-2">
<li>• RACI and DACI models</li>
<li>• Identifying tasks to delegate</li>
<li>• Building team capacity</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Decision Making</h3>
<ul class="text-gray-600 space-y-2">
<li>• OODA loop, DECIDE model</li>
<li>• Data-driven decisions</li>
<li>• Managing decision paralysis</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Conflict Management</h3>
<ul class="text-gray-600 space-y-2">
<li>• Conflict resolution models</li>
<li>• Mediation techniques</li>
<li>• Transforming conflict to opportunity</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Motivation</h3>
<ul class="text-gray-600 space-y-2">
<li>• Intrinsic vs extrinsic motivation</li>
<li>• SCARF and Drive frameworks</li>
<li>• Tailoring to individual needs</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Empathy & Compassion</h3>
<ul class="text-gray-600 space-y-2">
<li>• Building empathetic leadership</li>
<li>• Compassion without compromising</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Trust</h3>
<ul class="text-gray-600 space-y-2">
<li>• Trust-building exercises</li>
<li>• Trust in remote teams</li>
<li>• Rebuilding broken trust</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Psychological Safety</h3>
<ul class="text-gray-600 space-y-2">
<li>• Assessment techniques</li>
<li>• Creating safety in teams</li>
<li>• Connection to innovation</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Team Building</h3>
<ul class="text-gray-600 space-y-2">
<li>• Tuckman's team formation</li>
<li>• Remote team activities</li>
<li>• Cross-functional dynamics</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h3 class="text-xl font-bold mb-3">Agile Project Management</h3>
<ul class="text-gray-600 space-y-2">
<li>• Project roles and responsibilities</li>
<li>• Agile hierarchies</li>
<li>• Balancing agility with governance</li>
</ul>
</div>
</div>
</div>
<!-- Technical Coaching Section -->
<div class="mb-16">
<div class="flex items-center mb-8">
<img
src="img/coaching-technical.svg"
alt="Technical coaching icon"
class="w-8 h-8 mr-4"
width="24"
height="24"
/>
<h2 class="text-3xl font-bold">Technical Coaching</h2>
</div>
<p class="text-lg text-gray-600 mb-8">
Master technical skills and best practices in software development and
IT infrastructure.
</p>
<!-- Software and Web Development Subsection -->
<h3 class="text-2xl font-bold mb-6 text-gray-700">
Software and Web Development
</h3>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h4 class="text-xl font-bold mb-3">Scalability</h4>
<ul class="text-gray-600 space-y-2">
<li>• Horizontal vs vertical scaling</li>
<li>• Distributed systems principles</li>
<li>• Load balancing strategies</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h4 class="text-xl font-bold mb-3">Browser</h4>
<ul class="text-gray-600 space-y-2">
<li>• Developer tools mastery</li>
<li>• Performance optimization</li>
<li>• Extension development</li>
</ul>
</div>
</div>
<!-- Operating Systems Subsection -->
<h3 class="text-2xl font-bold mb-6 text-gray-700">Operating Systems</h3>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h4 class="text-xl font-bold mb-3">Linux</h4>
<ul class="text-gray-600 space-y-2">
<li>• Debian, Ubuntu</li>
<li>• RedHat, Fedora, CentOS</li>
<li>• Arch, Manjaro</li>
<li>• SUSE, openSUSE</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h4 class="text-xl font-bold mb-3">Windows</h4>
<ul class="text-gray-600 space-y-2">
<li>• Windows 10 & 11</li>
<li>• Windows Server 2019</li>
<li>• Windows Server 2022</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h4 class="text-xl font-bold mb-3">macOS</h4>
<ul class="text-gray-600 space-y-2">
<li>• macOS basics</li>
<li>• System administration</li>
<li>• Shell commands</li>
</ul>
</div>
</div>
<!-- Tools Subsection -->
<h3 class="text-2xl font-bold mb-6 text-gray-700">Development Tools</h3>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h4 class="text-xl font-bold mb-3">Git</h4>
<ul class="text-gray-600 space-y-2">
<li>• Advanced git workflows</li>
<li>• Git hooks and automation</li>
<li>• Collaboration strategies</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h4 class="text-xl font-bold mb-3">Docker</h4>
<ul class="text-gray-600 space-y-2">
<li>• Container optimization</li>
<li>• Docker Compose</li>
<li>• Kubernetes orchestration</li>
</ul>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<h4 class="text-xl font-bold mb-3">Visual Studio Code</h4>
<ul class="text-gray-600 space-y-2">
<li>• Extension ecosystem</li>
<li>• Customization and settings</li>
<li>• Productivity optimization</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Call to Action Section -->
<div class="bg-blue-600 text-white py-12">
<div class="container mx-auto px-6 text-center">
<h2 class="text-3xl font-bold mb-4">Ready to Accelerate Your Growth?</h2>
<p class="text-xl mb-6">
Let's work together to unlock your full potential
</p>
<button
class="bg-white text-blue-600 font-bold py-3 px-8 rounded-lg hover:bg-gray-100"
>
<a href="mailto:info@allucanget.biz">Schedule Your First Session</a>
</button>
</div>
</div>
{% endblock %}
+17
View File
@@ -0,0 +1,17 @@
<div class="section-card">
<h3 class="section-card-title">{{ card.title }}</h3>
{% if card.content %}
<div class="section-content">{{ card.content | safe }}</div>
{% endif %} {% if card.details %}
<div class="mt-4 space-y-3">
{% for detail in card.details %}
<div class="section-card-detail">
<h4 class="section-card-detail-title">{{ detail.title }}</h4>
{% if detail.content %}
<div class="section-card-detail-content">{{ detail.content | safe }}</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
</div>
+8
View File
@@ -0,0 +1,8 @@
<div id="hero">
<div class="container">
<h1>{{ page.title }}</h1>
{% if page.subtitle %}
<p>{{ page.subtitle }}</p>
{% endif %}
</div>
</div>
+13
View File
@@ -0,0 +1,13 @@
<div class="section">
<div class="section-container container">
<h2>{{ section.title }}</h2>
{% if section.content %}
<div class="section-content">{{ section.content | safe }}</div>
{% endif %} {% if section.cards %}
<div class="section-cards">
{% for card in section.cards %} {% include 'components/card.html' %} {%
endfor %}
</div>
{% endif %}
</div>
</div>
+238
View File
@@ -0,0 +1,238 @@
{% extends "_base.html" %}{% block content %}
<div class="bg-gray-50 py-12">
<div class="container mx-auto px-4">
<h1 class="text-4xl font-bold text-center mb-4">Imprint</h1>
<div class="mb-16">
<div class="flex items-center mb-8">
<img
src="img/imprint-shield.svg"
alt="Shield icon"
class="w-8 h-8 mr-4"
width="24"
height="24"
/>
<h2 class="text-3xl font-bold">AllYouCanGET - Sinn Consulting</h2>
</div>
<h2 class="text-xl font-bold">Impressum</h2>
<p class="text-lg text-gray-600 mb-8">
gemäß §5 Telemediengesetz bzw. § 5 Abs. 1 E-Commerce-Gesetz bzw. Art. 3
des Bundesgesetzes gegen den unlauteren Wettbewerb (UWG)
</p>
<div
class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-1 wp-block-columns-is-layout-flex"
>
<div
class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"
>
<p class="text-lg text-gray-600 mb-8">
All You Can GET<br />c/o Sinn Consulting<br />Im Dorn&auml;cker
16<br />CH-8967 Widen<br />georg AT allucanget DOT biz
</p>
</div>
</div>
<hr class="mb-3" />
<h3 class="text-xl font-bold mb-3"><strong>Overview</strong></h3>
<p class="text-lg text-gray-600 mb-8">
The following are the terms of an agreement between you and
AllYouCanGET. By accessing, or using this Web site, you acknowledge that
you have read, understand, and agree to be bound by these terms and to
comply with all applicable laws and regulations, including export and
re-export control laws and regulations. If you do not agree to these
terms, please do not use this Web site.
</p>
<p class="text-lg text-gray-600 mb-8">
AllYouCanGET may, without notice to you, at any time, revise these Terms
of Use and any other information contained in this Web site.
AllYouCanGET may also make improvements or changes in the products,
services, or programs described in this site at any time without notice.
</p>
<h3 class="text-xl font-bold mb-3"><strong>General</strong></h3>
<p class="text-lg text-gray-600 mb-8">
This Web site contains proprietary notices and copyright information,
the terms of which must be observed and followed. Please see the tab
entitled “Copyright and trademark information” for related information.
</p>
<p class="text-lg text-gray-600 mb-8">
AllYouCanGET grants you a non-exclusive, non-transferable, limited
permission to access and display the Web pages within this site as a
customer or potential customer of AllYouCanGET provided you comply with
these Terms of Use, and all copyright, trademark, and other proprietary
notices remain intact. You may only use a crawler to crawl this Web site
as permitted by this Web sites robots.txt protocol, and AllYouCanGET
may block any crawlers in its sole discretion. The use authorized under
this agreement is non-commercial in nature (e.g., you may not sell the
content you access on or through this Web site.) All other use of this
site is prohibited.
</p>
<p class="text-lg text-gray-600 mb-8">
Except for the limited permission in the preceding paragraph,
AllYouCanGET does not grant you any express or implied rights or
licenses under any patents, trademarks, copyrights, or other proprietary
or intellectual property rights. You may not mirror any of the content
from this site on another Web site or in any other media. Any software
and other materials that are made available for downloading, access, or
other use from this site with their own license terms will be governed
by such terms, conditions, and notices. Your failure to comply with such
terms or any of the terms on this site will result in automatic
termination of any rights granted to you, without prior notice, and you
must immediately destroy all copies of downloaded materials in your
possession, custody or control.
</p>
<h3 class="text-xl font-bold mb-3"><strong>Disclaimer</strong></h3>
<p class="text-lg text-gray-600 mb-8">
From time to time, this Web site may contain technical inaccuracies or
typographical errors, and we do not warrant the accuracy of any posted
information. Please confirm you are using the most up-to-date pages on
this Web site, and confirm the accuracy and completeness of information
before using it to make decisions relating to services, products, or
other matters described in this Web site.
</p>
<p class="text-lg text-gray-600 mb-8">
If any term in this Terms of Use is found by competent judicial
authority to be unenforceable in any respect, the validity of the
remainder of this Terms of Use will be unaffected, provided that such
unenforceability does not materially affect the parties rights under
this Terms of Use.
</p>
<h3 class="text-xl font-bold mb-3">
<strong>Forward-looking and cautionary statements</strong>
</h3>
<p class="text-lg text-gray-600 mb-8">
Except for historical information and discussions, statements set forth
throughout this web site may constitute forward-looking statements
within the meaning of the Private Securities Litigation Reform Act of
1995 or other applicable laws. These statements involve a number of
risks, uncertainties, and other factors that could cause actual results
to differ materially, as discussed in the company&#8217;s filings with
the U.S. Securities and Exchange Commission. See the “SEC filings” tab
under “Investor relations” on this Web site for copies of such filings.
</p>
<h3 class="text-xl font-bold mb-3">
<strong>Confidential information</strong>
</h3>
<p class="text-lg text-gray-600 mb-8">
AllYouCanGET does not want to receive confidential or proprietary
information from you through our Web site. Please note that any
information or material sent to AllYouCanGET will be deemed NOT to be
confidential. By sending AllYouCanGET any information or material, you
grant AllYouCanGET an unrestricted, irrevocable license to copy,
reproduce, publish, upload, post, transmit, distribute, publicly
display, perform, modify, create derivative works from, and otherwise
freely use, those materials or information. You also agree that
AllYouCanGET is free to use any ideas, concepts, know-how, or techniques
that you send us for any purpose. However, we will not release your name
or otherwise publicize the fact that you submitted materials or other
information to us unless: (a) we obtain your permission to use your
name; or (b) we first notify you that the materials or other information
you submit to a particular part of this site will be published or
otherwise used with your name on it; or (c) we are required to do so by
law. Personally-identifiable information that you submit to AllYouCanGET
for the purpose of receiving products or services will be handled in
accordance with our privacy policies. Please see the tab entitled
“Privacy” for information regarding AllYouCanGETs privacy policies.
</p>
<h3 class="text-xl font-bold mb-3">
<strong>U.S. government restricted rights</strong>
</h3>
<p class="text-lg text-gray-600 mb-8">
AllYouCanGET provides the software downloaded from this Web site to U.S.
Government users with “RESTRICTED RIGHTS.&#8221; Use, reproduction, or
disclosure is subject to the restrictions set forth in AllYouCanGETs
GSA ADP Schedule contract.
</p>
<h3 class="text-xl font-bold mb-3">
<strong>Global availability</strong>
</h3>
<p class="text-lg text-gray-600 mb-8">
Information AllYouCanGET publishes on the Internet may contain
references or cross references to AllYouCanGET products, programs and
services that are not announced or available in your country. Such
references do not imply that AllYouCanGET intends to announce or make
available such products, programs, or services in your country. Please
consult your local AllYouCanGET business contact for information
regarding the products, programs, and services that may be available to
you.
</p>
<h3 class="text-xl font-bold mb-3">
<strong>Business relationships</strong>
</h3>
<p class="text-lg text-gray-600 mb-8">
This Web site may provide links or references to non-AllYouCanGET Web
sites and resources. AllYouCanGET makes no representations, warranties,
or other commitments or endorsements whatsoever about any
non-AllYouCanGET Web sites or third-party resources (including any
Lenovo Web site) that may be referenced, accessible from, or linked to
any AllYouCanGET site. In addition, AllYouCanGET is not a party to or
responsible for any transactions you may enter into with third parties,
even if you learn of such parties (or use a link to such parties) from
an AllYouCanGET site. When you access a non-AllYouCanGET Web site, even
one that may contain the AllYouCanGET-logo, please understand that it is
independent from AllYouCanGET, and that AllYouCanGET does not control
the content on that Web site. It is up to you to take precautions to
protect yourself from viruses, worms, Trojan horses, and other
potentially destructive programs, and to protect your information.
</p>
<h3 class="text-xl font-bold mb-3">
<strong>Linking to this site</strong>
</h3>
<p class="text-lg text-gray-600 mb-8">
AllYouCanGET consents only to links to this Web site in which the link
and the pages that are activated by the link do not: (a) create frames
around any page on this Web site or use other techniques that alter in
any way the visual presentation or appearance of any content within this
site; (b) misrepresent your relationship with AllYouCanGET; (c) imply
that AllYouCanGET approves or endorses you, your Web site, or your
service or product offerings; and (d) present false or misleading
impressions about AllYouCanGET or otherwise damage the goodwill
associated with the AllYouCanGET name or trademarks. As a further
condition to being permitted to link to this site, you agree that
AllYouCanGET may at any time, in its sole discretion, terminate
permission to link to this Web site. In such event, you agree to
immediately remove all links to this Web site and to cease any related
use of AllYouCanGET trademarks.
</p>
<h3 class="text-xl font-bold mb-3">
<strong>DISCLAIMER OF WARRANTY</strong>
</h3>
<p class="text-lg text-gray-600 mb-8">
USE OF THIS SITE IS AT YOUR SOLE RISK. ALL MATERIALS, INFORMATION,
PRODUCTS, SOFTWARE, PROGRAMS, AND SERVICES ARE PROVIDED &#8220;AS
IS,&#8221; WITH NO WARRANTIES OR GUARANTEES WHATSOEVER. AllYouCanGET
EXPRESSLY DISCLAIMS TO THE FULLEST EXTENT PERMITTED BY LAW ALL EXPRESS,
IMPLIED, STATUTORY, AND OTHER WARRANTIES, GUARANTEES, OR
REPRESENTATIONS, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT
OF PROPRIETARY AND INTELLECTUAL PROPERTY RIGHTS. WITHOUT LIMITATION,
AllYouCanGET MAKES NO WARRANTY OR GUARANTEE THAT THIS WEB SITE WILL BE
UNINTERRUPTED, TIMELY, SECURE, OR ERROR-FREE.
</p>
<p class="text-lg text-gray-600 mb-8">
YOU UNDERSTAND AND AGREE THAT IF YOU DOWNLOAD OR OTHERWISE OBTAIN
MATERIALS, INFORMATION, PRODUCTS, SOFTWARE, PROGRAMS, OR SERVICES FROM
THIS WEB SITE, YOU DO SO AT YOUR OWN DISCRETION AND RISK AND THAT YOU
WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGES THAT MAY RESULT, INCLUDING
LOSS OF DATA OR DAMAGE TO YOUR COMPUTER SYSTEM. SOME JURISDICTIONS DO
NOT ALLOW THE EXCLUSION OF WARRANTIES, SO THE ABOVE EXCLUSIONS MAY NOT
APPLY TO YOU.
</p>
<h3 class="text-xl font-bold mb-3">
<strong>LIMITATION OF LIABILITY</strong>
</h3>
<p class="text-lg text-gray-600 mb-8">
TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
AllYouCanGET BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY TYPE
WHATSOEVER RELATED TO OR ARISING FROM THIS WEB SITE OR ANY USE OF THIS
WEB SITE, OR OF ANY SITE OR RESOURCE LINKED TO, REFERENCED, OR ACCESSED
THROUGH THIS WEB SITE, OR FOR THE USE OR DOWNLOADING OF, OR ACCESS TO,
ANY MATERIALS, INFORMATION, PRODUCTS, OR SERVICES, INCLUDING, WITHOUT
LIMITATION, ANY LOST PROFITS, BUSINESS INTERRUPTION, LOST SAVINGS OR
LOSS OF PROGRAMS OR OTHER DATA, EVEN IF AllYouCanGET IS EXPRESSLY
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THIS EXCLUSION AND WAIVER OF
LIABILITY APPLIES TO ALL CAUSES OF ACTION, WHETHER BASED ON CONTRACT,
WARRANTY, TORT, OR ANY OTHER LEGAL THEORIES.
</p>
</div>
</div>
</div>
{% endblock %}
+204
View File
@@ -0,0 +1,204 @@
{% extends "_base.html" %} {% block content %}
<div class="bg-gray-50 py-12">
<div class="container mx-auto px-6" id="services">
<h2 class="text-2xl md:text-4xl font-bold text-center mb-12">
Streamline operations, optimize performance, and drive innovation with
AllYouCanGET
</h2>
<div class="grid md:grid-cols-3 gap-8">
<a href="services.html">
<div class="bg-white p-6 rounded-lg shadow-lg service-card">
<div class="w-12 h-12 text-blue-600 mb-4">
<img
src="img/it-consulting.svg"
alt="IT Consulting"
class="lucide lucide-shield w-12 h-12 text-blue-600 mb-4"
width="24"
height="24"
/>
</div>
<h3 class="text-xl font-bold mb-3">IT Consulting</h3>
<p class="text-gray-600 mb-4">
Strategic technology solutions to drive your digital transformation
</p>
<ul>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">IT Strategy & Planning</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Technology Assessment</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Enterprise Architecture</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Cybersecurity</span>
</li>
</ul>
</div>
</a>
<a href="services.html">
<div class="bg-white p-6 rounded-lg shadow-lg service-card">
<div class="w-12 h-12 text-blue-600 mb-4">
<img
src="img/management-consulting.svg"
alt="Management Consulting"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
width="24"
height="24"
/>
</div>
<h3 class="text-xl font-bold mb-3">Management Consulting</h3>
<p class="text-gray-600 mb-4">
Optimize operations and accelerate business growth
</p>
<ul>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Strategy Development</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Process Optimization</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Change Management</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Financial Analysis</span>
</li>
</ul>
</div>
</a>
<a href="services.html">
<div class="bg-white p-6 rounded-lg shadow-lg service-card">
<div class="w-12 h-12 text-blue-600 mb-4">
<img
src="img/infrastructure.svg"
alt="Infrastructure Services"
class="lucide lucide-server w-12 h-12 text-blue-600 mb-4"
width="24"
height="24"
/>
</div>
<h3 class="text-xl font-bold mb-3">Infrastructure Services</h3>
<p class="text-gray-600 mb-4">
Build robust foundations for your business success
</p>
<ul>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Cloud Solutions</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Network Design</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">System Integration</span>
</li>
<li class="flex items-center mb-2">
<span class="text-green-500 mr-2"></span>
<span class="text-gray-700">Security Implementation</span>
</li>
</ul>
</div>
</a>
</div>
</div>
</div>
<div class="bg-gray-50 py-16">
<div class="container mx-auto px-6" id="partner">
<h2 class="text-3xl font-bold mb-4">Our Partners</h2>
<div class="items-center justify-center">
<p class="text-xl mb-8">
We collaborate with leading technology providers to deliver the best
solutions for your business.
</p>
<div class="flex items-center justify-center" id="partner-logos">
<img
src="img/ibm.svg"
height="24"
width="24"
alt="IBM"
class="h-16 w-auto"
/>
<img
src="img/microsoft.svg"
height="24"
width="24"
alt="Microsoft"
class="h-16 w-auto"
/>
<img
src="img/aws.svg"
height="24"
width="24"
alt="AWS"
class="h-16 w-auto"
/>
<img
src="img/google.svg"
height="24"
width="24"
alt="Google"
class="h-16 w-auto"
/>
<img
src="img/oracle.svg"
height="24"
width="24"
alt="Oracle"
class="h-16 w-32"
/>
<img
src="img/informatica.svg"
height="24"
width="24"
alt="Informatica"
class="h-16 w-auto"
/>
<img
src="img/sap.svg"
height="24"
width="24"
alt="SAP"
class="h-16 w-auto"
/>
<img
src="img/salesforce.svg"
height="24"
width="24"
alt="Salesforce"
class="h-16 w-auto"
/>
</div>
</div>
</div>
</div>
<div class="bg-blue-600 text-white py-16">
<div class="container mx-auto px-6 text-center">
<h2 class="text-3xl font-bold mb-4">Ready to Transform Your Business?</h2>
<p class="text-xl mb-8">Schedule a free consultation with our experts</p>
<button class="bigbutton">
<a href="mailto:info@allucanget.biz">Contact Us</a>
</button>
</div>
</div>
{% endblock %} {% block scripts %}
<script src="js/partner.js"></script>
<script>
document
.getElementByClass("service-card")
.addEventListener("click", function (e) {
window.location.href = "services.html";
});
</script>
{% endblock %}
+20
View File
@@ -0,0 +1,20 @@
{% extends "_base.html" %} {% block content %}
<!-- Hero Section with Page Title -->
{% include 'components/hero.html' %}
<!-- Sections with Cards -->
{% for section in page.sections %} {% include 'components/section.html' %} {%
endfor %}
<!-- Call to Action -->
<div id="call-to-action" class="bg-blue-600 text-white py-12">
<div id="cta-container" class="container">
<h2>Ready to Get Started?</h2>
<p>
Contact us today to learn more about how we can help you.
</p>
<iframe id="contact-form" src="http://contact.allucanget.biz/embed/contact" width="600" height="600" frameborder="0" allowfullscreen></iframe>
</div>
</div>
<script src="js/contact.js"></script>
{% endblock %}
+208
View File
@@ -0,0 +1,208 @@
{% extends "_base.html" %} {% block content %}
<div class="bg-gray-50 py-12">
<div class="container mx-auto px-6">
<h1 class="text-4xl font-bold text-center mb-4">Our Services</h1>
<p class="text-xl text-gray-600 text-center mb-12">
Comprehensive solutions to transform your business
</p>
<div class="mb-16">
<div class="flex items-center mb-8">
<img
src="img/it-consulting.svg"
height="24"
width="24"
alt="IT Consulting"
class="lucide lucide-shield w-8 h-8 text-blue-600 mr-4"
/>
<h2 class="text-3xl font-bold">IT Consulting</h2>
</div>
<p class="text-lg text-gray-600 mb-8">
Comprehensive IT solutions to drive digital transformation and optimize
your technology infrastructure.
</p>
<div class="grid md:grid-cols-3 gap-8">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/management-consulting.svg"
height="24"
width="24"
alt="IT Strategy & Planning"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">IT Strategy &amp; Planning</h3>
<p class="text-gray-600">
Develop technology roadmaps aligned with business objectives
</p>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/infrastructure.svg"
height="24"
width="24"
alt="Infrastructure Management"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">Infrastructure Management</h3>
<p class="text-gray-600">
Design and implement robust IT infrastructure solutions
</p>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/security.svg"
height="24"
width="24"
alt="Cybersecurity"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">Cybersecurity</h3>
<p class="text-gray-600">
Protect your assets with advanced security measures
</p>
</div>
</div>
</div>
<div class="mb-16">
<div class="flex items-center mb-8">
<img
src="img/barchart.svg"
height="24"
width="24"
alt="Management Consulting"
class="lucide lucide-shield w-8 h-8 text-blue-600 mr-4"
/>
<h2 class="text-3xl font-bold">Management Consulting</h2>
</div>
<p class="text-lg text-gray-600 mb-8">
Strategic business solutions to improve efficiency and drive growth.
</p>
<div class="grid md:grid-cols-3 gap-8">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/management-consulting.svg"
height="24"
width="24"
alt="Process Optimization"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">Process Optimization</h3>
<p class="text-gray-600">
Streamline operations and improve business efficiency
</p>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/people.svg"
height="24"
width="24"
alt="Change Management"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">Change Management</h3>
<p class="text-gray-600">
Guide organizational transformation effectively
</p>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/barchart.svg"
height="24"
width="24"
alt="Financial Analysis"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">Financial Analysis</h3>
<p class="text-gray-600">
Data-driven financial planning and optimization
</p>
</div>
</div>
</div>
<div class="mb-16">
<div class="flex items-center mb-8">
<img
src="img/infrastructure.svg"
height="24"
width="24"
alt="Infrastructure Services"
class="lucide lucide-shield w-8 h-8 text-blue-600 mr-4"
/>
<h2 class="text-3xl font-bold">Infrastructure Services</h2>
</div>
<p class="text-lg text-gray-600 mb-8">
Build robust foundations for your business success
</p>
<div class="grid md:grid-cols-3 gap-8">
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/cloud.svg"
height="24"
width="24"
alt="Cloud Solutions"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">Cloud Solutions</h3>
<p class="text-gray-600">
Leverage cloud technology for scalable solutions
</p>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/network.svg"
height="24"
width="24"
alt="Network Design"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">Network Design</h3>
<p class="text-gray-600">
Create secure and efficient network architectures
</p>
</div>
<div
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
>
<img
src="img/system-integration.svg"
height="24"
width="24"
alt="System Integration"
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
/>
<h3 class="text-xl font-bold mb-3">System Integration</h3>
<p class="text-gray-600">
Seamlessly integrate systems for optimal performance
</p>
</div>
</div>
</div>
</div>
</div>
<div class="bg-blue-600 text-white py-12">
<div class="container mx-auto px-6 text-center">
<h2 class="text-3xl font-bold mb-4">Need Customized Solutions?</h2>
<p class="text-xl mb-6">
Let's discuss how we can help transform your business
</p>
<button class="bigbutton">
<a href="mailto:info@allucanget.biz">Schedule Consultation</a>
</button>
</div>
</div>
{% endblock %}
+16
View File
@@ -0,0 +1,16 @@
from lib.markdown_parser import markdown_to_html_lines
def test_external_link_gets_target_rel():
md = '[external](https://example.com)'
html = markdown_to_html_lines(md)
assert 'href="https://example.com"' in html
assert 'target="_blank"' in html
assert 'rel="noopener noreferrer"' in html
def test_internal_link_no_target():
md = '[internal](/about)'
html = markdown_to_html_lines(md)
assert 'href="/about"' in html
assert 'target=' not in html
+133
View File
@@ -0,0 +1,133 @@
import textwrap
from lib import markdown_parser
def make_empty_state():
return {
'page': {'title': None, 'sections': []},
'current_section': None,
'current_card': None,
'current_detail': None,
'content_buffer': [],
'detail_buffer': [],
}
def test_flush_detail_buffer():
state = make_empty_state()
state['current_detail'] = {'title': 'D', 'content': ''}
state['detail_buffer'] = ['Line 1', 'Line 2']
markdown_parser.flush_detail_buffer(state)
assert 'Line 1' in state['current_detail']['content']
assert state['detail_buffer'] == []
def test_flush_content_buffer_to_card():
state = make_empty_state()
state['current_card'] = {'title': 'C', 'content': ''}
state['content_buffer'] = ['para 1', 'para 2']
markdown_parser.flush_content_buffer_to_card(state)
assert 'para 1' in state['current_card']['content']
def test_flush_content_buffer_to_section():
state = make_empty_state()
state['current_section'] = {'title': 'S', 'content': '', 'cards': []}
state['content_buffer'] = ['a', 'b']
markdown_parser.flush_content_buffer_to_section(state)
assert 'a' in state['current_section']['content']
def test_start_section_and_card_and_detail_and_process_line():
state = make_empty_state()
# start a section
markdown_parser.start_section('Sec1', state)
assert state['current_section']['title'] == 'Sec1'
assert state['page']['sections'][0]['title'] == 'Sec1'
# start a card
markdown_parser.start_card('Card1', state)
assert state['current_card']['title'] == 'Card1'
assert state['page']['sections'][0]['cards'][0]['title'] == 'Card1'
# start a detail
markdown_parser.start_detail('Det1', state)
assert state['current_detail']['title'] == 'Det1'
# process a normal content line into detail_buffer
markdown_parser.process_line_with_state('Detail line 1', state)
assert 'Detail line 1' in state['detail_buffer'][0]
# process an H3 to start a new card
markdown_parser.process_line_with_state('### NewCard', state)
assert state['current_card']['title'] == 'NewCard'
# process an H2 to start a new section
markdown_parser.process_line_with_state('## NewSection', state)
assert state['current_section']['title'] == 'NewSection'
def test_start_card_without_section_is_noop():
state = make_empty_state()
markdown_parser.start_card('Orphan', state)
assert state['current_card'] is None
assert state['page']['sections'] == []
def test_start_detail_without_card_is_noop():
state = make_empty_state()
markdown_parser.start_detail('Detail', state)
assert state['current_detail'] is None
assert state['detail_buffer'] == []
def test_process_h4_without_card_is_treated_as_content():
state = make_empty_state()
markdown_parser.process_line_with_state('#### Heading without card', state)
assert '#### Heading without card' in state['content_buffer']
def test_process_new_h1_flushes_section_content():
state = make_empty_state()
markdown_parser.start_section('First', state)
state['content_buffer'].append('Paragraph text')
markdown_parser.process_line_with_state('# New Page', state)
assert 'Paragraph text' in state['page']['sections'][0]['content']
assert state['page']['title'] == 'New Page'
def test_build_component_structure_matches_integration():
md = textwrap.dedent("""
# Title
## Section A
### Card A
Intro A
#### Detail X
Line X
""")
page = markdown_parser.build_component_structure(md, 'f.md')
assert page['title'] == 'Title'
assert page['sections'][0]['title'] == 'Section A'
card = page['sections'][0]['cards'][0]
assert card['title'] == 'Card A'
assert 'Intro A' in card['content']
assert 'Detail X' in card['details'][0]['title']
+351
View File
@@ -0,0 +1,351 @@
import textwrap
import pytest
from bs4 import BeautifulSoup
from markdown import Markdown
from xml.etree.ElementTree import Element, SubElement
from lib.markdown_parser import (
HeadingCollector,
HeadingExtension,
build_component_structure,
markdown_to_html_lines,
parse_markdown_file,
)
def test_h4_creates_card_details():
md = textwrap.dedent("""
# Page Title
## Section One
### Card One
Card intro paragraph.
#### Detail A
Detail content line 1.
- item 1
- item 2
#### Detail B
Another detail paragraph with [a link](https://example.com).
""")
page = build_component_structure(md, "test.md")
assert page['title'] == 'Page Title'
assert len(page['sections']) == 1
section = page['sections'][0]
assert section['title'] == 'Section One'
assert len(section['cards']) == 1
card = section['cards'][0]
assert card['title'] == 'Card One'
# content should include the intro paragraph converted to HTML
assert 'Card intro paragraph' in card['content']
# details should be present
assert 'details' in card
assert len(card['details']) == 2
assert card['details'][0]['title'] == 'Detail A'
assert 'item 1' in card['details'][0]['content']
assert card['details'][1]['title'] == 'Detail B'
assert 'https://example.com' in card['details'][1]['content']
def test_section_content_preserves_lists_before_first_card():
md = textwrap.dedent("""
# Title
## Section One
- Item A
- Item B
### Card Title
Card body
""")
page = build_component_structure(md, "test.md")
section = page['sections'][0]
assert '<ul>' in section['content']
assert '<li>Item A</li>' in section['content']
assert section['cards'][0]['title'] == 'Card Title'
def test_card_content_keeps_lists_when_section_changes():
md = textwrap.dedent("""
# Title
## Section One
### Card One
- First
- Second
## Section Two
Details
""")
page = build_component_structure(md, "test.md")
first_section = page['sections'][0]
card = first_section['cards'][0]
assert '<ul>' in card['content']
assert '<li>First</li>' in card['content']
def test_card_body_renders_list_items():
md = textwrap.dedent("""
# Title
## Section
### Card
- Alpha
- Beta
- Gamma
""")
page = build_component_structure(md, "test.md")
card = page['sections'][0]['cards'][0]
assert '<ul>' in card['content']
assert '<li>Alpha</li>' in card['content']
assert '<li>Gamma</li>' in card['content']
def test_external_links_add_target_attributes():
md = textwrap.dedent("""
# Title
## Section
Visit [Example](https://example.com) now.
""")
page = build_component_structure(md, "test.md")
section_html = page['sections'][0]['content']
soup = BeautifulSoup(section_html, 'html.parser')
anchor = soup.find('a')
assert anchor is not None
assert anchor['href'] == 'https://example.com'
assert anchor.get('target') == '_blank'
assert anchor.get('rel') == ['noopener', 'noreferrer']
def test_unsafe_links_are_neutralized():
md = textwrap.dedent("""
# Title
## Section
[Bad](javascript:alert('xss'))
""")
page = build_component_structure(md, "test.md")
section_html = page['sections'][0]['content']
soup = BeautifulSoup(section_html, 'html.parser')
anchor = soup.find('a')
assert anchor is not None
assert anchor['href'] == '#unsafe'
assert 'target' not in anchor.attrs
assert 'rel' not in anchor.attrs
def test_index_page_sections_and_headings_extracted():
text = """
# Title
Main intro paragraph.
## Section 1
Section 1 intro.
- List item 1 a
- List item 1 b
## Section 2
Section 2 intro.
- List item 2 a
- List item 2 b
"""
md = Markdown(extensions=[HeadingExtension()])
md.convert(text)
collector = md.treeprocessors['heading_collector']
headings = [h for h in getattr(collector, 'headings', []) if 'level' in h]
assert headings[0]['level'] == 1
assert headings[0]['text'] == 'Title'
assert headings[1]['level'] == 2
assert headings[1]['text'] == 'Section 1'
assert headings[2]['level'] == 2
assert headings[2]['text'] == 'Section 2'
def test_index_page_main_intro_extracted():
text = """
# Title
This is the main introduction paragraph for the index page.
## Section 1
Section content.
"""
md = Markdown(extensions=[HeadingExtension()])
md.convert(text)
collector = md.treeprocessors['heading_collector']
main_intro = getattr(collector, 'main_intro', '')
assert 'This is the main introduction paragraph for the index page.' in main_intro
def test_heading_extension_collects_headings_and_lists():
md = Markdown(extensions=[HeadingExtension()])
md.convert(textwrap.dedent("""
# Title
## Section with **Bold** and [Link](#target)
- Item A
- [Item B](#b) and more
"""))
collector = md.treeprocessors['heading_collector']
headings = getattr(collector, 'headings', [])
assert headings[0]['level'] == 1
assert headings[0]['text'] == 'Title'
assert headings[1]['level'] == 2
assert headings[1]['text'] == 'Section with Bold and Link'
list_entry = next(entry for entry in headings if entry.get('type') == 'ul')
assert list_entry['items'][0] == 'Item A'
assert 'Item B' in list_entry['items'][1]
def test_heading_collector_extract_text_handles_children():
collector = HeadingCollector(Markdown())
parent = Element('p')
child = SubElement(parent, 'strong')
child.text = 'Bold'
child.tail = ' tail'
nested = SubElement(child, 'em')
nested.text = 'inner'
text = collector._extract_text(parent)
assert 'Bold' in text
assert 'tail' in text
assert 'inner' in text
collector.headings = []
collector._process_element(parent)
assert collector.headings == []
def test_parse_markdown_file_sets_title_from_filename(tmp_path):
file_path = tmp_path / 'sample_page.md'
file_path.write_text('Just text without heading', encoding='utf-8')
page = parse_markdown_file(str(file_path))
assert page['title'] == 'Sample Page'
def test_parse_markdown_file_missing(tmp_path):
missing = tmp_path / 'not_there.md'
with pytest.raises(FileNotFoundError):
parse_markdown_file(str(missing))
def test_markdown_to_html_lines_handles_empty_and_blank_links():
assert markdown_to_html_lines('') == ''
html = markdown_to_html_lines(
'Before [Empty]() and [External](https://example.com)')
soup = BeautifulSoup(html, 'html.parser')
anchors = soup.find_all('a')
assert anchors[0]['href'] == ''
assert 'target' not in anchors[0].attrs
assert anchors[1]['target'] == '_blank'
def test_markdown_images_normalize_src_and_alt():
html = markdown_to_html_lines(
'![IT Consulting](assets/icons/it-consulting.svg)')
soup = BeautifulSoup(html, 'html.parser')
image = soup.find('img')
assert image is not None
assert image['src'] == 'img/it-consulting.svg'
assert image['alt'] == 'IT Consulting'
def test_markdown_images_add_alt_fallback():
html = markdown_to_html_lines('![](logo.svg)')
soup = BeautifulSoup(html, 'html.parser')
image = soup.find('img')
assert image is not None
assert image['src'] == 'img/logo.svg'
assert image['alt'] == 'logo'
def test_markdown_heading_with_inline_image_preserves_image():
html = markdown_to_html_lines('## Heading ![Graphic](img/graphic.svg)')
soup = BeautifulSoup(html, 'html.parser')
heading = soup.find('h2')
image = heading.find('img') if heading else None
assert heading is not None
assert heading.get_text(strip=True) == 'Heading'
assert image is not None
assert image['src'] == 'img/graphic.svg'
assert image['alt'] == 'Graphic'
def test_build_component_structure_converts_section_images():
md = textwrap.dedent("""
# Title
## Section With Visual
Intro text before image.
![Vision Diagram](assets/diagrams/vision.png)
""")
page = build_component_structure(md, "section.md")
section_html = page['sections'][0]['content']
soup = BeautifulSoup(section_html, 'html.parser')
image = soup.find('img')
assert image is not None
assert image['src'] == 'img/vision.png'
assert image['alt'] == 'Vision Diagram'
def test_build_component_structure_preserves_external_image_src():
md = textwrap.dedent("""
# Title
## Section
![Remote Logo](https://cdn.example.com/logo.svg)
""")
page = build_component_structure(md, "external.md")
section_html = page['sections'][0]['content']
soup = BeautifulSoup(section_html, 'html.parser')
image = soup.find('img')
assert image is not None
assert image['src'] == 'https://cdn.example.com/logo.svg'
assert image['alt'] == 'Remote Logo'
+15
View File
@@ -0,0 +1,15 @@
from lib.markdown_parser import markdown_to_html_lines
def test_javascript_link_neutralized():
md = '[bad](javascript:alert(1))'
html = markdown_to_html_lines(md)
assert 'href="#unsafe"' in html
assert 'javascript:' not in html
def test_data_link_neutralized():
md = '[bad](data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)'
html = markdown_to_html_lines(md)
assert 'href="#unsafe"' in html
assert 'data:' not in html
+101
View File
@@ -0,0 +1,101 @@
import os
from pathlib import Path
import pytest
from lib.utils import (
get_template_files,
render_template,
set_active_page_by_url,
minify_html,
js_minifier,
)
def test_get_template_files_filters_partials_and_non_html(
tmp_path: Path) -> None:
template_dir = tmp_path / "templates"
template_dir.mkdir()
(template_dir / "page.html").write_text("<h1>Page</h1>", encoding="utf-8")
(template_dir / "_partial.html").write_text("<p>Ignore</p>", encoding="utf-8")
(template_dir / "notes.txt").write_text("ignore", encoding="utf-8")
result = get_template_files(str(template_dir))
assert sorted(result) == ["page.html"]
def test_render_template_renders_with_context(tmp_path: Path) -> None:
template_dir = tmp_path / "templates"
template_dir.mkdir()
(template_dir /
"hello.html").write_text("Hello {{ name }}!", encoding="utf-8")
rendered = render_template(
"hello.html", {
"name": "World"}, template_dir=str(template_dir))
assert rendered == "Hello World!"
def test_set_active_page_by_url_marks_only_requested_page_active() -> None:
nav = {
"index.html": {"active": False},
"about.html": {"active": False},
}
set_active_page_by_url(nav, "about.html")
assert nav["about.html"]["active"] is True
assert nav["index.html"]["active"] is False
def test_minify_html_removes_comments_and_extra_whitespace() -> None:
html = "<div> Text </div> <!-- comment -->\n"
minified = minify_html(html)
assert minified == "<div> Text</div>"
def test_js_minifier_strips_comments_and_rewrites_files(
tmp_path: Path) -> None:
output_dir = tmp_path / "site"
js_dir = output_dir / "js"
js_dir.mkdir(parents=True)
js_path = js_dir / "app.js"
js_path.write_text(
"// comment\nvar x = 1; \n/* block */\nfunction test() { console.log(x); }\n",
encoding="utf-8",
)
# Ensure non-JS files are ignored
(js_dir / "readme.txt").write_text("skip", encoding="utf-8")
js_minifier(str(output_dir))
content = js_path.read_text(encoding="utf-8")
assert content == "var x = 1; function test() { console.log(x); }"
assert os.path.exists(js_dir / "readme.txt")
@pytest.mark.parametrize(
"initial, expected",
[
({"a.js": "const a = 1;"}, "const a = 1;"),
],
)
def test_js_minifier_handles_multiple_invocations(
tmp_path: Path, initial, expected) -> None:
output_dir = tmp_path / "dist"
js_dir = output_dir / "js"
js_dir.mkdir(parents=True)
for filename, content in initial.items():
(js_dir / filename).write_text(content, encoding="utf-8")
js_minifier(str(output_dir))
js_minifier(str(output_dir))
for filename in initial:
content = (js_dir / filename).read_text(encoding="utf-8")
assert content == expected