diff --git a/.idea/go.imports.xml b/.idea/go.imports.xml new file mode 100644 index 0000000..d7202f0 --- /dev/null +++ b/.idea/go.imports.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/assets/images/blog/brainminder.png b/assets/images/blog/brainminder.png new file mode 100644 index 0000000..490663b Binary files /dev/null and b/assets/images/blog/brainminder.png differ diff --git a/content/en/blog/brainminder-intro.md b/content/en/blog/brainminder-intro.md index 4fde7cd..94a362d 100644 --- a/content/en/blog/brainminder-intro.md +++ b/content/en/blog/brainminder-intro.md @@ -14,4 +14,5 @@ Items are shared with external users via a pre-authorized link and (optionally) It permits organizing personal knowledge in different types of items that can be created to one’s preference. Every item type has some basic fields to collect the information (like title, summary, description) but other fields can be created as preferred. -**BrainMinder** is already usable and very useful but is currently under heavy development and new features are added frequently. +**BrainMinder** has been created with [Golang](https://go.dev) programming language, use [SQLite](https://sqlite.org) as database and the Javascript tool [Unpoly](https://unpoly.com). +The software is already usable and very useful but is currently under heavy development and new features are added frequently. diff --git a/content/it/blog/android-communication-apps.md b/content/it/blog/android-communication-apps.md new file mode 100644 index 0000000..738e076 --- /dev/null +++ b/content/it/blog/android-communication-apps.md @@ -0,0 +1,17 @@ ++++ +tags = ['Software development', 'Web application', 'PWA'] +categories= ['Projects'] +images = ['images/blog/brainminder.png'] +services = ['web-application-development', 'custom-cms'] +title = 'BrainMinder - second brain web application' +date = '2025-10-30' +lastmod = '2025-10-30' +published = false + ++++ +Testo + + +Conversations +DeltaChat +Signal -> Molly diff --git a/content/it/blog/android-opensource-stores.md b/content/it/blog/android-opensource-stores.md new file mode 100644 index 0000000..18cc527 --- /dev/null +++ b/content/it/blog/android-opensource-stores.md @@ -0,0 +1,15 @@ ++++ +tags = ['Software development', 'Web application', 'PWA'] +categories= ['Projects'] +images = ['images/blog/brainminder.png'] +services = ['web-application-development', 'custom-cms'] +title = 'BrainMinder - second brain web application' +date = '2025-10-30' +lastmod = '2025-10-30' +published = false + ++++ +Testo + + +F-Droid \ No newline at end of file diff --git a/content/it/blog/brainminder-intro.md b/content/it/blog/brainminder-intro.md index 9b0d69a..ba2d6d0 100644 --- a/content/it/blog/brainminder-intro.md +++ b/content/it/blog/brainminder-intro.md @@ -16,4 +16,6 @@ I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizz Permette di suddividere il proprio archivio di conoscenze in tipi diversi di articoli che possono essere creati in base alle necessità. Ogni tipo di articolo ha alcuni tipi di campi predefiniti per raccogliere le informazioni (come titolo, sommario, descrizione) ma altri campi possono essere aggiunti secondo le proprie preferenze. -**BrainMinder** è già utilizzabile e molto utile, ma è attualmente in fase di intenso sviluppo e nuove funzionalità vengono aggiunte frequentemente. +**BrainMinder** è stato creato tramite il linguaggio [Golang](https://go.dev), utilizza il database [SQLite](https://sqlite.org) e il tool Javascript [Unpoly](https://unpoly.com). +Il programma è già utilizzabile e molto utile, ma è attualmente in fase di intenso sviluppo e nuove funzionalità vengono aggiunte frequentemente. + diff --git a/content/it/blog/from-windows-to-linux.md b/content/it/blog/from-windows-to-linux.md new file mode 100644 index 0000000..08e3425 --- /dev/null +++ b/content/it/blog/from-windows-to-linux.md @@ -0,0 +1,15 @@ ++++ +tags = ['Software development', 'Web application', 'PWA'] +categories= ['Projects'] +images = ['images/blog/brainminder.png'] +services = ['web-application-development', 'custom-cms'] +title = 'BrainMinder - second brain web application' +date = '2025-10-30' +lastmod = '2025-10-30' +published = false + ++++ +Testo + + +Alternative software, hardware usato diff --git a/content/it/blog/office-tools-privacy.md b/content/it/blog/office-tools-privacy.md new file mode 100644 index 0000000..2af9a6c --- /dev/null +++ b/content/it/blog/office-tools-privacy.md @@ -0,0 +1,17 @@ ++++ +tags = ['Software development', 'Web application', 'PWA'] +categories= ['Projects'] +images = ['images/blog/brainminder.png'] +services = ['web-application-development', 'custom-cms'] +title = 'BrainMinder - second brain web application' +date = '2025-10-30' +lastmod = '2025-10-30' +published = false ++++ +Testo + + +LibreOffice +Thunderbird + OpenGPG +LibreWolf, Waterfox, Brave +Mullvad Browser diff --git a/content/it/blog/vaultwarden-password-manager.md b/content/it/blog/vaultwarden-password-manager.md new file mode 100644 index 0000000..2af9a6c --- /dev/null +++ b/content/it/blog/vaultwarden-password-manager.md @@ -0,0 +1,17 @@ ++++ +tags = ['Software development', 'Web application', 'PWA'] +categories= ['Projects'] +images = ['images/blog/brainminder.png'] +services = ['web-application-development', 'custom-cms'] +title = 'BrainMinder - second brain web application' +date = '2025-10-30' +lastmod = '2025-10-30' +published = false ++++ +Testo + + +LibreOffice +Thunderbird + OpenGPG +LibreWolf, Waterfox, Brave +Mullvad Browser diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..2df2903 --- /dev/null +++ b/public/404.html @@ -0,0 +1,11 @@ +SpeedTech | 404 Page not found +

\ No newline at end of file diff --git a/public/blog/agiati-web-applications/index.html b/public/blog/agiati-web-applications/index.html new file mode 100644 index 0000000..6c22696 --- /dev/null +++ b/public/blog/agiati-web-applications/index.html @@ -0,0 +1,43 @@ +SpeedTech | Blog - Applicazioni web per contabilità, gestione soci e CMS personalizzato +

Blog

Applicazioni web per contabilità, gestione soci e CMS personalizzato

Cliente : Accademia degli Agiati (Rovereto - IT)

Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap

  • Database design
  • Logic and structure study
  • Applications implementation and development
  • Support and maintenance
  • CMS for the institutional website
Data pubblicazione : 2019-05-04 | Ultima modifica : 2019-05-04

Progetti | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/blog/altevie-geomapping/index.html b/public/blog/altevie-geomapping/index.html new file mode 100644 index 0000000..1821b5c --- /dev/null +++ b/public/blog/altevie-geomapping/index.html @@ -0,0 +1,43 @@ +SpeedTech | Blog - Applicazione per il tracciamento di Skibus con GPS +

Blog

Applicazione per il tracciamento di Skibus con GPS

Cliente : Altevie (Trento - IT)

Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps

  • Progettazione e sviluppo dell’applicazione
  • Installazione e configurazione del database e del server Linux
  • Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari
  • Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobus
Data pubblicazione : 2015-01-31 | Ultima modifica : 2015-01-31

Progetti | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/blog/amorcosmetics-ecommerce/index.html b/public/blog/amorcosmetics-ecommerce/index.html new file mode 100644 index 0000000..a8d20e9 --- /dev/null +++ b/public/blog/amorcosmetics-ecommerce/index.html @@ -0,0 +1,44 @@ +SpeedTech | Blog - Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezza +

Blog

Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezza

Cliente : Amor Cosmetics (Trento - IT)

Sito e-commerce website integrato con pagamenti tramite carta di credito

  • Migrazione sito web e aggiornamento
  • Riconfigurazione e revisione grafica
  • Servizio di hosting
Data pubblicazione : 2021-05-27 | Ultima modifica : 2021-05-27

Progetti | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/blog/amore-ecommerce/index.html b/public/blog/amore-ecommerce/index.html new file mode 100644 index 0000000..2f47382 --- /dev/null +++ b/public/blog/amore-ecommerce/index.html @@ -0,0 +1,45 @@ +SpeedTech | Blog - Installazione e personalizzazione sito e-commerce +

Blog

Installazione e personalizzazione sito e-commerce

Cliente : Ditta Amore (Rovereto - IT)

Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione

  • Installazione e configurazione della piattaforma di e-commerce OpenCart
  • Selezione, installazione e personalizzazione dei moduli
  • Integrazione del sistema di pagamento tramite carta di credito Stripe
  • Sviluppo del modulo di calcolo personalizzato delle spese di spedizione
  • Sviluppo di funzionalità personalizzate
Data pubblicazione : 2012-08-02 | Ultima modifica : 2012-08-02

Progetti | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/blog/automazione-casa-con-home-assistant/index.html b/public/blog/automazione-casa-con-home-assistant/index.html new file mode 100644 index 0000000..41e847a --- /dev/null +++ b/public/blog/automazione-casa-con-home-assistant/index.html @@ -0,0 +1,45 @@ +SpeedTech | Blog - Automazione casa con Home Assistant +

Blog

Automazione casa con Home Assistant

Home Assistant è uno strumento interamente open source per la domotica sia di ambienti residenziali che lavorativi.

Si compone di un server che può essere installato anche su una SBC (Single Board Computer) come RaspberryPi +in grado di comunicare con molti tipi divresi di dispositivi di diverse marche e con svariati protocolli di rete : Tasmota, Shelly, Sonoff, MQTT, Zigbee.

Le possibilità sono virtualmente infinite per automatizzare il comportamento dei diversi dispositivi combinandoli tra di loro tramite scripts +che possono tenere conto di ogni tipo di condizione ed interfacciarsi con ogni tipo di sensore : umidità, temperatura, presenza, velocità vento, etc …

Home Assistant

Alcune possibilità sono :

  • controllo apertura e chiusura tapparelle motorizzate e tende da sole
  • controllo varchi di accesso : cancelli, portoni
  • illuminazione interna ed esterna
  • irrigazioni orti e giardini
  • integrazione con sistemi di allarme antifurto eistenti o creazione di un sistema da zero
  • integrazione con sensori gas e allagamento

Il tutto programmabile in modalità automatica e configurabile e controllabile manualmente tramite interfaccia web ed app per smartphones e tablets, +anche da remoto o tramite tags NFC.

L’interfaccia utente è altamente personalizzabile e configurabile in base alle specifiche esigenze e può essere anche modificata la grafica tramite temi +personalizzati.

Home Assistant Minimalist Theme
Home Assistant Swakes Theme
Data pubblicazione : 2022-08-30 | Ultima modifica : 2022-08-30

Technology | +Home Assistant +| +Home Automation

\ No newline at end of file diff --git a/public/blog/botta-museum/index.html b/public/blog/botta-museum/index.html new file mode 100644 index 0000000..982f86e --- /dev/null +++ b/public/blog/botta-museum/index.html @@ -0,0 +1,47 @@ +SpeedTech | Blog - Museo e shop online +

Blog

Museo e shop online

Cliente : Museo Botta (Rovereto - IT)

Museo virtuale per modelli d’auto ed oggetti pubblicitari con e-commerce personalizzato

  • Impostazione del framework PHP Yii2
  • Implementazione del design del cliente
  • Integrazione del framework Bootstrap 3
  • Negozio online con sistema d’ordine e di pagamenti
  • Installazione e configurazione del server
Data pubblicazione : 2017-04-15 | Ultima modifica : 2017-04-15

Progetti | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

\ No newline at end of file diff --git a/public/blog/brainminder-intro/index.html b/public/blog/brainminder-intro/index.html new file mode 100644 index 0000000..e7cdebc --- /dev/null +++ b/public/blog/brainminder-intro/index.html @@ -0,0 +1,47 @@ +SpeedTech | Blog - BrainMinder - second brain web application +

Blog

BrainMinder - second brain web application

BrainMinder è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. +I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.

Permette di suddividere il proprio archivio di conoscenze in tipi diversi di articoli che possono essere creati in base alle necessità. +Ogni tipo di articolo ha alcuni tipi di campi predefiniti per raccogliere le informazioni (come titolo, sommario, descrizione) ma altri campi possono essere aggiunti secondo le proprie preferenze.

BrainMinder è stato creato tramite il linguaggio Golang, utilizza il database SQLite e il tool Javascript Unpoly. +Il programma è già utilizzabile e molto utile, ma è attualmente in fase di intenso sviluppo e nuove funzionalità vengono aggiunte frequentemente.

Data pubblicazione : 2025-10-30 | Ultima modifica : 2025-10-30

Projects | +Software Development +| +Web Application +| +PWA

\ No newline at end of file diff --git a/public/blog/cifrare-comprimere-email-server/index.html b/public/blog/cifrare-comprimere-email-server/index.html new file mode 100644 index 0000000..cb1342e --- /dev/null +++ b/public/blog/cifrare-comprimere-email-server/index.html @@ -0,0 +1,95 @@ +SpeedTech | Blog - Cifrare e comprimere le email lato server +

Blog

Cifrare e comprimere le email lato server

Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server +Dovecot permette di cifrare e comprimere i files che contengono la posta elettronica.

La compressione avviene tramite il plugin zlib mentre la cifratura tramite il plugin mail_crypt.

mail_plugins = $mail_plugins zlib mail_crypt
+

I due plugin possono essere poi configurati con diversi opzioni

plugin {
+  mail_crypt_global_private_key = </etc/dovecot/crypt/master.key
+  mail_crypt_global_public_key = </etc/dovecot/crypt/master.pub
+  mail_crypt_curve = prime256v1
+  mail_crypt_save_version = 2
+  zlib_save_level = 6
+  zlib_save = lz4
+}
+

Per la cifratura è inoltre necessario generare la coppia di chiavi : privata (master.key) per cifrare e pubblica (master.pub) per decifrare.

In questo modo nel caso vi fosse un’intrusione sul server ed i files delle email venissero trafugati, sarebbero illeggibili senza la chiave privata di decodifica.

Dal momento in cui la codifica e la compressione vengono attivate, tutti i nuovi messaggi verranno automaticamente cifrati e compressi in modo +completamente trasparente per l’utente finale.

Per cifrare e comprimere la posta preesistente è sufficiente spostare i messaggi da una cartella all’altra tramite un client IMAP. +In alternativa, con il seguente script bash è possibile avviare la cifratura di tutti i files di posta nella directory di esempio /var/vmail/domain/user/Maildir (la compressione non è possibile).

find /var/vmail/domain/user/Maildir -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
+if [[ $(head -c7 "$file") != "CRYPTED" ]]; then
+echo $file
+doveadm fs put crypt private_key_path=/etc/dovecot/crypt/master.key:public_key_path=/etc/dovecot/crypt/master.pub:posix:prefix=/ \
+  "$file" "$file"
+  chmod 600 "$file"
+  chown vmail:vmail "$file"
+fi
+done
+

Nel caso invece fosse necessario accedere ad uno o più files di email in chiaro, si possono utilizzare i seguenti scripts :

Per decifrare solamente (nel caso in cui i files non siano stati compressi)

find /var/vmail/domain/user/Maildir -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
+if [[ $(head -c7 "$file") == "CRYPTED" ]]; then
+  echo $file
+  doveadm fs get crypt private_key_path=/etc/dovecot/crypt/master.key:public_key_path=/etc/dovecot/crypt/master.pub:posix:prefix=/ \
+  "$file" > "/tmp/$(basename "$file")"
+  if [[ -s "/tmp/$(basename "$file")" ]]; then
+    chmod 600 "/tmp/$(basename "$file")"
+    chown vmail:vmail "/tmp/$(basename "$file")"
+    mv "/tmp/$(basename "$file")" "$file"
+  else
+    rm "/tmp/$(basename "$file")"
+  fi
+fi
+done
+

Per decifrare e decomprimere :

find /var/vmail/domain/user/Maildir -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
+if [[ $(head -c7 "$file") == "CRYPTED" ]]; then
+  echo $file
+  doveadm fs get compress lz4:0:crypt:private_key_path=/etc/dovecot/crypt/master.key:public_key_path=/etc/dovecot/crypt/master.pub:posix:prefix=/ \
+  "$file" > "/tmp/$(basename "$file")"
+  if [[ -s "/tmp/$(basename "$file")" ]]; then
+    chmod 600 "/tmp/$(basename "$file")"
+    chown vmail:vmail "/tmp/$(basename "$file")"
+    mv "/tmp/$(basename "$file")" "$file"
+  else
+    rm "/tmp/$(basename "$file")"
+  fi
+fi
+done
+
Data pubblicazione : 2022-07-08 | Ultima modifica : 2022-07-08

Soluzioni | +Security +| +Server +| +Privacy +| +Dovecot

\ No newline at end of file diff --git a/public/blog/cspolsa-renting/index.html b/public/blog/cspolsa-renting/index.html new file mode 100644 index 0000000..a6ae8d3 --- /dev/null +++ b/public/blog/cspolsa-renting/index.html @@ -0,0 +1,43 @@ +SpeedTech | Blog - Software per noleggio attrezzature per lo sci +

Blog

Software per noleggio attrezzature per lo sci

Cliente: Centro Snowboard Polsa (Rovereto - IT)

Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando :

  • Linguaggio ObjectPascal
  • Lazaurs IDE
  • MariaDB database
  • Server Linux locale

per il noleggio di sci ed accessori.

Data pubblicazione : 2017-12-12 | Ultima modifica : 2017-12-12

Progetti | +Software Development +| +Desktop Application

\ No newline at end of file diff --git a/public/blog/daxtor-firewall-vpn-server-farm/index.html b/public/blog/daxtor-firewall-vpn-server-farm/index.html new file mode 100644 index 0000000..bf0ecec --- /dev/null +++ b/public/blog/daxtor-firewall-vpn-server-farm/index.html @@ -0,0 +1,45 @@ +SpeedTech | Blog - Firewall, VPN e rete in server farm +

Blog

Firewall, VPN e rete in server farm

Cliente : Daxtor (Bolzano - IT)

Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm

  • Selezione dell’ hardware
  • Disegno della rete
  • Installazione e configurazione degli application server Linux
  • Installazione del database server Oracle
  • Configurazione e manutenzione dei firewalls ridondati
  • Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi
Data pubblicazione : 2002-06-07 | Ultima modifica : 2002-06-07

Progetti | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/blog/deflorian-server/index.html b/public/blog/deflorian-server/index.html new file mode 100644 index 0000000..6f3a651 --- /dev/null +++ b/public/blog/deflorian-server/index.html @@ -0,0 +1,43 @@ +SpeedTech | Blog - Server Linux come file e backup server +

Blog

Server Linux come file e backup server

Cliente : Deflorian Law Firm (Rovereto - IT)

Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi

  • Server Debian Linux installazione e configurazione di base
  • Configurazione del supporto software RAID
  • Configurazione del file server ed assegnazione dei privilegi agli utenti
  • Backup ridondato esterno con supporto per versioni dei files
Data pubblicazione : 2011-03-12 | Ultima modifica : 2011-03-12

Progetti | +NAS +| +Office Server

\ No newline at end of file diff --git a/public/blog/finova-firewall/index.html b/public/blog/finova-firewall/index.html new file mode 100644 index 0000000..1b00725 --- /dev/null +++ b/public/blog/finova-firewall/index.html @@ -0,0 +1,48 @@ +SpeedTech | Blog - Servers VPS, Firewall e VPN +

Blog

Servers VPS, Firewall e VPN

Cliente : Finova (Bolzano - IT)

Progettazione ed implementazione rete e sicurezza per servizi SAS

  • Hardware selection
  • Network design
  • Linux application server installation and configuration
  • VPN based on OpenVPN configuration and maintenance for access control
  • VPS management
Data pubblicazione : 2019-09-14 | Ultima modifica : 2019-09-14

Progetti | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

\ No newline at end of file diff --git a/public/blog/finova-oracle-apex/index.html b/public/blog/finova-oracle-apex/index.html new file mode 100644 index 0000000..6da5532 --- /dev/null +++ b/public/blog/finova-oracle-apex/index.html @@ -0,0 +1,40 @@ +SpeedTech | Blog - Database Oracle XE database e APEX +

Blog

Database Oracle XE database e APEX

Cliente : Finova (Bolzano - IT)

Database Oracle XE e APEX configurazione e installazione

  • Linux CentOS server installazione e confugrazione
  • Database Oracle XE database installazione e configurazione
  • APEX installazione e configurazione
  • Apache e Tomcat configurazione
Data pubblicazione : 2019-11-09 | Ultima modifica : 2019-11-09

\ No newline at end of file diff --git a/public/blog/guiet-web-development/index.html b/public/blog/guiet-web-development/index.html new file mode 100644 index 0000000..bc76e62 --- /dev/null +++ b/public/blog/guiet-web-development/index.html @@ -0,0 +1,45 @@ +SpeedTech | Blog - Svilluppo di applicazioni web +

Blog

Svilluppo di applicazioni web

Cliente : GUIET.com (Fribourg - CH)

Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati

  • Progettazione dei database
  • Studio della logica delle applicazioni ed implementazione dei backend
  • Sviluppo di funzionalità personalizzate
  • Supporto e manutenzione
  • Progettazione e sviluppo di CMS con supporto multilingua personalizzati
Data pubblicazione : 2015-08-03 | Ultima modifica : 2015-08-03

Progetti | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/blog/index.html b/public/blog/index.html new file mode 100644 index 0000000..70a4383 --- /dev/null +++ b/public/blog/index.html @@ -0,0 +1,71 @@ +SpeedTech | Blog +

BrainMinder - second brain web application

BrainMinder è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.

Continua a leggere

Projects | +Software Development +| +Web Application +| +PWA

Applicazione web con funzionalità di foglio di calcolo e sincronizzazione

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.

Continua a leggere

Progetti | +Software Development +| +Web Application

Database link con PostgreSQL

In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +PostgreSQL

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Procedure di sincronizzazione dati

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti con PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/blog/index.xml b/public/blog/index.xml new file mode 100644 index 0000000..7fbfd84 --- /dev/null +++ b/public/blog/index.xml @@ -0,0 +1,46 @@ +Blog on Information Technology Serviceshttps://speedtech.it/blog/Recent content in Blog on Information Technology ServicesHugo -- gohugo.ioitThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/blog/brainminder-intro/<p><strong>BrainMinder</strong> è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. +I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.</p>Applicazione web con funzionalità di foglio di calcolo e sincronizzazionehttps://speedtech.it/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/blog/wmtrento-spreadsheet-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database +con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p>Database link con PostgreSQLhttps://speedtech.it/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/blog/postgresql-database-link/<p>In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che +risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.</p>Procedure di sincronizzazione datihttps://speedtech.it/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/blog/wmtrento-data-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti +con PHP, CodeIgniter, MySQL, Joomla, Virtuemart</p>Automazione casa con Home Assistanthttps://speedtech.it/blog/automazione-casa-con-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/blog/automazione-casa-con-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> è uno strumento interamente open source per la domotica sia di ambienti residenziali che lavorativi.</p>Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p>Cifrare e comprimere le email lato serverhttps://speedtech.it/blog/cifrare-comprimere-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/cifrare-comprimere-email-server/<p>Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server +<a href="https://www.dovecot.org/">Dovecot</a> permette di cifrare e comprimere i files che contengono la posta elettronica.</p>VPN con router Fritz!Boxhttps://speedtech.it/blog/vpn-con-frizbox/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/vpn-con-frizbox/<p>I routers <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> di AVM forniscono già integrati due importanti servizi che consentono +la connettività da remoto :</p> +<ul> +<li><strong>DNS dinamico</strong></li> +<li><strong>VPN basata su protocollo ipsec</strong></li> +</ul>Installazione e configurazione Synology NAShttps://speedtech.it/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/blog/synology-nas/<p>Cliente : diversi</p> +<ul> +<li>Installazione e configurazione Synology : utenti, privilegi di condivisione e backup</li> +<li>Configurazione clients MS Windows</li> +</ul>Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezzahttps://speedtech.it/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/blog/amorcosmetics-ecommerce/<p>Cliente : Amor Cosmetics (Trento - IT)</p> +<p>Sito e-commerce website integrato con pagamenti tramite carta di credito</p>Database Oracle XE database e APEXhttps://speedtech.it/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/blog/finova-oracle-apex/Cliente : Finova (Bolzano - IT) +Database Oracle XE e APEX configurazione e installazione +Linux CentOS server installazione e confugrazione Database Oracle XE database installazione e configurazione APEX installazione e configurazione Apache e Tomcat configurazioneServers VPS, Firewall e VPNhttps://speedtech.it/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/blog/finova-firewall/<p>Cliente : Finova (Bolzano - IT)</p> +<p>Progettazione ed implementazione rete e sicurezza per servizi SAS</p>Applicazioni web per contabilità, gestione soci e CMS personalizzatohttps://speedtech.it/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/blog/agiati-web-applications/Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteSoftware per noleggio attrezzature per lo scihttps://speedtech.it/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/blog/cspolsa-renting/Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.Museo e shop onlinehttps://speedtech.it/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/blog/botta-museum/Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del serverSviluppo software per Drupalhttps://speedtech.it/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/blog/versantus-drupal.-development/Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)Firewalls, VPN e filtraggio contenutihttps://speedtech.it/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/blog/villamaria-firewalls/Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse webSvilluppo di applicazioni webhttps://speedtech.it/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/blog/guiet-web-development/Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzatiApplicazione per il tracciamento di Skibus con GPShttps://speedtech.it/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/blog/altevie-geomapping/Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobusInstallazione e personalizzazione sito e-commercehttps://speedtech.it/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzateServer Linux come file e backup serverhttps://speedtech.it/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/blog/deflorian-server/Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei filesSviluppo software per Drupalhttps://speedtech.it/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/blog/lrm-drupal-development/Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL)Firewall, VPN e rete in server farmhttps://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessiApplicazioni per CRM, Oracle e certificazione PCIhttps://speedtech.it/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/blog/sint-crm/Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro \ No newline at end of file diff --git a/public/blog/lrm-drupal-development/index.html b/public/blog/lrm-drupal-development/index.html new file mode 100644 index 0000000..6a3b7c3 --- /dev/null +++ b/public/blog/lrm-drupal-development/index.html @@ -0,0 +1,44 @@ +SpeedTech | Blog - Sviluppo software per Drupal +

Blog

Sviluppo software per Drupal

\ No newline at end of file diff --git a/public/blog/mariadb-replicazione-master-master-tramite-internet/index.html b/public/blog/mariadb-replicazione-master-master-tramite-internet/index.html new file mode 100644 index 0000000..2144b9f --- /dev/null +++ b/public/blog/mariadb-replicazione-master-master-tramite-internet/index.html @@ -0,0 +1,141 @@ +SpeedTech | Blog - Replicazione master-master MariaDB tramite Internet +

Blog

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.

Questa funzionalità può essere implementata anche tramite servers collegati tra di loro tramite Internet, +cifrando la connessione nativa di MariaDB tramite certificati SSL e controllando l’accesso al servizio +tramite firewall software (ufw ad esempio).

Supponendo quindi di disporre di 2 servers server1 e server2 le procedure +da seguire sono le seguenti.

1. Predisposizione delle regole dei firewall

Per far comunicare i due servers tra di loro, è necessario consentire la comunicazione sull porta TCP di +MariaDB (default 3306)

Su server2

ufw allow from server1-ip to server2-ip 3306 comment "Allow replication from server1"
+

Su server1

ufw allow from server2-ip to server1-ip 3306 comment "Allow replication from server2"
+
2. Generazione dei certificati SSL

Per rendere sicura la connessione tra i due servers si può sfruttare la connettività SSL già presente in MariaDB +generando la propria CA (Certification Authority) ed i rispettivi certificati per i due servers.

XCA è un ottimo software visuale per generare e mantenere i certificati SSL.

Un’alternativa alla connessione diretta e cifrata tramite SSL è la creazione di un VPN che colleghi i due servers.

3. Allineamento dati servers

Nel caso in cui i due servers contengano già dati, sarà necessario procedere con un allineamento +preventivo tramite esportazione ed importazione dei databases interessati, in modo che entrambi +i servers contengano gli stessi databases, tables e records.

4. Creare gli utenti dedicati su ogni server per consentire la replica

Su server1 creare l’utente per la connessione da server2 e dargli i permessi +per la replica verso server1

CREATE USER 'server2'@'server2-ip' IDENTIFIED BY 'server2pwd';
+GRANT REPLICATION SLAVE ON *.* TO 'server2'@'server2-ip';
+FLUSH PRIVILEGES;
+

Su server2 creare l’utente per la connessione da server1 e dargli i permessi +per la replica verso server2

CREATE USER 'server1'@'server1-ip' IDENTIFIED BY 'server1pwd';
+GRANT REPLICATION SLAVE ON *.* TO 'server1'@'server1-ip';
+FLUSH PRIVILEGES;
+
5. Configurare server1

In file server.conf :

key_buffer_size        = 64M
+max_allowed_packet     = 64M
+
+server-id   = 1
+report_host = server1
+log_bin                = /var/log/mysql/mysql-bin.log
+expire_logs_days        = 10
+
+relay_log       = /var/lib/mysql/relay-bin
+relay_log_index = /var/lib/mysql/relay-bin.index
+
+log-slave-updates
+auto_increment_increment=1
+auto_increment_offset=1
+slave-skip-errors=1062,1032,1007,1008,1050,1396
+skip-slave-start=FALSE
+
6. Configurare server2

In file server.conf :

key_buffer_size        = 64M
+max_allowed_packet     = 64M
+
+server-id   = 2
+report_host = server2
+log_bin                = /var/log/mysql/mysql-bin.log
+expire_logs_days        = 10
+
+relay_log       = /var/lib/mysql/relay-bin
+relay_log_index = /var/lib/mysql/relay-bin.index
+
+log-slave-updates
+auto_increment_increment=2
+auto_increment_offset=2
+slave-skip-errors=1062,1032,1007,1008,1050,1396
+skip-slave-start=FALSE
+
7. Configurare server1 come SLAVE di server2

Su server2 eseguire il comando :

SHOW MASTER STATUS \G;
+

e prendere nota dei valori : File e Position che andranno sostituiti nelle +variabili rispettivamente MASTER_LOG_FILE e MASTER_LOG_POS nel codice seguente +da eseguire su server1 :

CHANGE MASTER TO
+  MASTER_HOST='server2-ip',
+  MASTER_USER='server1',
+  MASTER_PASSWORD='server1pwd',
+  MASTER_PORT=3306,
+  MASTER_LOG_FILE='mysql-bin.000004',
+  MASTER_LOG_POS=17680369,
+  MASTER_CONNECT_RETRY=10,
+  MASTER_SSL=1,
+  MASTER_SSL_CA='/etc/mysql/ssl/ca.crt',
+  MASTER_SSL_CERT='/etc/mysql/ssl/server1.crt',
+  MASTER_SSL_KEY='/etc/mysql/ssl/server1.key';
+
+START SLAVE;
+

Verificare lo stato della replica slave con il comando :

SHOW SLAVE STATUS\G;
+
8. Configurare server2 come SLAVE di server1

Su server1 eseguire il comando :

SHOW MASTER STATUS \G;
+

e prendere nota dei valori : File e Position che andranno sostituiti nelle +variabili rispettivamente MASTER_LOG_FILE e MASTER_LOG_POS nel codice seguente +da eseguire su server2 :

CHANGE MASTER TO
+  MASTER_HOST='server1-ip',
+  MASTER_USER='server2',
+  MASTER_PASSWORD='server2pwd',
+  MASTER_PORT=3306,
+  MASTER_LOG_FILE='mysql-bin.000051',
+  MASTER_LOG_POS=825490817,
+  MASTER_CONNECT_RETRY=10,
+  MASTER_SSL=1,
+  MASTER_SSL_CA='/etc/mysql/ssl/ca.crt',
+  MASTER_SSL_CERT='/etc/mysql/ssl/server2.crt',
+  MASTER_SSL_KEY='/etc/mysql/ssl/server2.key';
+
+START SLAVE;
+

Verificare lo stato della replica slave con il comando :

SHOW SLAVE STATUS\G;
+
Data pubblicazione : 2022-07-19 | Ultima modifica : 2022-12-11

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/blog/page/1/index.html b/public/blog/page/1/index.html new file mode 100644 index 0000000..3f01305 --- /dev/null +++ b/public/blog/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/blog/ + \ No newline at end of file diff --git a/public/blog/page/2/index.html b/public/blog/page/2/index.html new file mode 100644 index 0000000..4624a2f --- /dev/null +++ b/public/blog/page/2/index.html @@ -0,0 +1,67 @@ +SpeedTech | Blog +

Automazione casa con Home Assistant

Home Assistant è uno strumento interamente open source per la domotica sia di ambienti residenziali che lavorativi.

Continua a leggere

Technology | +Home Assistant +| +Home Automation

Cifrare e comprimere le email lato server

Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server Dovecot permette di cifrare e comprimere i files che contengono la posta elettronica.

Continua a leggere

Soluzioni | +Security +| +Server +| +Privacy +| +Dovecot

VPN con router Fritz!Box

I routers Fritz!Box di AVM forniscono già integrati due importanti servizi che consentono la connettività da remoto : +DNS dinamico VPN basata su protocollo ipsec

Continua a leggere

Soluzioni | +Technology | +VPN +| +Router +| +Networking

Installazione e configurazione Synology NAS

Cliente : diversi +Installazione e configurazione Synology : utenti, privilegi di condivisione e backup Configurazione clients MS Windows

Continua a leggere

Soluzioni | +Technology | +Progetti | +NAS +| +File Server

Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezza

Cliente : Amor Cosmetics (Trento - IT) +Sito e-commerce website integrato con pagamenti tramite carta di credito

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/blog/page/3/index.html b/public/blog/page/3/index.html new file mode 100644 index 0000000..8e85eef --- /dev/null +++ b/public/blog/page/3/index.html @@ -0,0 +1,69 @@ +SpeedTech | Blog +

Database Oracle XE database e APEX

Cliente : Finova (Bolzano - IT) +Database Oracle XE e APEX configurazione e installazione +Linux CentOS server installazione e confugrazione Database Oracle XE database installazione e configurazione APEX installazione e configurazione Apache e Tomcat configurazione

Continua a leggere

Servers VPS, Firewall e VPN

Cliente : Finova (Bolzano - IT) +Progettazione ed implementazione rete e sicurezza per servizi SAS

Continua a leggere

Progetti | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Applicazioni web per contabilità, gestione soci e CMS personalizzato

Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional website

Continua a leggere

Progetti | +Software Development +| +Web Application

Software per noleggio attrezzature per lo sci

Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.

Continua a leggere

Progetti | +Software Development +| +Desktop Application

Museo e shop online

Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del server

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

\ No newline at end of file diff --git a/public/blog/page/4/index.html b/public/blog/page/4/index.html new file mode 100644 index 0000000..f16df44 --- /dev/null +++ b/public/blog/page/4/index.html @@ -0,0 +1,71 @@ +SpeedTech | Blog +

Sviluppo software per Drupal

Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Firewalls, VPN e filtraggio contenuti

Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse web

Continua a leggere

Firewall +| +VPN +| +Networking +| +OpnSense

Svilluppo di applicazioni web

Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzati

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Applicazione per il tracciamento di Skibus con GPS

Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobus

Continua a leggere

Progetti | +Software Development +| +Web Application

Installazione e personalizzazione sito e-commerce

Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzate

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/blog/page/5/index.html b/public/blog/page/5/index.html new file mode 100644 index 0000000..d04a498 --- /dev/null +++ b/public/blog/page/5/index.html @@ -0,0 +1,65 @@ +SpeedTech | Blog +

Server Linux come file e backup server

Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei files

Continua a leggere

Progetti | +NAS +| +Office Server

Sviluppo software per Drupal

Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Firewall, VPN e rete in server farm

Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi

Continua a leggere

Progetti | +VPN +| +Firewall +| +System Administration

Applicazioni per CRM, Oracle e certificazione PCI

Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro

Continua a leggere

Progetti | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/blog/postgresql-database-link/index.html b/public/blog/postgresql-database-link/index.html new file mode 100644 index 0000000..250a1da --- /dev/null +++ b/public/blog/postgresql-database-link/index.html @@ -0,0 +1,54 @@ +SpeedTech | Blog - Database link con PostgreSQL +

Blog

Database link con PostgreSQL

In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che +risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.

La nomenclatura utilizzata è la seguente :

  • serverorig : il server principale di origine
  • databaseorig : il database sul server principale di origine
  • serverdest : il server secondario di destinazione sul quale verrà creato il database link che punta a serverorig
  • schemaorig : lo schema di origine sul server principale
  • schemadest : lo schema di destinazione sul server secondario

1. Installazione dell’estensione

Il primo passo da compiere è installare su serverdest l’estensione postgres_fdw come utente postgres :

CREATE EXTENSION IF NOT EXISTS postgres_fdw;
+

Su serverorig creare un utente che consenta la connessione da serverdest e gli accessi +allo schema schemaorig e tabelle interessate. Per semplicità l’utente sarà userdest con +password passworddest e dovrà avere accesso alla tabella tableorig con i privilegi desiderati : +(SELECT, INSERT, UPDATE, DELETE)

Su serverdest :

CREATE serverorig FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'serverorig', port 'portorig', dbname 'databaseorig');
+

Creare su serverdest il mapping per l’utente (myuser) che deve poter usare il database link

CREATE USER MAPPING FOR myuser SERVER serverorig OPTIONS ( user 'userdest' , password 'passworddest');
+

5. Importare la struttura delle tabelle dallo schema principale ed assegnare i permessi

Su serverdest :

IMPORT FOREIGN SCHEMA schemaorig LIMIT TO (tableorig) FROM SERVER serverorig INTO schemadest;
+GRANT ALL ON TABLE schemadest.tableorig TO myuser;
+
Data pubblicazione : 2022-12-11 | Ultima modifica : 2022-12-11

Soluzioni | +Technology | +Server +| +Database +| +PostgreSQL

\ No newline at end of file diff --git a/public/blog/sint-crm/index.html b/public/blog/sint-crm/index.html new file mode 100644 index 0000000..96d3f0d --- /dev/null +++ b/public/blog/sint-crm/index.html @@ -0,0 +1,47 @@ +SpeedTech | Blog - Applicazioni per CRM, Oracle e certificazione PCI +

Blog

Applicazioni per CRM, Oracle e certificazione PCI

Cliente : SINT (Torino - IT)

Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI

  • Disegno ed implementazione del database Oracle
  • Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati
  • Applicazioni sia per il backend che il frontend del CRM
  • Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro
Data pubblicazione : 2000-06-05 | Ultima modifica : 2000-06-15

Progetti | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/blog/synology-nas/index.html b/public/blog/synology-nas/index.html new file mode 100644 index 0000000..2eec6eb --- /dev/null +++ b/public/blog/synology-nas/index.html @@ -0,0 +1,47 @@ +SpeedTech | Blog - Installazione e configurazione Synology NAS +

Blog

Installazione e configurazione Synology NAS

\ No newline at end of file diff --git a/public/blog/versantus-drupal.-development/index.html b/public/blog/versantus-drupal.-development/index.html new file mode 100644 index 0000000..c8540c5 --- /dev/null +++ b/public/blog/versantus-drupal.-development/index.html @@ -0,0 +1,44 @@ +SpeedTech | Blog - Sviluppo software per Drupal +

Blog

Sviluppo software per Drupal

\ No newline at end of file diff --git a/public/blog/villamaria-firewalls/index.html b/public/blog/villamaria-firewalls/index.html new file mode 100644 index 0000000..9ced77c --- /dev/null +++ b/public/blog/villamaria-firewalls/index.html @@ -0,0 +1,46 @@ +SpeedTech | Blog - Firewalls, VPN e filtraggio contenuti +

Blog

Firewalls, VPN e filtraggio contenuti

Cliente : Cooperativa VillaMaria (Rovereto - IT)

Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti

  • Configurazione dell’ hardware
  • Installazione del sistema di firewall e configurazione del supporto RAID
  • Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote
  • Installazione delle VPN per singole postazioni per consentire il tele lavoro
  • Filtraggio trasparente dei contenuti per controllare l’accesso alle risorse web
Data pubblicazione : 2016-01-14 | Ultima modifica : 2016-01-14

Firewall +| +VPN +| +Networking +| +OpnSense

\ No newline at end of file diff --git a/public/blog/vpn-con-frizbox/index.html b/public/blog/vpn-con-frizbox/index.html new file mode 100644 index 0000000..34dc117 --- /dev/null +++ b/public/blog/vpn-con-frizbox/index.html @@ -0,0 +1,54 @@ +SpeedTech | Blog - VPN con router Fritz!Box +

Blog

VPN con router Fritz!Box

I routers Fritz!Box di AVM forniscono già integrati due importanti servizi che consentono +la connettività da remoto :

  • DNS dinamico
  • VPN basata su protocollo ipsec

La nuova versione del firmware in fase di sviluppo, consentirà anche la creazione di VPN basate su Wireguard.

Il DNS dinamico associa l’IP pubblico del router ad un nome host sul dominio myfritz.net, permettendo +così di raggiungere il router tramite Internet anche qualora non si disponga di una connessione con IP statico.

Questa funzionalità è propedeutica all’implementazione delle VPN che Fritz!Box supporta. +Le VPN possono essere di 2 tipi :

  1. site to site : per connettere 2 o più apparati Fritz!Box (o anche apparati compatibili che supportino la medesima tipologia di VPN) tra di loro in modo da collegare le rispettive reti private.

    Questa funzionalità puà essere molto utile per collegare due sedi distaccate, quali 2 uffici geograficamente distanti oppure +casa con l’ufficio.

  2. client : per connettere un client (smartphone, tablet, computer) tramite VPN al router e raggiungere così la sua rete interna

    In questo modo è possibile far accedere i singoli collaboratori esterni alle risorse aziendali interne tramite un canale sicuro.

Fritz!Box creazione VPN

Le funzionalità di rete avanzate permettono anche di selezionare quali risorse interne possono accedere alla VPN, rendendo in questo modo +raggiungibili solo i servizi e dispositivi essenziali, migliorando la sicurezza.

Data pubblicazione : 2022-07-08 | Ultima modifica : 2022-07-08

Soluzioni | +Technology | +VPN +| +Router +| +Networking

\ No newline at end of file diff --git a/public/blog/wmtrento-data-sync/index.html b/public/blog/wmtrento-data-sync/index.html new file mode 100644 index 0000000..3e0a9c2 --- /dev/null +++ b/public/blog/wmtrento-data-sync/index.html @@ -0,0 +1,46 @@ +SpeedTech | Blog - Procedure di sincronizzazione dati +

Blog

Procedure di sincronizzazione dati

Cliente : Web Marketing Trento (Trento - IT)

Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti +con PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Data pubblicazione : 2022-11-07 | Ultima modifica : 2022-11-07

Progetti | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/blog/wmtrento-spreadsheet-sync/index.html b/public/blog/wmtrento-spreadsheet-sync/index.html new file mode 100644 index 0000000..8b9f58e --- /dev/null +++ b/public/blog/wmtrento-spreadsheet-sync/index.html @@ -0,0 +1,45 @@ +SpeedTech | Blog - Applicazione web con funzionalità di foglio di calcolo e sincronizzazione +

Blog

Applicazione web con funzionalità di foglio di calcolo e sincronizzazione

Cliente : Web Marketing Trento (Trento - IT)

Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database +con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.

Ho progettato e sviluppato una web application basata su framework CodeIgniter e che integra JSpreadsheet +che consente di interagire con il database di Virtuemart e-commerce per poter modificare dati dei prodotti in modalità foglio di calcolo.

Il frontend integra VueJS per un’interfaccia utente più efficiente e tutte le chiamate al backend vengono fatte tramite Ajax che restituiscono i dati in formato JSON.

Data pubblicazione : 2023-05-07 | Ultima modifica : 2023-05-07

Progetti | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/categories/index.html b/public/categories/index.html new file mode 100644 index 0000000..db1cbd2 --- /dev/null +++ b/public/categories/index.html @@ -0,0 +1,38 @@ +SpeedTech | Categories +
\ No newline at end of file diff --git a/public/categories/index.xml b/public/categories/index.xml new file mode 100644 index 0000000..429f302 --- /dev/null +++ b/public/categories/index.xml @@ -0,0 +1 @@ +Categories on Information Technology Serviceshttps://speedtech.it/categories/Recent content in Categories on Information Technology ServicesHugo -- gohugo.ioitThu, 30 Oct 2025 00:00:00 +0000Projectshttps://speedtech.it/categories/projects/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/categories/projects/Progettihttps://speedtech.it/categories/progetti/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/categories/progetti/Soluzionihttps://speedtech.it/categories/soluzioni/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/categories/soluzioni/Technologyhttps://speedtech.it/categories/technology/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/categories/technology/ \ No newline at end of file diff --git a/public/categories/page/1/index.html b/public/categories/page/1/index.html new file mode 100644 index 0000000..91817cb --- /dev/null +++ b/public/categories/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/categories/ + \ No newline at end of file diff --git a/public/categories/progetti/index.html b/public/categories/progetti/index.html new file mode 100644 index 0000000..0a4858d --- /dev/null +++ b/public/categories/progetti/index.html @@ -0,0 +1,70 @@ +SpeedTech | Progetti +

Applicazione web con funzionalità di foglio di calcolo e sincronizzazione

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.

Continua a leggere

Progetti | +Software Development +| +Web Application

Procedure di sincronizzazione dati

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti con PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Installazione e configurazione Synology NAS

Cliente : diversi +Installazione e configurazione Synology : utenti, privilegi di condivisione e backup Configurazione clients MS Windows

Continua a leggere

Soluzioni | +Technology | +Progetti | +NAS +| +File Server

Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezza

Cliente : Amor Cosmetics (Trento - IT) +Sito e-commerce website integrato con pagamenti tramite carta di credito

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

Servers VPS, Firewall e VPN

Cliente : Finova (Bolzano - IT) +Progettazione ed implementazione rete e sicurezza per servizi SAS

Continua a leggere

Progetti | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

\ No newline at end of file diff --git a/public/categories/progetti/index.xml b/public/categories/progetti/index.xml new file mode 100644 index 0000000..8b6151e --- /dev/null +++ b/public/categories/progetti/index.xml @@ -0,0 +1,31 @@ +Progetti on Information Technology Serviceshttps://speedtech.it/categories/progetti/Recent content in Progetti on Information Technology ServicesHugo -- gohugo.ioitSun, 07 May 2023 00:00:00 +0000Applicazione web con funzionalità di foglio di calcolo e sincronizzazionehttps://speedtech.it/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/blog/wmtrento-spreadsheet-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database +con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p>Procedure di sincronizzazione datihttps://speedtech.it/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/blog/wmtrento-data-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti +con PHP, CodeIgniter, MySQL, Joomla, Virtuemart</p>Installazione e configurazione Synology NAShttps://speedtech.it/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/blog/synology-nas/<p>Cliente : diversi</p> +<ul> +<li>Installazione e configurazione Synology : utenti, privilegi di condivisione e backup</li> +<li>Configurazione clients MS Windows</li> +</ul>Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezzahttps://speedtech.it/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/blog/amorcosmetics-ecommerce/<p>Cliente : Amor Cosmetics (Trento - IT)</p> +<p>Sito e-commerce website integrato con pagamenti tramite carta di credito</p>Servers VPS, Firewall e VPNhttps://speedtech.it/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/blog/finova-firewall/<p>Cliente : Finova (Bolzano - IT)</p> +<p>Progettazione ed implementazione rete e sicurezza per servizi SAS</p>Applicazioni web per contabilità, gestione soci e CMS personalizzatohttps://speedtech.it/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/blog/agiati-web-applications/Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteSoftware per noleggio attrezzature per lo scihttps://speedtech.it/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/blog/cspolsa-renting/Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.Museo e shop onlinehttps://speedtech.it/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/blog/botta-museum/Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del serverSviluppo software per Drupalhttps://speedtech.it/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/blog/versantus-drupal.-development/Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)Svilluppo di applicazioni webhttps://speedtech.it/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/blog/guiet-web-development/Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzatiApplicazione per il tracciamento di Skibus con GPShttps://speedtech.it/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/blog/altevie-geomapping/Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobusInstallazione e personalizzazione sito e-commercehttps://speedtech.it/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzateServer Linux come file e backup serverhttps://speedtech.it/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/blog/deflorian-server/Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei filesSviluppo software per Drupalhttps://speedtech.it/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/blog/lrm-drupal-development/Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL)Firewall, VPN e rete in server farmhttps://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessiApplicazioni per CRM, Oracle e certificazione PCIhttps://speedtech.it/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/blog/sint-crm/Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro \ No newline at end of file diff --git a/public/categories/progetti/page/1/index.html b/public/categories/progetti/page/1/index.html new file mode 100644 index 0000000..88dc490 --- /dev/null +++ b/public/categories/progetti/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/categories/progetti/ + \ No newline at end of file diff --git a/public/categories/progetti/page/2/index.html b/public/categories/progetti/page/2/index.html new file mode 100644 index 0000000..14bbcda --- /dev/null +++ b/public/categories/progetti/page/2/index.html @@ -0,0 +1,70 @@ +SpeedTech | Progetti +

Applicazioni web per contabilità, gestione soci e CMS personalizzato

Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional website

Continua a leggere

Progetti | +Software Development +| +Web Application

Software per noleggio attrezzature per lo sci

Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.

Continua a leggere

Progetti | +Software Development +| +Desktop Application

Museo e shop online

Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del server

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

Sviluppo software per Drupal

Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Svilluppo di applicazioni web

Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzati

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/categories/progetti/page/3/index.html b/public/categories/progetti/page/3/index.html new file mode 100644 index 0000000..149f4d4 --- /dev/null +++ b/public/categories/progetti/page/3/index.html @@ -0,0 +1,68 @@ +SpeedTech | Progetti +

Applicazione per il tracciamento di Skibus con GPS

Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobus

Continua a leggere

Progetti | +Software Development +| +Web Application

Installazione e personalizzazione sito e-commerce

Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzate

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

Server Linux come file e backup server

Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei files

Continua a leggere

Progetti | +NAS +| +Office Server

Sviluppo software per Drupal

Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Firewall, VPN e rete in server farm

Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi

Continua a leggere

Progetti | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/categories/progetti/page/4/index.html b/public/categories/progetti/page/4/index.html new file mode 100644 index 0000000..f587aea --- /dev/null +++ b/public/categories/progetti/page/4/index.html @@ -0,0 +1,47 @@ +SpeedTech | Progetti +

Applicazioni per CRM, Oracle e certificazione PCI

Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro

Continua a leggere

Progetti | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/categories/projects/index.html b/public/categories/projects/index.html new file mode 100644 index 0000000..8b3eab4 --- /dev/null +++ b/public/categories/projects/index.html @@ -0,0 +1,43 @@ +SpeedTech | Projects +

BrainMinder - second brain web application

BrainMinder è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.

Continua a leggere

Projects | +Software Development +| +Web Application +| +PWA

\ No newline at end of file diff --git a/public/categories/projects/index.xml b/public/categories/projects/index.xml new file mode 100644 index 0000000..578996e --- /dev/null +++ b/public/categories/projects/index.xml @@ -0,0 +1,2 @@ +Projects on Information Technology Serviceshttps://speedtech.it/categories/projects/Recent content in Projects on Information Technology ServicesHugo -- gohugo.ioitThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/blog/brainminder-intro/<p><strong>BrainMinder</strong> è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. +I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.</p> \ No newline at end of file diff --git a/public/categories/projects/page/1/index.html b/public/categories/projects/page/1/index.html new file mode 100644 index 0000000..a29dd9a --- /dev/null +++ b/public/categories/projects/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/categories/projects/ + \ No newline at end of file diff --git a/public/categories/soluzioni/index.html b/public/categories/soluzioni/index.html new file mode 100644 index 0000000..60c481b --- /dev/null +++ b/public/categories/soluzioni/index.html @@ -0,0 +1,76 @@ +SpeedTech | Soluzioni +

Database link con PostgreSQL

In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +PostgreSQL

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Cifrare e comprimere le email lato server

Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server Dovecot permette di cifrare e comprimere i files che contengono la posta elettronica.

Continua a leggere

Soluzioni | +Security +| +Server +| +Privacy +| +Dovecot

VPN con router Fritz!Box

I routers Fritz!Box di AVM forniscono già integrati due importanti servizi che consentono la connettività da remoto : +DNS dinamico VPN basata su protocollo ipsec

Continua a leggere

Soluzioni | +Technology | +VPN +| +Router +| +Networking

Installazione e configurazione Synology NAS

Cliente : diversi +Installazione e configurazione Synology : utenti, privilegi di condivisione e backup Configurazione clients MS Windows

Continua a leggere

Soluzioni | +Technology | +Progetti | +NAS +| +File Server

\ No newline at end of file diff --git a/public/categories/soluzioni/index.xml b/public/categories/soluzioni/index.xml new file mode 100644 index 0000000..69d4896 --- /dev/null +++ b/public/categories/soluzioni/index.xml @@ -0,0 +1,15 @@ +Soluzioni on Information Technology Serviceshttps://speedtech.it/categories/soluzioni/Recent content in Soluzioni on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Database link con PostgreSQLhttps://speedtech.it/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/blog/postgresql-database-link/<p>In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che +risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.</p>Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p>Cifrare e comprimere le email lato serverhttps://speedtech.it/blog/cifrare-comprimere-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/cifrare-comprimere-email-server/<p>Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server +<a href="https://www.dovecot.org/">Dovecot</a> permette di cifrare e comprimere i files che contengono la posta elettronica.</p>VPN con router Fritz!Boxhttps://speedtech.it/blog/vpn-con-frizbox/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/vpn-con-frizbox/<p>I routers <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> di AVM forniscono già integrati due importanti servizi che consentono +la connettività da remoto :</p> +<ul> +<li><strong>DNS dinamico</strong></li> +<li><strong>VPN basata su protocollo ipsec</strong></li> +</ul>Installazione e configurazione Synology NAShttps://speedtech.it/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/blog/synology-nas/<p>Cliente : diversi</p> +<ul> +<li>Installazione e configurazione Synology : utenti, privilegi di condivisione e backup</li> +<li>Configurazione clients MS Windows</li> +</ul> \ No newline at end of file diff --git a/public/categories/soluzioni/page/1/index.html b/public/categories/soluzioni/page/1/index.html new file mode 100644 index 0000000..d98795c --- /dev/null +++ b/public/categories/soluzioni/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/categories/soluzioni/ + \ No newline at end of file diff --git a/public/categories/technology/index.html b/public/categories/technology/index.html new file mode 100644 index 0000000..29953fd --- /dev/null +++ b/public/categories/technology/index.html @@ -0,0 +1,72 @@ +SpeedTech | Technology +

Automazione casa con Home Assistant

Home Assistant è uno strumento interamente open source per la domotica sia di ambienti residenziali che lavorativi.

Continua a leggere

Technology | +Home Assistant +| +Home Automation

Database link con PostgreSQL

In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +PostgreSQL

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

VPN con router Fritz!Box

I routers Fritz!Box di AVM forniscono già integrati due importanti servizi che consentono la connettività da remoto : +DNS dinamico VPN basata su protocollo ipsec

Continua a leggere

Soluzioni | +Technology | +VPN +| +Router +| +Networking

Installazione e configurazione Synology NAS

Cliente : diversi +Installazione e configurazione Synology : utenti, privilegi di condivisione e backup Configurazione clients MS Windows

Continua a leggere

Soluzioni | +Technology | +Progetti | +NAS +| +File Server

\ No newline at end of file diff --git a/public/categories/technology/index.xml b/public/categories/technology/index.xml new file mode 100644 index 0000000..3f6c1ba --- /dev/null +++ b/public/categories/technology/index.xml @@ -0,0 +1,14 @@ +Technology on Information Technology Serviceshttps://speedtech.it/categories/technology/Recent content in Technology on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Database link con PostgreSQLhttps://speedtech.it/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/blog/postgresql-database-link/<p>In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che +risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.</p>Automazione casa con Home Assistanthttps://speedtech.it/blog/automazione-casa-con-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/blog/automazione-casa-con-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> è uno strumento interamente open source per la domotica sia di ambienti residenziali che lavorativi.</p>Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p>VPN con router Fritz!Boxhttps://speedtech.it/blog/vpn-con-frizbox/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/vpn-con-frizbox/<p>I routers <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> di AVM forniscono già integrati due importanti servizi che consentono +la connettività da remoto :</p> +<ul> +<li><strong>DNS dinamico</strong></li> +<li><strong>VPN basata su protocollo ipsec</strong></li> +</ul>Installazione e configurazione Synology NAShttps://speedtech.it/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/blog/synology-nas/<p>Cliente : diversi</p> +<ul> +<li>Installazione e configurazione Synology : utenti, privilegi di condivisione e backup</li> +<li>Configurazione clients MS Windows</li> +</ul> \ No newline at end of file diff --git a/public/categories/technology/page/1/index.html b/public/categories/technology/page/1/index.html new file mode 100644 index 0000000..7de2c92 --- /dev/null +++ b/public/categories/technology/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/categories/technology/ + \ No newline at end of file diff --git a/public/css/base.css b/public/css/base.css new file mode 100644 index 0000000..d79aac1 --- /dev/null +++ b/public/css/base.css @@ -0,0 +1,774 @@ + +/* Dark theme */ +/* +@media (prefers-color-scheme: dark) { + :root, + ::backdrop { + color-scheme: dark; + --bg: #212121; + --accent-bg: #2b2b2b; + --text: #dcdcdc; + --text-light: #ababab; + --accent: #ffb300; + --accent-hover: #ffe099; + --accent-text: var(--bg); + --code: #f06292; + --preformatted: #ccc; + --disabled: #111; + } + */ + +/* Add a bit of transparency so light media isn't so glaring in dark mode */ +/* +img, +video { + opacity: 0.8; +} +} +*/ + +/* Reset */ + +/* Box sizing rules */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Prevent font size inflation */ +html { + -moz-text-size-adjust: none; + -webkit-text-size-adjust: none; + text-size-adjust: none; +} + +/* Remove default margin in favour of better control in authored CSS */ +body, h1, h2, h3, h4, p, +figure, blockquote, dl, dd { + margin-block-end: 0; +} + +/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */ +ul[role='list'], +ol[role='list'] { + list-style: none; +} + +/* Set core body defaults */ +body { + min-height: 100vh; + line-height: 1.5; + margin-left: 0; + margin-right: 0; +} + +/* Balance text wrapping on headings */ +h1, h2, +h3, h4 { + text-wrap: balance; +} + +/* A elements that don't have a class get default styles */ +a:not([class]) { + text-decoration-skip-ink: auto; + color: currentColor; +} + +/* Inherit fonts for inputs and buttons */ +input, button, +textarea, select { + font-family: inherit; + font-size: inherit; +} + +/* Anything that has been anchored to should have extra scroll margin */ +:target { + scroll-margin-block: 5ex; +} + +h1,h2,h3,h4,h5,h6, form { + margin: 0; + padding: 0; +} + +a { + text-decoration: none; + color: var(--primary-color); +} +/* End reset */ + +body { + padding-top: 100px; + font-family: Inter, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, Helvetica, Arial, "Helvetica Neue", sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.col, +.half, +.third, +.twothird, +.threequarter, +.quarter { + float: left; + width: 100% +} + +.col.rest { + overflow: hidden; +} + +.col.s1 { + width: 8.33333% +} + +.col.s2 { + width: 16.66666% +} + +.col.s3 { + width: 24.99999% +} + +.col.s4 { + width: 33.33333% +} + +.col.s5 { + width: 41.66666% +} + +.col.s6 { + width: 49.99999% +} + +.col.s7 { + width: 58.33333% +} + +.col.s8 { + width: 66.66666% +} + +.col.s9 { + width: 74.99999% +} + +.col.s10 { + width: 83.33333% +} + +.col.s11 { + width: 91.66666% +} + +.col.s12 { + width: 99.99999% +} + +.col.left { + text-align: left; +} + +.col.right { + text-align: right; +} + +.dropdown-item > i { + margin-right: 5px; + vertical-align: bottom; +} + +.show-large { + display: none; +} + +.icon { + vertical-align: middle; + display: inline-block; + width: 24px; + height: 24px; + background-color: currentColor; + -webkit-mask-image: var(--svg); + mask-image: var(--svg); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: 100% 100%; + mask-size: 100% 100%; +} + +.icon-responsive-menu { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M4.5 17.27q-.213 0-.356-.145T4 16.768t.144-.356t.356-.143h15q.213 0 .356.144q.144.144.144.357t-.144.356t-.356.143zm0-4.77q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-4.77q-.213 0-.356-.143Q4 7.443 4 7.23t.144-.356t.356-.143h15q.213 0 .356.144T20 7.23t-.144.356t-.356.144z'/%3E%3C/svg%3E"); + -webkit-mask-image: var(--svg); + mask-image: var(--svg); +} + +.container { + max-width: 1140px; + width: 100%; + margin: 0 auto; + clear: both; + overflow: auto; +} + +.row { + clear: both; + overflow: auto; +} + +#topnav { + background-color: var(--dark-color); + border-bottom: 1px solid #ddd; + padding: 0 10px; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + height: auto; + + .container { + display: flex; + align-items: center; + overflow: unset; + } + + ul > li >a { + color: white; + } + + .navbar-brand img { + height: 50px; + } +} + +#topmenu { + display: flex; + align-items: center; + justify-content: flex-end; + flex-grow: 1; +} + +#responsive-button { + display: none; + margin: 0; + padding: 0; + width: 32px; + height: 32px; + cursor: pointer +} + +#topmenu ul { + list-style: none; +} + +#topmenu ul li { + display: block; + float: left; + padding: 1rem; + position: relative; + text-decoration: none; + transition-duration: 0.5s; + font-weight: 500; +} + +#topmenu ul li.dropdown:after { + content: "\25BE"; + margin-left: 5px; + color: #fff; +} + +#topmenu ul.submenu { + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0,0,0,.15); + border-radius: .25rem; + visibility: hidden; + opacity: 0; + min-width: 5rem; + position: absolute; + transition: all 0.5s ease; + margin-top: 1rem; + left: 0; + display: none; + z-index: 2000; + padding: 0px; +} + +#topmenu ul.submenu li { + clear: both; + width: 100%; + text-align: left; + white-space: nowrap; + background-color: transparent; + border: 0; + padding: 5px 10px; +} + +#topmenu ul li ul li:hover { + background-color: #ccc; +} + +#topmenu ul li ul a { + color: var(--dark-color); +} + +#topmenu :is(ul li:hover > ul, li:focus-within > ul, ul li ul:hover, ul li ul:focus) { + visibility: visible; + opacity: 1; + display: block; +} + +#home-introduction { + h4 { + text-align: center; + } + + img { + display: block; + margin-right: auto !important; + margin-left: auto !important; + padding: .25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: .25rem; + max-width: 100%; + height: auto; + } +} + +#home-bottom { + margin-top: 20px; + padding-top: 20px; + padding-bottom: 20px; + background: #000 url("../img/bg-image-1.jpg") no-repeat; + color: white; + h2 { + text-align: center; + } + + p { + margin-top: 5px; + } +} + +header { + margin-bottom: 30px; +} + +header .col { + text-align: center; +} + +.list-group .row { + margin-bottom: 40px; +} + +.list-group .row h4 { + text-align: center +} + +footer { + background-color: var(--dark-color); + color: rgba(255, 255, 255, 0.7); + padding-top: 40px; + padding-bottom: 40px; + + .menu ul { + list-style-type: none; + padding-left: 0; + } +} + +.img-fluid { + max-width: 100% +} + +.text-center { + text-align: center; +} + +ul.pagination { + list-style-type: none; + display: flex; + justify-content: center; +} + +link { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; +} +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + background-color: #fff; + border-color: #dee2e6; +} + +.page-link { + position: relative; + display: block; + color: var(--primary-color); + padding: .375rem .75rem; + text-decoration: none; + background-color: #fff; + border: 1px solid #dee2e6; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; +} + +.page-item.active .page-link { + background-color: var(--primary-color); + border-color: var(--primary-color); + color: #fff; +} + +.page-item:not(:first-child) .page-link { + margin-left: -1px; +} + +.page-item:first-child .page-link { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; +} + +.page-item:last-child .page-link { + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem; +} + +#home-blog-posts { + margin-top: 30px; +} + +#home-blog-posts h3 { + margin-bottom: 20px; +} + +#home-blog-posts .article { + padding-bottom: 20px; + border-bottom: 1px solid #ccc; +} + +/* Extra small */ +@media (max-width: 576px) { + .table-all.responsive table, + .table-all.responsive thead, + .table-all.responsive tbody, + .table-all.responsive th, + .table-all.responsive td, + .table-all.responsive tr { + display: block; + } + + .table-all thead tr { + position: absolute; + top: -9999px; + left: -9999px; + } + + .table-all.responsive tr { + margin-bottom: 10px; + border: 1px solid #ddd; + } + + .table-all.responsive td { + border: none; + position: relative; + padding-left: 30%; + } + + .table-all.responsive td.no-label { + padding-left: 6px; + } + + .table-all.responsive td.title { + color: #2b5797; + font-weight: 400; + font-size: 18px; + } + + .table-all.responsive td:before { + position: absolute; + left: 6px; + content: attr(data-label); + font-weight: bold; + } + + .table-all.responsive td.no-label:before { + position: absolute; + left: 6px; + content: ""; + font-weight: bold; + } + + .hide-xsmall { + display: none !important + } +} + +/* Small */ +@media (min-width:577px) and (max-width: 767px) { +} + +/* Minimum small */ +@media (min-width:576px) { + .col.half { + width: 49.99999%; + } + .col.m6, .col.half:first-child { + padding-right:10px; + } +} + +/* Max small */ +@media (max-width: 767px) { + .col.s1 { + width: 8.33333% + } + + .col.s2 { + width: 16.66666% + } + + .col.s3 { + width: 24.99999% + } + + .col.s4 { + width: 33.33333% + } + + .col.s5 { + width: 41.66666% + } + + .col.s6 { + width: 49.99999% + } + + .col.s7 { + width: 58.33333% + } + + .col.s8 { + width: 66.66666% + } + + .col.s9 { + width: 74.99999% + } + + .col.s10 { + width: 83.33333% + } + + .col.s11 { + width: 91.66666% + } + + .col.s12 { + width: 99.99999% + } +} + +/* Medium */ +@media (min-width:768px) and (max-width: 991px) { + .col.m1 { + width: 8.33333% + } + + .col.m2 { + width: 16.66666% + } + + .col.m3 { + width: 24.99999% + } + + .col.m4 { + width: 33.33333% + } + + .col.m5 { + width: 41.66666% + } + + .col.m6 { + width: 49.99999% + } + + .col.m7 { + width: 58.33333% + } + + .col.m8 { + width: 66.66666% + } + + .col.m9 { + width: 74.99999% + } + + .col.m10 { + width: 83.33333% + } + + .col.m11 { + width: 91.66666% + } + + .col.m12 { + width: 99.99999% + } +} + +/* Min medium */ +@media (min-width: 768px) { + .hide-medium { + display: none !important + } +} + +/* Large */ +@media (min-width:992px) { + .col.l1 { + width: 8.33333% + } + + .col.l2 { + width: 16.66666% + } + + .col.l3 { + width: 24.99999% + } + + .col.l4 { + width: 33.33333% + } + + .col.l5 { + width: 41.66666% + } + + .col.l6 { + width: 49.99999% + } + + .col.l7 { + width: 58.33333% + } + + .col.l8 { + width: 66.66666% + } + + .col.l9 { + width: 74.99999% + } + + .col.l10 { + width: 83.33333% + } + + .col.l11 { + width: 91.66666% + } + + .col.l12 { + width: 99.99999% + } + + .hide-large { + display: none !important; + } + + .show-large { + display: inline !important; + } + + #main-sidebar { + display: block !important; + } + + .row > .half:first-child { + padding-right: 4px; + } + + .row > .half:nth-child(2) { + padding-left: 4px; + } +} + +@media screen and (max-width: 992px) { + body { + padding-top: 80px; + } + + #responsive-button { + display: block; + } + + #topnav { + padding-top: 10px; + padding-bottom: 10px; + } + + #topmenu { + position:relative; + } + + #topmenu ul { + background:var(--dark-color); + position:absolute; + z-index:3; + height:auto; + display:none; + top: 55px; + right: -30px; + flex-direction: column; + border-bottom-left-radius: 10px; + padding-left:0; + } + + #topmenu ul li { + padding-top:4px; + padding-bottom: 4px; + } + + #topmenu ul li.dropdown:after { + content: none; + } + + #topmenu ul.submenu { + width:100%; + position:static; + background: var(--dark-color); + color: #fff; + padding-top:4px; + padding-bottom: 4px; + margin-top:0; + margin-bottom:0; + } + + #topmenu ul.submenu li a{ + color: #fff; + } + + #topmenu li {display:block;float:left;width:auto;} + + #topmenu :is(ul li:hover > ul, li:focus-within > ul, ul li ul:hover, ul li ul:focus) { + display: flex; + } + + #topmenu.responsive ul {display: flex;visibility: visible; opacity: 1; margin-top:0} + #topmenu.responsive ul>li>ul.submenu>li {visibility: visible; display:block;} +} + +@media (max-width: 1140px) { + .container { + padding-left: 20px; + padding-right: 20px; + } +} \ No newline at end of file diff --git a/public/css/colors.css b/public/css/colors.css new file mode 100644 index 0000000..e139752 --- /dev/null +++ b/public/css/colors.css @@ -0,0 +1,8 @@ +/* Global variables. */ +:root, +::backdrop { + /* Default (light) theme */ + --bg-color: #fff; + --dark-color: rgba(33,37,41); + --primary-color: #2b5797; +} \ No newline at end of file diff --git a/public/css/main.css b/public/css/main.css new file mode 100644 index 0000000..7492eac --- /dev/null +++ b/public/css/main.css @@ -0,0 +1,175 @@ +@import "colors.css"; +@import "base.css"; + +.icon-desktop { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M9 20v-1h2v-2H3V4h18v13h-8v2h2v1zm-5-4h16V5H4zm0 0V5z'/%3E%3C/svg%3E"); +} + +.icon-cart { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M7.308 21.116q-.633 0-1.067-.434t-.433-1.066t.433-1.067q.434-.433 1.067-.433t1.066.433t.434 1.067t-.434 1.066t-1.066.434m9.384 0q-.632 0-1.066-.434t-.434-1.066t.434-1.067q.434-.433 1.066-.433t1.067.433q.433.434.433 1.067q0 .632-.433 1.066q-.434.434-1.067.434M5.881 5.5l2.669 5.616h6.635q.173 0 .307-.087q.135-.087.231-.24l2.616-4.75q.115-.212.019-.375q-.097-.164-.327-.164zm-.489-1h13.02q.651 0 .98.532q.33.531.035 1.095l-2.858 5.208q-.217.365-.564.573t-.763.208H8.1l-1.215 2.23q-.154.231-.01.5t.433.27h10.884v1H7.308q-.875 0-1.306-.738t-.021-1.482l1.504-2.68L3.808 3.5H2v-1h2.442zm3.158 6.616h7z'/%3E%3C/svg%3E"); +} + +.icon-layers { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M12 13.385L2.02 8.192L12 3l10 5.192zm0 3.807l-9.406-4.886l1.043-.573L12 16.052l8.383-4.32l1.042.574zM12 21l-9.406-4.887l1.043-.573L12 19.86l8.383-4.32l1.042.573z'/%3E%3C/svg%3E"); +} + +.icon-email{ + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='m15.489 21.27l-3.558-3.558l.708-.708l2.85 2.85l5.688-5.688l.708.707zM12 11l7.692-5H4.308zm0 1.116L4 6.885v10.5q0 .269.173.442t.443.173H9.4l1 1H4.616q-.691 0-1.153-.462T3 17.384V6.616q0-.691.463-1.153T4.615 5h14.77q.69 0 1.152.463T21 6.616v4.926l-1 1V6.885zm0 0'/%3E%3C/svg%3E"); +} + +.icon-server { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M4.616 20q-.691 0-1.153-.462T3 18.384V5.616q0-.691.463-1.153T4.615 4h4.577q.69 0 1.153.463t.463 1.153v12.769q0 .69-.463 1.153T9.192 20zm10.192 0q-.69 0-1.153-.462t-.463-1.153V5.615q0-.69.463-1.152T14.808 4h4.577q.69 0 1.152.463T21 5.616v12.769q0 .69-.463 1.153T19.385 20zM4.616 19h4.576q.27 0 .443-.173t.173-.442V5.615q0-.269-.174-.442Q9.462 5 9.192 5H4.616q-.27 0-.443.173T4 5.616v12.769q0 .269.173.442t.443.173m10.192 0h4.577q.269 0 .442-.173t.173-.442V5.615q0-.269-.173-.442T19.385 5h-4.577q-.27 0-.443.173t-.173.443v12.769q0 .269.173.442t.443.173m-9.423-4.615h3v-1h-3zm10.23 0h3v-1h-3zm-10.23-2.808h3v-1h-3zm10.23 0h3v-1h-3zM5.386 8.75h3v-1h-3zm10.23 0h3v-1h-3zM4.616 19H4h5.808zm10.193 0h-.616H20z'/%3E%3C/svg%3E"); +} + +.icon-cloud { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M4.654 19.346v-1h3.09q-1.794-1.561-2.519-3.073T4.5 12.077q0-2.454 1.402-4.409T9.5 4.942v1.062q-1.789.74-2.894 2.403T5.5 12.077q0 1.523.643 2.805t2.28 2.722v-3.027h1v4.77zM15 19.5q-1.02 0-1.76-.74T12.5 17q0-1.008.68-1.726t1.805-.768q.367-.881 1.147-1.444T18 12.5q1.229 0 2.134.815q.904.814 1.047 2.185h.307q.839 0 1.425.571t.587 1.404q0 .839-.58 1.432t-1.42.593zm3.4-8.77q-.252-1.14-.838-2.091t-1.985-2.223v3.007h-1v-4.77h4.77v1h-3.091q1.594 1.413 2.253 2.61q.658 1.199.897 2.468zM15 18.5h6.5q.412 0 .706-.294t.294-.706t-.294-.706t-.706-.294h-1.25v-.75q0-.937-.657-1.593T18 13.5t-1.564.57t-.667 1.372v.058H15q-.617 0-1.059.441q-.441.442-.441 1.059t.441 1.059q.442.441 1.059.441m3-2.5'/%3E%3C/svg%3E"); +} + +.icon-computer { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M1.77 19.462v-1h20.46v1zm2.846-2q-.691 0-1.153-.463T3 15.846V6.077q0-.69.463-1.153t1.152-.462h14.77q.69 0 1.152.462T21 6.077v9.77q0 .69-.463 1.152t-1.153.463zm0-1h14.769q.23 0 .423-.193t.192-.423V6.077q0-.23-.192-.423q-.193-.193-.424-.193H4.616q-.231 0-.424.193Q4 5.846 4 6.077v9.77q0 .23.192.422t.423.193m-.615 0v-11z'/%3E%3C/svg%3E"); +} + +.icon-security { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M12 20.962q-3.014-.895-5.007-3.651T5 11.1V5.692l7-2.615l7 2.615V11.1q0 3.454-1.993 6.21T12 20.963m0-1.062q2.425-.75 4.05-2.962T17.95 12H12V4.144L6 6.375v5.156q0 .194.05.469H12z'/%3E%3C/svg%3E"); +} + +.icon-robot { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M5 20v-4.043q0-.667.475-1.139q.474-.472 1.14-.472h10.77q.666 0 1.14.475T19 15.96V20zm4.289-7.423q-1.78 0-3.035-1.255Q5 10.068 5 8.29t1.254-3.035T9.29 4h5.423q1.78 0 3.034 1.254T19 8.29t-1.254 3.034t-3.034 1.254zM6 19h12v-3.038q0-.27-.173-.443t-.442-.173H6.615q-.269 0-.442.173T6 15.962zm3.289-7.423h5.422q1.385 0 2.337-.952T18 8.289t-.952-2.337T14.712 5H9.289q-1.385 0-2.337.952T6 8.289t.952 2.336t2.337.952m-.001-2.558q.31 0 .52-.21t.211-.52t-.21-.52t-.52-.211t-.52.21t-.211.52t.21.52t.52.211m5.423 0q.31 0 .52-.21t.211-.52t-.21-.52t-.52-.211t-.52.21t-.211.52t.21.52t.52.211M12 8.29'/%3E%3C/svg%3E"); +} + +.icon-phone { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='m17.77 9.462l-.72-.708l2.1-2.1h-5.88v-1h5.88l-2.088-2.089l.707-.719l3.308 3.32zM18.93 20q-2.528 0-5.184-1.266t-4.944-3.555q-2.27-2.288-3.536-4.935T4 5.07q0-.45.3-.76T5.05 4h2.473q.408 0 .712.257t.411.659L9.142 7.3q.07.42-.025.733t-.333.513L6.59 10.592q.616 1.117 1.361 2.076t1.59 1.817q.87.87 1.874 1.62q1.004.749 2.204 1.414l2.139-2.177q.244-.263.549-.347q.304-.083.674-.033l2.103.43q.408.1.662.411t.254.712v2.435q0 .45-.31.75t-.76.3M6.122 9.654l1.92-1.765q.095-.077.124-.212q.03-.135-.01-.25l-.443-2.12q-.039-.153-.135-.23T7.327 5H5.275q-.115 0-.192.077t-.077.192q.029 1.025.321 2.14t.794 2.245m8.45 8.334q1.014.502 2.16.743q1.148.24 2 .257q.115 0 .192-.077T19 18.72v-2.008q0-.153-.077-.25q-.077-.096-.23-.134l-1.85-.379q-.116-.039-.203-.01q-.086.03-.182.125zm0 0'/%3E%3C/svg%3E"); + +} + +.icon-git { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M15.698 7.287L8.712.302a1.03 1.03 0 0 0-1.457 0l-1.45 1.45l1.84 1.84a1.223 1.223 0 0 1 1.55 1.56l1.773 1.774a1.224 1.224 0 0 1 1.267 2.025a1.226 1.226 0 0 1-2.001-1.334L8.579 5.963v4.353q.177.085.324.231a1.226 1.226 0 1 1-1.332-.267V5.887a1.226 1.226 0 0 1-.666-1.608L5.093 2.465l-4.79 4.79a1.03 1.03 0 0 0 0 1.457l6.986 6.986a1.03 1.03 0 0 0 1.457 0l6.953-6.953a1.03 1.03 0 0 0 0-1.458'/%3E%3C/svg%3E"); +} + +.icon-location { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M11.5 13.5h1v-3h3v-1h-3v-3h-1v3h-3v1h3zm.5 7.52q-3.525-3.118-5.31-5.815q-1.786-2.697-1.786-4.909q0-3.173 2.066-5.234Q9.037 3 12 3t5.03 2.062q2.066 2.061 2.066 5.234q0 2.212-1.785 4.909q-1.786 2.697-5.311 5.814'/%3E%3C/svg%3E"); +} + +.icon-link { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M10.616 16.077H7.077q-1.692 0-2.884-1.192T3 12t1.193-2.885t2.884-1.193h3.539v1H7.077q-1.27 0-2.173.904Q4 10.731 4 12t.904 2.173t2.173.904h3.539zM8.5 12.5v-1h7v1zm4.885 3.577v-1h3.538q1.27 0 2.173-.904Q20 13.269 20 12t-.904-2.173t-2.173-.904h-3.538v-1h3.538q1.692 0 2.885 1.192T21 12t-1.193 2.885t-2.884 1.193z'/%3E%3C/svg%3E"); +} + +.icon-menu { + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M4 17.27v-1h16v1zm0-4.77v-1h16v1zm0-4.77v-1h16v1z'/%3E%3C/svg%3E"); + -webkit-mask-image: var(--svg); + mask-image: var(--svg); +} + +#home-introduction { + text-align: justify; + box-shadow: 0 10px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19) !important; + border-radius: 8px; + padding: 10px; + font-style: italic; +} + +#home-introduction p:first-child { + margin-top: 0; +} + +.service { + display: flex; + margin-top: 10px; + margin-bottom: 10px; +} + +footer .menu { + border-bottom: 1px solid; +} + +.blog-article-summary p { + margin-top: 0; +} + +.row.blog-article-item-list img, .articlecontent img, .servicecontent img { + box-shadow: 0 10px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19) !important; + border-radius: 8px; + padding: 10px; +} + +.articlecontent a { + color: var(--primary-color); + text-decoration: underline; +} + +.servicesidebar h4 { + margin-bottom: 16px; +} + +.servicesidebar .article { + margin-bottom: 16px; +} + +.servicesidebar img, .blogsidebar img { + box-shadow: 0 8px 14px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19) !important; + border-radius: 4px; + padding: 4px; +} + +.blog-article-title { + margin-bottom: 20px; + text-align: center; +} + +.blog-article-image { + padding-left: 20px; + padding-right: 20px; +} + +.blog-single .title { + margin-top: 20px; +} + +.blogsidebar { + margin-bottom: 20px; +} + +.blogsidebar .tags { + margin-bottom: 20px; +} + +.servicecontent { + padding-right: 10px; +} + +.articles.home { + margin-top: 20px; +} + +.articles.home img { + box-shadow: 0 10px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19) !important; + border-radius: 8px; +} + +.articles.home .article { + margin-top: 20px; + margin-bottom: 20px; +} + +figure.img-fluid img { + max-width: 100%; +} + +/* Min medium */ +@media (min-width: 767px) { + .servicesidebar, .blogsidebar { + border-left: 1px solid #ccc; + } + + .articlecontent, .servicecontent { + padding-left: 20px; + padding-right: 20px; + } +} + +/* Max small */ +@media (max-width: 767px) { + .servicesidebar, .blogsidebar { + margin-top: 30px; + } +} \ No newline at end of file diff --git a/public/en/404.html b/public/en/404.html new file mode 100644 index 0000000..1a91d5d --- /dev/null +++ b/public/en/404.html @@ -0,0 +1,11 @@ +SpeedTech | 404 Page not found +

\ No newline at end of file diff --git a/public/en/blog/agiati-web-applications/index.html b/public/en/blog/agiati-web-applications/index.html new file mode 100644 index 0000000..0f0b367 --- /dev/null +++ b/public/en/blog/agiati-web-applications/index.html @@ -0,0 +1,44 @@ +SpeedTech | Blog - Accounting, members and custom CMS applications +

Blog

Accounting, members and custom CMS applications

Client : Accademia degli Agiati (Rovereto - IT)

Technologies used : PHP, Yii Framework, MariaDB, Bootstrap

  • Database design
  • Logic and structure study
  • Applications implementation and development
  • Support and maintenance
  • CMS for the institutional website
Publish date : 2019-05-04 | Last change : 2019-05-04

Projects | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/en/blog/altevie-geomapping/index.html b/public/en/blog/altevie-geomapping/index.html new file mode 100644 index 0000000..46ccc54 --- /dev/null +++ b/public/en/blog/altevie-geomapping/index.html @@ -0,0 +1,44 @@ +SpeedTech | Blog - Skibus GPS map tracking application +

Blog

Skibus GPS map tracking application

Client : Altevie (Trento - IT)

Responsive web application with responsive map to track the position of gps equipped skibus

  • Application design and development
  • Server and database installation and configuration
  • Integration with external SOAP services to collect the bus positions and time schedule
  • Development of the map features with bus stop positions, realtime buses position and direction detection
Publish date : 2015-01-31 | Last change : 2015-01-31

Projects | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/en/blog/amorcosmetics-ecommerce/index.html b/public/en/blog/amorcosmetics-ecommerce/index.html new file mode 100644 index 0000000..76f3704 --- /dev/null +++ b/public/en/blog/amorcosmetics-ecommerce/index.html @@ -0,0 +1,46 @@ +SpeedTech | Blog - E-commerce website setup and customization for beauty products +

Blog

E-commerce website setup and customization for beauty products

\ No newline at end of file diff --git a/public/en/blog/amore-ecommerce/index.html b/public/en/blog/amore-ecommerce/index.html new file mode 100644 index 0000000..2fdee9f --- /dev/null +++ b/public/en/blog/amore-ecommerce/index.html @@ -0,0 +1,46 @@ +SpeedTech | Blog - E-commerce website setup and customization +

Blog

E-commerce website setup and customization

Cliente : Ditta Amore (Rovereto - IT)

E-commerce website integrated with credit card payments and shipping fees computation

  • E-commerce OpenCart platform setup and configuration
  • Modules selection, installation and customization
  • Credit card Stripe payment system integration
  • Custom shipment fees calculation module development
  • Development of custom features
Publish date : 2012-08-02 | Last change : 2012-08-02

Projects | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/en/blog/botta-museum/index.html b/public/en/blog/botta-museum/index.html new file mode 100644 index 0000000..4c031b1 --- /dev/null +++ b/public/en/blog/botta-museum/index.html @@ -0,0 +1,48 @@ +SpeedTech | Blog - Online museum and e-commerce +

Blog

Online museum and e-commerce

Client: Museo Botta (Rovereto - IT)

Car models and advertising objects virtual museum with custom e-commerce

  • Yii framework structure
  • Implementation of client design
  • Bootstrap 3 theming framework
  • Online shop and ordering and payment system
  • Server installation and configuration
Publish date : 2017-04-15 | Last change : 2017-04-15

Projects | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

\ No newline at end of file diff --git a/public/en/blog/brainminder-intro/index.html b/public/en/blog/brainminder-intro/index.html new file mode 100644 index 0000000..393bb0f --- /dev/null +++ b/public/en/blog/brainminder-intro/index.html @@ -0,0 +1,47 @@ +SpeedTech | Blog - BrainMinder - second brain web application +

Blog

BrainMinder - second brain web application

BrainMinder is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. +Items are shared with external users via a pre-authorized link and (optionally) an additional password.

It permits organizing personal knowledge in different types of items that can be created to one’s preference. Every item type has some basic fields to collect the information (like title, summary, description) but other fields can be created as preferred.

BrainMinder has been created with Golang programming language, use SQLite as database and the Javascript tool Unpoly. +The software is already usable and very useful but is currently under heavy development and new features are added frequently.

Publish date : 2025-10-30 | Last change : 2025-10-30

Projects | +Software Development +| +Web Application +| +PWA

\ No newline at end of file diff --git a/public/en/blog/cspolsa-renting/index.html b/public/en/blog/cspolsa-renting/index.html new file mode 100644 index 0000000..d5dad05 --- /dev/null +++ b/public/en/blog/cspolsa-renting/index.html @@ -0,0 +1,44 @@ +SpeedTech | Blog - Ski rental service software application +

Blog

Ski rental service software application

Client : Centro Snowboard Polsa (Rovereto - IT)

Design and development of a cross platform desktop application for MS Windows and Linux operating systems using :

  • ObjectPascal language
  • Lazaurs IDE
  • MariaDB database
  • Onsite Linux server

for skies and accessories renting.

Publish date : 2017-12-12 | Last change : 2017-12-12

Projects | +Software Development +| +Desktop Application

\ No newline at end of file diff --git a/public/en/blog/daxtor-firewall-vpn-server-farm/index.html b/public/en/blog/daxtor-firewall-vpn-server-farm/index.html new file mode 100644 index 0000000..15743eb --- /dev/null +++ b/public/en/blog/daxtor-firewall-vpn-server-farm/index.html @@ -0,0 +1,46 @@ +SpeedTech | Blog - Firewall, VPN and server farm network +

Blog

Firewall, VPN and server farm network

Client : Daxtor (Bolzano - IT)

Network and security design and implementation for SAS service in a server farm

  • Hardware selection
  • Network design
  • Linux application server installation and configuration
  • Oracle database server installation
  • Redundant firewalls configuration and maintenance
  • VPN based on IPSec and OpenVPN configuration and maintenance for access control
Publish date : 2002-06-07 | Last change : 2002-06-07

Projects | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/en/blog/deflorian-server/index.html b/public/en/blog/deflorian-server/index.html new file mode 100644 index 0000000..af83b99 --- /dev/null +++ b/public/en/blog/deflorian-server/index.html @@ -0,0 +1,44 @@ +SpeedTech | Blog - Linux file and backup server +

Blog

Linux file and backup server

Client : Deflorian Law Firm (Rovereto - IT)

Linux server to serve many users with different privileges in a MS Windows environment

  • Linux Debian server base installation and configuration
  • Software RAID support configuration
  • File server configuration and privileges assignment
  • External and redundant backup with versioning files support
Publish date : 2011-03-12 | Last change : 2011-03-12

Projects | +NAS +| +Office Server

\ No newline at end of file diff --git a/public/en/blog/encrypt-compress-email-server/index.html b/public/en/blog/encrypt-compress-email-server/index.html new file mode 100644 index 0000000..d06184e --- /dev/null +++ b/public/en/blog/encrypt-compress-email-server/index.html @@ -0,0 +1,95 @@ +SpeedTech | Blog - Encrypt and compress emails server side +

Blog

Encrypt and compress emails server side

To improve the security and privacy of users and save disk space, the mail server +Dovecot allows encrypting the files containing the e-mail messages.

Compression is done through the zlib plugin while encryption is done through the mail_crypt plugin.

mail_plugins = $mail_plugins zlib mail_crypt
+

The plugins can be configured with several options

plugin {
+  mail_crypt_global_private_key = </etc/dovecot/crypt/master.key
+  mail_crypt_global_public_key = </etc/dovecot/crypt/master.pub
+  mail_crypt_curve = prime256v1
+  mail_crypt_save_version = 2
+  zlib_save_level = 6
+  zlib_save = lz4
+}
+

To encrypt is necessary to create the key pair: private (master.key) to encrypt and public (master.pub) to decrypt.

In this way, in case of a server breach, and the e-mail files are stolen, they would be unreadable without the private key necessary to decrypt them.

From the moment the encryption and compression are active, all the new messages will be automatically encrypted and compressed in a transparent way for the final user.

To encrypt and compress pre-existing e-mails, simply move messages from one folder to another using an IMAP client. +Alternatively, the following bash script can be used to initiate encryption of all mail files in the example directory /var/vmail/domain/user/Maildir (compression is not possible AFAIK).

find /var/vmail/domain/user/Maildir -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
+if [[ $(head -c7 "$file") != "CRYPTED" ]]; then
+echo $file
+doveadm fs put crypt private_key_path=/etc/dovecot/crypt/master.key:public_key_path=/etc/dovecot/crypt/master.pub:posix:prefix=/ \
+  "$file" "$file"
+  chmod 600 "$file"
+  chown vmail:vmail "$file"
+fi
+done
+

In case, on the other hand, it is necessary to access one or more unencrypted email files, the following scripts can be used :

To decrypt only (in case the files have not been compressed)

find /var/vmail/domain/user/Maildir -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
+if [[ $(head -c7 "$file") == "CRYPTED" ]]; then
+  echo $file
+  doveadm fs get crypt private_key_path=/etc/dovecot/crypt/master.key:public_key_path=/etc/dovecot/crypt/master.pub:posix:prefix=/ \
+  "$file" > "/tmp/$(basename "$file")"
+  if [[ -s "/tmp/$(basename "$file")" ]]; then
+    chmod 600 "/tmp/$(basename "$file")"
+    chown vmail:vmail "/tmp/$(basename "$file")"
+    mv "/tmp/$(basename "$file")" "$file"
+  else
+    rm "/tmp/$(basename "$file")"
+  fi
+fi
+done
+

To decrypt and decompress :

find /var/vmail/domain/user/Maildir -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
+if [[ $(head -c7 "$file") == "CRYPTED" ]]; then
+  echo $file
+  doveadm fs get compress lz4:0:crypt:private_key_path=/etc/dovecot/crypt/master.key:public_key_path=/etc/dovecot/crypt/master.pub:posix:prefix=/ \
+  "$file" > "/tmp/$(basename "$file")"
+  if [[ -s "/tmp/$(basename "$file")" ]]; then
+    chmod 600 "/tmp/$(basename "$file")"
+    chown vmail:vmail "/tmp/$(basename "$file")"
+    mv "/tmp/$(basename "$file")" "$file"
+  else
+    rm "/tmp/$(basename "$file")"
+  fi
+fi
+done
+
Publish date : 2022-07-08 | Last change : 2022-07-08

Solutions | +Security +| +Server +| +Privacy +| +Dovecot

\ No newline at end of file diff --git a/public/en/blog/finova-firewall/index.html b/public/en/blog/finova-firewall/index.html new file mode 100644 index 0000000..f4e5511 --- /dev/null +++ b/public/en/blog/finova-firewall/index.html @@ -0,0 +1,50 @@ +SpeedTech | Blog - VPS servers, Firewall and VPN +

Blog

VPS servers, Firewall and VPN

Client : Finova (Bolzano - IT)

Network and security design and implementation for SAS services

  • Hardware selection
  • Network design
  • Linux application server installation and configuration
  • VPN based on OpenVPN configuration and maintenance for access control
  • VPS management
Publish date : 2019-09-14 | Last change : 2019-09-14

Projects | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

\ No newline at end of file diff --git a/public/en/blog/finova-oracle-apex/index.html b/public/en/blog/finova-oracle-apex/index.html new file mode 100644 index 0000000..705064f --- /dev/null +++ b/public/en/blog/finova-oracle-apex/index.html @@ -0,0 +1,48 @@ +SpeedTech | Blog - Oracle database and APEX +

Blog

Oracle database and APEX

Client : Finova (Bolzano - IT)

Oracle database and APEX configuration and installation

  • Linux CentOS server base installation and configuration
  • Oracle XE database installation and configuration
  • APEX installation and configuration
  • Apache and Tomcat configuration
Publish date : 2019-11-09 | Last change : 2019-11-09

Projects | +System Administration +| +Database +| +Server +| +Linux

\ No newline at end of file diff --git a/public/en/blog/fritzbox-vpn/index.html b/public/en/blog/fritzbox-vpn/index.html new file mode 100644 index 0000000..d000ea0 --- /dev/null +++ b/public/en/blog/fritzbox-vpn/index.html @@ -0,0 +1,54 @@ +SpeedTech | Blog - VPN with Fritz!Box router +

Blog

VPN with Fritz!Box router

AVM's Fritz!Box routers already provide built-in two important services that enable +remote connectivity :

  • Dynamic DNS
  • VPN based on ipsec protocol.

New firmware version under development, will also allow the creation of VPNs based on Wireguard.

Dynamic DNS associates the router’s public IP with a host name on the myfritz.net domain, allowing thus making it possible to reach the router over the Internet even if you do not have a connection with a static IP.

This functionality is preparatory to the implementation of the VPNs that Fritz!Box supports. +VPNs can be of 2 types :

  1. site to site : to connect 2 or more Fritz!Box devices (or even compatible devices that support the same type of VPN) to each other in order to connect their respective private networks.

    This feature can be very useful for connecting two remote locations, such as 2 geographically distant offices or +home with the office.

  2. client : to connect a client (smartphone, tablet, computer) via VPN to the router and thus reach its internal network

    This allows individual external employees to access internal company resources via a secure channel.

Fritz!Box VPN creation

Advanced networking features also allow you to select which internal resources can access the VPN, thus making +only essential services and devices reachable, improving security.

Publish date : 2022-07-08 | Last change : 2022-07-08

Security | +VPN | +VPN +| +Router +| +Networking

\ No newline at end of file diff --git a/public/en/blog/guiet-web-development/index.html b/public/en/blog/guiet-web-development/index.html new file mode 100644 index 0000000..57c6f64 --- /dev/null +++ b/public/en/blog/guiet-web-development/index.html @@ -0,0 +1,46 @@ +SpeedTech | Blog - Web application development +

Blog

Web application development

Client : GUIET.com (Fribourg - CH)

Drupal, CodeIgniter, Yii dev, custom CMS development

  • Database design
  • Application logic study and backend implementation
  • Custom features development
  • Support and maintenance
  • Custom multilingual CMS design and implementation
Publish date : 2015-08-03 | Last change : 2015-08-03

Projects | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/en/blog/home-automation-with-home-assistant/index.html b/public/en/blog/home-automation-with-home-assistant/index.html new file mode 100644 index 0000000..9367add --- /dev/null +++ b/public/en/blog/home-automation-with-home-assistant/index.html @@ -0,0 +1,46 @@ +SpeedTech | Blog - Home automation with Home Assistant +

Blog

Home automation with Home Assistant

Home Assistant is an entirely open source tool for home automation of both residential and business environments.

It consists of a server that can also be installed on an SBC (Single Board Computer) such as RaspberryPi +capable of communicating with many different types of devices of different brands and a variety of network protocols : Tasmota, Shelly, Sonoff, MQTT, Zigbee.

The possibilities are virtually endless for automating the behavior of different devices by combining them with each other via scripts +that can take into account all kinds of conditions and interface with all kinds of sensors : humidity, temperature, presence, wind speed, etc …

Home Assistant

Some possibilities are :

  • control opening and closing motorized roller shutters and awnings
  • access control : gates, doors
  • indoor and outdoor lighting
  • irrigation of gardens and vegetable gardens
  • integration with existing burglar alarm systems or creation of a system from scratch
  • integration with gas and flood sensors

All programmable in automatic mode and configurable and manually controllable via web interface and app for smartphones and tablets, +also remotely or via NFC tags.

The user interface is highly customizable and configurable according to specific needs, and graphics can also be changed via themes +customized.

Home Assistant Minimalist Theme
Home Assistant Swakes Theme
Publish date : 2022-08-30 | Last change : 2022-08-30

Technology | +Home Assistant +| +Home Automation

\ No newline at end of file diff --git a/public/en/blog/index.html b/public/en/blog/index.html new file mode 100644 index 0000000..a7a798d --- /dev/null +++ b/public/en/blog/index.html @@ -0,0 +1,73 @@ +SpeedTech | Blog +

BrainMinder - second brain web application

BrainMinder is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. Items are shared with external users via a pre-authorized link and (optionally) an additional password.

Read more

Projects | +Software Development +| +Web Application +| +PWA

Web spreadsheet application with sync capabilities

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS. +I designed and developed a web application based on CodeIgniter framework and integrating JSpreadsheet which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.

Read more

Projects | +Software Development +| +Web Application

Database link with PostgreSQL

In PostgreSQL, it is possible to create database links and connect two separate databases, whether they reside on the same server or on separate servers, as long as they are accessible over a network.

Read more

Solutions | +Technology | +Server +| +Database +| +PostgreSQL

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Data synchronization procedures

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/en/blog/index.xml b/public/en/blog/index.xml new file mode 100644 index 0000000..8175980 --- /dev/null +++ b/public/en/blog/index.xml @@ -0,0 +1,46 @@ +Blog on Information Technology Serviceshttps://speedtech.it/en/blog/Recent content in Blog on Information Technology ServicesHugo -- gohugo.ioenThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/en/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/blog/brainminder-intro/<p><strong>BrainMinder</strong> is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. +Items are shared with external users via a pre-authorized link and (optionally) an additional password.</p>Web spreadsheet application with sync capabilitieshttps://speedtech.it/en/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-spreadsheet-sync/<p>Client : Web Marketing Trento (Trento - IT)</p> +<p>Design and development of data synchronization procedures between different applications and databases +with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p> +<p>I designed and developed a web application based on CodeIgniter framework and integrating <a href="https://jspreadsheet.com/">JSpreadsheet</a> +which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.</p>Database link with PostgreSQLhttps://speedtech.it/en/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/blog/postgresql-database-link/<p>In PostgreSQL, it is possible to create database links and connect two separate databases, whether they +reside on the same server or on separate servers, as long as they are accessible over a network.</p>Data synchronization procedureshttps://speedtech.it/en/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-data-sync/Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, VirtuemartHome automation with Home Assistanthttps://speedtech.it/en/blog/home-automation-with-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/en/blog/home-automation-with-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> is an entirely open source tool for home automation of both residential and business environments.</p>MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p>Encrypt and compress emails server sidehttps://speedtech.it/en/blog/encrypt-compress-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/encrypt-compress-email-server/<p>To improve the security and privacy of users and save disk space, the mail server +<a href="https://www.dovecot.org/">Dovecot</a> allows encrypting the files containing the e-mail messages.</p>VPN with Fritz!Box routerhttps://speedtech.it/en/blog/fritzbox-vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/fritzbox-vpn/<p>AVM's <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> routers already provide built-in two important services that enable +remote connectivity :</p> +<ul> +<li><strong>Dynamic DNS</strong></li> +<li><strong>VPN based on ipsec protocol</strong>.</li> +</ul>Synology NAS installation and configurationhttps://speedtech.it/en/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/blog/synology-nas/Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configurationE-commerce website setup and customization for beauty productshttps://speedtech.it/en/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/en/blog/amorcosmetics-ecommerce/Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign HostingOracle database and APEXhttps://speedtech.it/en/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-oracle-apex/Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configurationVPS servers, Firewall and VPNhttps://speedtech.it/en/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-firewall/Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS managementAccounting, members and custom CMS applicationshttps://speedtech.it/en/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/en/blog/agiati-web-applications/Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteSki rental service software applicationhttps://speedtech.it/en/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/en/blog/cspolsa-renting/Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.Online museum and e-commercehttps://speedtech.it/en/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/en/blog/botta-museum/Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configurationDrupal software developmenthttps://speedtech.it/en/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/en/blog/versantus-drupal.-development/Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)Firewalls, VPN and content filteringhttps://speedtech.it/en/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/en/blog/villamaria-firewalls/Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resourcesWeb application developmenthttps://speedtech.it/en/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/en/blog/guiet-web-development/Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementationSkibus GPS map tracking applicationhttps://speedtech.it/en/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/en/blog/altevie-geomapping/Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detectionE-commerce website setup and customizationhttps://speedtech.it/en/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/en/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom featuresLinux file and backup serverhttps://speedtech.it/en/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/en/blog/deflorian-server/Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files supportDrupal software developmenthttps://speedtech.it/en/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/en/blog/lrm-drupal-development/Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL)Firewall, VPN and server farm networkhttps://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access controlCRM applications, Oracle and PCI certificationhttps://speedtech.it/en/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/blog/sint-crm/Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database \ No newline at end of file diff --git a/public/en/blog/lrm-drupal-development/index.html b/public/en/blog/lrm-drupal-development/index.html new file mode 100644 index 0000000..37a99d8 --- /dev/null +++ b/public/en/blog/lrm-drupal-development/index.html @@ -0,0 +1,45 @@ +SpeedTech | Blog - Drupal software development +

Blog

Drupal software development

\ No newline at end of file diff --git a/public/en/blog/mariadb-replicazione-master-master-tramite-internet/index.html b/public/en/blog/mariadb-replicazione-master-master-tramite-internet/index.html new file mode 100644 index 0000000..c332a76 --- /dev/null +++ b/public/en/blog/mariadb-replicazione-master-master-tramite-internet/index.html @@ -0,0 +1,142 @@ +SpeedTech | Blog - MariaDB replication master-master via Internet +

Blog

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via Galera, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.

This functionality can also be implemented through servers connected to each other via the Internet, +by encrypting MariaDB’s native connection via SSL certificates and controlling access to the service +via software firewalls (ufw for example).

Assuming then that we have 2 servers server1 and server2 the procedures +to follow are as follows.

1. Setting up firewall rules

In order for the two servers to communicate with each other, it is necessary to allow communication on the TCP port of +MariaDB (default 3306)

On server2

ufw allow from server1-ip to server2-ip 3306 comment "Allow replication from server1"
+

On server1

ufw allow from server2-ip to server1-ip 3306 comment "Allow replication from server2"
+
2. SSL certificates generation

To secure the connection between the two servers, one can take advantage of the SSL connectivity already present in MariaDB by +by generating your own CA (Certification Authority) and respective certificates for the two servers.

XCA is an excellent visual software for generating and maintaining SSL certificates.

An alternative to a direct, encrypted connection via SSL is to create a VPN linking the two servers.

3. Data servers alignment

In case the two servers already contain data, it will be necessary to proceed with an alignment +beforehand by exporting and importing the affected databases, so that both +servers contain the same databases, tables, and records.

4. Create the dedicated users on each server to enable replication

On server1 create the user for the connection from server2 and give it permissions +for replication to server1

CREATE USER 'server2'@'server2-ip' IDENTIFIED BY 'server2pwd';
+GRANT REPLICATION SLAVE ON *.* TO 'server2'@'server2-ip';
+FLUSH PRIVILEGES;
+

On server2 create the user for the connection from server1 and give it permissions +for replication to server2

CREATE USER 'server1'@'server1-ip' IDENTIFIED BY 'server1pwd';
+GRANT REPLICATION SLAVE ON *.* TO 'server1'@'server1-ip';
+FLUSH PRIVILEGES;
+
5. Configure server1

In file server.conf :

key_buffer_size        = 64M
+max_allowed_packet     = 64M
+
+server-id   = 1
+report_host = server1
+log_bin                = /var/log/mysql/mysql-bin.log
+expire_logs_days        = 10
+
+relay_log       = /var/lib/mysql/relay-bin
+relay_log_index = /var/lib/mysql/relay-bin.index
+
+log-slave-updates
+auto_increment_increment=1
+auto_increment_offset=1
+slave-skip-errors=1062,1032,1007,1008,1050,1396
+skip-slave-start=FALSE
+
6. Configure server2

In file server.conf :

key_buffer_size        = 64M
+max_allowed_packet     = 64M
+
+server-id   = 2
+report_host = server2
+log_bin                = /var/log/mysql/mysql-bin.log
+expire_logs_days        = 10
+
+relay_log       = /var/lib/mysql/relay-bin
+relay_log_index = /var/lib/mysql/relay-bin.index
+
+log-slave-updates
+auto_increment_increment=2
+auto_increment_offset=2
+slave-skip-errors=1062,1032,1007,1008,1050,1396
+skip-slave-start=FALSE
+
7. Configure server1 as server2 slave

On server2 execute the command :

SHOW MASTER STATUS \G;
+

and take note of the values : File and Position which are to be replaced in the +variables MASTER_LOG_FILE and MASTER_LOG_POS respectively in the following code +to be executed on server1 :

CHANGE MASTER TO
+  MASTER_HOST='server2-ip',
+  MASTER_USER='server1',
+  MASTER_PASSWORD='server1pwd',
+  MASTER_PORT=3306,
+  MASTER_LOG_FILE='mysql-bin.000004',
+  MASTER_LOG_POS=17680369,
+  MASTER_CONNECT_RETRY=10,
+  MASTER_SSL=1,
+  MASTER_SSL_CA='/etc/mysql/ssl/ca.crt',
+  MASTER_SSL_CERT='/etc/mysql/ssl/server1.crt',
+  MASTER_SSL_KEY='/etc/mysql/ssl/server1.key';
+
+START SLAVE;
+

Check the status of slave replication with the command :

SHOW SLAVE STATUS\G;
+
8. Configure server2 as server1 slave

On server1 execute the command :

SHOW MASTER STATUS \G;
+

and take note of the values : File and Position which are to be replaced in the +variables MASTER_LOG_FILE and MASTER_LOG_POS respectively in the following code +to be executed on server2 :

CHANGE MASTER TO
+  MASTER_HOST='server1-ip',
+  MASTER_USER='server2',
+  MASTER_PASSWORD='server2pwd',
+  MASTER_PORT=3306,
+  MASTER_LOG_FILE='mysql-bin.000051',
+  MASTER_LOG_POS=825490817,
+  MASTER_CONNECT_RETRY=10,
+  MASTER_SSL=1,
+  MASTER_SSL_CA='/etc/mysql/ssl/ca.crt',
+  MASTER_SSL_CERT='/etc/mysql/ssl/server2.crt',
+  MASTER_SSL_KEY='/etc/mysql/ssl/server2.key';
+
+START SLAVE;
+

Check the status of slave replication with the command :

SHOW SLAVE STATUS\G;
+
Publish date : 2022-07-19 | Last change : 2022-12-11

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/en/blog/page/1/index.html b/public/en/blog/page/1/index.html new file mode 100644 index 0000000..ac97a34 --- /dev/null +++ b/public/en/blog/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/blog/ + \ No newline at end of file diff --git a/public/en/blog/page/2/index.html b/public/en/blog/page/2/index.html new file mode 100644 index 0000000..bb89e5b --- /dev/null +++ b/public/en/blog/page/2/index.html @@ -0,0 +1,69 @@ +SpeedTech | Blog +

Home automation with Home Assistant

Home Assistant is an entirely open source tool for home automation of both residential and business environments.

Read more

Technology | +Home Assistant +| +Home Automation

Encrypt and compress emails server side

To improve the security and privacy of users and save disk space, the mail server Dovecot allows encrypting the files containing the e-mail messages.

Read more

Solutions | +Security +| +Server +| +Privacy +| +Dovecot

VPN with Fritz!Box router

AVM's Fritz!Box routers already provide built-in two important services that enable remote connectivity : +Dynamic DNS VPN based on ipsec protocol.

Read more

Security | +VPN | +VPN +| +Router +| +Networking

Synology NAS installation and configuration

Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configuration

Read more

Solutions | +Technology | +Projects | +NAS +| +File Server

E-commerce website setup and customization for beauty products

Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign Hosting

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/en/blog/page/3/index.html b/public/en/blog/page/3/index.html new file mode 100644 index 0000000..50c9ee6 --- /dev/null +++ b/public/en/blog/page/3/index.html @@ -0,0 +1,78 @@ +SpeedTech | Blog +

Oracle database and APEX

Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration

Read more

Projects | +System Administration +| +Database +| +Server +| +Linux

VPS servers, Firewall and VPN

Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS management

Read more

Projects | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Accounting, members and custom CMS applications

Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional website

Read more

Projects | +Software Development +| +Web Application

Ski rental service software application

Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.

Read more

Projects | +Software Development +| +Desktop Application

Online museum and e-commerce

Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configuration

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

\ No newline at end of file diff --git a/public/en/blog/page/4/index.html b/public/en/blog/page/4/index.html new file mode 100644 index 0000000..701efe9 --- /dev/null +++ b/public/en/blog/page/4/index.html @@ -0,0 +1,72 @@ +SpeedTech | Blog +

Drupal software development

Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Firewalls, VPN and content filtering

Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resources

Read more

Firewall +| +VPN +| +Networking +| +OpnSense

Web application development

Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementation

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Skibus GPS map tracking application

Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detection

Read more

Projects | +Software Development +| +Web Application

E-commerce website setup and customization

Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom features

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/en/blog/page/5/index.html b/public/en/blog/page/5/index.html new file mode 100644 index 0000000..79cfaee --- /dev/null +++ b/public/en/blog/page/5/index.html @@ -0,0 +1,66 @@ +SpeedTech | Blog +

Linux file and backup server

Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files support

Read more

Projects | +NAS +| +Office Server

Drupal software development

Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Firewall, VPN and server farm network

Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access control

Read more

Projects | +VPN +| +Firewall +| +System Administration

CRM applications, Oracle and PCI certification

Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database

Read more

Projects | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/en/blog/postgresql-database-link/index.html b/public/en/blog/postgresql-database-link/index.html new file mode 100644 index 0000000..6a35dbd --- /dev/null +++ b/public/en/blog/postgresql-database-link/index.html @@ -0,0 +1,55 @@ +SpeedTech | Blog - Database link with PostgreSQL +

Blog

Database link with PostgreSQL

In PostgreSQL, it is possible to create database links and connect two separate databases, whether they +reside on the same server or on separate servers, as long as they are accessible over a network.

The used nomenclature is :

  • serverorig : the source main server
  • databaseorig : the database name on the source main server
  • serverdest : the secondary destination server where the database link will be created pointing to serverorig
  • schemaorig : the schema on the main source server
  • schemadest : the schema on the secondary destination server

1. Extension installation

The first step is to install the extension postgres_fdw on serverdest as user postgres :

CREATE EXTENSION IF NOT EXISTS postgres_fdw;
+

On serverorig create the user that permits the connection from serverdest and has access +to the schema schemaorig and to the necessary tables. For simplicity we call the user userdest with +password passworddest and it should be able to access the table tableorig with the desired privileges : +(SELECT, INSERT, UPDATE, DELETE)

On serverdest :

CREATE serverorig FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'serverorig', port 'portorig', dbname 'databaseorig');
+

On serverdest create the mapping for the user (myuser) that should be able to use the database link

CREATE USER MAPPING FOR myuser SERVER serverorig OPTIONS ( user 'userdest' , password 'passworddest');
+

5. Import the tables structure from the main schema ad assign the privileges

On serverdest :

IMPORT FOREIGN SCHEMA schemaorig LIMIT TO (tableorig) FROM SERVER serverorig INTO schemadest;
+GRANT ALL ON TABLE schemadest.tableorig TO myuser;
+
Publish date : 2022-12-11 | Last change : 2022-12-11

Solutions | +Technology | +Server +| +Database +| +PostgreSQL

\ No newline at end of file diff --git a/public/en/blog/sint-crm/index.html b/public/en/blog/sint-crm/index.html new file mode 100644 index 0000000..99eee5d --- /dev/null +++ b/public/en/blog/sint-crm/index.html @@ -0,0 +1,48 @@ +SpeedTech | Blog - CRM applications, Oracle and PCI certification +

Blog

CRM applications, Oracle and PCI certification

Client : SINT (Torino - IT)

Suite of applications for CRM management, integrated with Oracle database and PCI compliant

  • Oracle Dabase design and implementation
  • Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports
  • Applications for CRM backend and frontend
  • Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database
Publish date : 2000-06-05 | Last change : 2000-06-15

Projects | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/en/blog/synology-nas/index.html b/public/en/blog/synology-nas/index.html new file mode 100644 index 0000000..99d39c8 --- /dev/null +++ b/public/en/blog/synology-nas/index.html @@ -0,0 +1,45 @@ +SpeedTech | Blog - Synology NAS installation and configuration +

Blog

Synology NAS installation and configuration

\ No newline at end of file diff --git a/public/en/blog/versantus-drupal.-development/index.html b/public/en/blog/versantus-drupal.-development/index.html new file mode 100644 index 0000000..a73139b --- /dev/null +++ b/public/en/blog/versantus-drupal.-development/index.html @@ -0,0 +1,45 @@ +SpeedTech | Blog - Drupal software development +

Blog

Drupal software development

\ No newline at end of file diff --git a/public/en/blog/villamaria-firewalls/index.html b/public/en/blog/villamaria-firewalls/index.html new file mode 100644 index 0000000..ec6a34f --- /dev/null +++ b/public/en/blog/villamaria-firewalls/index.html @@ -0,0 +1,47 @@ +SpeedTech | Blog - Firewalls, VPN and content filtering +

Blog

Firewalls, VPN and content filtering

Client : Cooperativa VillaMaria (Rovereto - IT)

Firewalls, VPN site-to-site and client-to-site, web and content access control

  • Hardware configuration
  • Firewall system installation and configuration with RAID support
  • Setup of VPN site-to-site based on OpenVPN to connect two remote sites
  • Setup of single VPN clients to allow remote working
  • Transparent content filtering to control the access to web resources
Publish date : 2016-01-14 | Last change : 2016-01-14

Firewall +| +VPN +| +Networking +| +OpnSense

\ No newline at end of file diff --git a/public/en/blog/wmtrento-data-sync/index.html b/public/en/blog/wmtrento-data-sync/index.html new file mode 100644 index 0000000..e4b7dc1 --- /dev/null +++ b/public/en/blog/wmtrento-data-sync/index.html @@ -0,0 +1,46 @@ +SpeedTech | Blog - Data synchronization procedures +

Blog

Data synchronization procedures

Client : Web Marketing Trento (Trento - IT)

Design and development of data synchronization procedures between different applications and databases +with PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Publish date : 2022-11-07 | Last change : 2022-11-07

Projects | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/en/blog/wmtrento-spreadsheet-sync/index.html b/public/en/blog/wmtrento-spreadsheet-sync/index.html new file mode 100644 index 0000000..5d55d0a --- /dev/null +++ b/public/en/blog/wmtrento-spreadsheet-sync/index.html @@ -0,0 +1,48 @@ +SpeedTech | Blog - Web spreadsheet application with sync capabilities +

Blog

Web spreadsheet application with sync capabilities

Client : Web Marketing Trento (Trento - IT)

Design and development of data synchronization procedures between different applications and databases +with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.

I designed and developed a web application based on CodeIgniter framework and integrating JSpreadsheet +which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.

The frontend integrates VueJS for a more efficient user interface, and all the calls to the backend are ajax and return the data in JSON format.

Publish date : 2023-05-07 | Last change : 2023-05-07

Projects | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/en/categories/index.html b/public/en/categories/index.html new file mode 100644 index 0000000..a539236 --- /dev/null +++ b/public/en/categories/index.html @@ -0,0 +1,39 @@ +SpeedTech | Categories +
\ No newline at end of file diff --git a/public/en/categories/index.xml b/public/en/categories/index.xml new file mode 100644 index 0000000..6bad7fc --- /dev/null +++ b/public/en/categories/index.xml @@ -0,0 +1 @@ +Categories on Information Technology Serviceshttps://speedtech.it/en/categories/Recent content in Categories on Information Technology ServicesHugo -- gohugo.ioenThu, 30 Oct 2025 00:00:00 +0000Projectshttps://speedtech.it/en/categories/projects/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/categories/projects/Solutionshttps://speedtech.it/en/categories/solutions/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/categories/solutions/Technologyhttps://speedtech.it/en/categories/technology/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/categories/technology/Securityhttps://speedtech.it/en/categories/security/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/categories/security/VPNhttps://speedtech.it/en/categories/vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/categories/vpn/ \ No newline at end of file diff --git a/public/en/categories/page/1/index.html b/public/en/categories/page/1/index.html new file mode 100644 index 0000000..ac686e4 --- /dev/null +++ b/public/en/categories/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/categories/ + \ No newline at end of file diff --git a/public/en/categories/projects/index.html b/public/en/categories/projects/index.html new file mode 100644 index 0000000..626e183 --- /dev/null +++ b/public/en/categories/projects/index.html @@ -0,0 +1,68 @@ +SpeedTech | Projects +

BrainMinder - second brain web application

BrainMinder is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. Items are shared with external users via a pre-authorized link and (optionally) an additional password.

Read more

Projects | +Software Development +| +Web Application +| +PWA

Web spreadsheet application with sync capabilities

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS. +I designed and developed a web application based on CodeIgniter framework and integrating JSpreadsheet which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.

Read more

Projects | +Software Development +| +Web Application

Data synchronization procedures

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Synology NAS installation and configuration

Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configuration

Read more

Solutions | +Technology | +Projects | +NAS +| +File Server

E-commerce website setup and customization for beauty products

Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign Hosting

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/en/categories/projects/index.xml b/public/en/categories/projects/index.xml new file mode 100644 index 0000000..e97ba32 --- /dev/null +++ b/public/en/categories/projects/index.xml @@ -0,0 +1,34 @@ +Projects on Information Technology Serviceshttps://speedtech.it/en/categories/projects/Recent content in Projects on Information Technology ServicesHugo -- gohugo.ioenThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/en/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/blog/brainminder-intro/<p><strong>BrainMinder</strong> is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. +Items are shared with external users via a pre-authorized link and (optionally) an additional password.</p>Web spreadsheet application with sync capabilitieshttps://speedtech.it/en/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-spreadsheet-sync/<p>Client : Web Marketing Trento (Trento - IT)</p> +<p>Design and development of data synchronization procedures between different applications and databases +with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p> +<p>I designed and developed a web application based on CodeIgniter framework and integrating <a href="https://jspreadsheet.com/">JSpreadsheet</a> +which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.</p>Data synchronization procedureshttps://speedtech.it/en/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-data-sync/Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, VirtuemartSynology NAS installation and configurationhttps://speedtech.it/en/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/blog/synology-nas/Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configurationE-commerce website setup and customization for beauty productshttps://speedtech.it/en/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/en/blog/amorcosmetics-ecommerce/Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign HostingOracle database and APEXhttps://speedtech.it/en/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-oracle-apex/Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configurationVPS servers, Firewall and VPNhttps://speedtech.it/en/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-firewall/Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS managementAccounting, members and custom CMS applicationshttps://speedtech.it/en/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/en/blog/agiati-web-applications/Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteSki rental service software applicationhttps://speedtech.it/en/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/en/blog/cspolsa-renting/Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.Online museum and e-commercehttps://speedtech.it/en/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/en/blog/botta-museum/Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configurationDrupal software developmenthttps://speedtech.it/en/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/en/blog/versantus-drupal.-development/Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)Web application developmenthttps://speedtech.it/en/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/en/blog/guiet-web-development/Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementationSkibus GPS map tracking applicationhttps://speedtech.it/en/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/en/blog/altevie-geomapping/Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detectionE-commerce website setup and customizationhttps://speedtech.it/en/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/en/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom featuresLinux file and backup serverhttps://speedtech.it/en/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/en/blog/deflorian-server/Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files supportDrupal software developmenthttps://speedtech.it/en/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/en/blog/lrm-drupal-development/Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL)Firewall, VPN and server farm networkhttps://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access controlCRM applications, Oracle and PCI certificationhttps://speedtech.it/en/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/blog/sint-crm/Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database \ No newline at end of file diff --git a/public/en/categories/projects/page/1/index.html b/public/en/categories/projects/page/1/index.html new file mode 100644 index 0000000..86fb10c --- /dev/null +++ b/public/en/categories/projects/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/categories/projects/ + \ No newline at end of file diff --git a/public/en/categories/projects/page/2/index.html b/public/en/categories/projects/page/2/index.html new file mode 100644 index 0000000..5c49214 --- /dev/null +++ b/public/en/categories/projects/page/2/index.html @@ -0,0 +1,78 @@ +SpeedTech | Projects +

Oracle database and APEX

Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration

Read more

Projects | +System Administration +| +Database +| +Server +| +Linux

VPS servers, Firewall and VPN

Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS management

Read more

Projects | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Accounting, members and custom CMS applications

Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional website

Read more

Projects | +Software Development +| +Web Application

Ski rental service software application

Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.

Read more

Projects | +Software Development +| +Desktop Application

Online museum and e-commerce

Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configuration

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

\ No newline at end of file diff --git a/public/en/categories/projects/page/3/index.html b/public/en/categories/projects/page/3/index.html new file mode 100644 index 0000000..e3d336d --- /dev/null +++ b/public/en/categories/projects/page/3/index.html @@ -0,0 +1,69 @@ +SpeedTech | Projects +

Drupal software development

Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Web application development

Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementation

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Skibus GPS map tracking application

Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detection

Read more

Projects | +Software Development +| +Web Application

E-commerce website setup and customization

Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom features

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

Linux file and backup server

Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files support

Read more

Projects | +NAS +| +Office Server

\ No newline at end of file diff --git a/public/en/categories/projects/page/4/index.html b/public/en/categories/projects/page/4/index.html new file mode 100644 index 0000000..a3c60a5 --- /dev/null +++ b/public/en/categories/projects/page/4/index.html @@ -0,0 +1,61 @@ +SpeedTech | Projects +

Drupal software development

Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Firewall, VPN and server farm network

Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access control

Read more

Projects | +VPN +| +Firewall +| +System Administration

CRM applications, Oracle and PCI certification

Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database

Read more

Projects | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/en/categories/security/index.html b/public/en/categories/security/index.html new file mode 100644 index 0000000..320adc8 --- /dev/null +++ b/public/en/categories/security/index.html @@ -0,0 +1,46 @@ +SpeedTech | Security +
\ No newline at end of file diff --git a/public/en/categories/security/index.xml b/public/en/categories/security/index.xml new file mode 100644 index 0000000..c98db40 --- /dev/null +++ b/public/en/categories/security/index.xml @@ -0,0 +1,6 @@ +Security on Information Technology Serviceshttps://speedtech.it/en/categories/security/Recent content in Security on Information Technology ServicesHugo -- gohugo.ioenFri, 08 Jul 2022 00:00:00 +0000VPN with Fritz!Box routerhttps://speedtech.it/en/blog/fritzbox-vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/fritzbox-vpn/<p>AVM's <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> routers already provide built-in two important services that enable +remote connectivity :</p> +<ul> +<li><strong>Dynamic DNS</strong></li> +<li><strong>VPN based on ipsec protocol</strong>.</li> +</ul> \ No newline at end of file diff --git a/public/en/categories/security/page/1/index.html b/public/en/categories/security/page/1/index.html new file mode 100644 index 0000000..3537af3 --- /dev/null +++ b/public/en/categories/security/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/categories/security/ + \ No newline at end of file diff --git a/public/en/categories/solutions/index.html b/public/en/categories/solutions/index.html new file mode 100644 index 0000000..2dcc433 --- /dev/null +++ b/public/en/categories/solutions/index.html @@ -0,0 +1,70 @@ +SpeedTech | Solutions +

Database link with PostgreSQL

In PostgreSQL, it is possible to create database links and connect two separate databases, whether they reside on the same server or on separate servers, as long as they are accessible over a network.

Read more

Solutions | +Technology | +Server +| +Database +| +PostgreSQL

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Encrypt and compress emails server side

To improve the security and privacy of users and save disk space, the mail server Dovecot allows encrypting the files containing the e-mail messages.

Read more

Solutions | +Security +| +Server +| +Privacy +| +Dovecot

Synology NAS installation and configuration

Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configuration

Read more

Solutions | +Technology | +Projects | +NAS +| +File Server

\ No newline at end of file diff --git a/public/en/categories/solutions/index.xml b/public/en/categories/solutions/index.xml new file mode 100644 index 0000000..a887ffb --- /dev/null +++ b/public/en/categories/solutions/index.xml @@ -0,0 +1,7 @@ +Solutions on Information Technology Serviceshttps://speedtech.it/en/categories/solutions/Recent content in Solutions on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000Database link with PostgreSQLhttps://speedtech.it/en/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/blog/postgresql-database-link/<p>In PostgreSQL, it is possible to create database links and connect two separate databases, whether they +reside on the same server or on separate servers, as long as they are accessible over a network.</p>MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p>Encrypt and compress emails server sidehttps://speedtech.it/en/blog/encrypt-compress-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/encrypt-compress-email-server/<p>To improve the security and privacy of users and save disk space, the mail server +<a href="https://www.dovecot.org/">Dovecot</a> allows encrypting the files containing the e-mail messages.</p>Synology NAS installation and configurationhttps://speedtech.it/en/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/blog/synology-nas/Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configuration \ No newline at end of file diff --git a/public/en/categories/solutions/page/1/index.html b/public/en/categories/solutions/page/1/index.html new file mode 100644 index 0000000..033a6e4 --- /dev/null +++ b/public/en/categories/solutions/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/categories/solutions/ + \ No newline at end of file diff --git a/public/en/categories/technology/index.html b/public/en/categories/technology/index.html new file mode 100644 index 0000000..f555fd7 --- /dev/null +++ b/public/en/categories/technology/index.html @@ -0,0 +1,66 @@ +SpeedTech | Technology +

Home automation with Home Assistant

Home Assistant is an entirely open source tool for home automation of both residential and business environments.

Read more

Technology | +Home Assistant +| +Home Automation

Database link with PostgreSQL

In PostgreSQL, it is possible to create database links and connect two separate databases, whether they reside on the same server or on separate servers, as long as they are accessible over a network.

Read more

Solutions | +Technology | +Server +| +Database +| +PostgreSQL

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Synology NAS installation and configuration

Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configuration

Read more

Solutions | +Technology | +Projects | +NAS +| +File Server

\ No newline at end of file diff --git a/public/en/categories/technology/index.xml b/public/en/categories/technology/index.xml new file mode 100644 index 0000000..35091fc --- /dev/null +++ b/public/en/categories/technology/index.xml @@ -0,0 +1,6 @@ +Technology on Information Technology Serviceshttps://speedtech.it/en/categories/technology/Recent content in Technology on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000Database link with PostgreSQLhttps://speedtech.it/en/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/blog/postgresql-database-link/<p>In PostgreSQL, it is possible to create database links and connect two separate databases, whether they +reside on the same server or on separate servers, as long as they are accessible over a network.</p>Home automation with Home Assistanthttps://speedtech.it/en/blog/home-automation-with-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/en/blog/home-automation-with-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> is an entirely open source tool for home automation of both residential and business environments.</p>MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p>Synology NAS installation and configurationhttps://speedtech.it/en/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/blog/synology-nas/Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configuration \ No newline at end of file diff --git a/public/en/categories/technology/page/1/index.html b/public/en/categories/technology/page/1/index.html new file mode 100644 index 0000000..51a37b9 --- /dev/null +++ b/public/en/categories/technology/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/categories/technology/ + \ No newline at end of file diff --git a/public/en/categories/vpn/index.html b/public/en/categories/vpn/index.html new file mode 100644 index 0000000..2334b26 --- /dev/null +++ b/public/en/categories/vpn/index.html @@ -0,0 +1,46 @@ +SpeedTech | VPN +
\ No newline at end of file diff --git a/public/en/categories/vpn/index.xml b/public/en/categories/vpn/index.xml new file mode 100644 index 0000000..7549c78 --- /dev/null +++ b/public/en/categories/vpn/index.xml @@ -0,0 +1,6 @@ +VPN on Information Technology Serviceshttps://speedtech.it/en/categories/vpn/Recent content in VPN on Information Technology ServicesHugo -- gohugo.ioenFri, 08 Jul 2022 00:00:00 +0000VPN with Fritz!Box routerhttps://speedtech.it/en/blog/fritzbox-vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/fritzbox-vpn/<p>AVM's <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> routers already provide built-in two important services that enable +remote connectivity :</p> +<ul> +<li><strong>Dynamic DNS</strong></li> +<li><strong>VPN based on ipsec protocol</strong>.</li> +</ul> \ No newline at end of file diff --git a/public/en/categories/vpn/page/1/index.html b/public/en/categories/vpn/page/1/index.html new file mode 100644 index 0000000..b9c958f --- /dev/null +++ b/public/en/categories/vpn/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/categories/vpn/ + \ No newline at end of file diff --git a/public/en/index.html b/public/en/index.html new file mode 100644 index 0000000..d877c0b --- /dev/null +++ b/public/en/index.html @@ -0,0 +1,40 @@ +SpeedTech | Information Technology Services +

Design and development of custom web and desktop software applications for website backends, e-commerce platforms, management systems, and PWAs +(Progressive Web Applications) using open source technologies that respect privacy and European digital sovereignty.

Installation, configuration, and maintenance of dedicated Linux servers on-site or remotely.

Installation, configuration, and maintenance of Linux desktop clients as an alternative to Microsoft Windows.

Open source, privacy-friendly, and encrypted solutions for: email, messaging, document sharing, and password management.

Latest articles

BrainMinder - second brain web application

BrainMinder is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. Items are shared with external users via a pre-authorized link and (optionally) an additional password.

Read more

Projects | +Software Development +| +Web Application +| +PWA

Web spreadsheet application with sync capabilities

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS. +I designed and developed a web application based on CodeIgniter framework and integrating JSpreadsheet which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.

Read more

Projects | +Software Development +| +Web Application

Database link with PostgreSQL

In PostgreSQL, it is possible to create database links and connect two separate databases, whether they reside on the same server or on separate servers, as long as they are accessible over a network.

Read more

Solutions | +Technology | +Server +| +Database +| +PostgreSQL

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/en/index.xml b/public/en/index.xml new file mode 100644 index 0000000..c57ebbe --- /dev/null +++ b/public/en/index.xml @@ -0,0 +1,65 @@ +Information Technology Serviceshttps://speedtech.it/en/Recent content on Information Technology ServicesHugo -- gohugo.ioenThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/en/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/blog/brainminder-intro/<p><strong>BrainMinder</strong> is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. +Items are shared with external users via a pre-authorized link and (optionally) an additional password.</p>Web spreadsheet application with sync capabilitieshttps://speedtech.it/en/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-spreadsheet-sync/<p>Client : Web Marketing Trento (Trento - IT)</p> +<p>Design and development of data synchronization procedures between different applications and databases +with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p> +<p>I designed and developed a web application based on CodeIgniter framework and integrating <a href="https://jspreadsheet.com/">JSpreadsheet</a> +which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.</p>Database link with PostgreSQLhttps://speedtech.it/en/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/blog/postgresql-database-link/<p>In PostgreSQL, it is possible to create database links and connect two separate databases, whether they +reside on the same server or on separate servers, as long as they are accessible over a network.</p>Data synchronization procedureshttps://speedtech.it/en/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-data-sync/Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, VirtuemartHome automation with Home Assistanthttps://speedtech.it/en/blog/home-automation-with-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/en/blog/home-automation-with-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> is an entirely open source tool for home automation of both residential and business environments.</p>MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p>Encrypt and compress emails server sidehttps://speedtech.it/en/blog/encrypt-compress-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/encrypt-compress-email-server/<p>To improve the security and privacy of users and save disk space, the mail server +<a href="https://www.dovecot.org/">Dovecot</a> allows encrypting the files containing the e-mail messages.</p>VPN with Fritz!Box routerhttps://speedtech.it/en/blog/fritzbox-vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/fritzbox-vpn/<p>AVM's <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> routers already provide built-in two important services that enable +remote connectivity :</p> +<ul> +<li><strong>Dynamic DNS</strong></li> +<li><strong>VPN based on ipsec protocol</strong>.</li> +</ul>Synology NAS installation and configurationhttps://speedtech.it/en/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/blog/synology-nas/Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configurationE-commerce website setup and customization for beauty productshttps://speedtech.it/en/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/en/blog/amorcosmetics-ecommerce/Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign HostingOracle database and APEXhttps://speedtech.it/en/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-oracle-apex/Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configurationVPS servers, Firewall and VPNhttps://speedtech.it/en/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-firewall/Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS managementAccounting, members and custom CMS applicationshttps://speedtech.it/en/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/en/blog/agiati-web-applications/Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteSki rental service software applicationhttps://speedtech.it/en/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/en/blog/cspolsa-renting/Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.Online museum and e-commercehttps://speedtech.it/en/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/en/blog/botta-museum/Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configurationDrupal software developmenthttps://speedtech.it/en/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/en/blog/versantus-drupal.-development/Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)Firewalls, VPN and content filteringhttps://speedtech.it/en/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/en/blog/villamaria-firewalls/Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resourcesWeb application developmenthttps://speedtech.it/en/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/en/blog/guiet-web-development/Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementationSkibus GPS map tracking applicationhttps://speedtech.it/en/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/en/blog/altevie-geomapping/Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detectionE-commerce website setup and customizationhttps://speedtech.it/en/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/en/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom featuresLinux file and backup serverhttps://speedtech.it/en/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/en/blog/deflorian-server/Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files supportDrupal software developmenthttps://speedtech.it/en/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/en/blog/lrm-drupal-development/Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL)Firewall, VPN and server farm networkhttps://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access controlCRM applications, Oracle and PCI certificationhttps://speedtech.it/en/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/blog/sint-crm/Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle databaseSoftware applications design and developmenthttps://speedtech.it/en/service/applications-development/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/applications-development/Software applications (project management, time tracking, inventory, accounting, and billing) that can run on every modern web browser, accessible from anywhere from any device, and that use the most efficient development frameworks connected with the best open source databases: MariaDB, PostgreSQL, SQLite. +The applications are accessible from everywhere (only an Internet connection is necessary), don’t require an installation and can be used simultaneously by many users and support every operating system (MS Windows, Linux, Apple) and every mobile device (smartphone and tablet).E-commerce platforms design, development and integrationhttps://speedtech.it/en/service/e-commerce/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/e-commerce/Design and development of custom solutions tailored to the specific client need both for physical and virtual products integrated with the shipping cost calculation and tracking. +Installation, configuration and maintenance of open-source e-commerce platforms (Woocommerce, OpenCart), as well as engineering and implementation of customised solutions. Integration with different payment gateways : (Stripe, Paypal, Satispay). +Technologies used Language and development framework: PHP, CodeIgniter, HTMX Database : MariaDB, PostgreSQL +Applications Every type of business that can sell its products and services on the Internet.Linux clients: installation and configurationhttps://speedtech.it/en/service/linux-clients/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/linux-clients/There are many advantages of using the Linux operating system as a client on the desktop and laptop, both at home and at an office +SECURITY Linux is immune to viruses and malware, so no protection software, like antivirus or anti-malware, is necessary. +EFFICIENCY Linux works well also on older hardware because it can use the machine resources more efficiently. +PRIVACY Linux provides many free and open source solutions to protect user privacy allowing encryption of the entire disk or only the user data.Managed Linux servershttps://speedtech.it/en/service/managed-linux-servers/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/managed-linux-servers/Complete management of physical or virtual multifunction servers equipped with open source Linux distributions. +Sizing Installation Configuration Maintenance Upgrade Migration Linux servers can offer a wide range of services : mail, web, backup, cloud, source code repository &hellip; +Access to services from the outside can be made secure using a VPN with OpenVPN or Wireguard or via SSH tunnels, and the server can be protected by its software firewall and security can be increased by integrating Security Enhanced Linux support.Online and offline collaboration solutionshttps://speedtech.it/en/service/online-offline-collaboration-solutions/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/online-offline-collaboration-solutions/A Network Attached Storage (NAS) solution, allows you to centralize your business&rsquo; important documents and share them with your collaborators. It also allows you to centralize the backup of your most important data. +A NAS can be built either with dedicated hardware such as Synology, or on generic hardware and selected according to the customer&rsquo;s specific needs. +Tecnology used NextCloud, OpenMediaVault, TrueNAS, Synology, Seafile +Applications Internal and external file and document sharing Centralized access to activity documents with diversified privileges Centralized and shared collaboration platform Centralized backupOpen source home automation solutionshttps://speedtech.it/en/service/domotic-opensource/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/domotic-opensource/Remote control with private access also via Wireguard VPN. Ability to receive real-time notifications through different channels. +Tecnology used Home Assistant, Tasmota, Shelly, Sonoff, Athom +Applications Automazione illuminazione interna ed esterna Automazione irrigazione Automazione tapparelle Apertura / chiusura cancelli e basculantiPrivate E-mail: hosting, security, privacy and archivinghttps://speedtech.it/en/service/private-e-mail/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/private-e-mail/Our mail servers are located in Germany and are based only on open source software: Linux Debian, Postfix, Dovecot, Rspamd, Roundcube. +The servers are hosted in the Contabo data centers and all the communications between the servers and the clients are encrypted with OpenSSL valid certificates signed by LetsEncrypt. +Features Reduntant servers Antispam Inbound antispam filter implemented through rspamd software Deliverability Deliverability guaranteed through DKIM and DMARC technologies Webmail with a responsive interface that can be used with every type of device (computer, smartphone, tablet).Security structures: firewalls, VPN, encryption, backupshttps://speedtech.it/en/service/security-firewalls-vpn/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/security-firewalls-vpn/Firewalls Software and hardware solutions to protect networks and servers for every need : +homes and small offices large offices branch offices servers VPN Virtual Private Network solutions to access a remote network in a secure mode or to connect two or more remote locations with an encrypted connection. A VPN can be implmented using IPSec, OpenVPN and WireGuard software and allows individual computers, tablets or smartphones to connect to a secure network through an encrypted channel and use remote resources as transparently as if they were physically connected to the same network.Websites backends and custom CMS development and integrationhttps://speedtech.it/en/service/custom-cms/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/custom-cms/Design and development of custom CMS backend and frontend engines with modern frameworks. Integration of the CMS with external services. +There are many advantages to choosing a custom CMS in the place of a pre-built solution : +the website and its features are a lot faster efficient use of the hardware and software resources customized backend for an efficient and straightforward workflow more features can be added quickly and easily more freedom both for the client and the developer: every type of customization is possible security: the frontend and backend have separate access because they are two distinct applications. \ No newline at end of file diff --git a/public/en/service/applications-development/index.html b/public/en/service/applications-development/index.html new file mode 100644 index 0000000..75f93a7 --- /dev/null +++ b/public/en/service/applications-development/index.html @@ -0,0 +1,13 @@ +SpeedTech | Software applications design and development +

Software applications design and development

Software applications accessible from anywhere and from any device

Software applications (project management, time tracking, inventory, accounting, and billing) that can run on every modern web browser, accessible from anywhere from any device, and that use the most efficient development frameworks connected with the best open source databases: MariaDB, PostgreSQL, SQLite.

The applications are accessible from everywhere (only an Internet connection is necessary), don’t require an installation and can be used simultaneously by many users and support every operating system (MS Windows, Linux, Apple) and every mobile device (smartphone and tablet).

Tecnology used

Language and development framework : PHP, CodeIgniter, HTMX, Ionic Framework, FreePascal and Lazarus IDE +Database : MariaDB, PostgreSQL, SQLite

Applications

  • Project management
  • Time tracking
  • Inventory
  • Accounting and billing
  • Custom applications
  • Inventory management
  • Accounting and bookkeeping
  • Domotic system control
  • Renting shops

The developed applications can be cross-platform and work in the same way on any computer and operating system

\ No newline at end of file diff --git a/public/en/service/custom-cms/index.html b/public/en/service/custom-cms/index.html new file mode 100644 index 0000000..86943ce --- /dev/null +++ b/public/en/service/custom-cms/index.html @@ -0,0 +1,12 @@ +SpeedTech | Websites backends and custom CMS development and integration +

Websites backends and custom CMS development and integration

Design, development and integration of websites backends and custom CMS backend and frontend engines

Design and development of custom CMS backend and frontend engines with modern frameworks. Integration of the CMS with external services.

There are many advantages to choosing a custom CMS in the place of a pre-built solution :

  • the website and its features are a lot faster
  • efficient use of the hardware and software resources
  • customized backend for an efficient and straightforward workflow
  • more features can be added quickly and easily
  • more freedom both for the client and the developer: every type of customization is possible
  • security: the frontend and backend have separate access because they are two distinct applications. The access to the backend can be blocked during the night, the weekends, or during periods of inactivity

Technologies used

Language and development framework: PHP, CodeIgniter, HTMX +Database : MariaDB, PostgreSQL, SQLite

Applications

  • Public websites
  • Intranet
  • Internal documentation
\ No newline at end of file diff --git a/public/en/service/domotic-opensource/index.html b/public/en/service/domotic-opensource/index.html new file mode 100644 index 0000000..0be89e9 --- /dev/null +++ b/public/en/service/domotic-opensource/index.html @@ -0,0 +1,14 @@ +SpeedTech | Open source home automation solutions +

Open source home automation solutions

Software and hardware solutions for open source home automation based on Home Assistant

Remote control with private access also via Wireguard VPN. +Ability to receive real-time notifications through different channels.

Tecnology used

Home Assistant, Tasmota, Shelly, Sonoff, Athom

Applications

  • Automazione illuminazione interna ed esterna
  • Automazione irrigazione
  • Automazione tapparelle
  • Apertura / chiusura cancelli e basculanti
\ No newline at end of file diff --git a/public/en/service/e-commerce/index.html b/public/en/service/e-commerce/index.html new file mode 100644 index 0000000..aba100c --- /dev/null +++ b/public/en/service/e-commerce/index.html @@ -0,0 +1,16 @@ +SpeedTech | E-commerce platforms design, development and integration +

E-commerce platforms design, development and integration

Design and development of backend and frontend solutions

Design and development of custom solutions tailored to the specific client need both for physical and virtual products integrated with the shipping cost calculation and tracking.

Installation, configuration and maintenance of open-source e-commerce platforms (Woocommerce, OpenCart), as well as engineering and implementation of customised solutions. +Integration with different payment gateways : (Stripe, Paypal, Satispay).

Technologies used

Language and development framework: PHP, CodeIgniter, HTMX +Database : MariaDB, PostgreSQL

Applications

Every type of business that can sell its products and services on the Internet.

\ No newline at end of file diff --git a/public/en/service/index.xml b/public/en/service/index.xml new file mode 100644 index 0000000..419249f --- /dev/null +++ b/public/en/service/index.xml @@ -0,0 +1,20 @@ +Services on Information Technology Serviceshttps://speedtech.it/en/service/Recent content in Services on Information Technology ServicesHugo -- gohugo.ioenSoftware applications design and developmenthttps://speedtech.it/en/service/applications-development/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/applications-development/Software applications (project management, time tracking, inventory, accounting, and billing) that can run on every modern web browser, accessible from anywhere from any device, and that use the most efficient development frameworks connected with the best open source databases: MariaDB, PostgreSQL, SQLite. +The applications are accessible from everywhere (only an Internet connection is necessary), don’t require an installation and can be used simultaneously by many users and support every operating system (MS Windows, Linux, Apple) and every mobile device (smartphone and tablet).E-commerce platforms design, development and integrationhttps://speedtech.it/en/service/e-commerce/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/e-commerce/Design and development of custom solutions tailored to the specific client need both for physical and virtual products integrated with the shipping cost calculation and tracking. +Installation, configuration and maintenance of open-source e-commerce platforms (Woocommerce, OpenCart), as well as engineering and implementation of customised solutions. Integration with different payment gateways : (Stripe, Paypal, Satispay). +Technologies used Language and development framework: PHP, CodeIgniter, HTMX Database : MariaDB, PostgreSQL +Applications Every type of business that can sell its products and services on the Internet.Linux clients: installation and configurationhttps://speedtech.it/en/service/linux-clients/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/linux-clients/There are many advantages of using the Linux operating system as a client on the desktop and laptop, both at home and at an office +SECURITY Linux is immune to viruses and malware, so no protection software, like antivirus or anti-malware, is necessary. +EFFICIENCY Linux works well also on older hardware because it can use the machine resources more efficiently. +PRIVACY Linux provides many free and open source solutions to protect user privacy allowing encryption of the entire disk or only the user data.Managed Linux servershttps://speedtech.it/en/service/managed-linux-servers/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/managed-linux-servers/Complete management of physical or virtual multifunction servers equipped with open source Linux distributions. +Sizing Installation Configuration Maintenance Upgrade Migration Linux servers can offer a wide range of services : mail, web, backup, cloud, source code repository &hellip; +Access to services from the outside can be made secure using a VPN with OpenVPN or Wireguard or via SSH tunnels, and the server can be protected by its software firewall and security can be increased by integrating Security Enhanced Linux support.Online and offline collaboration solutionshttps://speedtech.it/en/service/online-offline-collaboration-solutions/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/online-offline-collaboration-solutions/A Network Attached Storage (NAS) solution, allows you to centralize your business&rsquo; important documents and share them with your collaborators. It also allows you to centralize the backup of your most important data. +A NAS can be built either with dedicated hardware such as Synology, or on generic hardware and selected according to the customer&rsquo;s specific needs. +Tecnology used NextCloud, OpenMediaVault, TrueNAS, Synology, Seafile +Applications Internal and external file and document sharing Centralized access to activity documents with diversified privileges Centralized and shared collaboration platform Centralized backupOpen source home automation solutionshttps://speedtech.it/en/service/domotic-opensource/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/domotic-opensource/Remote control with private access also via Wireguard VPN. Ability to receive real-time notifications through different channels. +Tecnology used Home Assistant, Tasmota, Shelly, Sonoff, Athom +Applications Automazione illuminazione interna ed esterna Automazione irrigazione Automazione tapparelle Apertura / chiusura cancelli e basculantiPrivate E-mail: hosting, security, privacy and archivinghttps://speedtech.it/en/service/private-e-mail/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/private-e-mail/Our mail servers are located in Germany and are based only on open source software: Linux Debian, Postfix, Dovecot, Rspamd, Roundcube. +The servers are hosted in the Contabo data centers and all the communications between the servers and the clients are encrypted with OpenSSL valid certificates signed by LetsEncrypt. +Features Reduntant servers Antispam Inbound antispam filter implemented through rspamd software Deliverability Deliverability guaranteed through DKIM and DMARC technologies Webmail with a responsive interface that can be used with every type of device (computer, smartphone, tablet).Security structures: firewalls, VPN, encryption, backupshttps://speedtech.it/en/service/security-firewalls-vpn/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/security-firewalls-vpn/Firewalls Software and hardware solutions to protect networks and servers for every need : +homes and small offices large offices branch offices servers VPN Virtual Private Network solutions to access a remote network in a secure mode or to connect two or more remote locations with an encrypted connection. A VPN can be implmented using IPSec, OpenVPN and WireGuard software and allows individual computers, tablets or smartphones to connect to a secure network through an encrypted channel and use remote resources as transparently as if they were physically connected to the same network.Websites backends and custom CMS development and integrationhttps://speedtech.it/en/service/custom-cms/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/en/service/custom-cms/Design and development of custom CMS backend and frontend engines with modern frameworks. Integration of the CMS with external services. +There are many advantages to choosing a custom CMS in the place of a pre-built solution : +the website and its features are a lot faster efficient use of the hardware and software resources customized backend for an efficient and straightforward workflow more features can be added quickly and easily more freedom both for the client and the developer: every type of customization is possible security: the frontend and backend have separate access because they are two distinct applications. \ No newline at end of file diff --git a/public/en/service/linux-clients/index.html b/public/en/service/linux-clients/index.html new file mode 100644 index 0000000..d83b54e --- /dev/null +++ b/public/en/service/linux-clients/index.html @@ -0,0 +1,14 @@ +SpeedTech | Linux clients: installation and configuration +

Linux clients: installation and configuration

Study, evaluation of needs and selection of appropriate, specific Linux distribution for client's particular needs. Configuration of basic system and peripheral, control and display device drivers, implementation, testing and client long-term support

There are many advantages of using the Linux operating system as a client on the desktop and laptop, both at home and at an office

SECURITY

Linux is immune to viruses and malware, so no protection software, like antivirus or anti-malware, is necessary.

EFFICIENCY

Linux works well also on older hardware because it can use the machine resources more efficiently.

PRIVACY

Linux provides many free and open source solutions to protect user privacy allowing encryption of the entire disk or only the user data.

CUSTOMIZATION

Many user interfaces are available and every interface can be easily customized.

SOFTWARE AVAILABILITY

A lot of high-quality, free, and open-source software is available to satisfy every need.

MAINTENANCE

Linux is easy to maintain, use and backup. In case an installation from scratch is necessary it is easy to migrate the user data and preferences.

COST SAVINGS

Most Linux distributions are completely free and there are no license costs.

The suggested Linux distributions for a desktop are Linux Mint and Zorin OS

\ No newline at end of file diff --git a/public/en/service/managed-linux-servers/index.html b/public/en/service/managed-linux-servers/index.html new file mode 100644 index 0000000..c7b1dfc --- /dev/null +++ b/public/en/service/managed-linux-servers/index.html @@ -0,0 +1,13 @@ +SpeedTech | Managed Linux servers +

Managed Linux servers

Installation, configuration and maintenance of Linux servers on both physical and virtual (VPS) hardware

Complete management of physical or virtual multifunction servers equipped with open source Linux distributions.

  • Sizing
  • Installation
  • Configuration
  • Maintenance
  • Upgrade
  • Migration

Linux servers can offer a wide range of services : mail, web, backup, cloud, source code repository …

Access to services from the outside can be made secure using a VPN with OpenVPN or Wireguard or via SSH tunnels, and the server can be protected by its software firewall and security can be increased by integrating Security Enhanced Linux support.

Connections to the web server can be encrypted using SSL certificates from Let’s Encrypt (free) or using commercial certificates.

Tecnology used

  • Operating systems basd on Linux : Debian, RockyLinux
  • Backup : Borg, Kopia, restic
  • Cloud : Nextcloud
  • Database : PostgreSQL, MariaDB
  • Mail : Postfix, Dovecot, Roundcube, Rspamd
  • Password management : Vaultwarden

Applications

  • Mail private server
  • Database server
  • Backup server
  • Private cloud and file server
  • Private server for password storage
  • Private source code repository for developers

A full range of installation, support, and maintenance services, particularly suitable for small businesses, with on-call or annual support contracts.

Support is provided remotely via control software.

\ No newline at end of file diff --git a/public/en/service/online-offline-collaboration-solutions/index.html b/public/en/service/online-offline-collaboration-solutions/index.html new file mode 100644 index 0000000..ae2b85f --- /dev/null +++ b/public/en/service/online-offline-collaboration-solutions/index.html @@ -0,0 +1,15 @@ +SpeedTech | Online and offline collaboration solutions +

Online and offline collaboration solutions

Online and offline collaboration solutions with NextCloud, OpenMediaVault, TrueNAS e Synology

A Network Attached Storage (NAS) solution, allows you to centralize your business’ important documents and share them with your +collaborators. It also allows you to centralize the backup of your most important data.

A NAS can be built either with dedicated hardware such as Synology, or on generic hardware and selected according to the customer’s specific needs.

Tecnology used

NextCloud, OpenMediaVault, TrueNAS, Synology, Seafile

Applications

  • Internal and external file and document sharing
  • Centralized access to activity documents with diversified privileges
  • Centralized and shared collaboration platform
  • Centralized backup
\ No newline at end of file diff --git a/public/en/service/private-e-mail/index.html b/public/en/service/private-e-mail/index.html new file mode 100644 index 0000000..b328d11 --- /dev/null +++ b/public/en/service/private-e-mail/index.html @@ -0,0 +1,13 @@ +SpeedTech | Private E-mail: hosting, security, privacy and archiving +

Private E-mail: hosting, security, privacy and archiving

Intelligently-managed, high-performance mail server solutions that fully preserve your privacy

Our mail servers are located in Germany and are based only on open source software: Linux Debian, Postfix, Dovecot, Rspamd, Roundcube.

The servers are hosted in the Contabo data centers and all the communications between the servers and the clients are encrypted with OpenSSL valid certificates signed by LetsEncrypt.

Features

  • Reduntant servers
  • Antispam
  • Inbound antispam filter implemented through rspamd software
  • Deliverability
  • Deliverability guaranteed through DKIM and DMARC technologies
  • Webmail with a responsive interface that can be used with every type of device (computer, smartphone, tablet).
  • Each user can :
    • change his password
    • set a vacation message
    • change the desired spam level protection
    • encrypt his emails with GPG
  • Server-side email encryption and compression for complete privacy protection
  • Crypted and versioned backup of the emails on an external cloud service

Additional available features

  • Dedicated server
  • The service can be implemented on a dedicated and private server
  • Collaboration platform
  • Automatic and scheduled backup
  • A copy of the emails can be copied to client storage for backup
\ No newline at end of file diff --git a/public/en/service/security-firewalls-vpn/index.html b/public/en/service/security-firewalls-vpn/index.html new file mode 100644 index 0000000..60010c2 --- /dev/null +++ b/public/en/service/security-firewalls-vpn/index.html @@ -0,0 +1,17 @@ +SpeedTech | Security structures: firewalls, VPN, encryption, backups +

Security structures: firewalls, VPN, encryption, backups

Software and hardware solutions to protect your network, your servers and your sensible data

Firewalls

Software and hardware solutions to protect networks and servers for every need :

  • homes and small offices
  • large offices
  • branch offices
  • servers

VPN

Virtual Private Network solutions to access a remote network in a secure mode or to connect two or more remote locations with an encrypted connection. +A VPN can be implmented using IPSec, OpenVPN and WireGuard software and allows individual computers, tablets or smartphones to connect to a secure network through an encrypted channel and use remote resources as transparently as if they were physically connected to the same network. +A VPN also allows two or more branch offices to be connected, enabling them to colalborate on the same servers transparently.

Cifratura dati

Open source solutions to encrypt and protect sensitive data on servers, computers, tablets and smartphones. +Data encryption ensures privacy protection even in case of system intrusion or when a device is lost or compromised.

Email privacy and authenticity can be guaranteed by using GPG and integrating it with email software: only the owner of the private key and password can read emails that have previously been encrypted with his or her public key.

Backup

Having an automatic, efficient and easily accessible backup of your data is essential. Different software and hardware solutions are available to cover every need. +To ensure maximum reliability several physical locations of backups should be implemented. And to preserve privacy, backups should always be encrypted. +A backup to S3 storage that supports versioning and object locking also guards against ransomware attacks.

\ No newline at end of file diff --git a/public/en/sitemap.xml b/public/en/sitemap.xml new file mode 100644 index 0000000..8d073be --- /dev/null +++ b/public/en/sitemap.xml @@ -0,0 +1 @@ +https://speedtech.it/en/blog/2025-10-30T00:00:00+00:00https://speedtech.it/en/blog/brainminder-intro/2025-10-30T00:00:00+00:00https://speedtech.it/en/categories/2025-10-30T00:00:00+00:00https://speedtech.it/en/2025-10-30T00:00:00+00:00https://speedtech.it/en/categories/projects/2025-10-30T00:00:00+00:00https://speedtech.it/en/tags/pwa/2025-10-30T00:00:00+00:00https://speedtech.it/en/tags/software-development/2025-10-30T00:00:00+00:00https://speedtech.it/en/tags/2025-10-30T00:00:00+00:00https://speedtech.it/en/tags/web-application/2025-10-30T00:00:00+00:00https://speedtech.it/en/blog/wmtrento-spreadsheet-sync/2023-05-07T00:00:00+00:00https://speedtech.it/en/tags/database/2022-12-11T00:00:00+00:00https://speedtech.it/en/blog/postgresql-database-link/2022-12-11T00:00:00+00:00https://speedtech.it/en/tags/postgresql/2022-12-11T00:00:00+00:00https://speedtech.it/en/tags/server/2022-12-11T00:00:00+00:00https://speedtech.it/en/categories/solutions/2022-12-11T00:00:00+00:00https://speedtech.it/en/categories/technology/2022-12-11T00:00:00+00:00https://speedtech.it/en/tags/custom-cms/2022-11-07T00:00:00+00:00https://speedtech.it/en/blog/wmtrento-data-sync/2022-11-07T00:00:00+00:00https://speedtech.it/en/tags/home-assistant/2022-08-30T00:00:00+00:00https://speedtech.it/en/tags/home-automation/2022-08-30T00:00:00+00:00https://speedtech.it/en/blog/home-automation-with-home-assistant/2022-08-30T00:00:00+00:00https://speedtech.it/en/tags/firewall/2022-12-11T00:00:00+00:00https://speedtech.it/en/tags/mariadb/2022-12-11T00:00:00+00:00https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/2022-12-11T00:00:00+00:00https://speedtech.it/en/tags/openssl/2022-12-11T00:00:00+00:00https://speedtech.it/en/tags/ufw/2022-12-11T00:00:00+00:00https://speedtech.it/en/tags/dovecot/2022-07-08T00:00:00+00:00https://speedtech.it/en/blog/encrypt-compress-email-server/2022-07-08T00:00:00+00:00https://speedtech.it/en/tags/networking/2022-07-08T00:00:00+00:00https://speedtech.it/en/tags/privacy/2022-07-08T00:00:00+00:00https://speedtech.it/en/tags/router/2022-07-08T00:00:00+00:00https://speedtech.it/en/tags/security/2022-07-08T00:00:00+00:00https://speedtech.it/en/categories/security/2022-07-08T00:00:00+00:00https://speedtech.it/en/tags/vpn/2022-07-08T00:00:00+00:00https://speedtech.it/en/categories/vpn/2022-07-08T00:00:00+00:00https://speedtech.it/en/blog/fritzbox-vpn/2022-07-08T00:00:00+00:00https://speedtech.it/en/tags/file-server/2021-07-03T00:00:00+00:00https://speedtech.it/en/tags/nas/2021-07-03T00:00:00+00:00https://speedtech.it/en/blog/synology-nas/2021-07-03T00:00:00+00:00https://speedtech.it/en/tags/e-commerce/2021-05-27T00:00:00+00:00https://speedtech.it/en/blog/amorcosmetics-ecommerce/2021-05-27T00:00:00+00:00https://speedtech.it/en/tags/linux/2019-11-09T00:00:00+00:00https://speedtech.it/en/blog/finova-oracle-apex/2019-11-09T00:00:00+00:00https://speedtech.it/en/tags/system-administration/2019-11-09T00:00:00+00:00https://speedtech.it/en/tags/opnsense/2019-09-14T00:00:00+00:00https://speedtech.it/en/blog/finova-firewall/2019-09-14T00:00:00+00:00https://speedtech.it/en/blog/agiati-web-applications/2019-05-04T00:00:00+00:00https://speedtech.it/en/tags/desktop-application/2017-12-12T00:00:00+00:00https://speedtech.it/en/blog/cspolsa-renting/2017-12-12T00:00:00+00:00https://speedtech.it/en/blog/botta-museum/2017-04-15T00:00:00+00:00https://speedtech.it/en/blog/versantus-drupal.-development/2016-02-03T00:00:00+00:00https://speedtech.it/en/blog/villamaria-firewalls/2016-01-14T00:00:00+00:00https://speedtech.it/en/blog/guiet-web-development/2015-08-03T00:00:00+00:00https://speedtech.it/en/blog/altevie-geomapping/2015-01-31T00:00:00+00:00https://speedtech.it/en/blog/amore-ecommerce/2012-08-02T00:00:00+00:00https://speedtech.it/en/blog/deflorian-server/2011-03-12T00:00:00+00:00https://speedtech.it/en/tags/office-server/2011-03-12T00:00:00+00:00https://speedtech.it/en/blog/lrm-drupal-development/2010-06-13T00:00:00+00:00https://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/2002-06-07T00:00:00+00:00https://speedtech.it/en/blog/sint-crm/2000-06-15T00:00:00+00:00https://speedtech.it/en/tags/oracle-database/2000-06-15T00:00:00+00:00https://speedtech.it/en/tags/pascal/2000-06-15T00:00:00+00:00https://speedtech.it/en/service/applications-development/https://speedtech.it/en/service/e-commerce/https://speedtech.it/en/service/linux-clients/https://speedtech.it/en/service/managed-linux-servers/https://speedtech.it/en/service/online-offline-collaboration-solutions/https://speedtech.it/en/service/domotic-opensource/https://speedtech.it/en/service/private-e-mail/https://speedtech.it/en/service/security-firewalls-vpn/https://speedtech.it/en/service/https://speedtech.it/en/service/custom-cms/ \ No newline at end of file diff --git a/public/en/tags/custom-cms/index.html b/public/en/tags/custom-cms/index.html new file mode 100644 index 0000000..70de866 --- /dev/null +++ b/public/en/tags/custom-cms/index.html @@ -0,0 +1,73 @@ +SpeedTech | Custom CMS +

Data synchronization procedures

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Online museum and e-commerce

Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configuration

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

Drupal software development

Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Web application development

Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementation

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Drupal software development

Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/en/tags/custom-cms/index.xml b/public/en/tags/custom-cms/index.xml new file mode 100644 index 0000000..66ea760 --- /dev/null +++ b/public/en/tags/custom-cms/index.xml @@ -0,0 +1,8 @@ +Custom CMS on Information Technology Serviceshttps://speedtech.it/en/tags/custom-cms/Recent content in Custom CMS on Information Technology ServicesHugo -- gohugo.ioenMon, 07 Nov 2022 00:00:00 +0000Data synchronization procedureshttps://speedtech.it/en/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-data-sync/Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, VirtuemartOnline museum and e-commercehttps://speedtech.it/en/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/en/blog/botta-museum/Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configurationDrupal software developmenthttps://speedtech.it/en/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/en/blog/versantus-drupal.-development/Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)Web application developmenthttps://speedtech.it/en/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/en/blog/guiet-web-development/Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementationDrupal software developmenthttps://speedtech.it/en/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/en/blog/lrm-drupal-development/Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL) \ No newline at end of file diff --git a/public/en/tags/custom-cms/page/1/index.html b/public/en/tags/custom-cms/page/1/index.html new file mode 100644 index 0000000..6b26588 --- /dev/null +++ b/public/en/tags/custom-cms/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/custom-cms/ + \ No newline at end of file diff --git a/public/en/tags/database/index.html b/public/en/tags/database/index.html new file mode 100644 index 0000000..fc00d01 --- /dev/null +++ b/public/en/tags/database/index.html @@ -0,0 +1,66 @@ +SpeedTech | Database +

Database link with PostgreSQL

In PostgreSQL, it is possible to create database links and connect two separate databases, whether they reside on the same server or on separate servers, as long as they are accessible over a network.

Read more

Solutions | +Technology | +Server +| +Database +| +PostgreSQL

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Oracle database and APEX

Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration

Read more

Projects | +System Administration +| +Database +| +Server +| +Linux

\ No newline at end of file diff --git a/public/en/tags/database/index.xml b/public/en/tags/database/index.xml new file mode 100644 index 0000000..3751e42 --- /dev/null +++ b/public/en/tags/database/index.xml @@ -0,0 +1,7 @@ +Database on Information Technology Serviceshttps://speedtech.it/en/tags/database/Recent content in Database on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000Database link with PostgreSQLhttps://speedtech.it/en/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/blog/postgresql-database-link/<p>In PostgreSQL, it is possible to create database links and connect two separate databases, whether they +reside on the same server or on separate servers, as long as they are accessible over a network.</p>MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p>Oracle database and APEXhttps://speedtech.it/en/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-oracle-apex/Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration \ No newline at end of file diff --git a/public/en/tags/database/page/1/index.html b/public/en/tags/database/page/1/index.html new file mode 100644 index 0000000..3bb9a1b --- /dev/null +++ b/public/en/tags/database/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/database/ + \ No newline at end of file diff --git a/public/en/tags/desktop-application/index.html b/public/en/tags/desktop-application/index.html new file mode 100644 index 0000000..6917cf8 --- /dev/null +++ b/public/en/tags/desktop-application/index.html @@ -0,0 +1,53 @@ +SpeedTech | Desktop Application +

Ski rental service software application

Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.

Read more

Projects | +Software Development +| +Desktop Application

CRM applications, Oracle and PCI certification

Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database

Read more

Projects | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/en/tags/desktop-application/index.xml b/public/en/tags/desktop-application/index.xml new file mode 100644 index 0000000..487a757 --- /dev/null +++ b/public/en/tags/desktop-application/index.xml @@ -0,0 +1,5 @@ +Desktop Application on Information Technology Serviceshttps://speedtech.it/en/tags/desktop-application/Recent content in Desktop Application on Information Technology ServicesHugo -- gohugo.ioenTue, 12 Dec 2017 00:00:00 +0000Ski rental service software applicationhttps://speedtech.it/en/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/en/blog/cspolsa-renting/Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.CRM applications, Oracle and PCI certificationhttps://speedtech.it/en/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/blog/sint-crm/Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database \ No newline at end of file diff --git a/public/en/tags/desktop-application/page/1/index.html b/public/en/tags/desktop-application/page/1/index.html new file mode 100644 index 0000000..cb3e074 --- /dev/null +++ b/public/en/tags/desktop-application/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/desktop-application/ + \ No newline at end of file diff --git a/public/en/tags/dovecot/index.html b/public/en/tags/dovecot/index.html new file mode 100644 index 0000000..979a9c1 --- /dev/null +++ b/public/en/tags/dovecot/index.html @@ -0,0 +1,46 @@ +SpeedTech | Dovecot +
\ No newline at end of file diff --git a/public/en/tags/dovecot/index.xml b/public/en/tags/dovecot/index.xml new file mode 100644 index 0000000..5224b9a --- /dev/null +++ b/public/en/tags/dovecot/index.xml @@ -0,0 +1,2 @@ +Dovecot on Information Technology Serviceshttps://speedtech.it/en/tags/dovecot/Recent content in Dovecot on Information Technology ServicesHugo -- gohugo.ioenFri, 08 Jul 2022 00:00:00 +0000Encrypt and compress emails server sidehttps://speedtech.it/en/blog/encrypt-compress-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/encrypt-compress-email-server/<p>To improve the security and privacy of users and save disk space, the mail server +<a href="https://www.dovecot.org/">Dovecot</a> allows encrypting the files containing the e-mail messages.</p> \ No newline at end of file diff --git a/public/en/tags/dovecot/page/1/index.html b/public/en/tags/dovecot/page/1/index.html new file mode 100644 index 0000000..2c7cf38 --- /dev/null +++ b/public/en/tags/dovecot/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/dovecot/ + \ No newline at end of file diff --git a/public/en/tags/e-commerce/index.html b/public/en/tags/e-commerce/index.html new file mode 100644 index 0000000..8065bb0 --- /dev/null +++ b/public/en/tags/e-commerce/index.html @@ -0,0 +1,62 @@ +SpeedTech | E-Commerce +

E-commerce website setup and customization for beauty products

Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign Hosting

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

Online museum and e-commerce

Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configuration

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

E-commerce website setup and customization

Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom features

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/en/tags/e-commerce/index.xml b/public/en/tags/e-commerce/index.xml new file mode 100644 index 0000000..8b609be --- /dev/null +++ b/public/en/tags/e-commerce/index.xml @@ -0,0 +1,7 @@ +E-Commerce on Information Technology Serviceshttps://speedtech.it/en/tags/e-commerce/Recent content in E-Commerce on Information Technology ServicesHugo -- gohugo.ioenThu, 27 May 2021 00:00:00 +0000E-commerce website setup and customization for beauty productshttps://speedtech.it/en/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/en/blog/amorcosmetics-ecommerce/Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign HostingOnline museum and e-commercehttps://speedtech.it/en/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/en/blog/botta-museum/Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configurationE-commerce website setup and customizationhttps://speedtech.it/en/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/en/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom features \ No newline at end of file diff --git a/public/en/tags/e-commerce/page/1/index.html b/public/en/tags/e-commerce/page/1/index.html new file mode 100644 index 0000000..84384e2 --- /dev/null +++ b/public/en/tags/e-commerce/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/e-commerce/ + \ No newline at end of file diff --git a/public/en/tags/file-server/index.html b/public/en/tags/file-server/index.html new file mode 100644 index 0000000..3485527 --- /dev/null +++ b/public/en/tags/file-server/index.html @@ -0,0 +1,45 @@ +SpeedTech | File Server +
\ No newline at end of file diff --git a/public/en/tags/file-server/index.xml b/public/en/tags/file-server/index.xml new file mode 100644 index 0000000..78f7ca6 --- /dev/null +++ b/public/en/tags/file-server/index.xml @@ -0,0 +1,2 @@ +File Server on Information Technology Serviceshttps://speedtech.it/en/tags/file-server/Recent content in File Server on Information Technology ServicesHugo -- gohugo.ioenSat, 03 Jul 2021 00:00:00 +0000Synology NAS installation and configurationhttps://speedtech.it/en/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/blog/synology-nas/Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configuration \ No newline at end of file diff --git a/public/en/tags/file-server/page/1/index.html b/public/en/tags/file-server/page/1/index.html new file mode 100644 index 0000000..9a4cc89 --- /dev/null +++ b/public/en/tags/file-server/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/file-server/ + \ No newline at end of file diff --git a/public/en/tags/firewall/index.html b/public/en/tags/firewall/index.html new file mode 100644 index 0000000..c422550 --- /dev/null +++ b/public/en/tags/firewall/index.html @@ -0,0 +1,77 @@ +SpeedTech | Firewall +

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

VPS servers, Firewall and VPN

Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS management

Read more

Projects | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewalls, VPN and content filtering

Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resources

Read more

Firewall +| +VPN +| +Networking +| +OpnSense

Firewall, VPN and server farm network

Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access control

Read more

Projects | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/en/tags/firewall/index.xml b/public/en/tags/firewall/index.xml new file mode 100644 index 0000000..223a40a --- /dev/null +++ b/public/en/tags/firewall/index.xml @@ -0,0 +1,10 @@ +Firewall on Information Technology Serviceshttps://speedtech.it/en/tags/firewall/Recent content in Firewall on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p>VPS servers, Firewall and VPNhttps://speedtech.it/en/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-firewall/Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS managementFirewalls, VPN and content filteringhttps://speedtech.it/en/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/en/blog/villamaria-firewalls/Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resourcesFirewall, VPN and server farm networkhttps://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access control \ No newline at end of file diff --git a/public/en/tags/firewall/page/1/index.html b/public/en/tags/firewall/page/1/index.html new file mode 100644 index 0000000..8ee1c74 --- /dev/null +++ b/public/en/tags/firewall/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/firewall/ + \ No newline at end of file diff --git a/public/en/tags/home-assistant/index.html b/public/en/tags/home-assistant/index.html new file mode 100644 index 0000000..453a2bd --- /dev/null +++ b/public/en/tags/home-assistant/index.html @@ -0,0 +1,42 @@ +SpeedTech | Home Assistant +
\ No newline at end of file diff --git a/public/en/tags/home-assistant/index.xml b/public/en/tags/home-assistant/index.xml new file mode 100644 index 0000000..8483eff --- /dev/null +++ b/public/en/tags/home-assistant/index.xml @@ -0,0 +1 @@ +Home Assistant on Information Technology Serviceshttps://speedtech.it/en/tags/home-assistant/Recent content in Home Assistant on Information Technology ServicesHugo -- gohugo.ioenTue, 30 Aug 2022 00:00:00 +0000Home automation with Home Assistanthttps://speedtech.it/en/blog/home-automation-with-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/en/blog/home-automation-with-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> is an entirely open source tool for home automation of both residential and business environments.</p> \ No newline at end of file diff --git a/public/en/tags/home-assistant/page/1/index.html b/public/en/tags/home-assistant/page/1/index.html new file mode 100644 index 0000000..eb3bb27 --- /dev/null +++ b/public/en/tags/home-assistant/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/home-assistant/ + \ No newline at end of file diff --git a/public/en/tags/home-automation/index.html b/public/en/tags/home-automation/index.html new file mode 100644 index 0000000..8ab17ed --- /dev/null +++ b/public/en/tags/home-automation/index.html @@ -0,0 +1,42 @@ +SpeedTech | Home Automation +
\ No newline at end of file diff --git a/public/en/tags/home-automation/index.xml b/public/en/tags/home-automation/index.xml new file mode 100644 index 0000000..4f215dd --- /dev/null +++ b/public/en/tags/home-automation/index.xml @@ -0,0 +1 @@ +Home Automation on Information Technology Serviceshttps://speedtech.it/en/tags/home-automation/Recent content in Home Automation on Information Technology ServicesHugo -- gohugo.ioenTue, 30 Aug 2022 00:00:00 +0000Home automation with Home Assistanthttps://speedtech.it/en/blog/home-automation-with-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/en/blog/home-automation-with-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> is an entirely open source tool for home automation of both residential and business environments.</p> \ No newline at end of file diff --git a/public/en/tags/home-automation/page/1/index.html b/public/en/tags/home-automation/page/1/index.html new file mode 100644 index 0000000..9bdc0fe --- /dev/null +++ b/public/en/tags/home-automation/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/home-automation/ + \ No newline at end of file diff --git a/public/en/tags/index.html b/public/en/tags/index.html new file mode 100644 index 0000000..75c3f4e --- /dev/null +++ b/public/en/tags/index.html @@ -0,0 +1,39 @@ +SpeedTech | Tags +
\ No newline at end of file diff --git a/public/en/tags/index.xml b/public/en/tags/index.xml new file mode 100644 index 0000000..daccbcf --- /dev/null +++ b/public/en/tags/index.xml @@ -0,0 +1 @@ +Tags on Information Technology Serviceshttps://speedtech.it/en/tags/Recent content in Tags on Information Technology ServicesHugo -- gohugo.ioenThu, 30 Oct 2025 00:00:00 +0000PWAhttps://speedtech.it/en/tags/pwa/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/tags/pwa/Software Developmenthttps://speedtech.it/en/tags/software-development/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/tags/software-development/Web Applicationhttps://speedtech.it/en/tags/web-application/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/tags/web-application/Databasehttps://speedtech.it/en/tags/database/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/tags/database/PostgreSQLhttps://speedtech.it/en/tags/postgresql/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/tags/postgresql/Serverhttps://speedtech.it/en/tags/server/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/tags/server/Custom CMShttps://speedtech.it/en/tags/custom-cms/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/en/tags/custom-cms/Home Assistanthttps://speedtech.it/en/tags/home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/en/tags/home-assistant/Home Automationhttps://speedtech.it/en/tags/home-automation/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/en/tags/home-automation/Firewallhttps://speedtech.it/en/tags/firewall/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/firewall/MariaDBhttps://speedtech.it/en/tags/mariadb/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/mariadb/OpenSSLhttps://speedtech.it/en/tags/openssl/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/openssl/UFWhttps://speedtech.it/en/tags/ufw/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/ufw/Dovecothttps://speedtech.it/en/tags/dovecot/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/dovecot/Networkinghttps://speedtech.it/en/tags/networking/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/networking/Privacyhttps://speedtech.it/en/tags/privacy/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/privacy/Routerhttps://speedtech.it/en/tags/router/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/router/Securityhttps://speedtech.it/en/tags/security/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/security/VPNhttps://speedtech.it/en/tags/vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/tags/vpn/File Serverhttps://speedtech.it/en/tags/file-server/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/tags/file-server/NAShttps://speedtech.it/en/tags/nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/tags/nas/E-Commercehttps://speedtech.it/en/tags/e-commerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/en/tags/e-commerce/Linuxhttps://speedtech.it/en/tags/linux/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/tags/linux/System Administrationhttps://speedtech.it/en/tags/system-administration/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/tags/system-administration/OpnSensehttps://speedtech.it/en/tags/opnsense/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/tags/opnsense/Desktop Applicationhttps://speedtech.it/en/tags/desktop-application/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/en/tags/desktop-application/Office Serverhttps://speedtech.it/en/tags/office-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/en/tags/office-server/Oracle Databasehttps://speedtech.it/en/tags/oracle-database/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/tags/oracle-database/Pascalhttps://speedtech.it/en/tags/pascal/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/tags/pascal/ \ No newline at end of file diff --git a/public/en/tags/linux/index.html b/public/en/tags/linux/index.html new file mode 100644 index 0000000..c50b4e5 --- /dev/null +++ b/public/en/tags/linux/index.html @@ -0,0 +1,48 @@ +SpeedTech | Linux +

Oracle database and APEX

Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration

Read more

Projects | +System Administration +| +Database +| +Server +| +Linux

\ No newline at end of file diff --git a/public/en/tags/linux/index.xml b/public/en/tags/linux/index.xml new file mode 100644 index 0000000..3b11b7c --- /dev/null +++ b/public/en/tags/linux/index.xml @@ -0,0 +1,3 @@ +Linux on Information Technology Serviceshttps://speedtech.it/en/tags/linux/Recent content in Linux on Information Technology ServicesHugo -- gohugo.ioenSat, 09 Nov 2019 00:00:00 +0000Oracle database and APEXhttps://speedtech.it/en/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-oracle-apex/Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration \ No newline at end of file diff --git a/public/en/tags/linux/page/1/index.html b/public/en/tags/linux/page/1/index.html new file mode 100644 index 0000000..a581477 --- /dev/null +++ b/public/en/tags/linux/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/linux/ + \ No newline at end of file diff --git a/public/en/tags/mariadb/index.html b/public/en/tags/mariadb/index.html new file mode 100644 index 0000000..60a2fd9 --- /dev/null +++ b/public/en/tags/mariadb/index.html @@ -0,0 +1,51 @@ +SpeedTech | MariaDB +

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/en/tags/mariadb/index.xml b/public/en/tags/mariadb/index.xml new file mode 100644 index 0000000..a12f334 --- /dev/null +++ b/public/en/tags/mariadb/index.xml @@ -0,0 +1,4 @@ +MariaDB on Information Technology Serviceshttps://speedtech.it/en/tags/mariadb/Recent content in MariaDB on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p> \ No newline at end of file diff --git a/public/en/tags/mariadb/page/1/index.html b/public/en/tags/mariadb/page/1/index.html new file mode 100644 index 0000000..9b666d8 --- /dev/null +++ b/public/en/tags/mariadb/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/mariadb/ + \ No newline at end of file diff --git a/public/en/tags/nas/index.html b/public/en/tags/nas/index.html new file mode 100644 index 0000000..354bd16 --- /dev/null +++ b/public/en/tags/nas/index.html @@ -0,0 +1,50 @@ +SpeedTech | NAS +

Synology NAS installation and configuration

Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configuration

Read more

Solutions | +Technology | +Projects | +NAS +| +File Server

Linux file and backup server

Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files support

Read more

Projects | +NAS +| +Office Server

\ No newline at end of file diff --git a/public/en/tags/nas/index.xml b/public/en/tags/nas/index.xml new file mode 100644 index 0000000..19a0970 --- /dev/null +++ b/public/en/tags/nas/index.xml @@ -0,0 +1,4 @@ +NAS on Information Technology Serviceshttps://speedtech.it/en/tags/nas/Recent content in NAS on Information Technology ServicesHugo -- gohugo.ioenSat, 03 Jul 2021 00:00:00 +0000Synology NAS installation and configurationhttps://speedtech.it/en/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/en/blog/synology-nas/Client : several ones +Synology installation and configuration : users, sharing privileges and backup MS Windows clients configurationLinux file and backup serverhttps://speedtech.it/en/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/en/blog/deflorian-server/Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files support \ No newline at end of file diff --git a/public/en/tags/nas/page/1/index.html b/public/en/tags/nas/page/1/index.html new file mode 100644 index 0000000..6061f82 --- /dev/null +++ b/public/en/tags/nas/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/nas/ + \ No newline at end of file diff --git a/public/en/tags/networking/index.html b/public/en/tags/networking/index.html new file mode 100644 index 0000000..b2afb7a --- /dev/null +++ b/public/en/tags/networking/index.html @@ -0,0 +1,65 @@ +SpeedTech | Networking +

VPN with Fritz!Box router

AVM's Fritz!Box routers already provide built-in two important services that enable remote connectivity : +Dynamic DNS VPN based on ipsec protocol.

Read more

Security | +VPN | +VPN +| +Router +| +Networking

VPS servers, Firewall and VPN

Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS management

Read more

Projects | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewalls, VPN and content filtering

Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resources

Read more

Firewall +| +VPN +| +Networking +| +OpnSense

\ No newline at end of file diff --git a/public/en/tags/networking/index.xml b/public/en/tags/networking/index.xml new file mode 100644 index 0000000..cb78254 --- /dev/null +++ b/public/en/tags/networking/index.xml @@ -0,0 +1,10 @@ +Networking on Information Technology Serviceshttps://speedtech.it/en/tags/networking/Recent content in Networking on Information Technology ServicesHugo -- gohugo.ioenFri, 08 Jul 2022 00:00:00 +0000VPN with Fritz!Box routerhttps://speedtech.it/en/blog/fritzbox-vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/fritzbox-vpn/<p>AVM's <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> routers already provide built-in two important services that enable +remote connectivity :</p> +<ul> +<li><strong>Dynamic DNS</strong></li> +<li><strong>VPN based on ipsec protocol</strong>.</li> +</ul>VPS servers, Firewall and VPNhttps://speedtech.it/en/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-firewall/Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS managementFirewalls, VPN and content filteringhttps://speedtech.it/en/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/en/blog/villamaria-firewalls/Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resources \ No newline at end of file diff --git a/public/en/tags/networking/page/1/index.html b/public/en/tags/networking/page/1/index.html new file mode 100644 index 0000000..1bb0a0d --- /dev/null +++ b/public/en/tags/networking/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/networking/ + \ No newline at end of file diff --git a/public/en/tags/office-server/index.html b/public/en/tags/office-server/index.html new file mode 100644 index 0000000..a64e3b5 --- /dev/null +++ b/public/en/tags/office-server/index.html @@ -0,0 +1,44 @@ +SpeedTech | Office Server +

Linux file and backup server

Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files support

Read more

Projects | +NAS +| +Office Server

\ No newline at end of file diff --git a/public/en/tags/office-server/index.xml b/public/en/tags/office-server/index.xml new file mode 100644 index 0000000..6a95fc5 --- /dev/null +++ b/public/en/tags/office-server/index.xml @@ -0,0 +1,3 @@ +Office Server on Information Technology Serviceshttps://speedtech.it/en/tags/office-server/Recent content in Office Server on Information Technology ServicesHugo -- gohugo.ioenSat, 12 Mar 2011 00:00:00 +0000Linux file and backup serverhttps://speedtech.it/en/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/en/blog/deflorian-server/Client : Deflorian Law Firm (Rovereto - IT) +Linux server to serve many users with different privileges in a MS Windows environment +Linux Debian server base installation and configuration Software RAID support configuration File server configuration and privileges assignment External and redundant backup with versioning files support \ No newline at end of file diff --git a/public/en/tags/office-server/page/1/index.html b/public/en/tags/office-server/page/1/index.html new file mode 100644 index 0000000..10385ef --- /dev/null +++ b/public/en/tags/office-server/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/office-server/ + \ No newline at end of file diff --git a/public/en/tags/openssl/index.html b/public/en/tags/openssl/index.html new file mode 100644 index 0000000..b4c3e30 --- /dev/null +++ b/public/en/tags/openssl/index.html @@ -0,0 +1,51 @@ +SpeedTech | OpenSSL +

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/en/tags/openssl/index.xml b/public/en/tags/openssl/index.xml new file mode 100644 index 0000000..0041467 --- /dev/null +++ b/public/en/tags/openssl/index.xml @@ -0,0 +1,4 @@ +OpenSSL on Information Technology Serviceshttps://speedtech.it/en/tags/openssl/Recent content in OpenSSL on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p> \ No newline at end of file diff --git a/public/en/tags/openssl/page/1/index.html b/public/en/tags/openssl/page/1/index.html new file mode 100644 index 0000000..2670e4b --- /dev/null +++ b/public/en/tags/openssl/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/openssl/ + \ No newline at end of file diff --git a/public/en/tags/opnsense/index.html b/public/en/tags/opnsense/index.html new file mode 100644 index 0000000..206a15b --- /dev/null +++ b/public/en/tags/opnsense/index.html @@ -0,0 +1,58 @@ +SpeedTech | OpnSense +

VPS servers, Firewall and VPN

Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS management

Read more

Projects | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewalls, VPN and content filtering

Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resources

Read more

Firewall +| +VPN +| +Networking +| +OpnSense

\ No newline at end of file diff --git a/public/en/tags/opnsense/index.xml b/public/en/tags/opnsense/index.xml new file mode 100644 index 0000000..bcecf73 --- /dev/null +++ b/public/en/tags/opnsense/index.xml @@ -0,0 +1,5 @@ +OpnSense on Information Technology Serviceshttps://speedtech.it/en/tags/opnsense/Recent content in OpnSense on Information Technology ServicesHugo -- gohugo.ioenSat, 14 Sep 2019 00:00:00 +0000VPS servers, Firewall and VPNhttps://speedtech.it/en/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-firewall/Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS managementFirewalls, VPN and content filteringhttps://speedtech.it/en/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/en/blog/villamaria-firewalls/Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resources \ No newline at end of file diff --git a/public/en/tags/opnsense/page/1/index.html b/public/en/tags/opnsense/page/1/index.html new file mode 100644 index 0000000..0b6d3d8 --- /dev/null +++ b/public/en/tags/opnsense/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/opnsense/ + \ No newline at end of file diff --git a/public/en/tags/oracle-database/index.html b/public/en/tags/oracle-database/index.html new file mode 100644 index 0000000..08b385e --- /dev/null +++ b/public/en/tags/oracle-database/index.html @@ -0,0 +1,48 @@ +SpeedTech | Oracle Database +

CRM applications, Oracle and PCI certification

Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database

Read more

Projects | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/en/tags/oracle-database/index.xml b/public/en/tags/oracle-database/index.xml new file mode 100644 index 0000000..a7dba95 --- /dev/null +++ b/public/en/tags/oracle-database/index.xml @@ -0,0 +1,3 @@ +Oracle Database on Information Technology Serviceshttps://speedtech.it/en/tags/oracle-database/Recent content in Oracle Database on Information Technology ServicesHugo -- gohugo.ioenThu, 15 Jun 2000 00:00:00 +0000CRM applications, Oracle and PCI certificationhttps://speedtech.it/en/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/blog/sint-crm/Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database \ No newline at end of file diff --git a/public/en/tags/oracle-database/page/1/index.html b/public/en/tags/oracle-database/page/1/index.html new file mode 100644 index 0000000..c691261 --- /dev/null +++ b/public/en/tags/oracle-database/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/oracle-database/ + \ No newline at end of file diff --git a/public/en/tags/page/1/index.html b/public/en/tags/page/1/index.html new file mode 100644 index 0000000..a43f133 --- /dev/null +++ b/public/en/tags/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/ + \ No newline at end of file diff --git a/public/en/tags/pascal/index.html b/public/en/tags/pascal/index.html new file mode 100644 index 0000000..499cfe5 --- /dev/null +++ b/public/en/tags/pascal/index.html @@ -0,0 +1,48 @@ +SpeedTech | Pascal +

CRM applications, Oracle and PCI certification

Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database

Read more

Projects | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/en/tags/pascal/index.xml b/public/en/tags/pascal/index.xml new file mode 100644 index 0000000..fc34675 --- /dev/null +++ b/public/en/tags/pascal/index.xml @@ -0,0 +1,3 @@ +Pascal on Information Technology Serviceshttps://speedtech.it/en/tags/pascal/Recent content in Pascal on Information Technology ServicesHugo -- gohugo.ioenThu, 15 Jun 2000 00:00:00 +0000CRM applications, Oracle and PCI certificationhttps://speedtech.it/en/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/blog/sint-crm/Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database \ No newline at end of file diff --git a/public/en/tags/pascal/page/1/index.html b/public/en/tags/pascal/page/1/index.html new file mode 100644 index 0000000..6bfcac8 --- /dev/null +++ b/public/en/tags/pascal/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/pascal/ + \ No newline at end of file diff --git a/public/en/tags/postgresql/index.html b/public/en/tags/postgresql/index.html new file mode 100644 index 0000000..3744bcc --- /dev/null +++ b/public/en/tags/postgresql/index.html @@ -0,0 +1,45 @@ +SpeedTech | PostgreSQL +
\ No newline at end of file diff --git a/public/en/tags/postgresql/index.xml b/public/en/tags/postgresql/index.xml new file mode 100644 index 0000000..abfcb6e --- /dev/null +++ b/public/en/tags/postgresql/index.xml @@ -0,0 +1,2 @@ +PostgreSQL on Information Technology Serviceshttps://speedtech.it/en/tags/postgresql/Recent content in PostgreSQL on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000Database link with PostgreSQLhttps://speedtech.it/en/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/blog/postgresql-database-link/<p>In PostgreSQL, it is possible to create database links and connect two separate databases, whether they +reside on the same server or on separate servers, as long as they are accessible over a network.</p> \ No newline at end of file diff --git a/public/en/tags/postgresql/page/1/index.html b/public/en/tags/postgresql/page/1/index.html new file mode 100644 index 0000000..c27d678 --- /dev/null +++ b/public/en/tags/postgresql/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/postgresql/ + \ No newline at end of file diff --git a/public/en/tags/privacy/index.html b/public/en/tags/privacy/index.html new file mode 100644 index 0000000..dc3c5b9 --- /dev/null +++ b/public/en/tags/privacy/index.html @@ -0,0 +1,46 @@ +SpeedTech | Privacy +
\ No newline at end of file diff --git a/public/en/tags/privacy/index.xml b/public/en/tags/privacy/index.xml new file mode 100644 index 0000000..005e630 --- /dev/null +++ b/public/en/tags/privacy/index.xml @@ -0,0 +1,2 @@ +Privacy on Information Technology Serviceshttps://speedtech.it/en/tags/privacy/Recent content in Privacy on Information Technology ServicesHugo -- gohugo.ioenFri, 08 Jul 2022 00:00:00 +0000Encrypt and compress emails server sidehttps://speedtech.it/en/blog/encrypt-compress-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/encrypt-compress-email-server/<p>To improve the security and privacy of users and save disk space, the mail server +<a href="https://www.dovecot.org/">Dovecot</a> allows encrypting the files containing the e-mail messages.</p> \ No newline at end of file diff --git a/public/en/tags/privacy/page/1/index.html b/public/en/tags/privacy/page/1/index.html new file mode 100644 index 0000000..4349c9d --- /dev/null +++ b/public/en/tags/privacy/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/privacy/ + \ No newline at end of file diff --git a/public/en/tags/pwa/index.html b/public/en/tags/pwa/index.html new file mode 100644 index 0000000..8dbd6dd --- /dev/null +++ b/public/en/tags/pwa/index.html @@ -0,0 +1,44 @@ +SpeedTech | PWA +
\ No newline at end of file diff --git a/public/en/tags/pwa/index.xml b/public/en/tags/pwa/index.xml new file mode 100644 index 0000000..de0a2ee --- /dev/null +++ b/public/en/tags/pwa/index.xml @@ -0,0 +1,2 @@ +PWA on Information Technology Serviceshttps://speedtech.it/en/tags/pwa/Recent content in PWA on Information Technology ServicesHugo -- gohugo.ioenThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/en/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/blog/brainminder-intro/<p><strong>BrainMinder</strong> is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. +Items are shared with external users via a pre-authorized link and (optionally) an additional password.</p> \ No newline at end of file diff --git a/public/en/tags/pwa/page/1/index.html b/public/en/tags/pwa/page/1/index.html new file mode 100644 index 0000000..ee030e1 --- /dev/null +++ b/public/en/tags/pwa/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/pwa/ + \ No newline at end of file diff --git a/public/en/tags/router/index.html b/public/en/tags/router/index.html new file mode 100644 index 0000000..33dfa19 --- /dev/null +++ b/public/en/tags/router/index.html @@ -0,0 +1,46 @@ +SpeedTech | Router +
\ No newline at end of file diff --git a/public/en/tags/router/index.xml b/public/en/tags/router/index.xml new file mode 100644 index 0000000..f15a961 --- /dev/null +++ b/public/en/tags/router/index.xml @@ -0,0 +1,6 @@ +Router on Information Technology Serviceshttps://speedtech.it/en/tags/router/Recent content in Router on Information Technology ServicesHugo -- gohugo.ioenFri, 08 Jul 2022 00:00:00 +0000VPN with Fritz!Box routerhttps://speedtech.it/en/blog/fritzbox-vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/fritzbox-vpn/<p>AVM's <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> routers already provide built-in two important services that enable +remote connectivity :</p> +<ul> +<li><strong>Dynamic DNS</strong></li> +<li><strong>VPN based on ipsec protocol</strong>.</li> +</ul> \ No newline at end of file diff --git a/public/en/tags/router/page/1/index.html b/public/en/tags/router/page/1/index.html new file mode 100644 index 0000000..ca9e9db --- /dev/null +++ b/public/en/tags/router/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/router/ + \ No newline at end of file diff --git a/public/en/tags/security/index.html b/public/en/tags/security/index.html new file mode 100644 index 0000000..ed9637f --- /dev/null +++ b/public/en/tags/security/index.html @@ -0,0 +1,46 @@ +SpeedTech | Security +
\ No newline at end of file diff --git a/public/en/tags/security/index.xml b/public/en/tags/security/index.xml new file mode 100644 index 0000000..fdba867 --- /dev/null +++ b/public/en/tags/security/index.xml @@ -0,0 +1,2 @@ +Security on Information Technology Serviceshttps://speedtech.it/en/tags/security/Recent content in Security on Information Technology ServicesHugo -- gohugo.ioenFri, 08 Jul 2022 00:00:00 +0000Encrypt and compress emails server sidehttps://speedtech.it/en/blog/encrypt-compress-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/encrypt-compress-email-server/<p>To improve the security and privacy of users and save disk space, the mail server +<a href="https://www.dovecot.org/">Dovecot</a> allows encrypting the files containing the e-mail messages.</p> \ No newline at end of file diff --git a/public/en/tags/security/page/1/index.html b/public/en/tags/security/page/1/index.html new file mode 100644 index 0000000..d3d29eb --- /dev/null +++ b/public/en/tags/security/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/security/ + \ No newline at end of file diff --git a/public/en/tags/server/index.html b/public/en/tags/server/index.html new file mode 100644 index 0000000..0494ea0 --- /dev/null +++ b/public/en/tags/server/index.html @@ -0,0 +1,73 @@ +SpeedTech | Server +

Database link with PostgreSQL

In PostgreSQL, it is possible to create database links and connect two separate databases, whether they reside on the same server or on separate servers, as long as they are accessible over a network.

Read more

Solutions | +Technology | +Server +| +Database +| +PostgreSQL

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Encrypt and compress emails server side

To improve the security and privacy of users and save disk space, the mail server Dovecot allows encrypting the files containing the e-mail messages.

Read more

Solutions | +Security +| +Server +| +Privacy +| +Dovecot

Oracle database and APEX

Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration

Read more

Projects | +System Administration +| +Database +| +Server +| +Linux

\ No newline at end of file diff --git a/public/en/tags/server/index.xml b/public/en/tags/server/index.xml new file mode 100644 index 0000000..43ee6ca --- /dev/null +++ b/public/en/tags/server/index.xml @@ -0,0 +1,8 @@ +Server on Information Technology Serviceshttps://speedtech.it/en/tags/server/Recent content in Server on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000Database link with PostgreSQLhttps://speedtech.it/en/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/en/blog/postgresql-database-link/<p>In PostgreSQL, it is possible to create database links and connect two separate databases, whether they +reside on the same server or on separate servers, as long as they are accessible over a network.</p>MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p>Encrypt and compress emails server sidehttps://speedtech.it/en/blog/encrypt-compress-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/encrypt-compress-email-server/<p>To improve the security and privacy of users and save disk space, the mail server +<a href="https://www.dovecot.org/">Dovecot</a> allows encrypting the files containing the e-mail messages.</p>Oracle database and APEXhttps://speedtech.it/en/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-oracle-apex/Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration \ No newline at end of file diff --git a/public/en/tags/server/page/1/index.html b/public/en/tags/server/page/1/index.html new file mode 100644 index 0000000..9fad5c2 --- /dev/null +++ b/public/en/tags/server/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/server/ + \ No newline at end of file diff --git a/public/en/tags/software-development/index.html b/public/en/tags/software-development/index.html new file mode 100644 index 0000000..5e72bcc --- /dev/null +++ b/public/en/tags/software-development/index.html @@ -0,0 +1,67 @@ +SpeedTech | Software Development +

BrainMinder - second brain web application

BrainMinder is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. Items are shared with external users via a pre-authorized link and (optionally) an additional password.

Read more

Projects | +Software Development +| +Web Application +| +PWA

Web spreadsheet application with sync capabilities

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS. +I designed and developed a web application based on CodeIgniter framework and integrating JSpreadsheet which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.

Read more

Projects | +Software Development +| +Web Application

Data synchronization procedures

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

E-commerce website setup and customization for beauty products

Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign Hosting

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

Accounting, members and custom CMS applications

Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional website

Read more

Projects | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/en/tags/software-development/index.xml b/public/en/tags/software-development/index.xml new file mode 100644 index 0000000..a56d181 --- /dev/null +++ b/public/en/tags/software-development/index.xml @@ -0,0 +1,25 @@ +Software Development on Information Technology Serviceshttps://speedtech.it/en/tags/software-development/Recent content in Software Development on Information Technology ServicesHugo -- gohugo.ioenThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/en/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/blog/brainminder-intro/<p><strong>BrainMinder</strong> is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. +Items are shared with external users via a pre-authorized link and (optionally) an additional password.</p>Web spreadsheet application with sync capabilitieshttps://speedtech.it/en/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-spreadsheet-sync/<p>Client : Web Marketing Trento (Trento - IT)</p> +<p>Design and development of data synchronization procedures between different applications and databases +with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p> +<p>I designed and developed a web application based on CodeIgniter framework and integrating <a href="https://jspreadsheet.com/">JSpreadsheet</a> +which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.</p>Data synchronization procedureshttps://speedtech.it/en/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-data-sync/Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, VirtuemartE-commerce website setup and customization for beauty productshttps://speedtech.it/en/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/en/blog/amorcosmetics-ecommerce/Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign HostingAccounting, members and custom CMS applicationshttps://speedtech.it/en/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/en/blog/agiati-web-applications/Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteSki rental service software applicationhttps://speedtech.it/en/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/en/blog/cspolsa-renting/Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.Online museum and e-commercehttps://speedtech.it/en/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/en/blog/botta-museum/Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configurationDrupal software developmenthttps://speedtech.it/en/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/en/blog/versantus-drupal.-development/Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)Web application developmenthttps://speedtech.it/en/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/en/blog/guiet-web-development/Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementationSkibus GPS map tracking applicationhttps://speedtech.it/en/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/en/blog/altevie-geomapping/Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detectionE-commerce website setup and customizationhttps://speedtech.it/en/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/en/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom featuresDrupal software developmenthttps://speedtech.it/en/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/en/blog/lrm-drupal-development/Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL)CRM applications, Oracle and PCI certificationhttps://speedtech.it/en/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/en/blog/sint-crm/Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database \ No newline at end of file diff --git a/public/en/tags/software-development/page/1/index.html b/public/en/tags/software-development/page/1/index.html new file mode 100644 index 0000000..601a9ce --- /dev/null +++ b/public/en/tags/software-development/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/software-development/ + \ No newline at end of file diff --git a/public/en/tags/software-development/page/2/index.html b/public/en/tags/software-development/page/2/index.html new file mode 100644 index 0000000..defcf28 --- /dev/null +++ b/public/en/tags/software-development/page/2/index.html @@ -0,0 +1,71 @@ +SpeedTech | Software Development +

Ski rental service software application

Client : Centro Snowboard Polsa (Rovereto - IT) +Design and development of a cross platform desktop application for MS Windows and Linux operating systems using : +ObjectPascal language Lazaurs IDE MariaDB database Onsite Linux server for skies and accessories renting.

Read more

Projects | +Software Development +| +Desktop Application

Online museum and e-commerce

Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configuration

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

Drupal software development

Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Web application development

Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementation

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Skibus GPS map tracking application

Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detection

Read more

Projects | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/en/tags/software-development/page/3/index.html b/public/en/tags/software-development/page/3/index.html new file mode 100644 index 0000000..0bcc727 --- /dev/null +++ b/public/en/tags/software-development/page/3/index.html @@ -0,0 +1,61 @@ +SpeedTech | Software Development +

E-commerce website setup and customization

Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom features

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

Drupal software development

Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

CRM applications, Oracle and PCI certification

Client : SINT (Torino - IT) +Suite of applications for CRM management, integrated with Oracle database and PCI compliant +Oracle Dabase design and implementation Desktop applications development with unique features : auto updates, self contained Oracle client, integrated reports Applications for CRM backend and frontend Applications and database infrastructure PCI compliant to store securely sensible information : design and development of an innovative and extremely secure system to save encrypted data in the Oracle database

Read more

Projects | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/en/tags/system-administration/index.html b/public/en/tags/system-administration/index.html new file mode 100644 index 0000000..99ade29 --- /dev/null +++ b/public/en/tags/system-administration/index.html @@ -0,0 +1,66 @@ +SpeedTech | System Administration +

Oracle database and APEX

Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configuration

Read more

Projects | +System Administration +| +Database +| +Server +| +Linux

VPS servers, Firewall and VPN

Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS management

Read more

Projects | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewall, VPN and server farm network

Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access control

Read more

Projects | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/en/tags/system-administration/index.xml b/public/en/tags/system-administration/index.xml new file mode 100644 index 0000000..6afc2f8 --- /dev/null +++ b/public/en/tags/system-administration/index.xml @@ -0,0 +1,7 @@ +System Administration on Information Technology Serviceshttps://speedtech.it/en/tags/system-administration/Recent content in System Administration on Information Technology ServicesHugo -- gohugo.ioenSat, 09 Nov 2019 00:00:00 +0000Oracle database and APEXhttps://speedtech.it/en/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-oracle-apex/Client : Finova (Bolzano - IT) +Oracle database and APEX configuration and installation +Linux CentOS server base installation and configuration Oracle XE database installation and configuration APEX installation and configuration Apache and Tomcat configurationVPS servers, Firewall and VPNhttps://speedtech.it/en/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-firewall/Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS managementFirewall, VPN and server farm networkhttps://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access control \ No newline at end of file diff --git a/public/en/tags/system-administration/page/1/index.html b/public/en/tags/system-administration/page/1/index.html new file mode 100644 index 0000000..4be64ba --- /dev/null +++ b/public/en/tags/system-administration/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/system-administration/ + \ No newline at end of file diff --git a/public/en/tags/ufw/index.html b/public/en/tags/ufw/index.html new file mode 100644 index 0000000..477c9b2 --- /dev/null +++ b/public/en/tags/ufw/index.html @@ -0,0 +1,51 @@ +SpeedTech | UFW +

MariaDB replication master-master via Internet

MariaDB (and MySQL) allow master-slave replication to be configured between two servers. A master-master type of replication can be implemented via Galera, but it requires at least 3 servers. If you have 2 servers, you can configure master-master replication by by cross-duplicating the master-slave replication.

Read more

Solutions | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/en/tags/ufw/index.xml b/public/en/tags/ufw/index.xml new file mode 100644 index 0000000..4ed0018 --- /dev/null +++ b/public/en/tags/ufw/index.xml @@ -0,0 +1,4 @@ +UFW on Information Technology Serviceshttps://speedtech.it/en/tags/ufw/Recent content in UFW on Information Technology ServicesHugo -- gohugo.ioenSun, 11 Dec 2022 00:00:00 +0000MariaDB replication master-master via Internethttps://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (and MySQL) allow master-slave replication to be configured between two servers. +A master-master type of replication can be implemented via <a href="https://galeracluster.com/">Galera</a>, but it requires +at least 3 servers. If you have 2 servers, you can configure master-master replication by +by cross-duplicating the master-slave replication.</p> \ No newline at end of file diff --git a/public/en/tags/ufw/page/1/index.html b/public/en/tags/ufw/page/1/index.html new file mode 100644 index 0000000..f65b09f --- /dev/null +++ b/public/en/tags/ufw/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/ufw/ + \ No newline at end of file diff --git a/public/en/tags/vpn/index.html b/public/en/tags/vpn/index.html new file mode 100644 index 0000000..3ea15ae --- /dev/null +++ b/public/en/tags/vpn/index.html @@ -0,0 +1,72 @@ +SpeedTech | VPN +

VPN with Fritz!Box router

AVM's Fritz!Box routers already provide built-in two important services that enable remote connectivity : +Dynamic DNS VPN based on ipsec protocol.

Read more

Security | +VPN | +VPN +| +Router +| +Networking

VPS servers, Firewall and VPN

Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS management

Read more

Projects | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewalls, VPN and content filtering

Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resources

Read more

Firewall +| +VPN +| +Networking +| +OpnSense

Firewall, VPN and server farm network

Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access control

Read more

Projects | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/en/tags/vpn/index.xml b/public/en/tags/vpn/index.xml new file mode 100644 index 0000000..65113ac --- /dev/null +++ b/public/en/tags/vpn/index.xml @@ -0,0 +1,12 @@ +VPN on Information Technology Serviceshttps://speedtech.it/en/tags/vpn/Recent content in VPN on Information Technology ServicesHugo -- gohugo.ioenFri, 08 Jul 2022 00:00:00 +0000VPN with Fritz!Box routerhttps://speedtech.it/en/blog/fritzbox-vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/en/blog/fritzbox-vpn/<p>AVM's <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> routers already provide built-in two important services that enable +remote connectivity :</p> +<ul> +<li><strong>Dynamic DNS</strong></li> +<li><strong>VPN based on ipsec protocol</strong>.</li> +</ul>VPS servers, Firewall and VPNhttps://speedtech.it/en/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/en/blog/finova-firewall/Client : Finova (Bolzano - IT) +Network and security design and implementation for SAS services +Hardware selection Network design Linux application server installation and configuration VPN based on OpenVPN configuration and maintenance for access control VPS managementFirewalls, VPN and content filteringhttps://speedtech.it/en/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/en/blog/villamaria-firewalls/Client : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN site-to-site and client-to-site, web and content access control +Hardware configuration Firewall system installation and configuration with RAID support Setup of VPN site-to-site based on OpenVPN to connect two remote sites Setup of single VPN clients to allow remote working Transparent content filtering to control the access to web resourcesFirewall, VPN and server farm networkhttps://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/en/blog/daxtor-firewall-vpn-server-farm/Client : Daxtor (Bolzano - IT) +Network and security design and implementation for SAS service in a server farm +Hardware selection Network design Linux application server installation and configuration Oracle database server installation Redundant firewalls configuration and maintenance VPN based on IPSec and OpenVPN configuration and maintenance for access control \ No newline at end of file diff --git a/public/en/tags/vpn/page/1/index.html b/public/en/tags/vpn/page/1/index.html new file mode 100644 index 0000000..294c3a8 --- /dev/null +++ b/public/en/tags/vpn/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/vpn/ + \ No newline at end of file diff --git a/public/en/tags/web-application/index.html b/public/en/tags/web-application/index.html new file mode 100644 index 0000000..5066f5c --- /dev/null +++ b/public/en/tags/web-application/index.html @@ -0,0 +1,67 @@ +SpeedTech | Web Application +

BrainMinder - second brain web application

BrainMinder is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. Items are shared with external users via a pre-authorized link and (optionally) an additional password.

Read more

Projects | +Software Development +| +Web Application +| +PWA

Web spreadsheet application with sync capabilities

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS. +I designed and developed a web application based on CodeIgniter framework and integrating JSpreadsheet which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.

Read more

Projects | +Software Development +| +Web Application

Data synchronization procedures

Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

E-commerce website setup and customization for beauty products

Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign Hosting

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

Accounting, members and custom CMS applications

Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional website

Read more

Projects | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/en/tags/web-application/index.xml b/public/en/tags/web-application/index.xml new file mode 100644 index 0000000..c427afb --- /dev/null +++ b/public/en/tags/web-application/index.xml @@ -0,0 +1,21 @@ +Web Application on Information Technology Serviceshttps://speedtech.it/en/tags/web-application/Recent content in Web Application on Information Technology ServicesHugo -- gohugo.ioenThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/en/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/en/blog/brainminder-intro/<p><strong>BrainMinder</strong> is a software tool to organize and store knowledge, share it with others, analyze situations, ideas, and problems, and make pondered decisions. +Items are shared with external users via a pre-authorized link and (optionally) an additional password.</p>Web spreadsheet application with sync capabilitieshttps://speedtech.it/en/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-spreadsheet-sync/<p>Client : Web Marketing Trento (Trento - IT)</p> +<p>Design and development of data synchronization procedures between different applications and databases +with a spreadsheet interface with : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p> +<p>I designed and developed a web application based on CodeIgniter framework and integrating <a href="https://jspreadsheet.com/">JSpreadsheet</a> +which allows interaction with the Virtuemart ecommerce database to be able to edit product data in spreadsheet mode.</p>Data synchronization procedureshttps://speedtech.it/en/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/en/blog/wmtrento-data-sync/Client : Web Marketing Trento (Trento - IT) +Design and development of data synchronization procedures between different applications and databases with PHP, CodeIgniter, MySQL, Joomla, VirtuemartE-commerce website setup and customization for beauty productshttps://speedtech.it/en/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/en/blog/amorcosmetics-ecommerce/Client : Amor Cosmetics (Trento - IT) +E-commerce website integrated with credit card payments +Website migration and upgrade Configuration and graphic review and redesign HostingAccounting, members and custom CMS applicationshttps://speedtech.it/en/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/en/blog/agiati-web-applications/Client : Accademia degli Agiati (Rovereto - IT) +Technologies used : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteOnline museum and e-commercehttps://speedtech.it/en/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/en/blog/botta-museum/Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configurationDrupal software developmenthttps://speedtech.it/en/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/en/blog/versantus-drupal.-development/Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)Web application developmenthttps://speedtech.it/en/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/en/blog/guiet-web-development/Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementationSkibus GPS map tracking applicationhttps://speedtech.it/en/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/en/blog/altevie-geomapping/Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detectionE-commerce website setup and customizationhttps://speedtech.it/en/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/en/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom featuresDrupal software developmenthttps://speedtech.it/en/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/en/blog/lrm-drupal-development/Client : LeftRightMinds (Vancouver - CA) +Drupal custom modules development (Drupal, PHP, MySQL) \ No newline at end of file diff --git a/public/en/tags/web-application/page/1/index.html b/public/en/tags/web-application/page/1/index.html new file mode 100644 index 0000000..d521867 --- /dev/null +++ b/public/en/tags/web-application/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/en/tags/web-application/ + \ No newline at end of file diff --git a/public/en/tags/web-application/page/2/index.html b/public/en/tags/web-application/page/2/index.html new file mode 100644 index 0000000..9edd042 --- /dev/null +++ b/public/en/tags/web-application/page/2/index.html @@ -0,0 +1,73 @@ +SpeedTech | Web Application +

Online museum and e-commerce

Client: Museo Botta (Rovereto - IT) +Car models and advertising objects virtual museum with custom e-commerce +Yii framework structure Implementation of client design Bootstrap 3 theming framework Online shop and ordering and payment system Server installation and configuration

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

Drupal software development

Client : Versantus (Oxford - UK) +Drupal CMS custom modules development (Drupal, PHP, MySQL)

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Web application development

Client : GUIET.com (Fribourg - CH) +Drupal, CodeIgniter, Yii dev, custom CMS development +Database design Application logic study and backend implementation Custom features development Support and maintenance Custom multilingual CMS design and implementation

Read more

Projects | +Software Development +| +Web Application +| +Custom CMS

Skibus GPS map tracking application

Client : Altevie (Trento - IT) +Responsive web application with responsive map to track the position of gps equipped skibus +Application design and development Server and database installation and configuration Integration with external SOAP services to collect the bus positions and time schedule Development of the map features with bus stop positions, realtime buses position and direction detection

Read more

Projects | +Software Development +| +Web Application

E-commerce website setup and customization

Cliente : Ditta Amore (Rovereto - IT) +E-commerce website integrated with credit card payments and shipping fees computation +E-commerce OpenCart platform setup and configuration Modules selection, installation and customization Credit card Stripe payment system integration Custom shipment fees calculation module development Development of custom features

Read more

Projects | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/en/tags/web-application/page/3/index.html b/public/en/tags/web-application/page/3/index.html new file mode 100644 index 0000000..7617e77 --- /dev/null +++ b/public/en/tags/web-application/page/3/index.html @@ -0,0 +1,45 @@ +SpeedTech | Web Application +
\ No newline at end of file diff --git a/public/images/blog/brainminder.png b/public/images/blog/brainminder.png new file mode 100644 index 0000000..490663b Binary files /dev/null and b/public/images/blog/brainminder.png differ diff --git a/public/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_200x0_resize_box_3.png b/public/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_200x0_resize_box_3.png new file mode 100644 index 0000000..ac9e3ff Binary files /dev/null and b/public/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_200x0_resize_box_3.png differ diff --git a/public/images/blog/encrypt-compress-emails-on-server.jpg b/public/images/blog/encrypt-compress-emails-on-server.jpg new file mode 100644 index 0000000..155c99b Binary files /dev/null and b/public/images/blog/encrypt-compress-emails-on-server.jpg differ diff --git a/public/images/blog/fritzbox.jpg b/public/images/blog/fritzbox.jpg new file mode 100644 index 0000000..5cb8c10 Binary files /dev/null and b/public/images/blog/fritzbox.jpg differ diff --git a/public/images/blog/home-assistant.jpg b/public/images/blog/home-assistant.jpg new file mode 100644 index 0000000..0213ad8 Binary files /dev/null and b/public/images/blog/home-assistant.jpg differ diff --git a/public/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_200x0_resize_q75_box.jpg b/public/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..0a9c653 Binary files /dev/null and b/public/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_200x0_resize_q75_box.jpg differ diff --git a/public/images/blog/mariadb-replication-master-master.jpg b/public/images/blog/mariadb-replication-master-master.jpg new file mode 100644 index 0000000..fc537ee Binary files /dev/null and b/public/images/blog/mariadb-replication-master-master.jpg differ diff --git a/public/images/blog/postgresql.jpg b/public/images/blog/postgresql.jpg new file mode 100644 index 0000000..2717c6f Binary files /dev/null and b/public/images/blog/postgresql.jpg differ diff --git a/public/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_200x0_resize_q75_box.jpg b/public/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..a0798b8 Binary files /dev/null and b/public/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_200x0_resize_q75_box.jpg differ diff --git a/public/images/project/agiati-web-application-development.png b/public/images/project/agiati-web-application-development.png new file mode 100644 index 0000000..8ef988d Binary files /dev/null and b/public/images/project/agiati-web-application-development.png differ diff --git a/public/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_200x0_resize_box_3.png b/public/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_200x0_resize_box_3.png new file mode 100644 index 0000000..c7b0162 Binary files /dev/null and b/public/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_200x0_resize_box_3.png differ diff --git a/public/images/project/altevie-web-application-geolocation.png b/public/images/project/altevie-web-application-geolocation.png new file mode 100644 index 0000000..986d433 Binary files /dev/null and b/public/images/project/altevie-web-application-geolocation.png differ diff --git a/public/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_200x0_resize_box_3.png b/public/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_200x0_resize_box_3.png new file mode 100644 index 0000000..2cd183b Binary files /dev/null and b/public/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_200x0_resize_box_3.png differ diff --git a/public/images/project/amor-cosmetics-ecommerce.png b/public/images/project/amor-cosmetics-ecommerce.png new file mode 100644 index 0000000..6430093 Binary files /dev/null and b/public/images/project/amor-cosmetics-ecommerce.png differ diff --git a/public/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_200x0_resize_box_3.png b/public/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_200x0_resize_box_3.png new file mode 100644 index 0000000..feafaf3 Binary files /dev/null and b/public/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_200x0_resize_box_3.png differ diff --git a/public/images/project/amore-ecommerce.png b/public/images/project/amore-ecommerce.png new file mode 100644 index 0000000..6149551 Binary files /dev/null and b/public/images/project/amore-ecommerce.png differ diff --git a/public/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_200x0_resize_box_3.png b/public/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_200x0_resize_box_3.png new file mode 100644 index 0000000..7e9dc2f Binary files /dev/null and b/public/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_200x0_resize_box_3.png differ diff --git a/public/images/project/botta-online-museum.png b/public/images/project/botta-online-museum.png new file mode 100644 index 0000000..a531e4f Binary files /dev/null and b/public/images/project/botta-online-museum.png differ diff --git a/public/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_200x0_resize_box_3.png b/public/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_200x0_resize_box_3.png new file mode 100644 index 0000000..0f28152 Binary files /dev/null and b/public/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_200x0_resize_box_3.png differ diff --git a/public/images/project/coopvillamaria-opnsense-firewalls.jpg b/public/images/project/coopvillamaria-opnsense-firewalls.jpg new file mode 100644 index 0000000..0e53c5a Binary files /dev/null and b/public/images/project/coopvillamaria-opnsense-firewalls.jpg differ diff --git a/public/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_200x0_resize_q75_box.jpg b/public/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..4b18c73 Binary files /dev/null and b/public/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_200x0_resize_q75_box.jpg differ diff --git a/public/images/project/cspolsa-renting-software.jpg b/public/images/project/cspolsa-renting-software.jpg new file mode 100644 index 0000000..f87c9df Binary files /dev/null and b/public/images/project/cspolsa-renting-software.jpg differ diff --git a/public/images/project/daxtor-firewall-vpn-server-farm.jpg b/public/images/project/daxtor-firewall-vpn-server-farm.jpg new file mode 100644 index 0000000..83e3ddf Binary files /dev/null and b/public/images/project/daxtor-firewall-vpn-server-farm.jpg differ diff --git a/public/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_200x0_resize_q75_box.jpg b/public/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..03d3761 Binary files /dev/null and b/public/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_200x0_resize_q75_box.jpg differ diff --git a/public/images/project/deflorian-server.png b/public/images/project/deflorian-server.png new file mode 100644 index 0000000..038a049 Binary files /dev/null and b/public/images/project/deflorian-server.png differ diff --git a/public/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_200x0_resize_box_3.png b/public/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_200x0_resize_box_3.png new file mode 100644 index 0000000..45fcc0a Binary files /dev/null and b/public/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_200x0_resize_box_3.png differ diff --git a/public/images/project/finova-oracle-apex.png b/public/images/project/finova-oracle-apex.png new file mode 100644 index 0000000..2eedeac Binary files /dev/null and b/public/images/project/finova-oracle-apex.png differ diff --git a/public/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_200x0_resize_box_3.png b/public/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_200x0_resize_box_3.png new file mode 100644 index 0000000..6a29bb4 Binary files /dev/null and b/public/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_200x0_resize_box_3.png differ diff --git a/public/images/project/finova-vps-servers-firewall-vpn.jpg b/public/images/project/finova-vps-servers-firewall-vpn.jpg new file mode 100644 index 0000000..c485420 Binary files /dev/null and b/public/images/project/finova-vps-servers-firewall-vpn.jpg differ diff --git a/public/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_200x0_resize_q75_box.jpg b/public/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..6700ca4 Binary files /dev/null and b/public/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_200x0_resize_q75_box.jpg differ diff --git a/public/images/project/guiet-web-application-development.jpg b/public/images/project/guiet-web-application-development.jpg new file mode 100644 index 0000000..6591714 Binary files /dev/null and b/public/images/project/guiet-web-application-development.jpg differ diff --git a/public/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_200x0_resize_q75_box.jpg b/public/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..8c441aa Binary files /dev/null and b/public/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_200x0_resize_q75_box.jpg differ diff --git a/public/images/project/lrm-drupal.png b/public/images/project/lrm-drupal.png new file mode 100644 index 0000000..67bdd62 Binary files /dev/null and b/public/images/project/lrm-drupal.png differ diff --git a/public/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_200x0_resize_box_3.png b/public/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_200x0_resize_box_3.png new file mode 100644 index 0000000..dfb7ff7 Binary files /dev/null and b/public/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_200x0_resize_box_3.png differ diff --git a/public/images/project/sint-crm.jpg b/public/images/project/sint-crm.jpg new file mode 100644 index 0000000..0282c93 Binary files /dev/null and b/public/images/project/sint-crm.jpg differ diff --git a/public/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_200x0_resize_q75_box.jpg b/public/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..f8a93e7 Binary files /dev/null and b/public/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_200x0_resize_q75_box.jpg differ diff --git a/public/images/project/synology-nas.jpg b/public/images/project/synology-nas.jpg new file mode 100644 index 0000000..45b4a11 Binary files /dev/null and b/public/images/project/synology-nas.jpg differ diff --git a/public/images/project/versantus-drupal.jpg b/public/images/project/versantus-drupal.jpg new file mode 100644 index 0000000..2a99096 Binary files /dev/null and b/public/images/project/versantus-drupal.jpg differ diff --git a/public/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_200x0_resize_q75_box.jpg b/public/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..623729a Binary files /dev/null and b/public/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_200x0_resize_q75_box.jpg differ diff --git a/public/images/project/wmtrento-data-sync.jpg b/public/images/project/wmtrento-data-sync.jpg new file mode 100644 index 0000000..48ee2f2 Binary files /dev/null and b/public/images/project/wmtrento-data-sync.jpg differ diff --git a/public/images/project/wmtrento-jspreadsheet.jpg b/public/images/project/wmtrento-jspreadsheet.jpg new file mode 100644 index 0000000..235e42a Binary files /dev/null and b/public/images/project/wmtrento-jspreadsheet.jpg differ diff --git a/public/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_200x0_resize_q75_box.jpg b/public/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..fad559f Binary files /dev/null and b/public/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_200x0_resize_q75_box.jpg differ diff --git a/public/images/service/application-development.jpg b/public/images/service/application-development.jpg new file mode 100644 index 0000000..a8c381b Binary files /dev/null and b/public/images/service/application-development.jpg differ diff --git a/public/images/service/custom-cms.jpg b/public/images/service/custom-cms.jpg new file mode 100644 index 0000000..d48f430 Binary files /dev/null and b/public/images/service/custom-cms.jpg differ diff --git a/public/images/service/domotic-open-source.webp b/public/images/service/domotic-open-source.webp new file mode 100644 index 0000000..e3a59ab Binary files /dev/null and b/public/images/service/domotic-open-source.webp differ diff --git a/public/images/service/e-commerce.jpg b/public/images/service/e-commerce.jpg new file mode 100644 index 0000000..d232a30 Binary files /dev/null and b/public/images/service/e-commerce.jpg differ diff --git a/public/images/service/e-mail-service.png b/public/images/service/e-mail-service.png new file mode 100644 index 0000000..83987fe Binary files /dev/null and b/public/images/service/e-mail-service.png differ diff --git a/public/images/service/linux-clients.png b/public/images/service/linux-clients.png new file mode 100644 index 0000000..f399af8 Binary files /dev/null and b/public/images/service/linux-clients.png differ diff --git a/public/images/service/linux-servers.jpg b/public/images/service/linux-servers.jpg new file mode 100644 index 0000000..6f5106b Binary files /dev/null and b/public/images/service/linux-servers.jpg differ diff --git a/public/images/service/offline-online-collaboration.webp b/public/images/service/offline-online-collaboration.webp new file mode 100644 index 0000000..4889561 Binary files /dev/null and b/public/images/service/offline-online-collaboration.webp differ diff --git a/public/images/service/security.jpg b/public/images/service/security.jpg new file mode 100644 index 0000000..bf6d20d Binary files /dev/null and b/public/images/service/security.jpg differ diff --git a/public/img/apple-touch-icon.png b/public/img/apple-touch-icon.png new file mode 100644 index 0000000..971a54f Binary files /dev/null and b/public/img/apple-touch-icon.png differ diff --git a/public/img/bg-contact.jpg b/public/img/bg-contact.jpg new file mode 100644 index 0000000..0aedb35 Binary files /dev/null and b/public/img/bg-contact.jpg differ diff --git a/public/img/bg-footer.jpg b/public/img/bg-footer.jpg new file mode 100644 index 0000000..bfbbda1 Binary files /dev/null and b/public/img/bg-footer.jpg differ diff --git a/public/img/bg-header.jpg b/public/img/bg-header.jpg new file mode 100644 index 0000000..252b349 Binary files /dev/null and b/public/img/bg-header.jpg differ diff --git a/public/img/bg-image-1.jpg b/public/img/bg-image-1.jpg new file mode 100644 index 0000000..bfbbda1 Binary files /dev/null and b/public/img/bg-image-1.jpg differ diff --git a/public/img/bg-image-2.jpg b/public/img/bg-image-2.jpg new file mode 100644 index 0000000..8240ebf Binary files /dev/null and b/public/img/bg-image-2.jpg differ diff --git a/public/img/blog/dashcam-switch.jpg b/public/img/blog/dashcam-switch.jpg new file mode 100644 index 0000000..2f69d7e Binary files /dev/null and b/public/img/blog/dashcam-switch.jpg differ diff --git a/public/img/blog/fritzbox-vpn.png b/public/img/blog/fritzbox-vpn.png new file mode 100644 index 0000000..b59a076 Binary files /dev/null and b/public/img/blog/fritzbox-vpn.png differ diff --git a/public/img/blog/home-assistant-minimalist.png b/public/img/blog/home-assistant-minimalist.png new file mode 100644 index 0000000..eaf5563 Binary files /dev/null and b/public/img/blog/home-assistant-minimalist.png differ diff --git a/public/img/blog/home-assistant-swakes.jpg b/public/img/blog/home-assistant-swakes.jpg new file mode 100644 index 0000000..c121200 Binary files /dev/null and b/public/img/blog/home-assistant-swakes.jpg differ diff --git a/public/img/blog/home-assistant.png b/public/img/blog/home-assistant.png new file mode 100644 index 0000000..ab08fc7 Binary files /dev/null and b/public/img/blog/home-assistant.png differ diff --git a/public/img/carousel/brainminder.webp b/public/img/carousel/brainminder.webp new file mode 100644 index 0000000..c86b921 Binary files /dev/null and b/public/img/carousel/brainminder.webp differ diff --git a/public/img/carousel/carousel-email-service_1140_500-min.png b/public/img/carousel/carousel-email-service_1140_500-min.png new file mode 100644 index 0000000..fc11077 Binary files /dev/null and b/public/img/carousel/carousel-email-service_1140_500-min.png differ diff --git a/public/img/carousel/carousel-email-service_1140_500-min.webp b/public/img/carousel/carousel-email-service_1140_500-min.webp new file mode 100644 index 0000000..8cde715 Binary files /dev/null and b/public/img/carousel/carousel-email-service_1140_500-min.webp differ diff --git a/public/img/carousel/carousel-email-service_1140_500.png b/public/img/carousel/carousel-email-service_1140_500.png new file mode 100644 index 0000000..fc11077 Binary files /dev/null and b/public/img/carousel/carousel-email-service_1140_500.png differ diff --git a/public/img/carousel/carousel-email-service_1140_500.webp b/public/img/carousel/carousel-email-service_1140_500.webp new file mode 100644 index 0000000..d406b68 Binary files /dev/null and b/public/img/carousel/carousel-email-service_1140_500.webp differ diff --git a/public/img/carousel/carousel-linux-clients_1140_500-min.png b/public/img/carousel/carousel-linux-clients_1140_500-min.png new file mode 100644 index 0000000..7b65f41 Binary files /dev/null and b/public/img/carousel/carousel-linux-clients_1140_500-min.png differ diff --git a/public/img/carousel/carousel-linux-clients_1140_500.png b/public/img/carousel/carousel-linux-clients_1140_500.png new file mode 100644 index 0000000..7b65f41 Binary files /dev/null and b/public/img/carousel/carousel-linux-clients_1140_500.png differ diff --git a/public/img/carousel/carousel-opnsense-min.png b/public/img/carousel/carousel-opnsense-min.png new file mode 100644 index 0000000..44002f7 Binary files /dev/null and b/public/img/carousel/carousel-opnsense-min.png differ diff --git a/public/img/carousel/carousel-opnsense.png b/public/img/carousel/carousel-opnsense.png new file mode 100644 index 0000000..cd0fc39 Binary files /dev/null and b/public/img/carousel/carousel-opnsense.png differ diff --git a/public/img/carousel/carousel-servers-office_1140_500-min.jpg b/public/img/carousel/carousel-servers-office_1140_500-min.jpg new file mode 100644 index 0000000..da33922 Binary files /dev/null and b/public/img/carousel/carousel-servers-office_1140_500-min.jpg differ diff --git a/public/img/carousel/carousel-servers-office_1140_500.jpg b/public/img/carousel/carousel-servers-office_1140_500.jpg new file mode 100644 index 0000000..4d98676 Binary files /dev/null and b/public/img/carousel/carousel-servers-office_1140_500.jpg differ diff --git a/public/img/carousel/email-service_1140_500-min.png b/public/img/carousel/email-service_1140_500-min.png new file mode 100644 index 0000000..fc11077 Binary files /dev/null and b/public/img/carousel/email-service_1140_500-min.png differ diff --git a/public/img/carousel/email-service_1140_500.png b/public/img/carousel/email-service_1140_500.png new file mode 100644 index 0000000..fc11077 Binary files /dev/null and b/public/img/carousel/email-service_1140_500.png differ diff --git a/public/img/carousel/vps-management-min.jpg b/public/img/carousel/vps-management-min.jpg new file mode 100644 index 0000000..334b2ad Binary files /dev/null and b/public/img/carousel/vps-management-min.jpg differ diff --git a/public/img/carousel/vps-management.jpg b/public/img/carousel/vps-management.jpg new file mode 100644 index 0000000..334b2ad Binary files /dev/null and b/public/img/carousel/vps-management.jpg differ diff --git a/public/img/favicon.ico b/public/img/favicon.ico new file mode 100644 index 0000000..9edf2b9 Binary files /dev/null and b/public/img/favicon.ico differ diff --git a/public/img/favicon/android-icon-144x144.png b/public/img/favicon/android-icon-144x144.png new file mode 100644 index 0000000..6d86992 Binary files /dev/null and b/public/img/favicon/android-icon-144x144.png differ diff --git a/public/img/favicon/android-icon-192x192.png b/public/img/favicon/android-icon-192x192.png new file mode 100644 index 0000000..f15010c Binary files /dev/null and b/public/img/favicon/android-icon-192x192.png differ diff --git a/public/img/favicon/android-icon-36x36.png b/public/img/favicon/android-icon-36x36.png new file mode 100644 index 0000000..268d024 Binary files /dev/null and b/public/img/favicon/android-icon-36x36.png differ diff --git a/public/img/favicon/android-icon-48x48.png b/public/img/favicon/android-icon-48x48.png new file mode 100644 index 0000000..00ee088 Binary files /dev/null and b/public/img/favicon/android-icon-48x48.png differ diff --git a/public/img/favicon/android-icon-72x72.png b/public/img/favicon/android-icon-72x72.png new file mode 100644 index 0000000..0681756 Binary files /dev/null and b/public/img/favicon/android-icon-72x72.png differ diff --git a/public/img/favicon/android-icon-96x96.png b/public/img/favicon/android-icon-96x96.png new file mode 100644 index 0000000..c3de60c Binary files /dev/null and b/public/img/favicon/android-icon-96x96.png differ diff --git a/public/img/favicon/apple-icon-114x114.png b/public/img/favicon/apple-icon-114x114.png new file mode 100644 index 0000000..96ab6ee Binary files /dev/null and b/public/img/favicon/apple-icon-114x114.png differ diff --git a/public/img/favicon/apple-icon-120x120.png b/public/img/favicon/apple-icon-120x120.png new file mode 100644 index 0000000..e2f36df Binary files /dev/null and b/public/img/favicon/apple-icon-120x120.png differ diff --git a/public/img/favicon/apple-icon-144x144.png b/public/img/favicon/apple-icon-144x144.png new file mode 100644 index 0000000..6d86992 Binary files /dev/null and b/public/img/favicon/apple-icon-144x144.png differ diff --git a/public/img/favicon/apple-icon-152x152.png b/public/img/favicon/apple-icon-152x152.png new file mode 100644 index 0000000..a196fa6 Binary files /dev/null and b/public/img/favicon/apple-icon-152x152.png differ diff --git a/public/img/favicon/apple-icon-180x180.png b/public/img/favicon/apple-icon-180x180.png new file mode 100644 index 0000000..ec1017a Binary files /dev/null and b/public/img/favicon/apple-icon-180x180.png differ diff --git a/public/img/favicon/apple-icon-57x57.png b/public/img/favicon/apple-icon-57x57.png new file mode 100644 index 0000000..970b6bb Binary files /dev/null and b/public/img/favicon/apple-icon-57x57.png differ diff --git a/public/img/favicon/apple-icon-60x60.png b/public/img/favicon/apple-icon-60x60.png new file mode 100644 index 0000000..839095a Binary files /dev/null and b/public/img/favicon/apple-icon-60x60.png differ diff --git a/public/img/favicon/apple-icon-72x72.png b/public/img/favicon/apple-icon-72x72.png new file mode 100644 index 0000000..0681756 Binary files /dev/null and b/public/img/favicon/apple-icon-72x72.png differ diff --git a/public/img/favicon/apple-icon-76x76.png b/public/img/favicon/apple-icon-76x76.png new file mode 100644 index 0000000..c419701 Binary files /dev/null and b/public/img/favicon/apple-icon-76x76.png differ diff --git a/public/img/favicon/apple-icon-precomposed.png b/public/img/favicon/apple-icon-precomposed.png new file mode 100644 index 0000000..bf8c161 Binary files /dev/null and b/public/img/favicon/apple-icon-precomposed.png differ diff --git a/public/img/favicon/apple-icon.png b/public/img/favicon/apple-icon.png new file mode 100644 index 0000000..bf8c161 Binary files /dev/null and b/public/img/favicon/apple-icon.png differ diff --git a/public/img/favicon/browserconfig.xml b/public/img/favicon/browserconfig.xml new file mode 100644 index 0000000..c554148 --- /dev/null +++ b/public/img/favicon/browserconfig.xml @@ -0,0 +1,2 @@ + +#ffffff \ No newline at end of file diff --git a/public/img/favicon/favicon-16x16.png b/public/img/favicon/favicon-16x16.png new file mode 100644 index 0000000..05660ab Binary files /dev/null and b/public/img/favicon/favicon-16x16.png differ diff --git a/public/img/favicon/favicon-32x32.png b/public/img/favicon/favicon-32x32.png new file mode 100644 index 0000000..e69b230 Binary files /dev/null and b/public/img/favicon/favicon-32x32.png differ diff --git a/public/img/favicon/favicon-96x96.png b/public/img/favicon/favicon-96x96.png new file mode 100644 index 0000000..c3de60c Binary files /dev/null and b/public/img/favicon/favicon-96x96.png differ diff --git a/public/img/favicon/favicon.ico b/public/img/favicon/favicon.ico new file mode 100644 index 0000000..9edf2b9 Binary files /dev/null and b/public/img/favicon/favicon.ico differ diff --git a/public/img/favicon/manifest.json b/public/img/favicon/manifest.json new file mode 100644 index 0000000..013d4a6 --- /dev/null +++ b/public/img/favicon/manifest.json @@ -0,0 +1,41 @@ +{ + "name": "App", + "icons": [ + { + "src": "\/android-icon-36x36.png", + "sizes": "36x36", + "type": "image\/png", + "density": "0.75" + }, + { + "src": "\/android-icon-48x48.png", + "sizes": "48x48", + "type": "image\/png", + "density": "1.0" + }, + { + "src": "\/android-icon-72x72.png", + "sizes": "72x72", + "type": "image\/png", + "density": "1.5" + }, + { + "src": "\/android-icon-96x96.png", + "sizes": "96x96", + "type": "image\/png", + "density": "2.0" + }, + { + "src": "\/android-icon-144x144.png", + "sizes": "144x144", + "type": "image\/png", + "density": "3.0" + }, + { + "src": "\/android-icon-192x192.png", + "sizes": "192x192", + "type": "image\/png", + "density": "4.0" + } + ] +} \ No newline at end of file diff --git a/public/img/favicon/ms-icon-144x144.png b/public/img/favicon/ms-icon-144x144.png new file mode 100644 index 0000000..6d86992 Binary files /dev/null and b/public/img/favicon/ms-icon-144x144.png differ diff --git a/public/img/favicon/ms-icon-150x150.png b/public/img/favicon/ms-icon-150x150.png new file mode 100644 index 0000000..a410e51 Binary files /dev/null and b/public/img/favicon/ms-icon-150x150.png differ diff --git a/public/img/favicon/ms-icon-310x310.png b/public/img/favicon/ms-icon-310x310.png new file mode 100644 index 0000000..8c7b28d Binary files /dev/null and b/public/img/favicon/ms-icon-310x310.png differ diff --git a/public/img/favicon/ms-icon-70x70.png b/public/img/favicon/ms-icon-70x70.png new file mode 100644 index 0000000..800f403 Binary files /dev/null and b/public/img/favicon/ms-icon-70x70.png differ diff --git a/public/img/home-header.jpg b/public/img/home-header.jpg new file mode 100644 index 0000000..7d04d84 Binary files /dev/null and b/public/img/home-header.jpg differ diff --git a/public/img/logo.svg b/public/img/logo.svg new file mode 100644 index 0000000..8f8c046 --- /dev/null +++ b/public/img/logo.svg @@ -0,0 +1 @@ +logo \ No newline at end of file diff --git a/public/img/profile.svg b/public/img/profile.svg new file mode 100644 index 0000000..afaa4f4 --- /dev/null +++ b/public/img/profile.svg @@ -0,0 +1 @@ +profile \ No newline at end of file diff --git a/public/img/roberto.jpg b/public/img/roberto.jpg new file mode 100644 index 0000000..4e67bfe Binary files /dev/null and b/public/img/roberto.jpg differ diff --git a/public/img/speedtech-logo.png b/public/img/speedtech-logo.png new file mode 100644 index 0000000..e7e5da5 Binary files /dev/null and b/public/img/speedtech-logo.png differ diff --git a/public/img/speedtech_website_for_gitea.webp b/public/img/speedtech_website_for_gitea.webp new file mode 100644 index 0000000..d9f08a0 Binary files /dev/null and b/public/img/speedtech_website_for_gitea.webp differ diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..074747b --- /dev/null +++ b/public/index.html @@ -0,0 +1,39 @@ +SpeedTech | Information Technology Services +

Progettazione e realizzazione di applicativi software web e desktop personalizzati per backend siti web, piattaforme di ecommerce, gestionali e PWA +(Progressive Web Application) con tecnologie open source e rispettose della privacy e della sovranità digitale europea.

Installazione, configurazione e manutenzione di servers Linux dedicati in sede o remoti.

Installazione, configurazione e manutenzione di client Linux desktop come alternativa a Microsoft Windows.

Soluzioni open source, rispettose della privacy e cifrate per : posta elettronica, messaggistica, condivisione documenti, gestione password.

Ultimi articoli

BrainMinder - second brain web application

BrainMinder è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.

Continua a leggere

Projects | +Software Development +| +Web Application +| +PWA

Applicazione web con funzionalità di foglio di calcolo e sincronizzazione

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.

Continua a leggere

Progetti | +Software Development +| +Web Application

Database link con PostgreSQL

In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +PostgreSQL

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/index.xml b/public/index.xml new file mode 100644 index 0000000..499cb21 --- /dev/null +++ b/public/index.xml @@ -0,0 +1,64 @@ +Information Technology Serviceshttps://speedtech.it/Recent content on Information Technology ServicesHugo -- gohugo.ioitThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/blog/brainminder-intro/<p><strong>BrainMinder</strong> è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. +I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.</p>Applicazione web con funzionalità di foglio di calcolo e sincronizzazionehttps://speedtech.it/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/blog/wmtrento-spreadsheet-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database +con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p>Database link con PostgreSQLhttps://speedtech.it/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/blog/postgresql-database-link/<p>In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che +risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.</p>Procedure di sincronizzazione datihttps://speedtech.it/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/blog/wmtrento-data-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti +con PHP, CodeIgniter, MySQL, Joomla, Virtuemart</p>Automazione casa con Home Assistanthttps://speedtech.it/blog/automazione-casa-con-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/blog/automazione-casa-con-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> è uno strumento interamente open source per la domotica sia di ambienti residenziali che lavorativi.</p>Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p>Cifrare e comprimere le email lato serverhttps://speedtech.it/blog/cifrare-comprimere-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/cifrare-comprimere-email-server/<p>Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server +<a href="https://www.dovecot.org/">Dovecot</a> permette di cifrare e comprimere i files che contengono la posta elettronica.</p>VPN con router Fritz!Boxhttps://speedtech.it/blog/vpn-con-frizbox/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/vpn-con-frizbox/<p>I routers <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> di AVM forniscono già integrati due importanti servizi che consentono +la connettività da remoto :</p> +<ul> +<li><strong>DNS dinamico</strong></li> +<li><strong>VPN basata su protocollo ipsec</strong></li> +</ul>Installazione e configurazione Synology NAShttps://speedtech.it/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/blog/synology-nas/<p>Cliente : diversi</p> +<ul> +<li>Installazione e configurazione Synology : utenti, privilegi di condivisione e backup</li> +<li>Configurazione clients MS Windows</li> +</ul>Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezzahttps://speedtech.it/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/blog/amorcosmetics-ecommerce/<p>Cliente : Amor Cosmetics (Trento - IT)</p> +<p>Sito e-commerce website integrato con pagamenti tramite carta di credito</p>Database Oracle XE database e APEXhttps://speedtech.it/blog/finova-oracle-apex/Sat, 09 Nov 2019 00:00:00 +0000https://speedtech.it/blog/finova-oracle-apex/Cliente : Finova (Bolzano - IT) +Database Oracle XE e APEX configurazione e installazione +Linux CentOS server installazione e confugrazione Database Oracle XE database installazione e configurazione APEX installazione e configurazione Apache e Tomcat configurazioneServers VPS, Firewall e VPNhttps://speedtech.it/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/blog/finova-firewall/<p>Cliente : Finova (Bolzano - IT)</p> +<p>Progettazione ed implementazione rete e sicurezza per servizi SAS</p>Applicazioni web per contabilità, gestione soci e CMS personalizzatohttps://speedtech.it/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/blog/agiati-web-applications/Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteSoftware per noleggio attrezzature per lo scihttps://speedtech.it/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/blog/cspolsa-renting/Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.Museo e shop onlinehttps://speedtech.it/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/blog/botta-museum/Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del serverSviluppo software per Drupalhttps://speedtech.it/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/blog/versantus-drupal.-development/Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)Firewalls, VPN e filtraggio contenutihttps://speedtech.it/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/blog/villamaria-firewalls/Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse webSvilluppo di applicazioni webhttps://speedtech.it/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/blog/guiet-web-development/Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzatiApplicazione per il tracciamento di Skibus con GPShttps://speedtech.it/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/blog/altevie-geomapping/Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobusInstallazione e personalizzazione sito e-commercehttps://speedtech.it/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzateServer Linux come file e backup serverhttps://speedtech.it/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/blog/deflorian-server/Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei filesSviluppo software per Drupalhttps://speedtech.it/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/blog/lrm-drupal-development/Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL)Firewall, VPN e rete in server farmhttps://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessiApplicazioni per CRM, Oracle e certificazione PCIhttps://speedtech.it/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/blog/sint-crm/Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuroSviluppo backend siti web e CMS personalizzatihttps://speedtech.it/servizio/backend-siti-web-cms-personalizzati/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/backend-siti-web-cms-personalizzati/Progettazione e sviluppo di backend per siti web e CMS personalizzati con i più moderni frameworks. Integrazione del CMS con servizi esterni. +Vi sono molti vantaggi nello scegliere un CMS personalizzato rispetto ad una soluzione pre confezionata : +maggiore velocità del sito e delle sue funzionalità utilizzo efficiente delle risorse hardware e software backend personalizzato per un workflow efficiente ed immediato facilità e velocità nell&rsquo;aggiungere nuove funzioni maggiore libertà sia per il cliente che per lo sviluppatore : possibile ogni tipo di personalizzazione sicurezza : frontend e backend accedono con accessi separati, perchè di fatto sono due applicativi distinti.Sistemi clients con Linux: installazione e configurazionehttps://speedtech.it/servizio/clients-con-linux/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/clients-con-linux/Ci sono molti vantaggi nell&rsquo;utilizzare il sistema operativo Linux come client su dekstop e laptop, sia a casa che in ufficio. +Sicurezza Linux è immune a virus e malaware, così nessuna protezione software è necessaria, come antivirus e antimalaware, è necessaria +Efficienza Linux funziona bene alche su hardware meno recente in quanto è in grado di utilizzare le risorse della macchina con una migliore efficienza +Privacy Linux fornisce molte soluzioni open source e gratuite per proteggere la privacy dell&rsquo;utente consentendo di cifrarel&rsquo;intero disco o solo i dati degli utentiSoluzioni di condivisione e collaborazione online e offlinehttps://speedtech.it/servizio/soluzioni-collaborazione-online-offline/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/soluzioni-collaborazione-online-offline/Una soluzione NAS (Network Attached Storage), consente di centralizzare i documenti importanti della propria attività e di condividerli con i collaboratori. Consente inoltre anche di centralizzare il backup dei dati più importanti. +Un NAS può essere realizzato sia con hardware dedicato come Synology, oppure su hardware generico e selezionato in base alle specifiche necessità del cliente. +Tecnologie utilizzate NextCloud, OpenMediaVault, TrueNAS, Synology, Seafile +Applicazioni Condivisione files e documenti interna ed esterna Accesso centralizzato ai documenti dell&rsquo;attività con privilegi diversificati Piattaforma di collaborazione centralizzata e condivisa Backup centralizzatoSoluzioni di domotica open sourcehttps://speedtech.it/servizio/domotica-opensource/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/domotica-opensource/Controllo remoto con accesso privato anche tramite VPN Wireguard. Possibilità di ricevere notifiche in tempo reale attraverso diversi canali. +Tecnologie utilizzate Home Assistant, Tasmota, Shelly, Sonoff, Athom +Applicazioni Automazione illuminazione interna ed esterna Automazione irrigazione Automazione tapparelle Apertura / chiusura cancelli e basculantiServers Linux gestitihttps://speedtech.it/servizio/servers-linux-gestiti/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/servers-linux-gestiti/Gestione completa di server multifunzione fisici o virtuali equipaggiati con le distribuzioni Linux open source. +Dimensionamento Installazione Configurazione Manutenzione Aggiornamento Migrazione I server Linux servers posso offrire una vasta gamma di servizi : mail, web, backup, cloud, repository codice sorgente &hellip; +L&rsquo;accesso ai servizi dal&rsquo;esterno può essere reso sicuro utilizzando una VPN con OpenVPN o Wireguard o tramite tunnels SSH e il server può essere protetto dal suo firewall software e la sicurezza può essere incrementata integrando il supporto Security Enhanced Linux.E-mail privata: hosting, sicurezza ed archiviazionehttps://speedtech.it/servizio/e-mail-privata/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/e-mail-privata/I servers di posta elettronica che utilizzo si trovano in Germania e sono dotati esclusivamente di software open source : Linux Debian, Postfix, Dovecot, Rspamd, Roundcube. +I servers si trovano nei datacenters di Contabo e tutte le comunicazioni tra servers e clients sono cifrate con certificati OpenSSL validi firmati da LetsEncrypt. +Funzionalità Servers ridondati Antispam Filtro antispam implementato tramite il software rspamd Garanzia di consegna La consegna dei messaggi ai destinatari è garantita tramite le tecnologie DKIM e DMARC Webmail con interfaccia responsive che può essere utilizzata con ogni tipo di dispositivo (computer, smartphone, tablet).Strutture di sicurezza: firewalls, soluzioni di crifratura, backupshttps://speedtech.it/servizio/sicurezza-firewalls-vpn/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/sicurezza-firewalls-vpn/Firewalls Soluzioni software e hardware per proteggere le reti ed i server per ogni esigenza : +case e piccoli uffici grandi uffici sedi distaccate servers VPN Soluzioni Virtual Private Network per accedere ad una rete remota in modalità sicura o per connettere due o più sedi distaccate con una connessione cifrata. Una VPN puà essere implmentata utilizzando software IPSec, OpenVPN e WireGuard e permette a singoli computer, tablets o smartphones di connettersi ad una rete protetta attraverso un canale cifrato e di utilizzare le risorse remote in modo trasparente come se fossero fisicamente connessi alla stessa rete.Sviluppo e integrazione di piattaforme per l'e-commercehttps://speedtech.it/servizio/soluzioni-e-commerce/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/soluzioni-e-commerce/Progettazione e sviluppo di soluzioni personalizzate in base alle necessità specifiche del cliente, sia per prodotti fisici che virtuali, integrate con il calcolo dei costi di spedizione ed il tracking della merce spedita. +Installazione, configurazione e manutenzione di soluzioni ecommerce open source (Woocommerce, OpenCart), progettazione e sviluppo di soluzione personalizzate. Integrazione con diversi gateway di pagamento : (Stripe, Paypal, Satispay). +Tecnologie utilizzate Linguaggio e framework di sviluppo : PHP, CodeIgniter, HTMX Database : MariaDB, PostgreSQLProgettazione e sviluppo di applicazioni softwarehttps://speedtech.it/servizio/sviluppo-applicazioni/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/sviluppo-applicazioni/Applicazioni (gestione progetti, registrazione attività, magazzino, contabilià e fatturazione) progettate per funzionare in ogni moderno browser web, accessibili ovunque da ogni dispositivo e che utilizzano i più efficienti frameworks di sviluppo connessi con i migliori databases open source : MariaDB, PostgreSQL, SQLite +Le applicazioni sono accessibili da ovunque nel mondo (è sufficiente una connessione ad Internet), non richiedono nessuna installazione e possono essere utilizzati contemporaneamente da più postazioni e possono essere utlizzati da qualsiasi sistema operativo (MS Windows, Linux, Apple), compresi i dispositivi mobili (smartphone e tablet). \ No newline at end of file diff --git a/public/it/index.html b/public/it/index.html new file mode 100644 index 0000000..acdb9ab --- /dev/null +++ b/public/it/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/ + \ No newline at end of file diff --git a/public/it/sitemap.xml b/public/it/sitemap.xml new file mode 100644 index 0000000..fad0d93 --- /dev/null +++ b/public/it/sitemap.xml @@ -0,0 +1 @@ +https://speedtech.it/blog/2025-10-30T00:00:00+00:00https://speedtech.it/blog/brainminder-intro/2025-10-30T00:00:00+00:00https://speedtech.it/categories/2025-10-30T00:00:00+00:00https://speedtech.it/2025-10-30T00:00:00+00:00https://speedtech.it/categories/projects/2025-10-30T00:00:00+00:00https://speedtech.it/tags/pwa/2025-10-30T00:00:00+00:00https://speedtech.it/tags/software-development/2025-10-30T00:00:00+00:00https://speedtech.it/tags/2025-10-30T00:00:00+00:00https://speedtech.it/tags/web-application/2025-10-30T00:00:00+00:00https://speedtech.it/blog/wmtrento-spreadsheet-sync/2023-05-07T00:00:00+00:00https://speedtech.it/categories/progetti/2023-05-07T00:00:00+00:00https://speedtech.it/tags/database/2022-12-11T00:00:00+00:00https://speedtech.it/blog/postgresql-database-link/2022-12-11T00:00:00+00:00https://speedtech.it/tags/postgresql/2022-12-11T00:00:00+00:00https://speedtech.it/tags/server/2022-12-11T00:00:00+00:00https://speedtech.it/categories/soluzioni/2022-12-11T00:00:00+00:00https://speedtech.it/categories/technology/2022-12-11T00:00:00+00:00https://speedtech.it/tags/custom-cms/2022-11-07T00:00:00+00:00https://speedtech.it/blog/wmtrento-data-sync/2022-11-07T00:00:00+00:00https://speedtech.it/blog/automazione-casa-con-home-assistant/2022-08-30T00:00:00+00:00https://speedtech.it/tags/home-assistant/2022-08-30T00:00:00+00:00https://speedtech.it/tags/home-automation/2022-08-30T00:00:00+00:00https://speedtech.it/tags/firewall/2022-12-11T00:00:00+00:00https://speedtech.it/tags/mariadb/2022-12-11T00:00:00+00:00https://speedtech.it/tags/openssl/2022-12-11T00:00:00+00:00https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/2022-12-11T00:00:00+00:00https://speedtech.it/tags/ufw/2022-12-11T00:00:00+00:00https://speedtech.it/blog/cifrare-comprimere-email-server/2022-07-08T00:00:00+00:00https://speedtech.it/tags/dovecot/2022-07-08T00:00:00+00:00https://speedtech.it/tags/networking/2022-07-08T00:00:00+00:00https://speedtech.it/tags/privacy/2022-07-08T00:00:00+00:00https://speedtech.it/tags/router/2022-07-08T00:00:00+00:00https://speedtech.it/tags/security/2022-07-08T00:00:00+00:00https://speedtech.it/tags/vpn/2022-07-08T00:00:00+00:00https://speedtech.it/blog/vpn-con-frizbox/2022-07-08T00:00:00+00:00https://speedtech.it/tags/file-server/2021-07-03T00:00:00+00:00https://speedtech.it/blog/synology-nas/2021-07-03T00:00:00+00:00https://speedtech.it/tags/nas/2021-07-03T00:00:00+00:00https://speedtech.it/blog/amorcosmetics-ecommerce/2021-05-27T00:00:00+00:00https://speedtech.it/tags/e-commerce/2021-05-27T00:00:00+00:00https://speedtech.it/blog/finova-oracle-apex/2019-11-09T00:00:00+00:00https://speedtech.it/tags/opnsense/2019-09-14T00:00:00+00:00https://speedtech.it/blog/finova-firewall/2019-09-14T00:00:00+00:00https://speedtech.it/tags/system-administration/2019-09-14T00:00:00+00:00https://speedtech.it/blog/agiati-web-applications/2019-05-04T00:00:00+00:00https://speedtech.it/tags/desktop-application/2017-12-12T00:00:00+00:00https://speedtech.it/blog/cspolsa-renting/2017-12-12T00:00:00+00:00https://speedtech.it/blog/botta-museum/2017-04-15T00:00:00+00:00https://speedtech.it/blog/versantus-drupal.-development/2016-02-03T00:00:00+00:00https://speedtech.it/blog/villamaria-firewalls/2016-01-14T00:00:00+00:00https://speedtech.it/blog/guiet-web-development/2015-08-03T00:00:00+00:00https://speedtech.it/blog/altevie-geomapping/2015-01-31T00:00:00+00:00https://speedtech.it/blog/amore-ecommerce/2012-08-02T00:00:00+00:00https://speedtech.it/tags/office-server/2011-03-12T00:00:00+00:00https://speedtech.it/blog/deflorian-server/2011-03-12T00:00:00+00:00https://speedtech.it/blog/lrm-drupal-development/2010-06-13T00:00:00+00:00https://speedtech.it/blog/daxtor-firewall-vpn-server-farm/2002-06-07T00:00:00+00:00https://speedtech.it/blog/sint-crm/2000-06-15T00:00:00+00:00https://speedtech.it/tags/oracle-database/2000-06-15T00:00:00+00:00https://speedtech.it/tags/pascal/2000-06-15T00:00:00+00:00https://speedtech.it/servizio/backend-siti-web-cms-personalizzati/https://speedtech.it/servizio/clients-con-linux/https://speedtech.it/servizio/soluzioni-collaborazione-online-offline/https://speedtech.it/servizio/domotica-opensource/https://speedtech.it/servizio/servers-linux-gestiti/https://speedtech.it/servizio/e-mail-privata/https://speedtech.it/servizio/https://speedtech.it/servizio/sicurezza-firewalls-vpn/https://speedtech.it/servizio/soluzioni-e-commerce/https://speedtech.it/servizio/sviluppo-applicazioni/ \ No newline at end of file diff --git a/public/js/fslightbox.js b/public/js/fslightbox.js new file mode 100644 index 0000000..0db6557 --- /dev/null +++ b/public/js/fslightbox.js @@ -0,0 +1 @@ +!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}(window,(function(){return function(e){var t={};function n(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(o,i,function(t){return e[t]}.bind(null,i));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);var o,i="fslightbox-",r="".concat(i,"styles"),s="".concat(i,"cursor-grabbing"),a="".concat(i,"full-dimension"),c="".concat(i,"flex-centered"),l="".concat(i,"open"),u="".concat(i,"transform-transition"),d="".concat(i,"absoluted"),f="".concat(i,"slide-btn"),p="".concat(f,"-container"),h="".concat(i,"fade-in"),m="".concat(i,"fade-out"),g=h+"-strong",v=m+"-strong",b="".concat(i,"opacity-"),x="".concat(b,"1"),y="".concat(i,"source");function w(e){return(w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function S(e){var t=e.stageIndexes,n=e.core.stageManager,o=e.props.sources.length-1;n.getPreviousSlideIndex=function(){return 0===t.current?o:t.current-1},n.getNextSlideIndex=function(){return t.current===o?0:t.current+1},n.updateStageIndexes=0===o?function(){}:1===o?function(){0===t.current?(t.next=1,delete t.previous):(t.previous=0,delete t.next)}:function(){t.previous=n.getPreviousSlideIndex(),t.next=n.getNextSlideIndex()},n.i=o<=2?function(){return!0}:function(e){var n=t.current;if(0===n&&e===o||n===o&&0===e)return!0;var i=n-e;return-1===i||0===i||1===i}}"object"===("undefined"==typeof document?"undefined":w(document))&&((o=document.createElement("style")).className=r,o.appendChild(document.createTextNode(".fslightbox-absoluted{position:absolute;top:0;left:0}.fslightbox-fade-in{animation:fslightbox-fade-in .3s cubic-bezier(0,0,.7,1)}.fslightbox-fade-out{animation:fslightbox-fade-out .3s ease}.fslightbox-fade-in-strong{animation:fslightbox-fade-in-strong .3s cubic-bezier(0,0,.7,1)}.fslightbox-fade-out-strong{animation:fslightbox-fade-out-strong .3s ease}@keyframes fslightbox-fade-in{from{opacity:.65}to{opacity:1}}@keyframes fslightbox-fade-out{from{opacity:.35}to{opacity:0}}@keyframes fslightbox-fade-in-strong{from{opacity:.3}to{opacity:1}}@keyframes fslightbox-fade-out-strong{from{opacity:1}to{opacity:0}}.fslightbox-cursor-grabbing{cursor:grabbing}.fslightbox-full-dimension{width:100%;height:100%}.fslightbox-open{overflow:hidden;height:100%}.fslightbox-flex-centered{display:flex;justify-content:center;align-items:center}.fslightbox-opacity-0{opacity:0!important}.fslightbox-opacity-1{opacity:1!important}.fslightbox-scrollbarfix{padding-right:17px}.fslightbox-transform-transition{transition:transform .3s}.fslightbox-container{font-family:Arial,sans-serif;position:fixed;top:0;left:0;background:linear-gradient(rgba(30,30,30,.9),#000 1810%);touch-action:pinch-zoom;z-index:1000000000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fslightbox-container *{box-sizing:border-box}.fslightbox-svg-path{transition:fill .15s ease;fill:#ddd}.fslightbox-nav{height:45px;width:100%;position:absolute;top:0;left:0}.fslightbox-slide-number-container{display:flex;justify-content:center;align-items:center;position:relative;height:100%;font-size:15px;color:#d7d7d7;z-index:0;max-width:55px;text-align:left}.fslightbox-slide-number-container .fslightbox-flex-centered{height:100%}.fslightbox-slash{display:block;margin:0 5px;width:1px;height:12px;transform:rotate(15deg);background:#fff}.fslightbox-toolbar{position:absolute;z-index:3;right:0;top:0;height:100%;display:flex;background:rgba(35,35,35,.65)}.fslightbox-toolbar-button{height:100%;width:45px;cursor:pointer}.fslightbox-toolbar-button:hover .fslightbox-svg-path{fill:#fff}.fslightbox-slide-btn-container{display:flex;align-items:center;padding:12px 12px 12px 6px;position:absolute;top:50%;cursor:pointer;z-index:3;transform:translateY(-50%)}@media (min-width:476px){.fslightbox-slide-btn-container{padding:22px 22px 22px 6px}}@media (min-width:768px){.fslightbox-slide-btn-container{padding:30px 30px 30px 6px}}.fslightbox-slide-btn-container:hover .fslightbox-svg-path{fill:#f1f1f1}.fslightbox-slide-btn{padding:9px;font-size:26px;background:rgba(35,35,35,.65)}@media (min-width:768px){.fslightbox-slide-btn{padding:10px}}@media (min-width:1600px){.fslightbox-slide-btn{padding:11px}}.fslightbox-slide-btn-container-previous{left:0}@media (max-width:475.99px){.fslightbox-slide-btn-container-previous{padding-left:3px}}.fslightbox-slide-btn-container-next{right:0;padding-left:12px;padding-right:3px}@media (min-width:476px){.fslightbox-slide-btn-container-next{padding-left:22px}}@media (min-width:768px){.fslightbox-slide-btn-container-next{padding-left:30px}}@media (min-width:476px){.fslightbox-slide-btn-container-next{padding-right:6px}}.fslightbox-down-event-detector{position:absolute;z-index:1}.fslightbox-slide-swiping-hoverer{z-index:4}.fslightbox-invalid-file-wrapper{font-size:22px;color:#eaebeb;margin:auto}.fslightbox-video{object-fit:cover}.fslightbox-youtube-iframe{border:0}.fslightboxl{display:block;margin:auto;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:67px;height:67px}.fslightboxl div{box-sizing:border-box;display:block;position:absolute;width:54px;height:54px;margin:6px;border:5px solid;border-color:#999 transparent transparent transparent;border-radius:50%;animation:fslightboxl 1.2s cubic-bezier(.5,0,.5,1) infinite}.fslightboxl div:nth-child(1){animation-delay:-.45s}.fslightboxl div:nth-child(2){animation-delay:-.3s}.fslightboxl div:nth-child(3){animation-delay:-.15s}@keyframes fslightboxl{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.fslightbox-source{position:relative;z-index:2;opacity:0}")),document.head.appendChild(o));function L(e){var t,n=e.props,o=0,i={};this.getSourceTypeFromLocalStorageByUrl=function(e){return t[e]?t[e]:r(e)},this.handleReceivedSourceTypeForUrl=function(e,n){if(!1===i[n]&&(o--,"invalid"!==e?i[n]=e:delete i[n],0===o)){!function(e,t){for(var n in t)e[n]=t[n]}(t,i);try{localStorage.setItem("fslightbox-types",JSON.stringify(t))}catch(e){}}};var r=function(e){o++,i[e]=!1};if(n.disableLocalStorage)this.getSourceTypeFromLocalStorageByUrl=function(){},this.handleReceivedSourceTypeForUrl=function(){};else{try{t=JSON.parse(localStorage.getItem("fslightbox-types"))}catch(e){}t||(t={},this.getSourceTypeFromLocalStorageByUrl=r)}}function A(e,t,n,o){var i=e.data,r=e.elements.sources,s=n/o,a=0;this.adjustSize=function(){if((a=i.maxSourceWidth/s)i.maxSourceHeight?i.maxSourceHeight:o,c()};var c=function(){r[t].style.width=a*s+"px",r[t].style.height=a+"px"}}function C(e,t){var n=this,o=e.collections.sourceSizers,i=e.elements,r=i.sourceAnimationWrappers,s=i.sources,a=e.isl,c=e.resolve;function l(e,n){o[t]=c(A,[t,e,n]),o[t].adjustSize()}this.runActions=function(e,o){a[t]=!0,s[t].classList.add(x),r[t].classList.add(g),r[t].removeChild(r[t].firstChild),l(e,o),n.runActions=l}}function E(e,t){var n,o=this,i=e.elements.sources,r=e.props,s=(0,e.resolve)(C,[t]);this.handleImageLoad=function(e){var t=e.target,n=t.naturalWidth,o=t.naturalHeight;s.runActions(n,o)},this.handleVideoLoad=function(e){var t=e.target,o=t.videoWidth,i=t.videoHeight;n=!0,s.runActions(o,i)},this.handleNotMetaDatedVideoLoad=function(){n||o.handleYoutubeLoad()},this.handleYoutubeLoad=function(){var e=1920,t=1080;r.maxYoutubeDimensions&&(e=r.maxYoutubeDimensions.width,t=r.maxYoutubeDimensions.height),s.runActions(e,t)},this.handleCustomLoad=function(){var e=i[t],n=e.offsetWidth,r=e.offsetHeight;n&&r?s.runActions(n,r):setTimeout(o.handleCustomLoad)}}function F(e,t,n){var o=e.elements.sources,i=e.props.customClasses,r=i[t]?i[t]:"";o[t].className=n+" "+r}function I(e,t){var n=e.elements.sources,o=e.props.customAttributes;for(var i in o[t])n[t].setAttribute(i,o[t][i])}function T(e,t){var n=e.collections.sourceLoadHandlers,o=e.elements,i=o.sources,r=o.sourceAnimationWrappers,s=e.props.sources;i[t]=document.createElement("img"),F(e,t,y),i[t].src=s[t],i[t].onload=n[t].handleImageLoad,I(e,t),r[t].appendChild(i[t])}function N(e,t){var n=e.collections.sourceLoadHandlers,o=e.elements,i=o.sources,r=o.sourceAnimationWrappers,s=e.props,a=s.sources,c=s.videosPosters;i[t]=document.createElement("video"),F(e,t,y),i[t].src=a[t],i[t].onloadedmetadata=function(e){n[t].handleVideoLoad(e)},i[t].controls=!0,I(e,t),c[t]&&(i[t].poster=c[t]);var l=document.createElement("source");l.src=a[t],i[t].appendChild(l),setTimeout(n[t].handleNotMetaDatedVideoLoad,3e3),r[t].appendChild(i[t])}function z(e,t){var n=e.collections.sourceLoadHandlers,o=e.elements,r=o.sources,s=o.sourceAnimationWrappers,a=e.props.sources;r[t]=document.createElement("iframe"),F(e,t,"".concat(y," ").concat(i,"youtube-iframe"));var c=a[t],l=c.split("?")[1];r[t].src="https://www.youtube.com/embed/".concat(c.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/)[2],"?").concat(l||""),r[t].allowFullscreen=!0,I(e,t),s[t].appendChild(r[t]),n[t].handleYoutubeLoad()}function P(e,t){var n=e.collections.sourceLoadHandlers,o=e.elements,i=o.sources,r=o.sourceAnimationWrappers,s=e.props.sources;i[t]=s[t],F(e,t,"".concat(i[t].className," ").concat(y)),r[t].appendChild(i[t]),n[t].handleCustomLoad()}function k(e,t){var n=e.elements,o=n.sources,r=n.sourceAnimationWrappers;e.props.sources;o[t]=document.createElement("div"),o[t].className="".concat(i,"invalid-file-wrapper ").concat(c),o[t].innerHTML="Invalid source",r[t].classList.add(g),r[t].removeChild(r[t].firstChild),r[t].appendChild(o[t])}function H(e){var t=e.collections,n=t.sourceLoadHandlers,o=t.sourcesRenderFunctions,i=e.core.sourceDisplayFacade,r=e.resolve;this.runActionsForSourceTypeAndIndex=function(t,s){var a;switch("invalid"!==t&&(n[s]=r(E,[s])),t){case"image":a=T;break;case"video":a=N;break;case"youtube":a=z;break;case"custom":a=P;break;default:a=k}o[s]=function(){return a(e,s)},i.displaySourcesWhichShouldBeDisplayed()}}function W(){var e,t,n,o={isUrlYoutubeOne:function(e){var t=document.createElement("a");return t.href=e,"www.youtube.com"===t.hostname||"youtu.be"===t.hostname},getTypeFromResponseContentType:function(e){return e.slice(0,e.indexOf("/"))}};function i(){if(4!==n.readyState){if(2===n.readyState){var e;switch(o.getTypeFromResponseContentType(n.getResponseHeader("content-type"))){case"image":e="image";break;case"video":e="video";break;default:e="invalid"}n.onreadystatechange=null,n.abort(),t(e)}}else t("invalid")}this.setUrlToCheck=function(t){e=t},this.getSourceType=function(r){if(o.isUrlYoutubeOne(e))return r("youtube");t=r,(n=new XMLHttpRequest).onreadystatechange=i,n.open("GET",e,!0),n.send()}}function R(e,t,n){var o=e.props,i=o.types,r=o.type,s=o.sources,a=e.resolve;this.getTypeSetByClientForIndex=function(e){var t;return i&&i[e]?t=i[e]:r&&(t=r),t},this.retrieveTypeWithXhrForIndex=function(e){var o=a(W);o.setUrlToCheck(s[e]),o.getSourceType((function(o){t.handleReceivedSourceTypeForUrl(o,s[e]),n.runActionsForSourceTypeAndIndex(o,e)}))}}function D(e,t){var n=e.core.stageManager,o=e.elements,i=o.smw,r=o.sourceWrappersContainer,s=e.props,l=0,f=document.createElement("div");function p(e){f.style.transform="translateX(".concat(e+l,"px)"),l=0}function h(){return(1+s.slideDistance)*innerWidth}f.className="".concat(d," ").concat(a," ").concat(c),f.s=function(){f.style.display="flex"},f.h=function(){f.style.display="none"},f.a=function(){f.classList.add(u)},f.d=function(){f.classList.remove(u)},f.n=function(){f.style.removeProperty("transform")},f.v=function(e){return l=e,f},f.ne=function(){p(-h())},f.z=function(){p(0)},f.p=function(){p(h())},n.i(t)||f.h(),i[t]=f,r.appendChild(f),function(e,t){var n=e.elements,o=n.smw,i=n.sourceAnimationWrappers,r=document.createElement("div"),s=document.createElement("div");s.className="fslightboxl";for(var a=0;a<3;a++){var c=document.createElement("div");s.appendChild(c)}r.appendChild(s),o[t].appendChild(r),i[t]=r}(e,t)}function O(e,t,n,o){var r=document.createElementNS("http://www.w3.org/2000/svg","svg");r.setAttributeNS(null,"width",t),r.setAttributeNS(null,"height",t),r.setAttributeNS(null,"viewBox",n);var s=document.createElementNS("http://www.w3.org/2000/svg","path");return s.setAttributeNS(null,"class","".concat(i,"svg-path")),s.setAttributeNS(null,"d",o),r.appendChild(s),e.appendChild(r),r}function M(e,t){var n=document.createElement("div");return n.className="".concat(i,"toolbar-button ").concat(c),n.title=t,e.appendChild(n),n}function j(e,t){var n=document.createElement("div");n.className="".concat(i,"toolbar"),t.appendChild(n),function(e,t){var n=e.componentsServices,o=e.data,i=e.fs,r="M4.5 11H3v4h4v-1.5H4.5V11zM3 7h1.5V4.5H7V3H3v4zm10.5 6.5H11V15h4v-4h-1.5v2.5zM11 3v1.5h2.5V7H15V3h-4z",s=M(t);s.title="Enter fullscreen";var a=O(s,"20px","0 0 18 18",r);n.ofs=function(){o.ifs=!0,s.title="Exit fullscreen",a.setAttributeNS(null,"width","24px"),a.setAttributeNS(null,"height","24px"),a.setAttributeNS(null,"viewBox","0 0 950 1024"),a.firstChild.setAttributeNS(null,"d","M682 342h128v84h-212v-212h84v128zM598 810v-212h212v84h-128v128h-84zM342 342v-128h84v212h-212v-84h128zM214 682v-84h212v212h-84v-128h-128z")},n.xfs=function(){o.ifs=!1,s.title="Enter fullscreen",a.setAttributeNS(null,"width","20px"),a.setAttributeNS(null,"height","20px"),a.setAttributeNS(null,"viewBox","0 0 18 18"),a.firstChild.setAttributeNS(null,"d",r)},s.onclick=i.t}(e,n),function(e,t){var n=M(t,"Close");n.onclick=e.core.lightboxCloser.closeLightbox,O(n,"20px","0 0 24 24","M 4.7070312 3.2929688 L 3.2929688 4.7070312 L 10.585938 12 L 3.2929688 19.292969 L 4.7070312 20.707031 L 12 13.414062 L 19.292969 20.707031 L 20.707031 19.292969 L 13.414062 12 L 20.707031 4.7070312 L 19.292969 3.2929688 L 12 10.585938 L 4.7070312 3.2929688 z")}(e,n)}function X(e){var t=e.props.sources,n=e.elements.container,o=document.createElement("div");o.className="".concat(i,"nav"),n.appendChild(o),j(e,o),t.length>1&&function(e,t){var n=e.componentsServices,o=e.props.sources,r=(e.stageIndexes,document.createElement("div"));r.className="".concat(i,"slide-number-container");var s=document.createElement("div");s.className=c;var a=document.createElement("span");n.setSlideNumber=function(e){return a.innerHTML=e};var l=document.createElement("span");l.className="".concat(i,"slash");var u=document.createElement("div");u.innerHTML=o.length,r.appendChild(s),s.appendChild(a),s.appendChild(l),s.appendChild(u),t.appendChild(r),setTimeout((function(){s.offsetWidth>55&&(r.style.justifyContent="flex-start")}))}(e,o)}function B(e,t,n,o){var i=e.elements.container,r=n.charAt(0).toUpperCase()+n.slice(1),s=document.createElement("div");s.className="".concat(p," ").concat(p,"-").concat(n),s.title="".concat(r," slide"),s.onclick=t,function(e,t){var n=document.createElement("div");n.className="".concat(f," ").concat(c),O(n,"20px","0 0 20 20",t),e.appendChild(n)}(s,o),i.appendChild(s)}function U(e){var t=e.core,n=t.lightboxCloser,o=t.slideChangeFacade,i=e.fs;this.listener=function(e){switch(e.key){case"Escape":n.closeLightbox();break;case"ArrowLeft":o.changeToPrevious();break;case"ArrowRight":o.changeToNext();break;case"F11":e.preventDefault(),i.t()}}}function q(e){var t=e.elements,n=e.sourcePointerProps,o=e.stageIndexes;function i(e,o){t.smw[e].v(n.swipedX)[o]()}this.runActionsForEvent=function(e){var r,a,c;t.container.contains(t.slideSwipingHoverer)||t.container.appendChild(t.slideSwipingHoverer),r=t.container,a=s,(c=r.classList).contains(a)||c.add(a),n.swipedX=e.screenX-n.downScreenX;var l=o.previous,u=o.next;i(o.current,"z"),void 0!==l&&n.swipedX>0?i(l,"ne"):void 0!==u&&n.swipedX<0&&i(u,"p")}}function V(e){var t=e.props.sources,n=e.resolve,o=e.sourcePointerProps,i=n(q);1===t.length?this.listener=function(){o.swipedX=1}:this.listener=function(e){o.isPointering&&i.runActionsForEvent(e)}}function _(e){var t=e.core.slideIndexChanger,n=e.elements.smw,o=e.stageIndexes,i=e.sws;function r(e){var t=n[o.current];t.a(),t[e]()}function s(e,t){void 0!==e&&(n[e].s(),n[e][t]())}this.runPositiveSwipedXActions=function(){var e=o.previous;if(void 0===e)r("z");else{r("p");var n=o.next;t.changeTo(e);var a=o.previous;i.d(a),i.b(n),r("z"),s(a,"ne")}},this.runNegativeSwipedXActions=function(){var e=o.next;if(void 0===e)r("z");else{r("ne");var n=o.previous;t.changeTo(e);var a=o.next;i.d(a),i.b(n),r("z"),s(a,"p")}}}function Y(e,t){e.contains(t)&&e.removeChild(t)}function J(e){var t=e.core.lightboxCloser,n=e.elements,o=e.resolve,i=e.sourcePointerProps,r=o(_);this.runNoSwipeActions=function(){Y(n.container,n.slideSwipingHoverer),i.isSourceDownEventTarget||t.closeLightbox(),i.isPointering=!1},this.runActions=function(){i.swipedX>0?r.runPositiveSwipedXActions():r.runNegativeSwipedXActions(),Y(n.container,n.slideSwipingHoverer),n.container.classList.remove(s),i.isPointering=!1}}function G(e){var t=e.resolve,n=e.sourcePointerProps,o=t(J);this.listener=function(){n.isPointering&&(n.swipedX?o.runActions():o.runNoSwipeActions())}}function $(e){var t=this,n=e.core,o=n.eventsDispatcher,i=n.globalEventsController,r=n.scrollbarRecompensor,s=e.data,a=e.elements,c=e.fs,u=e.props,d=e.sourcePointerProps;this.isLightboxFadingOut=!1,this.runActions=function(){t.isLightboxFadingOut=!0,a.container.classList.add(v),i.removeListeners(),u.exitFullscreenOnClose&&s.ifs&&c.x(),setTimeout((function(){t.isLightboxFadingOut=!1,d.isPointering=!1,a.container.classList.remove(v),document.documentElement.classList.remove(l),r.removeRecompense(),document.body.removeChild(a.container),o.dispatch("onClose")}),270)}}function K(e,t){var n=e.classList;n.contains(t)&&n.remove(t)}function Q(e){var t,n,o;n=(t=e).core.eventsDispatcher,o=t.props,n.dispatch=function(e){o[e]&&o[e]()},function(e){var t=e.componentsServices,n=e.data,o=e.fs,i=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"];function r(e){for(var t=0;tinnerHeight&&(document.body.style.marginRight=t.scrollbarWidth+"px")}n.addRecompense=function(){"complete"===document.readyState?o():addEventListener("load",(function(){o(),n.addRecompense=o}))},n.removeRecompense=function(){document.body.style.removeProperty("margin-right")}}(e),function(e){var t=e.core,n=t.slideChangeFacade,o=t.slideIndexChanger,i=t.stageManager;e.props.sources.length>1?(n.changeToPrevious=function(){o.jumpTo(i.getPreviousSlideIndex())},n.changeToNext=function(){o.jumpTo(i.getNextSlideIndex())}):(n.changeToPrevious=function(){},n.changeToNext=function(){})}(e),function(e){var t=e.componentsServices,n=e.core,o=n.slideIndexChanger,i=n.sourceDisplayFacade,r=n.stageManager,s=e.elements,a=s.smw,c=s.sourceAnimationWrappers,l=e.isl,u=e.stageIndexes,d=e.sws;o.changeTo=function(e){u.current=e,r.updateStageIndexes(),t.setSlideNumber(e+1),i.displaySourcesWhichShouldBeDisplayed()},o.jumpTo=function(e){var t=u.previous,n=u.current,i=u.next,s=l[n],f=l[e];o.changeTo(e);for(var p=0;p1&&(n=(t=e).core.slideChangeFacade,B(t,n.changeToPrevious,"previous","M18.271,9.212H3.615l4.184-4.184c0.306-0.306,0.306-0.801,0-1.107c-0.306-0.306-0.801-0.306-1.107,0L1.21,9.403C1.194,9.417,1.174,9.421,1.158,9.437c-0.181,0.181-0.242,0.425-0.209,0.66c0.005,0.038,0.012,0.071,0.022,0.109c0.028,0.098,0.075,0.188,0.142,0.271c0.021,0.026,0.021,0.061,0.045,0.085c0.015,0.016,0.034,0.02,0.05,0.033l5.484,5.483c0.306,0.307,0.801,0.307,1.107,0c0.306-0.305,0.306-0.801,0-1.105l-4.184-4.185h14.656c0.436,0,0.788-0.353,0.788-0.788S18.707,9.212,18.271,9.212z"),B(t,n.changeToNext,"next","M1.729,9.212h14.656l-4.184-4.184c-0.307-0.306-0.307-0.801,0-1.107c0.305-0.306,0.801-0.306,1.106,0l5.481,5.482c0.018,0.014,0.037,0.019,0.053,0.034c0.181,0.181,0.242,0.425,0.209,0.66c-0.004,0.038-0.012,0.071-0.021,0.109c-0.028,0.098-0.075,0.188-0.143,0.271c-0.021,0.026-0.021,0.061-0.045,0.085c-0.015,0.016-0.034,0.02-0.051,0.033l-5.483,5.483c-0.306,0.307-0.802,0.307-1.106,0c-0.307-0.305-0.307-0.801,0-1.105l4.184-4.185H1.729c-0.436,0-0.788-0.353-0.788-0.788S1.293,9.212,1.729,9.212z")),function(e){for(var t=e.props.sources,n=e.resolve,o=n(L),i=n(H),r=n(R,[o,i]),s=0;s0&&void 0!==arguments[0]?arguments[0]:0,i=m.previous,a=m.current,d=m.next;m.current=n,p.i||S(e),u.updateStageIndexes(),p.i?(v.c(),v.a(),v.b(i),v.b(a),v.b(d),o.dispatch("onShow")):b(),c.displaySourcesWhichShouldBeDisplayed(),t.setSlideNumber(n+1),document.body.appendChild(h.container),document.documentElement.classList.add(l),s.addRecompense(),r.attachListeners(),f.runActions(),h.smw[m.current].n(),o.dispatch("onOpen")}}function ee(e,t,n){return(ee=te()?Reflect.construct.bind():function(e,t,n){var o=[null];o.push.apply(o,t);var i=new(Function.bind.apply(e,o));return n&&ne(i,n.prototype),i}).apply(null,arguments)}function te(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function ne(e,t){return(ne=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function oe(e){return function(e){if(Array.isArray(e))return ie(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return ie(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ie(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ie(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n1&&void 0!==arguments[1]?arguments[1]:[];return n.unshift(e),ee(t,oe(n))},this.collections={sourceLoadHandlers:[],sourcesRenderFunctions:[],sourceSizers:[]},this.core={eventsDispatcher:{},globalEventsController:{},lightboxCloser:{},lightboxUpdater:{},scrollbarRecompensor:{},slideChangeFacade:{},slideIndexChanger:{},sourcesPointerDown:{},sourceDisplayFacade:{},stageManager:{},windowResizeActioner:{}},this.fs={},this.sws={},Z(this),this.close=function(){return e.core.lightboxCloser.closeLightbox()}},window.fsLightboxInstances={},re(),window.refreshFsLightbox=function(){for(var e in fsLightboxInstances){var t=fsLightboxInstances[e].props;fsLightboxInstances[e]=new FsLightbox,fsLightboxInstances[e].props=t,fsLightboxInstances[e].props.sources=[],fsLightboxInstances[e].elements.a=[]}re()}}])})); \ No newline at end of file diff --git a/public/js/htmx/ext/ajax-header.js b/public/js/htmx/ext/ajax-header.js new file mode 100644 index 0000000..5c6221b --- /dev/null +++ b/public/js/htmx/ext/ajax-header.js @@ -0,0 +1,7 @@ +htmx.defineExtension('ajax-header', { + onEvent: function (name, evt) { + if (name === "htmx:configRequest") { + evt.detail.headers['X-Requested-With'] = 'XMLHttpRequest'; + } + } +}); \ No newline at end of file diff --git a/public/js/htmx/ext/alpine-morph.js b/public/js/htmx/ext/alpine-morph.js new file mode 100644 index 0000000..1872dae --- /dev/null +++ b/public/js/htmx/ext/alpine-morph.js @@ -0,0 +1,16 @@ +htmx.defineExtension('alpine-morph', { + isInlineSwap: function (swapStyle) { + return swapStyle === 'morph'; + }, + handleSwap: function (swapStyle, target, fragment) { + if (swapStyle === 'morph') { + if (fragment.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + Alpine.morph(target, fragment.firstElementChild); + return [target]; + } else { + Alpine.morph(target, fragment.outerHTML); + return [target]; + } + } + } +}); \ No newline at end of file diff --git a/public/js/htmx/ext/class-tools.js b/public/js/htmx/ext/class-tools.js new file mode 100644 index 0000000..1cf4b42 --- /dev/null +++ b/public/js/htmx/ext/class-tools.js @@ -0,0 +1,92 @@ +(function () { + + function splitOnWhitespace(trigger) { + return trigger.split(/\s+/); + } + + function parseClassOperation(trimmedValue) { + var split = splitOnWhitespace(trimmedValue); + if (split.length > 1) { + var operation = split[0]; + var classDef = split[1].trim(); + var cssClass; + var delay; + if (classDef.indexOf(":") > 0) { + var splitCssClass = classDef.split(':'); + cssClass = splitCssClass[0]; + delay = htmx.parseInterval(splitCssClass[1]); + } else { + cssClass = classDef; + delay = 100; + } + return { + operation: operation, + cssClass: cssClass, + delay: delay + } + } else { + return null; + } + } + + function performOperation(elt, classOperation, classList, currentRunTime) { + setTimeout(function () { + elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass); + }, currentRunTime) + } + + function toggleOperation(elt, classOperation, classList, currentRunTime) { + setTimeout(function () { + setInterval(function () { + elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass); + }, classOperation.delay); + }, currentRunTime) + } + + function processClassList(elt, classList) { + var runs = classList.split("&"); + for (var i = 0; i < runs.length; i++) { + var run = runs[i]; + var currentRunTime = 0; + var classOperations = run.split(","); + for (var j = 0; j < classOperations.length; j++) { + var value = classOperations[j]; + var trimmedValue = value.trim(); + var classOperation = parseClassOperation(trimmedValue); + if (classOperation) { + if (classOperation.operation === "toggle") { + toggleOperation(elt, classOperation, classList, currentRunTime); + currentRunTime = currentRunTime + classOperation.delay; + } else { + currentRunTime = currentRunTime + classOperation.delay; + performOperation(elt, classOperation, classList, currentRunTime); + } + } + } + } + } + + function maybeProcessClasses(elt) { + if (elt.getAttribute) { + var classList = elt.getAttribute("classes") || elt.getAttribute("data-classes"); + if (classList) { + processClassList(elt, classList); + } + } + } + + htmx.defineExtension('class-tools', { + onEvent: function (name, evt) { + if (name === "htmx:afterProcessNode") { + var elt = evt.detail.elt; + maybeProcessClasses(elt); + if (elt.querySelectorAll) { + var children = elt.querySelectorAll("[classes], [data-classes]"); + for (var i = 0; i < children.length; i++) { + maybeProcessClasses(children[i]); + } + } + } + } + }); +})(); \ No newline at end of file diff --git a/public/js/htmx/ext/client-side-templates.js b/public/js/htmx/ext/client-side-templates.js new file mode 100644 index 0000000..2bace41 --- /dev/null +++ b/public/js/htmx/ext/client-side-templates.js @@ -0,0 +1,96 @@ +htmx.defineExtension('client-side-templates', { + transformResponse : function(text, xhr, elt) { + + var mustacheTemplate = htmx.closest(elt, "[mustache-template]"); + if (mustacheTemplate) { + var data = JSON.parse(text); + var templateId = mustacheTemplate.getAttribute('mustache-template'); + var template = htmx.find("#" + templateId); + if (template) { + return Mustache.render(template.innerHTML, data); + } else { + throw "Unknown mustache template: " + templateId; + } + } + + var mustacheArrayTemplate = htmx.closest(elt, "[mustache-array-template]"); + if (mustacheArrayTemplate) { + var data = JSON.parse(text); + var templateId = mustacheArrayTemplate.getAttribute('mustache-array-template'); + var template = htmx.find("#" + templateId); + if (template) { + return Mustache.render(template.innerHTML, {"data": data }); + } else { + throw "Unknown mustache template: " + templateId; + } + } + + var handlebarsTemplate = htmx.closest(elt, "[handlebars-template]"); + if (handlebarsTemplate) { + var data = JSON.parse(text); + var templateId = handlebarsTemplate.getAttribute('handlebars-template'); + var templateElement = htmx.find('#' + templateId).innerHTML; + var renderTemplate = Handlebars.compile(templateElement); + if (renderTemplate) { + return renderTemplate(data); + } else { + throw "Unknown handlebars template: " + templateId; + } + } + + var handlebarsArrayTemplate = htmx.closest(elt, "[handlebars-array-template]"); + if (handlebarsArrayTemplate) { + var data = JSON.parse(text); + var templateId = handlebarsArrayTemplate.getAttribute('handlebars-array-template'); + var templateElement = htmx.find('#' + templateId).innerHTML; + var renderTemplate = Handlebars.compile(templateElement); + if (renderTemplate) { + return renderTemplate(data); + } else { + throw "Unknown handlebars template: " + templateId; + } + } + + var nunjucksTemplate = htmx.closest(elt, "[nunjucks-template]"); + if (nunjucksTemplate) { + var data = JSON.parse(text); + var templateName = nunjucksTemplate.getAttribute('nunjucks-template'); + var template = htmx.find('#' + templateName); + if (template) { + return nunjucks.renderString(template.innerHTML, data); + } else { + return nunjucks.render(templateName, data); + } + } + + var xsltTemplate = htmx.closest(elt, "[xslt-template]"); + if (xsltTemplate) { + var templateId = xsltTemplate.getAttribute('xslt-template'); + var template = htmx.find("#" + templateId); + if (template) { + var content = template.innerHTML ? new DOMParser().parseFromString(template.innerHTML, 'application/xml') + : template.contentDocument; + var processor = new XSLTProcessor(); + processor.importStylesheet(content); + var data = new DOMParser().parseFromString(text, "application/xml"); + var frag = processor.transformToFragment(data, document); + return new XMLSerializer().serializeToString(frag); + } else { + throw "Unknown XSLT template: " + templateId; + } + } + + var nunjucksArrayTemplate = htmx.closest(elt, "[nunjucks-array-template]"); + if (nunjucksArrayTemplate) { + var data = JSON.parse(text); + var templateName = nunjucksArrayTemplate.getAttribute('nunjucks-array-template'); + var template = htmx.find('#' + templateName); + if (template) { + return nunjucks.renderString(template.innerHTML, {"data": data}); + } else { + return nunjucks.render(templateName, {"data": data}); + } + } + return text; + } +}); diff --git a/public/js/htmx/ext/debug.js b/public/js/htmx/ext/debug.js new file mode 100644 index 0000000..861ee74 --- /dev/null +++ b/public/js/htmx/ext/debug.js @@ -0,0 +1,11 @@ +htmx.defineExtension('debug', { + onEvent: function (name, evt) { + if (console.debug) { + console.debug(name, evt); + } else if (console) { + console.log("DEBUG:", name, evt); + } else { + throw "NO CONSOLE SUPPORTED" + } + } +}); diff --git a/public/js/htmx/ext/disable-element.js b/public/js/htmx/ext/disable-element.js new file mode 100644 index 0000000..07bef62 --- /dev/null +++ b/public/js/htmx/ext/disable-element.js @@ -0,0 +1,18 @@ +"use strict"; + +// Disable Submit Button +htmx.defineExtension('disable-element', { + onEvent: function (name, evt) { + let elt = evt.detail.elt; + let target = elt.getAttribute("hx-disable-element"); + let targetElements = (target == "self") ? [ elt ] : document.querySelectorAll(target); + + for (var i = 0; i < targetElements.length; i++) { + if (name === "htmx:beforeRequest" && targetElements[i]) { + targetElements[i].disabled = true; + } else if (name == "htmx:afterRequest" && targetElements[i]) { + targetElements[i].disabled = false; + } + } + } +}); \ No newline at end of file diff --git a/public/js/htmx/ext/event-header.js b/public/js/htmx/ext/event-header.js new file mode 100644 index 0000000..c7d2933 --- /dev/null +++ b/public/js/htmx/ext/event-header.js @@ -0,0 +1,37 @@ +(function(){ + function stringifyEvent(event) { + var obj = {}; + for (var key in event) { + obj[key] = event[key]; + } + return JSON.stringify(obj, function(key, value){ + if(value instanceof Node){ + var nodeRep = value.tagName; + if (nodeRep) { + nodeRep = nodeRep.toLowerCase(); + if(value.id){ + nodeRep += "#" + value.id; + } + if(value.classList && value.classList.length){ + nodeRep += "." + value.classList.toString().replace(" ", ".") + } + return nodeRep; + } else { + return "Node" + } + } + if (value instanceof Window) return 'Window'; + return value; + }); + } + + htmx.defineExtension('event-header', { + onEvent: function (name, evt) { + if (name === "htmx:configRequest") { + if (evt.detail.triggeringEvent) { + evt.detail.headers['Triggering-Event'] = stringifyEvent(evt.detail.triggeringEvent); + } + } + } + }); +})(); diff --git a/public/js/htmx/ext/head-support.js b/public/js/htmx/ext/head-support.js new file mode 100644 index 0000000..67cfc69 --- /dev/null +++ b/public/js/htmx/ext/head-support.js @@ -0,0 +1,141 @@ +//========================================================== +// head-support.js +// +// An extension to htmx 1.0 to add head tag merging. +//========================================================== +(function(){ + + var api = null; + + function log() { + //console.log(arguments); + } + + function mergeHead(newContent, defaultMergeStrategy) { + + if (newContent && newContent.indexOf(' -1) { + const htmlDoc = document.createElement("html"); + // remove svgs to avoid conflicts + var contentWithSvgsRemoved = newContent.replace(/]*>|>)([\s\S]*?)<\/svg>/gim, ''); + // extract head tag + var headTag = contentWithSvgsRemoved.match(/(]*>|>)([\s\S]*?)<\/head>)/im); + + // if the head tag exists... + if (headTag) { + + var added = [] + var removed = [] + var preserved = [] + var nodesToAppend = [] + + htmlDoc.innerHTML = headTag; + var newHeadTag = htmlDoc.querySelector("head"); + var currentHead = document.head; + + if (newHeadTag == null) { + return; + } else { + // put all new head elements into a Map, by their outerHTML + var srcToNewHeadNodes = new Map(); + for (const newHeadChild of newHeadTag.children) { + srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild); + } + } + + + + // determine merge strategy + var mergeStrategy = api.getAttributeValue(newHeadTag, "hx-head") || defaultMergeStrategy; + + // get the current head + for (const currentHeadElt of currentHead.children) { + + // If the current head element is in the map + var inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML); + var isReAppended = currentHeadElt.getAttribute("hx-head") === "re-eval"; + var isPreserved = api.getAttributeValue(currentHeadElt, "hx-preserve") === "true"; + if (inNewContent || isPreserved) { + if (isReAppended) { + // remove the current version and let the new version replace it and re-execute + removed.push(currentHeadElt); + } else { + // this element already exists and should not be re-appended, so remove it from + // the new content map, preserving it in the DOM + srcToNewHeadNodes.delete(currentHeadElt.outerHTML); + preserved.push(currentHeadElt); + } + } else { + if (mergeStrategy === "append") { + // we are appending and this existing element is not new content + // so if and only if it is marked for re-append do we do anything + if (isReAppended) { + removed.push(currentHeadElt); + nodesToAppend.push(currentHeadElt); + } + } else { + // if this is a merge, we remove this content since it is not in the new head + if (api.triggerEvent(document.body, "htmx:removingHeadElement", {headElement: currentHeadElt}) !== false) { + removed.push(currentHeadElt); + } + } + } + } + + // Push the tremaining new head elements in the Map into the + // nodes to append to the head tag + nodesToAppend.push(...srcToNewHeadNodes.values()); + log("to append: ", nodesToAppend); + + for (const newNode of nodesToAppend) { + log("adding: ", newNode); + var newElt = document.createRange().createContextualFragment(newNode.outerHTML); + log(newElt); + if (api.triggerEvent(document.body, "htmx:addingHeadElement", {headElement: newElt}) !== false) { + currentHead.appendChild(newElt); + added.push(newElt); + } + } + + // remove all removed elements, after we have appended the new elements to avoid + // additional network requests for things like style sheets + for (const removedElement of removed) { + if (api.triggerEvent(document.body, "htmx:removingHeadElement", {headElement: removedElement}) !== false) { + currentHead.removeChild(removedElement); + } + } + + api.triggerEvent(document.body, "htmx:afterHeadMerge", {added: added, kept: preserved, removed: removed}); + } + } + } + + htmx.defineExtension("head-support", { + init: function(apiRef) { + // store a reference to the internal API. + api = apiRef; + + htmx.on('htmx:afterSwap', function(evt){ + var serverResponse = evt.detail.xhr.response; + if (api.triggerEvent(document.body, "htmx:beforeHeadMerge", evt.detail)) { + mergeHead(serverResponse, evt.detail.boosted ? "merge" : "append"); + } + }) + + htmx.on('htmx:historyRestore', function(evt){ + if (api.triggerEvent(document.body, "htmx:beforeHeadMerge", evt.detail)) { + if (evt.detail.cacheMiss) { + mergeHead(evt.detail.serverResponse, "merge"); + } else { + mergeHead(evt.detail.item.head, "merge"); + } + } + }) + + htmx.on('htmx:historyItemCreated', function(evt){ + var historyItem = evt.detail.item; + historyItem.head = document.head.outerHTML; + }) + } + }); + +})() \ No newline at end of file diff --git a/public/js/htmx/ext/htmx-shoelace.js b/public/js/htmx/ext/htmx-shoelace.js new file mode 100644 index 0000000..4d79c75 --- /dev/null +++ b/public/js/htmx/ext/htmx-shoelace.js @@ -0,0 +1,45 @@ +const slTypes = 'sl-checkbox, sl-color-picker, sl-input, sl-radio-group, sl-range, sl-rating, sl-select, sl-switch, sl-textarea' + +/* Lightly modified version of the same function in htmx.js */ +function shouldInclude(elt) { + + // sl-rating doesn't have a name attribute exposed through the Shoelace API (for elt.name) so this check needs to come before the name==="" check + if (elt.tagName === 'SL-RATING' && elt.getAttribute('name')) { + return true + } + + if (elt.name === "" || elt.name == null || elt.disabled || elt.closest("fieldset[disabled]")) { + return false + } + + if (elt.tagName === 'SL-CHECKBOX' || elt.tagName === 'SL-SWITCH') { + return elt.checked + } + + if (elt.tagName === "SL-RADIO-GROUP") { + return elt.value.length > 0 + } + + return true; +} + +htmx.defineExtension('shoelace', { + onEvent : function(name, evt) { + if ((name === "htmx:configRequest") && (evt.detail.elt.tagName === 'FORM')) { + evt.detail.elt.querySelectorAll(slTypes).forEach((elt) => { + if (shouldInclude(elt)) { + if (elt.tagName === 'SL-CHECKBOX' || elt.tagName === 'SL-SWITCH') { + // Shoelace normally does this bit internally when the formdata event fires, but htmx doesn't fire the formdata event, so we do it here instead. See https://github.com/shoelace-style/shoelace/issues/1891 + evt.detail.parameters[elt.name] = elt.value || 'on' + + } else if (elt.tagName == 'SL-RATING') { + evt.detail.parameters[elt.getAttribute('name')] = elt.value + + } else { + evt.detail.parameters[elt.name] = elt.value + } + } + }) + } + } +}) \ No newline at end of file diff --git a/public/js/htmx/ext/include-vals.js b/public/js/htmx/ext/include-vals.js new file mode 100644 index 0000000..d8f5ce4 --- /dev/null +++ b/public/js/htmx/ext/include-vals.js @@ -0,0 +1,24 @@ +(function(){ + + function mergeObjects(obj1, obj2) { + for (var key in obj2) { + if (obj2.hasOwnProperty(key)) { + obj1[key] = obj2[key]; + } + } + return obj1; + } + + htmx.defineExtension('include-vals', { + onEvent: function (name, evt) { + if (name === "htmx:configRequest") { + var includeValsElt = htmx.closest(evt.detail.elt, "[include-vals],[data-include-vals]"); + if (includeValsElt) { + var includeVals = includeValsElt.getAttribute("include-vals") || includeValsElt.getAttribute("data-include-vals"); + var valuesToInclude = eval("({" + includeVals + "})"); + mergeObjects(evt.detail.parameters, valuesToInclude); + } + } + } + }); +})(); diff --git a/public/js/htmx/ext/json-enc.js b/public/js/htmx/ext/json-enc.js new file mode 100644 index 0000000..db0aa36 --- /dev/null +++ b/public/js/htmx/ext/json-enc.js @@ -0,0 +1,12 @@ +htmx.defineExtension('json-enc', { + onEvent: function (name, evt) { + if (name === "htmx:configRequest") { + evt.detail.headers['Content-Type'] = "application/json"; + } + }, + + encodeParameters : function(xhr, parameters, elt) { + xhr.overrideMimeType('text/json'); + return (JSON.stringify(parameters)); + } +}); \ No newline at end of file diff --git a/public/js/htmx/ext/loading-states.js b/public/js/htmx/ext/loading-states.js new file mode 100644 index 0000000..c8ab51d --- /dev/null +++ b/public/js/htmx/ext/loading-states.js @@ -0,0 +1,183 @@ +;(function () { + let loadingStatesUndoQueue = [] + + function loadingStateContainer(target) { + return htmx.closest(target, '[data-loading-states]') || document.body + } + + function mayProcessUndoCallback(target, callback) { + if (document.body.contains(target)) { + callback() + } + } + + function mayProcessLoadingStateByPath(elt, requestPath) { + const pathElt = htmx.closest(elt, '[data-loading-path]') + if (!pathElt) { + return true + } + + return pathElt.getAttribute('data-loading-path') === requestPath + } + + function queueLoadingState(sourceElt, targetElt, doCallback, undoCallback) { + const delayElt = htmx.closest(sourceElt, '[data-loading-delay]') + if (delayElt) { + const delayInMilliseconds = + delayElt.getAttribute('data-loading-delay') || 200 + const timeout = setTimeout(function () { + doCallback() + + loadingStatesUndoQueue.push(function () { + mayProcessUndoCallback(targetElt, undoCallback) + }) + }, delayInMilliseconds) + + loadingStatesUndoQueue.push(function () { + mayProcessUndoCallback(targetElt, function () { clearTimeout(timeout) }) + }) + } else { + doCallback() + loadingStatesUndoQueue.push(function () { + mayProcessUndoCallback(targetElt, undoCallback) + }) + } + } + + function getLoadingStateElts(loadingScope, type, path) { + return Array.from(htmx.findAll(loadingScope, "[" + type + "]")).filter( + function (elt) { return mayProcessLoadingStateByPath(elt, path) } + ) + } + + function getLoadingTarget(elt) { + if (elt.getAttribute('data-loading-target')) { + return Array.from( + htmx.findAll(elt.getAttribute('data-loading-target')) + ) + } + return [elt] + } + + htmx.defineExtension('loading-states', { + onEvent: function (name, evt) { + if (name === 'htmx:beforeRequest') { + const container = loadingStateContainer(evt.target) + + const loadingStateTypes = [ + 'data-loading', + 'data-loading-class', + 'data-loading-class-remove', + 'data-loading-disable', + 'data-loading-aria-busy', + ] + + let loadingStateEltsByType = {} + + loadingStateTypes.forEach(function (type) { + loadingStateEltsByType[type] = getLoadingStateElts( + container, + type, + evt.detail.pathInfo.requestPath + ) + }) + + loadingStateEltsByType['data-loading'].forEach(function (sourceElt) { + getLoadingTarget(sourceElt).forEach(function (targetElt) { + queueLoadingState( + sourceElt, + targetElt, + function () { + targetElt.style.display = + sourceElt.getAttribute('data-loading') || + 'inline-block' }, + function () { targetElt.style.display = 'none' } + ) + }) + }) + + loadingStateEltsByType['data-loading-class'].forEach( + function (sourceElt) { + const classNames = sourceElt + .getAttribute('data-loading-class') + .split(' ') + + getLoadingTarget(sourceElt).forEach(function (targetElt) { + queueLoadingState( + sourceElt, + targetElt, + function () { + classNames.forEach(function (className) { + targetElt.classList.add(className) + }) + }, + function() { + classNames.forEach(function (className) { + targetElt.classList.remove(className) + }) + } + ) + }) + } + ) + + loadingStateEltsByType['data-loading-class-remove'].forEach( + function (sourceElt) { + const classNames = sourceElt + .getAttribute('data-loading-class-remove') + .split(' ') + + getLoadingTarget(sourceElt).forEach(function (targetElt) { + queueLoadingState( + sourceElt, + targetElt, + function () { + classNames.forEach(function (className) { + targetElt.classList.remove(className) + }) + }, + function() { + classNames.forEach(function (className) { + targetElt.classList.add(className) + }) + } + ) + }) + } + ) + + loadingStateEltsByType['data-loading-disable'].forEach( + function (sourceElt) { + getLoadingTarget(sourceElt).forEach(function (targetElt) { + queueLoadingState( + sourceElt, + targetElt, + function() { targetElt.disabled = true }, + function() { targetElt.disabled = false } + ) + }) + } + ) + + loadingStateEltsByType['data-loading-aria-busy'].forEach( + function (sourceElt) { + getLoadingTarget(sourceElt).forEach(function (targetElt) { + queueLoadingState( + sourceElt, + targetElt, + function () { targetElt.setAttribute("aria-busy", "true") }, + function () { targetElt.removeAttribute("aria-busy") } + ) + }) + } + ) + } + + if (name === 'htmx:beforeOnLoad') { + while (loadingStatesUndoQueue.length > 0) { + loadingStatesUndoQueue.shift()() + } + } + }, + }) +})() diff --git a/public/js/htmx/ext/method-override.js b/public/js/htmx/ext/method-override.js new file mode 100644 index 0000000..2e3504c --- /dev/null +++ b/public/js/htmx/ext/method-override.js @@ -0,0 +1,11 @@ +htmx.defineExtension('method-override', { + onEvent: function (name, evt) { + if (name === "htmx:configRequest") { + var method = evt.detail.verb; + if (method !== "get" || method !== "post") { + evt.detail.headers['X-HTTP-Method-Override'] = method.toUpperCase(); + evt.detail.verb = "post"; + } + } + } +}); diff --git a/public/js/htmx/ext/morphdom-swap.js b/public/js/htmx/ext/morphdom-swap.js new file mode 100644 index 0000000..a1e53ce --- /dev/null +++ b/public/js/htmx/ext/morphdom-swap.js @@ -0,0 +1,17 @@ +htmx.defineExtension('morphdom-swap', { + isInlineSwap: function(swapStyle) { + return swapStyle === 'morphdom'; + }, + handleSwap: function (swapStyle, target, fragment) { + if (swapStyle === 'morphdom') { + if (fragment.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + // IE11 doesn't support DocumentFragment.firstElementChild + morphdom(target, fragment.firstElementChild || fragment.firstChild); + return [target]; + } else { + morphdom(target, fragment.outerHTML); + return [target]; + } + } + } +}); diff --git a/public/js/htmx/ext/multi-swap.js b/public/js/htmx/ext/multi-swap.js new file mode 100644 index 0000000..f38f5b0 --- /dev/null +++ b/public/js/htmx/ext/multi-swap.js @@ -0,0 +1,45 @@ +(function () { + + /** @type {import("../htmx").HtmxInternalApi} */ + var api; + + htmx.defineExtension('multi-swap', { + init: function (apiRef) { + api = apiRef; + }, + isInlineSwap: function (swapStyle) { + return swapStyle.indexOf('multi:') === 0; + }, + handleSwap: function (swapStyle, target, fragment, settleInfo) { + if (swapStyle.indexOf('multi:') === 0) { + var selectorToSwapStyle = {}; + var elements = swapStyle.replace(/^multi\s*:\s*/, '').split(/\s*,\s*/); + + elements.map(function (element) { + var split = element.split(/\s*:\s*/); + var elementSelector = split[0]; + var elementSwapStyle = typeof (split[1]) !== "undefined" ? split[1] : "innerHTML"; + + if (elementSelector.charAt(0) !== '#') { + console.error("HTMX multi-swap: unsupported selector '" + elementSelector + "'. Only ID selectors starting with '#' are supported."); + return; + } + + selectorToSwapStyle[elementSelector] = elementSwapStyle; + }); + + for (var selector in selectorToSwapStyle) { + var swapStyle = selectorToSwapStyle[selector]; + var elementToSwap = fragment.querySelector(selector); + if (elementToSwap) { + api.oobSwap(swapStyle, elementToSwap, settleInfo); + } else { + console.warn("HTMX multi-swap: selector '" + selector + "' not found in source content."); + } + } + + return true; + } + } + }); +})(); \ No newline at end of file diff --git a/public/js/htmx/ext/path-deps.js b/public/js/htmx/ext/path-deps.js new file mode 100644 index 0000000..4987e50 --- /dev/null +++ b/public/js/htmx/ext/path-deps.js @@ -0,0 +1,60 @@ +(function(undefined){ + 'use strict'; + + // Save a reference to the global object (window in the browser) + var _root = this; + + function dependsOn(pathSpec, url) { + if (pathSpec === "ignore") { + return false; + } + var dependencyPath = pathSpec.split("/"); + var urlPath = url.split("/"); + for (var i = 0; i < urlPath.length; i++) { + var dependencyElement = dependencyPath.shift(); + var pathElement = urlPath[i]; + if (dependencyElement !== pathElement && dependencyElement !== "*") { + return false; + } + if (dependencyPath.length === 0 || (dependencyPath.length === 1 && dependencyPath[0] === "")) { + return true; + } + } + return false; + } + + function refreshPath(path) { + var eltsWithDeps = htmx.findAll("[path-deps]"); + for (var i = 0; i < eltsWithDeps.length; i++) { + var elt = eltsWithDeps[i]; + if (dependsOn(elt.getAttribute('path-deps'), path)) { + htmx.trigger(elt, "path-deps"); + } + } + } + + htmx.defineExtension('path-deps', { + onEvent: function (name, evt) { + if (name === "htmx:beforeOnLoad") { + var config = evt.detail.requestConfig; + // mutating call + if (config.verb !== "get" && evt.target.getAttribute('path-deps') !== 'ignore') { + refreshPath(config.path); + } + } + } + }); + + /** + * ******************** + * Expose functionality + * ******************** + */ + + _root.PathDeps = { + refresh: function(path) { + refreshPath(path); + } + }; + +}).call(this); diff --git a/public/js/htmx/ext/preload.js b/public/js/htmx/ext/preload.js new file mode 100644 index 0000000..a749370 --- /dev/null +++ b/public/js/htmx/ext/preload.js @@ -0,0 +1,147 @@ +// This adds the "preload" extension to htmx. By default, this will +// preload the targets of any tags with `href` or `hx-get` attributes +// if they also have a `preload` attribute as well. See documentation +// for more details +htmx.defineExtension("preload", { + + onEvent: function(name, event) { + + // Only take actions on "htmx:afterProcessNode" + if (name !== "htmx:afterProcessNode") { + return; + } + + // SOME HELPER FUNCTIONS WE'LL NEED ALONG THE WAY + + // attr gets the closest non-empty value from the attribute. + var attr = function(node, property) { + if (node == undefined) {return undefined;} + return node.getAttribute(property) || node.getAttribute("data-" + property) || attr(node.parentElement, property) + } + + // load handles the actual HTTP fetch, and uses htmx.ajax in cases where we're + // preloading an htmx resource (this sends the same HTTP headers as a regular htmx request) + var load = function(node) { + + // Called after a successful AJAX request, to mark the + // content as loaded (and prevent additional AJAX calls.) + var done = function(html) { + if (!node.preloadAlways) { + node.preloadState = "DONE" + } + + if (attr(node, "preload-images") == "true") { + document.createElement("div").innerHTML = html // create and populate a node to load linked resources, too. + } + } + + return function() { + + // If this value has already been loaded, then do not try again. + if (node.preloadState !== "READY") { + return; + } + + // Special handling for HX-GET - use built-in htmx.ajax function + // so that headers match other htmx requests, then set + // node.preloadState = TRUE so that requests are not duplicated + // in the future + var hxGet = node.getAttribute("hx-get") || node.getAttribute("data-hx-get") + if (hxGet) { + htmx.ajax("GET", hxGet, { + source: node, + handler:function(elt, info) { + done(info.xhr.responseText); + } + }); + return; + } + + // Otherwise, perform a standard xhr request, then set + // node.preloadState = TRUE so that requests are not duplicated + // in the future. + if (node.getAttribute("href")) { + var r = new XMLHttpRequest(); + r.open("GET", node.getAttribute("href")); + r.onload = function() {done(r.responseText);}; + r.send(); + return; + } + } + } + + // This function processes a specific node and sets up event handlers. + // We'll search for nodes and use it below. + var init = function(node) { + + // If this node DOES NOT include a "GET" transaction, then there's nothing to do here. + if (node.getAttribute("href") + node.getAttribute("hx-get") + node.getAttribute("data-hx-get") == "") { + return; + } + + // Guarantee that we only initialize each node once. + if (node.preloadState !== undefined) { + return; + } + + // Get event name from config. + var on = attr(node, "preload") || "mousedown" + const always = on.indexOf("always") !== -1 + if (always) { + on = on.replace('always', '').trim() + } + + // FALL THROUGH to here means we need to add an EventListener + + // Apply the listener to the node + node.addEventListener(on, function(evt) { + if (node.preloadState === "PAUSE") { // Only add one event listener + node.preloadState = "READY"; // Required for the `load` function to trigger + + // Special handling for "mouseover" events. Wait 100ms before triggering load. + if (on === "mouseover") { + window.setTimeout(load(node), 100); + } else { + load(node)() // all other events trigger immediately. + } + } + }) + + // Special handling for certain built-in event handlers + switch (on) { + + case "mouseover": + // Mirror `touchstart` events (fires immediately) + node.addEventListener("touchstart", load(node)); + + // WHhen the mouse leaves, immediately disable the preload + node.addEventListener("mouseout", function(evt) { + if ((evt.target === node) && (node.preloadState === "READY")) { + node.preloadState = "PAUSE"; + } + }) + break; + + case "mousedown": + // Mirror `touchstart` events (fires immediately) + node.addEventListener("touchstart", load(node)); + break; + } + + // Mark the node as ready to run. + node.preloadState = "PAUSE"; + node.preloadAlways = always; + htmx.trigger(node, "preload:init") // This event can be used to load content immediately. + } + + // Search for all child nodes that have a "preload" attribute + event.target.querySelectorAll("[preload]").forEach(function(node) { + + // Initialize the node with the "preload" attribute + init(node) + + // Initialize all child elements that are anchors or have `hx-get` (use with care) + node.querySelectorAll("a,[hx-get],[data-hx-get]").forEach(init) + }) + } +}) diff --git a/public/js/htmx/ext/rails-method.js b/public/js/htmx/ext/rails-method.js new file mode 100644 index 0000000..5d48ecc --- /dev/null +++ b/public/js/htmx/ext/rails-method.js @@ -0,0 +1,10 @@ +htmx.defineExtension('rails-method', { + onEvent: function (name, evt) { + if (name === "configRequest.htmx") { + var methodOverride = evt.detail.headers['X-HTTP-Method-Override']; + if (methodOverride) { + evt.detail.parameters['_method'] = methodOverride; + } + } + } +}); diff --git a/public/js/htmx/ext/remove-me.js b/public/js/htmx/ext/remove-me.js new file mode 100644 index 0000000..42be993 --- /dev/null +++ b/public/js/htmx/ext/remove-me.js @@ -0,0 +1,27 @@ +(function(){ + function maybeRemoveMe(elt) { + var timing = elt.getAttribute("remove-me") || elt.getAttribute("data-remove-me"); + if (timing) { + setTimeout(function () { + elt.parentElement.removeChild(elt); + }, htmx.parseInterval(timing)); + } + } + + htmx.defineExtension('remove-me', { + onEvent: function (name, evt) { + if (name === "htmx:afterProcessNode") { + var elt = evt.detail.elt; + if (elt.getAttribute) { + maybeRemoveMe(elt); + if (elt.querySelectorAll) { + var children = elt.querySelectorAll("[remove-me], [data-remove-me]"); + for (var i = 0; i < children.length; i++) { + maybeRemoveMe(children[i]); + } + } + } + } + } + }); +})(); diff --git a/public/js/htmx/ext/response-targets.js b/public/js/htmx/ext/response-targets.js new file mode 100644 index 0000000..dd6fd41 --- /dev/null +++ b/public/js/htmx/ext/response-targets.js @@ -0,0 +1,130 @@ +(function(){ + + /** @type {import("../htmx").HtmxInternalApi} */ + var api; + + var attrPrefix = 'hx-target-'; + + // IE11 doesn't support string.startsWith + function startsWith(str, prefix) { + return str.substring(0, prefix.length) === prefix + } + + /** + * @param {HTMLElement} elt + * @param {number} respCode + * @returns {HTMLElement | null} + */ + function getRespCodeTarget(elt, respCodeNumber) { + if (!elt || !respCodeNumber) return null; + + var respCode = respCodeNumber.toString(); + + // '*' is the original syntax, as the obvious character for a wildcard. + // The 'x' alternative was added for maximum compatibility with HTML + // templating engines, due to ambiguity around which characters are + // supported in HTML attributes. + // + // Start with the most specific possible attribute and generalize from + // there. + var attrPossibilities = [ + respCode, + + respCode.substr(0, 2) + '*', + respCode.substr(0, 2) + 'x', + + respCode.substr(0, 1) + '*', + respCode.substr(0, 1) + 'x', + respCode.substr(0, 1) + '**', + respCode.substr(0, 1) + 'xx', + + '*', + 'x', + '***', + 'xxx', + ]; + if (startsWith(respCode, '4') || startsWith(respCode, '5')) { + attrPossibilities.push('error'); + } + + for (var i = 0; i < attrPossibilities.length; i++) { + var attr = attrPrefix + attrPossibilities[i]; + var attrValue = api.getClosestAttributeValue(elt, attr); + if (attrValue) { + if (attrValue === "this") { + return api.findThisElement(elt, attr); + } else { + return api.querySelectorExt(elt, attrValue); + } + } + } + + return null; + } + + /** @param {Event} evt */ + function handleErrorFlag(evt) { + if (evt.detail.isError) { + if (htmx.config.responseTargetUnsetsError) { + evt.detail.isError = false; + } + } else if (htmx.config.responseTargetSetsError) { + evt.detail.isError = true; + } + } + + htmx.defineExtension('response-targets', { + + /** @param {import("../htmx").HtmxInternalApi} apiRef */ + init: function (apiRef) { + api = apiRef; + + if (htmx.config.responseTargetUnsetsError === undefined) { + htmx.config.responseTargetUnsetsError = true; + } + if (htmx.config.responseTargetSetsError === undefined) { + htmx.config.responseTargetSetsError = false; + } + if (htmx.config.responseTargetPrefersExisting === undefined) { + htmx.config.responseTargetPrefersExisting = false; + } + if (htmx.config.responseTargetPrefersRetargetHeader === undefined) { + htmx.config.responseTargetPrefersRetargetHeader = true; + } + }, + + /** + * @param {string} name + * @param {Event} evt + */ + onEvent: function (name, evt) { + if (name === "htmx:beforeSwap" && + evt.detail.xhr && + evt.detail.xhr.status !== 200) { + if (evt.detail.target) { + if (htmx.config.responseTargetPrefersExisting) { + evt.detail.shouldSwap = true; + handleErrorFlag(evt); + return true; + } + if (htmx.config.responseTargetPrefersRetargetHeader && + evt.detail.xhr.getAllResponseHeaders().match(/HX-Retarget:/i)) { + evt.detail.shouldSwap = true; + handleErrorFlag(evt); + return true; + } + } + if (!evt.detail.requestConfig) { + return true; + } + var target = getRespCodeTarget(evt.detail.requestConfig.elt, evt.detail.xhr.status); + if (target) { + handleErrorFlag(evt); + evt.detail.shouldSwap = true; + evt.detail.target = target; + } + return true; + } + } + }); +})(); diff --git a/public/js/htmx/ext/restored.js b/public/js/htmx/ext/restored.js new file mode 100644 index 0000000..6f65267 --- /dev/null +++ b/public/js/htmx/ext/restored.js @@ -0,0 +1,15 @@ +htmx.defineExtension('restored', { + onEvent : function(name, evt) { + if (name === 'htmx:restored'){ + var restoredElts = evt.detail.document.querySelectorAll( + "[hx-trigger='restored'],[data-hx-trigger='restored']" + ); + // need a better way to do this, would prefer to just trigger from evt.detail.elt + var foundElt = Array.from(restoredElts).find( + (x) => (x.outerHTML === evt.detail.elt.outerHTML) + ); + var restoredEvent = evt.detail.triggerEvent(foundElt, 'restored'); + } + return; + } +}) \ No newline at end of file diff --git a/public/js/htmx/ext/sse.js b/public/js/htmx/ext/sse.js new file mode 100644 index 0000000..75c875a --- /dev/null +++ b/public/js/htmx/ext/sse.js @@ -0,0 +1,322 @@ +/* +Server Sent Events Extension +============================ +This extension adds support for Server Sent Events to htmx. See /www/extensions/sse.md for usage instructions. + +*/ + +(function(){ + + /** @type {import("../htmx").HtmxInternalApi} */ + var api; + + htmx.defineExtension("sse", { + + /** + * Init saves the provided reference to the internal HTMX API. + * + * @param {import("../htmx").HtmxInternalApi} api + * @returns void + */ + init: function(apiRef) { + // store a reference to the internal API. + api = apiRef; + + // set a function in the public API for creating new EventSource objects + if (htmx.createEventSource == undefined) { + htmx.createEventSource = createEventSource; + } + }, + + /** + * onEvent handles all events passed to this extension. + * + * @param {string} name + * @param {Event} evt + * @returns void + */ + onEvent: function(name, evt) { + + switch (name) { + + // Try to remove remove an EventSource when elements are removed + case "htmx:beforeCleanupElement": + var internalData = api.getInternalData(evt.target) + if (internalData.sseEventSource) { + internalData.sseEventSource.close(); + } + return; + + // Try to create EventSources when elements are processed + case "htmx:afterProcessNode": + createEventSourceOnElement(evt.target); + } + } + }); + + /////////////////////////////////////////////// + // HELPER FUNCTIONS + /////////////////////////////////////////////// + + + /** + * createEventSource is the default method for creating new EventSource objects. + * it is hoisted into htmx.config.createEventSource to be overridden by the user, if needed. + * + * @param {string} url + * @returns EventSource + */ + function createEventSource(url) { + return new EventSource(url, {withCredentials:true}); + } + + function splitOnWhitespace(trigger) { + return trigger.trim().split(/\s+/); + } + + function getLegacySSEURL(elt) { + var legacySSEValue = api.getAttributeValue(elt, "hx-sse"); + if (legacySSEValue) { + var values = splitOnWhitespace(legacySSEValue); + for (var i = 0; i < values.length; i++) { + var value = values[i].split(/:(.+)/); + if (value[0] === "connect") { + return value[1]; + } + } + } + } + + function getLegacySSESwaps(elt) { + var legacySSEValue = api.getAttributeValue(elt, "hx-sse"); + var returnArr = []; + if (legacySSEValue) { + var values = splitOnWhitespace(legacySSEValue); + for (var i = 0; i < values.length; i++) { + var value = values[i].split(/:(.+)/); + if (value[0] === "swap") { + returnArr.push(value[1]); + } + } + } + return returnArr; + } + + /** + * createEventSourceOnElement creates a new EventSource connection on the provided element. + * If a usable EventSource already exists, then it is returned. If not, then a new EventSource + * is created and stored in the element's internalData. + * @param {HTMLElement} elt + * @param {number} retryCount + * @returns {EventSource | null} + */ + function createEventSourceOnElement(elt, retryCount) { + + if (elt == null) { + return null; + } + + var internalData = api.getInternalData(elt); + + // get URL from element's attribute + var sseURL = api.getAttributeValue(elt, "sse-connect"); + + + if (sseURL == undefined) { + var legacyURL = getLegacySSEURL(elt) + if (legacyURL) { + sseURL = legacyURL; + } else { + return null; + } + } + + // Connect to the EventSource + var source = htmx.createEventSource(sseURL); + internalData.sseEventSource = source; + + // Create event handlers + source.onerror = function (err) { + + // Log an error event + api.triggerErrorEvent(elt, "htmx:sseError", {error:err, source:source}); + + // If parent no longer exists in the document, then clean up this EventSource + if (maybeCloseSSESource(elt)) { + return; + } + + // Otherwise, try to reconnect the EventSource + if (source.readyState === EventSource.CLOSED) { + retryCount = retryCount || 0; + var timeout = Math.random() * (2 ^ retryCount) * 500; + window.setTimeout(function() { + createEventSourceOnElement(elt, Math.min(7, retryCount+1)); + }, timeout); + } + }; + + source.onopen = function (evt) { + api.triggerEvent(elt, "htmx:sseOpen", {source: source}); + } + + // Add message handlers for every `sse-swap` attribute + queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function(child) { + + var sseSwapAttr = api.getAttributeValue(child, "sse-swap"); + if (sseSwapAttr) { + var sseEventNames = sseSwapAttr.split(","); + } else { + var sseEventNames = getLegacySSESwaps(child); + } + + for (var i = 0 ; i < sseEventNames.length ; i++) { + var sseEventName = sseEventNames[i].trim(); + var listener = function(event) { + + // If the parent is missing then close SSE and remove listener + if (maybeCloseSSESource(elt)) { + source.removeEventListener(sseEventName, listener); + return; + } + + // swap the response into the DOM and trigger a notification + swap(child, event.data); + api.triggerEvent(elt, "htmx:sseMessage", event); + }; + + // Register the new listener + api.getInternalData(elt).sseEventListener = listener; + source.addEventListener(sseEventName, listener); + } + }); + + // Add message handlers for every `hx-trigger="sse:*"` attribute + queryAttributeOnThisOrChildren(elt, "hx-trigger").forEach(function(child) { + + var sseEventName = api.getAttributeValue(child, "hx-trigger"); + if (sseEventName == null) { + return; + } + + // Only process hx-triggers for events with the "sse:" prefix + if (sseEventName.slice(0, 4) != "sse:") { + return; + } + + var listener = function(event) { + + // If parent is missing, then close SSE and remove listener + if (maybeCloseSSESource(elt)) { + source.removeEventListener(sseEventName, listener); + return; + } + + // Trigger events to be handled by the rest of htmx + htmx.trigger(child, sseEventName, event); + htmx.trigger(child, "htmx:sseMessage", event); + } + + // Register the new listener + api.getInternalData(elt).sseEventListener = listener; + source.addEventListener(sseEventName.slice(4), listener); + }); + } + + /** + * maybeCloseSSESource confirms that the parent element still exists. + * If not, then any associated SSE source is closed and the function returns true. + * + * @param {HTMLElement} elt + * @returns boolean + */ + function maybeCloseSSESource(elt) { + if (!api.bodyContains(elt)) { + var source = api.getInternalData(elt).sseEventSource; + if (source != undefined) { + source.close(); + // source = null + return true; + } + } + return false; + } + + /** + * queryAttributeOnThisOrChildren returns all nodes that contain the requested attributeName, INCLUDING THE PROVIDED ROOT ELEMENT. + * + * @param {HTMLElement} elt + * @param {string} attributeName + */ + function queryAttributeOnThisOrChildren(elt, attributeName) { + + var result = []; + + // If the parent element also contains the requested attribute, then add it to the results too. + if (api.hasAttribute(elt, attributeName) || api.hasAttribute(elt, "hx-sse")) { + result.push(elt); + } + + // Search all child nodes that match the requested attribute + elt.querySelectorAll("[" + attributeName + "], [data-" + attributeName + "], [hx-sse], [data-hx-sse]").forEach(function(node) { + result.push(node); + }); + + return result; + } + + /** + * @param {HTMLElement} elt + * @param {string} content + */ + function swap(elt, content) { + + api.withExtensions(elt, function(extension) { + content = extension.transformResponse(content, null, elt); + }); + + var swapSpec = api.getSwapSpecification(elt); + var target = api.getTarget(elt); + var settleInfo = api.makeSettleInfo(elt); + + api.selectAndSwap(swapSpec.swapStyle, target, elt, content, settleInfo); + + settleInfo.elts.forEach(function (elt) { + if (elt.classList) { + elt.classList.add(htmx.config.settlingClass); + } + api.triggerEvent(elt, 'htmx:beforeSettle'); + }); + + // Handle settle tasks (with delay if requested) + if (swapSpec.settleDelay > 0) { + setTimeout(doSettle(settleInfo), swapSpec.settleDelay); + } else { + doSettle(settleInfo)(); + } + } + + /** + * doSettle mirrors much of the functionality in htmx that + * settles elements after their content has been swapped. + * TODO: this should be published by htmx, and not duplicated here + * @param {import("../htmx").HtmxSettleInfo} settleInfo + * @returns () => void + */ + function doSettle(settleInfo) { + + return function() { + settleInfo.tasks.forEach(function (task) { + task.call(); + }); + + settleInfo.elts.forEach(function (elt) { + if (elt.classList) { + elt.classList.remove(htmx.config.settlingClass); + } + api.triggerEvent(elt, 'htmx:afterSettle'); + }); + } + } + +})(); \ No newline at end of file diff --git a/public/js/htmx/ext/ws.js b/public/js/htmx/ext/ws.js new file mode 100644 index 0000000..3366e9e --- /dev/null +++ b/public/js/htmx/ext/ws.js @@ -0,0 +1,477 @@ +/* +WebSockets Extension +============================ +This extension adds support for WebSockets to htmx. See /www/extensions/ws.md for usage instructions. +*/ + +(function () { + + /** @type {import("../htmx").HtmxInternalApi} */ + var api; + + htmx.defineExtension("ws", { + + /** + * init is called once, when this extension is first registered. + * @param {import("../htmx").HtmxInternalApi} apiRef + */ + init: function (apiRef) { + + // Store reference to internal API + api = apiRef; + + // Default function for creating new EventSource objects + if (!htmx.createWebSocket) { + htmx.createWebSocket = createWebSocket; + } + + // Default setting for reconnect delay + if (!htmx.config.wsReconnectDelay) { + htmx.config.wsReconnectDelay = "full-jitter"; + } + }, + + /** + * onEvent handles all events passed to this extension. + * + * @param {string} name + * @param {Event} evt + */ + onEvent: function (name, evt) { + + switch (name) { + + // Try to close the socket when elements are removed + case "htmx:beforeCleanupElement": + + var internalData = api.getInternalData(evt.target) + + if (internalData.webSocket) { + internalData.webSocket.close(); + } + return; + + // Try to create websockets when elements are processed + case "htmx:beforeProcessNode": + var parent = evt.target; + + forEach(queryAttributeOnThisOrChildren(parent, "ws-connect"), function (child) { + ensureWebSocket(child) + }); + forEach(queryAttributeOnThisOrChildren(parent, "ws-send"), function (child) { + ensureWebSocketSend(child) + }); + } + } + }); + + function splitOnWhitespace(trigger) { + return trigger.trim().split(/\s+/); + } + + function getLegacyWebsocketURL(elt) { + var legacySSEValue = api.getAttributeValue(elt, "hx-ws"); + if (legacySSEValue) { + var values = splitOnWhitespace(legacySSEValue); + for (var i = 0; i < values.length; i++) { + var value = values[i].split(/:(.+)/); + if (value[0] === "connect") { + return value[1]; + } + } + } + } + + /** + * ensureWebSocket creates a new WebSocket on the designated element, using + * the element's "ws-connect" attribute. + * @param {HTMLElement} socketElt + * @returns + */ + function ensureWebSocket(socketElt) { + + // If the element containing the WebSocket connection no longer exists, then + // do not connect/reconnect the WebSocket. + if (!api.bodyContains(socketElt)) { + return; + } + + // Get the source straight from the element's value + var wssSource = api.getAttributeValue(socketElt, "ws-connect") + + if (wssSource == null || wssSource === "") { + var legacySource = getLegacyWebsocketURL(socketElt); + if (legacySource == null) { + return; + } else { + wssSource = legacySource; + } + } + + // Guarantee that the wssSource value is a fully qualified URL + if (wssSource.indexOf("/") === 0) { + var base_part = location.hostname + (location.port ? ':' + location.port : ''); + if (location.protocol === 'https:') { + wssSource = "wss://" + base_part + wssSource; + } else if (location.protocol === 'http:') { + wssSource = "ws://" + base_part + wssSource; + } + } + + var socketWrapper = createWebsocketWrapper(socketElt, function () { + return htmx.createWebSocket(wssSource) + }); + + socketWrapper.addEventListener('message', function (event) { + if (maybeCloseWebSocketSource(socketElt)) { + return; + } + + var response = event.data; + if (!api.triggerEvent(socketElt, "htmx:wsBeforeMessage", { + message: response, + socketWrapper: socketWrapper.publicInterface + })) { + return; + } + + api.withExtensions(socketElt, function (extension) { + response = extension.transformResponse(response, null, socketElt); + }); + + var settleInfo = api.makeSettleInfo(socketElt); + var fragment = api.makeFragment(response); + + if (fragment.children.length) { + var children = Array.from(fragment.children); + for (var i = 0; i < children.length; i++) { + api.oobSwap(api.getAttributeValue(children[i], "hx-swap-oob") || "true", children[i], settleInfo); + } + } + + api.settleImmediately(settleInfo.tasks); + api.triggerEvent(socketElt, "htmx:wsAfterMessage", { message: response, socketWrapper: socketWrapper.publicInterface }) + }); + + // Put the WebSocket into the HTML Element's custom data. + api.getInternalData(socketElt).webSocket = socketWrapper; + } + + /** + * @typedef {Object} WebSocketWrapper + * @property {WebSocket} socket + * @property {Array<{message: string, sendElt: Element}>} messageQueue + * @property {number} retryCount + * @property {(message: string, sendElt: Element) => void} sendImmediately sendImmediately sends message regardless of websocket connection state + * @property {(message: string, sendElt: Element) => void} send + * @property {(event: string, handler: Function) => void} addEventListener + * @property {() => void} handleQueuedMessages + * @property {() => void} init + * @property {() => void} close + */ + /** + * + * @param socketElt + * @param socketFunc + * @returns {WebSocketWrapper} + */ + function createWebsocketWrapper(socketElt, socketFunc) { + var wrapper = { + socket: null, + messageQueue: [], + retryCount: 0, + + /** @type {Object} */ + events: {}, + + addEventListener: function (event, handler) { + if (this.socket) { + this.socket.addEventListener(event, handler); + } + + if (!this.events[event]) { + this.events[event] = []; + } + + this.events[event].push(handler); + }, + + sendImmediately: function (message, sendElt) { + if (!this.socket) { + api.triggerErrorEvent() + } + if (sendElt && api.triggerEvent(sendElt, 'htmx:wsBeforeSend', { + message: message, + socketWrapper: this.publicInterface + })) { + this.socket.send(message); + sendElt && api.triggerEvent(sendElt, 'htmx:wsAfterSend', { + message: message, + socketWrapper: this.publicInterface + }) + } + }, + + send: function (message, sendElt) { + if (this.socket.readyState !== this.socket.OPEN) { + this.messageQueue.push({ message: message, sendElt: sendElt }); + } else { + this.sendImmediately(message, sendElt); + } + }, + + handleQueuedMessages: function () { + while (this.messageQueue.length > 0) { + var queuedItem = this.messageQueue[0] + if (this.socket.readyState === this.socket.OPEN) { + this.sendImmediately(queuedItem.message, queuedItem.sendElt); + this.messageQueue.shift(); + } else { + break; + } + } + }, + + init: function () { + if (this.socket && this.socket.readyState === this.socket.OPEN) { + // Close discarded socket + this.socket.close() + } + + // Create a new WebSocket and event handlers + /** @type {WebSocket} */ + var socket = socketFunc(); + + // The event.type detail is added for interface conformance with the + // other two lifecycle events (open and close) so a single handler method + // can handle them polymorphically, if required. + api.triggerEvent(socketElt, "htmx:wsConnecting", { event: { type: 'connecting' } }); + + this.socket = socket; + + socket.onopen = function (e) { + wrapper.retryCount = 0; + api.triggerEvent(socketElt, "htmx:wsOpen", { event: e, socketWrapper: wrapper.publicInterface }); + wrapper.handleQueuedMessages(); + } + + socket.onclose = function (e) { + // If socket should not be connected, stop further attempts to establish connection + // If Abnormal Closure/Service Restart/Try Again Later, then set a timer to reconnect after a pause. + if (!maybeCloseWebSocketSource(socketElt) && [1006, 1012, 1013].indexOf(e.code) >= 0) { + var delay = getWebSocketReconnectDelay(wrapper.retryCount); + setTimeout(function () { + wrapper.retryCount += 1; + wrapper.init(); + }, delay); + } + + // Notify client code that connection has been closed. Client code can inspect `event` field + // to determine whether closure has been valid or abnormal + api.triggerEvent(socketElt, "htmx:wsClose", { event: e, socketWrapper: wrapper.publicInterface }) + }; + + socket.onerror = function (e) { + api.triggerErrorEvent(socketElt, "htmx:wsError", { error: e, socketWrapper: wrapper }); + maybeCloseWebSocketSource(socketElt); + }; + + var events = this.events; + Object.keys(events).forEach(function (k) { + events[k].forEach(function (e) { + socket.addEventListener(k, e); + }) + }); + }, + + close: function () { + this.socket.close() + } + } + + wrapper.init(); + + wrapper.publicInterface = { + send: wrapper.send.bind(wrapper), + sendImmediately: wrapper.sendImmediately.bind(wrapper), + queue: wrapper.messageQueue + }; + + return wrapper; + } + + /** + * ensureWebSocketSend attaches trigger handles to elements with + * "ws-send" attribute + * @param {HTMLElement} elt + */ + function ensureWebSocketSend(elt) { + var legacyAttribute = api.getAttributeValue(elt, "hx-ws"); + if (legacyAttribute && legacyAttribute !== 'send') { + return; + } + + var webSocketParent = api.getClosestMatch(elt, hasWebSocket) + processWebSocketSend(webSocketParent, elt); + } + + /** + * hasWebSocket function checks if a node has webSocket instance attached + * @param {HTMLElement} node + * @returns {boolean} + */ + function hasWebSocket(node) { + return api.getInternalData(node).webSocket != null; + } + + /** + * processWebSocketSend adds event listeners to the
element so that + * messages can be sent to the WebSocket server when the form is submitted. + * @param {HTMLElement} socketElt + * @param {HTMLElement} sendElt + */ + function processWebSocketSend(socketElt, sendElt) { + var nodeData = api.getInternalData(sendElt); + var triggerSpecs = api.getTriggerSpecs(sendElt); + triggerSpecs.forEach(function (ts) { + api.addTriggerHandler(sendElt, ts, nodeData, function (elt, evt) { + if (maybeCloseWebSocketSource(socketElt)) { + return; + } + + /** @type {WebSocketWrapper} */ + var socketWrapper = api.getInternalData(socketElt).webSocket; + var headers = api.getHeaders(sendElt, api.getTarget(sendElt)); + var results = api.getInputValues(sendElt, 'post'); + var errors = results.errors; + var rawParameters = results.values; + var expressionVars = api.getExpressionVars(sendElt); + var allParameters = api.mergeObjects(rawParameters, expressionVars); + var filteredParameters = api.filterValues(allParameters, sendElt); + + var sendConfig = { + parameters: filteredParameters, + unfilteredParameters: allParameters, + headers: headers, + errors: errors, + + triggeringEvent: evt, + messageBody: undefined, + socketWrapper: socketWrapper.publicInterface + }; + + if (!api.triggerEvent(elt, 'htmx:wsConfigSend', sendConfig)) { + return; + } + + if (errors && errors.length > 0) { + api.triggerEvent(elt, 'htmx:validation:halted', errors); + return; + } + + var body = sendConfig.messageBody; + if (body === undefined) { + var toSend = Object.assign({}, sendConfig.parameters); + if (sendConfig.headers) + toSend['HEADERS'] = headers; + body = JSON.stringify(toSend); + } + + socketWrapper.send(body, elt); + + if (evt && api.shouldCancel(evt, elt)) { + evt.preventDefault(); + } + }); + }); + } + + /** + * getWebSocketReconnectDelay is the default easing function for WebSocket reconnects. + * @param {number} retryCount // The number of retries that have already taken place + * @returns {number} + */ + function getWebSocketReconnectDelay(retryCount) { + + /** @type {"full-jitter" | ((retryCount:number) => number)} */ + var delay = htmx.config.wsReconnectDelay; + if (typeof delay === 'function') { + return delay(retryCount); + } + if (delay === 'full-jitter') { + var exp = Math.min(retryCount, 6); + var maxDelay = 1000 * Math.pow(2, exp); + return maxDelay * Math.random(); + } + + logError('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"'); + } + + /** + * maybeCloseWebSocketSource checks to the if the element that created the WebSocket + * still exists in the DOM. If NOT, then the WebSocket is closed and this function + * returns TRUE. If the element DOES EXIST, then no action is taken, and this function + * returns FALSE. + * + * @param {*} elt + * @returns + */ + function maybeCloseWebSocketSource(elt) { + if (!api.bodyContains(elt)) { + api.getInternalData(elt).webSocket.close(); + return true; + } + return false; + } + + /** + * createWebSocket is the default method for creating new WebSocket objects. + * it is hoisted into htmx.createWebSocket to be overridden by the user, if needed. + * + * @param {string} url + * @returns WebSocket + */ + function createWebSocket(url) { + var sock = new WebSocket(url, []); + sock.binaryType = htmx.config.wsBinaryType; + return sock; + } + + /** + * queryAttributeOnThisOrChildren returns all nodes that contain the requested attributeName, INCLUDING THE PROVIDED ROOT ELEMENT. + * + * @param {HTMLElement} elt + * @param {string} attributeName + */ + function queryAttributeOnThisOrChildren(elt, attributeName) { + + var result = [] + + // If the parent element also contains the requested attribute, then add it to the results too. + if (api.hasAttribute(elt, attributeName) || api.hasAttribute(elt, "hx-ws")) { + result.push(elt); + } + + // Search all child nodes that match the requested attribute + elt.querySelectorAll("[" + attributeName + "], [data-" + attributeName + "], [data-hx-ws], [hx-ws]").forEach(function (node) { + result.push(node) + }) + + return result + } + + /** + * @template T + * @param {T[]} arr + * @param {(T) => void} func + */ + function forEach(arr, func) { + if (arr) { + for (var i = 0; i < arr.length; i++) { + func(arr[i]); + } + } + } + +})(); + diff --git a/public/js/htmx/htmx.d.ts b/public/js/htmx/htmx.d.ts new file mode 100644 index 0000000..ee9c6d9 --- /dev/null +++ b/public/js/htmx/htmx.d.ts @@ -0,0 +1,399 @@ +// https://htmx.org/reference/#api + +/** + * This method adds a class to the given element. + * + * https://htmx.org/api/#addClass + * + * @param elt the element to add the class to + * @param clazz the class to add + * @param delay the delay (in milliseconds before class is added) + */ +export function addClass(elt: Element, clazz: string, delay?: number): void; + +/** + * Issues an htmx-style AJAX request + * + * https://htmx.org/api/#ajax + * + * @param verb 'GET', 'POST', etc. + * @param path the URL path to make the AJAX + * @param element the element to target (defaults to the **body**) + * @returns Promise that resolves immediately if no request is sent, or when the request is complete + */ +export function ajax(verb: string, path: string, element: Element): Promise; + +/** + * Issues an htmx-style AJAX request + * + * https://htmx.org/api/#ajax + * + * @param verb 'GET', 'POST', etc. + * @param path the URL path to make the AJAX + * @param selector a selector for the target + * @returns Promise that resolves immediately if no request is sent, or when the request is complete + */ +export function ajax(verb: string, path: string, selector: string): Promise; + +/** + * Issues an htmx-style AJAX request + * + * https://htmx.org/api/#ajax + * + * @param verb 'GET', 'POST', etc. + * @param path the URL path to make the AJAX + * @param context a context object that contains any of the following + * @returns Promise that resolves immediately if no request is sent, or when the request is complete + */ +export function ajax( + verb: string, + path: string, + context: Partial<{ source: any; event: any; handler: any; target: any; swap: any; values: any; headers: any }> +): Promise; + +/** + * Finds the closest matching element in the given elements parentage, inclusive of the element + * + * https://htmx.org/api/#closest + * + * @param elt the element to find the selector from + * @param selector the selector to find + */ +export function closest(elt: Element, selector: string): Element | null; + +/** + * A property holding the configuration htmx uses at runtime. + * + * Note that using a [meta tag](https://htmx.org/docs/#config) is the preferred mechanism for setting these properties. + * + * https://htmx.org/api/#config + */ +export var config: HtmxConfig; + +/** + * A property used to create new [Server Sent Event](https://htmx.org/docs/#sse) sources. This can be updated to provide custom SSE setup. + * + * https://htmx.org/api/#createEventSource + */ +export var createEventSource: (url: string) => EventSource; + +/** + * A property used to create new [WebSocket](https://htmx.org/docs/#websockets). This can be updated to provide custom WebSocket setup. + * + * https://htmx.org/api/#createWebSocket + */ +export var createWebSocket: (url: string) => WebSocket; + +/** + * Defines a new htmx [extension](https://htmx.org/extensions). + * + * https://htmx.org/api/#defineExtension + * + * @param name the extension name + * @param ext the extension definition + */ +export function defineExtension(name: string, ext: HtmxExtension): void; + +/** + * Finds an element matching the selector + * + * https://htmx.org/api/#find + * + * @param selector the selector to match + */ +export function find(selector: string): Element | null; + +/** + * Finds an element matching the selector + * + * https://htmx.org/api/#find + * + * @param elt the root element to find the matching element in, inclusive + * @param selector the selector to match + */ +export function find(elt: Element, selector: string): Element | null; + +/** + * Finds all elements matching the selector + * + * https://htmx.org/api/#findAll + * + * @param selector the selector to match + */ +export function findAll(selector: string): NodeListOf; + +/** + * Finds all elements matching the selector + * + * https://htmx.org/api/#findAll + * + * @param elt the root element to find the matching elements in, inclusive + * @param selector the selector to match + */ +export function findAll(elt: Element, selector: string): NodeListOf; + +/** + * Log all htmx events, useful for debugging. + * + * https://htmx.org/api/#logAll + */ +export function logAll(): void; + +/** + * The logger htmx uses to log with + * + * https://htmx.org/api/#logger + */ +export var logger: (elt: Element, eventName: string, detail: any) => void | null; + +/** + * Removes an event listener from an element + * + * https://htmx.org/api/#off + * + * @param eventName the event name to remove the listener from + * @param listener the listener to remove + */ +export function off(eventName: string, listener: (evt: Event) => void): (evt: Event) => void; + +/** + * Removes an event listener from an element + * + * https://htmx.org/api/#off + * + * @param target the element to remove the listener from + * @param eventName the event name to remove the listener from + * @param listener the listener to remove + */ +export function off(target: string, eventName: string, listener: (evt: Event) => void): (evt: Event) => void; + +/** + * Adds an event listener to an element + * + * https://htmx.org/api/#on + * + * @param eventName the event name to add the listener for + * @param listener the listener to add + */ +export function on(eventName: string, listener: (evt: Event) => void): (evt: Event) => void; + +/** + * Adds an event listener to an element + * + * https://htmx.org/api/#on + * + * @param target the element to add the listener to + * @param eventName the event name to add the listener for + * @param listener the listener to add + */ +export function on(target: string, eventName: string, listener: (evt: Event) => void): (evt: Event) => void; + +/** + * Adds a callback for the **htmx:load** event. This can be used to process new content, for example initializing the content with a javascript library + * + * https://htmx.org/api/#onLoad + * + * @param callback the callback to call on newly loaded content + */ +export function onLoad(callback: (element: Element) => void): void; + +/** + * Parses an interval string consistent with the way htmx does. Useful for plugins that have timing-related attributes. + * + * Caution: Accepts an int followed by either **s** or **ms**. All other values use **parseFloat** + * + * https://htmx.org/api/#parseInterval + * + * @param str timing string + */ +export function parseInterval(str: string): number; + +/** + * Processes new content, enabling htmx behavior. This can be useful if you have content that is added to the DOM outside of the normal htmx request cycle but still want htmx attributes to work. + * + * https://htmx.org/api/#process + * + * @param element element to process + */ +export function process(element: Element): void; + +/** + * Removes an element from the DOM + * + * https://htmx.org/api/#remove + * + * @param elt element to remove + * @param delay the delay (in milliseconds before element is removed) + */ +export function remove(elt: Element, delay?: number): void; + +/** + * Removes a class from the given element + * + * https://htmx.org/api/#removeClass + * + * @param elt element to remove the class from + * @param clazz the class to remove + * @param delay the delay (in milliseconds before class is removed) + */ +export function removeClass(elt: Element, clazz: string, delay?: number): void; + +/** + * Removes the given extension from htmx + * + * https://htmx.org/api/#removeExtension + * + * @param name the name of the extension to remove + */ +export function removeExtension(name: string): void; + +/** + * Takes the given class from its siblings, so that among its siblings, only the given element will have the class. + * + * https://htmx.org/api/#takeClass + * + * @param elt the element that will take the class + * @param clazz the class to take + */ +export function takeClass(elt: Element, clazz: string): void; + +/** + * Toggles the given class on an element + * + * https://htmx.org/api/#toggleClass + * + * @param elt the element to toggle the class on + * @param clazz the class to toggle + */ +export function toggleClass(elt: Element, clazz: string): void; + +/** + * Triggers a given event on an element + * + * https://htmx.org/api/#trigger + * + * @param elt the element to trigger the event on + * @param name the name of the event to trigger + * @param detail details for the event + */ +export function trigger(elt: Element, name: string, detail: any): void; + +/** + * Returns the input values that would resolve for a given element via the htmx value resolution mechanism + * + * https://htmx.org/api/#values + * + * @param elt the element to resolve values on + * @param requestType the request type (e.g. **get** or **post**) non-GET's will include the enclosing form of the element. Defaults to **post** + */ +export function values(elt: Element, requestType?: string): any; + +export const version: string; + +export interface HtmxConfig { + /** + * The attributes to settle during the settling phase. + * @default ["class", "style", "width", "height"] + */ + attributesToSettle?: ["class", "style", "width", "height"] | string[]; + /** + * If the focused element should be scrolled into view. + * @default false + */ + defaultFocusScroll?: boolean; + /** + * The default delay between completing the content swap and settling attributes. + * @default 20 + */ + defaultSettleDelay?: number; + /** + * The default delay between receiving a response from the server and doing the swap. + * @default 0 + */ + defaultSwapDelay?: number; + /** + * The default swap style to use if **[hx-swap](https://htmx.org/attributes/hx-swap)** is omitted. + * @default "innerHTML" + */ + defaultSwapStyle?: "innerHTML" | string; + /** + * The number of pages to keep in **localStorage** for history support. + * @default 10 + */ + historyCacheSize?: number; + /** + * Whether or not to use history. + * @default true + */ + historyEnabled?: boolean; + /** + * If true, htmx will inject a small amount of CSS into the page to make indicators invisible unless the **htmx-indicator** class is present. + * @default true + */ + includeIndicatorStyles?: boolean; + /** + * The class to place on indicators when a request is in flight. + * @default "htmx-indicator" + */ + indicatorClass?: "htmx-indicator" | string; + /** + * The class to place on triggering elements when a request is in flight. + * @default "htmx-request" + */ + requestClass?: "htmx-request" | string; + /** + * The class to temporarily place on elements that htmx has added to the DOM. + * @default "htmx-added" + */ + addedClass?: "htmx-added" | string; + /** + * The class to place on target elements when htmx is in the settling phase. + * @default "htmx-settling" + */ + settlingClass?: "htmx-settling" | string; + /** + * The class to place on target elements when htmx is in the swapping phase. + * @default "htmx-swapping" + */ + swappingClass?: "htmx-swapping" | string; + /** + * Allows the use of eval-like functionality in htmx, to enable **hx-vars**, trigger conditions & script tag evaluation. Can be set to **false** for CSP compatibility. + * @default true + */ + allowEval?: boolean; + /** + * Use HTML template tags for parsing content from the server. This allows you to use Out of Band content when returning things like table rows, but it is *not* IE11 compatible. + * @default false + */ + useTemplateFragments?: boolean; + /** + * Allow cross-site Access-Control requests using credentials such as cookies, authorization headers or TLS client certificates. + * @default false + */ + withCredentials?: boolean; + /** + * The default implementation of **getWebSocketReconnectDelay** for reconnecting after unexpected connection loss by the event code **Abnormal Closure**, **Service Restart** or **Try Again Later**. + * @default "full-jitter" + */ + wsReconnectDelay?: "full-jitter" | string | ((retryCount: number) => number); + // following don't appear in the docs + /** @default false */ + refreshOnHistoryMiss?: boolean; + /** @default 0 */ + timeout?: number; + /** @default "[hx-disable], [data-hx-disable]" */ + disableSelector?: "[hx-disable], [data-hx-disable]" | string; + /** @default "smooth" */ + scrollBehavior?: "smooth" | "auto"; +} + +/** + * https://htmx.org/extensions/#defining + */ +export interface HtmxExtension { + onEvent?: (name: string, evt: CustomEvent) => any; + transformResponse?: (text: any, xhr: XMLHttpRequest, elt: any) => any; + isInlineSwap?: (swapStyle: any) => any; + handleSwap?: (swapStyle: any, target: any, fragment: any, settleInfo: any) => any; + encodeParameters?: (xhr: XMLHttpRequest, parameters: any, elt: any) => any; +} diff --git a/public/js/htmx/htmx.js b/public/js/htmx/htmx.js new file mode 100644 index 0000000..9a8f109 --- /dev/null +++ b/public/js/htmx/htmx.js @@ -0,0 +1,3818 @@ +// UMD insanity +// This code sets up support for (in order) AMD, ES6 modules, and globals. +(function (root, factory) { + //@ts-ignore + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + //@ts-ignore + define([], factory); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals + root.htmx = root.htmx || factory(); + } +}(typeof self !== 'undefined' ? self : this, function () { +return (function () { + 'use strict'; + + // Public API + //** @type {import("./htmx").HtmxApi} */ + // TODO: list all methods in public API + var htmx = { + onLoad: onLoadHelper, + process: processNode, + on: addEventListenerImpl, + off: removeEventListenerImpl, + trigger : triggerEvent, + ajax : ajaxHelper, + find : find, + findAll : findAll, + closest : closest, + values : function(elt, type){ + var inputValues = getInputValues(elt, type || "post"); + return inputValues.values; + }, + remove : removeElement, + addClass : addClassToElement, + removeClass : removeClassFromElement, + toggleClass : toggleClassOnElement, + takeClass : takeClassForElement, + defineExtension : defineExtension, + removeExtension : removeExtension, + logAll : logAll, + logNone : logNone, + logger : null, + config : { + historyEnabled:true, + historyCacheSize:10, + refreshOnHistoryMiss:false, + defaultSwapStyle:'innerHTML', + defaultSwapDelay:0, + defaultSettleDelay:20, + includeIndicatorStyles:true, + indicatorClass:'htmx-indicator', + requestClass:'htmx-request', + addedClass:'htmx-added', + settlingClass:'htmx-settling', + swappingClass:'htmx-swapping', + allowEval:true, + allowScriptTags:true, + inlineScriptNonce:'', + attributesToSettle:["class", "style", "width", "height"], + withCredentials:false, + timeout:0, + wsReconnectDelay: 'full-jitter', + wsBinaryType: 'blob', + disableSelector: "[hx-disable], [data-hx-disable]", + useTemplateFragments: false, + scrollBehavior: 'smooth', + defaultFocusScroll: false, + getCacheBusterParam: false, + globalViewTransitions: false, + methodsThatUseUrlParams: ["get"], + selfRequestsOnly: false, + scrollIntoViewOnBoost: true + }, + parseInterval:parseInterval, + _:internalEval, + createEventSource: function(url){ + return new EventSource(url, {withCredentials:true}) + }, + createWebSocket: function(url){ + var sock = new WebSocket(url, []); + sock.binaryType = htmx.config.wsBinaryType; + return sock; + }, + version: "1.9.7" + }; + + /** @type {import("./htmx").HtmxInternalApi} */ + var internalAPI = { + addTriggerHandler: addTriggerHandler, + bodyContains: bodyContains, + canAccessLocalStorage: canAccessLocalStorage, + findThisElement: findThisElement, + filterValues: filterValues, + hasAttribute: hasAttribute, + getAttributeValue: getAttributeValue, + getClosestAttributeValue: getClosestAttributeValue, + getClosestMatch: getClosestMatch, + getExpressionVars: getExpressionVars, + getHeaders: getHeaders, + getInputValues: getInputValues, + getInternalData: getInternalData, + getSwapSpecification: getSwapSpecification, + getTriggerSpecs: getTriggerSpecs, + getTarget: getTarget, + makeFragment: makeFragment, + mergeObjects: mergeObjects, + makeSettleInfo: makeSettleInfo, + oobSwap: oobSwap, + querySelectorExt: querySelectorExt, + selectAndSwap: selectAndSwap, + settleImmediately: settleImmediately, + shouldCancel: shouldCancel, + triggerEvent: triggerEvent, + triggerErrorEvent: triggerErrorEvent, + withExtensions: withExtensions, + } + + var VERBS = ['get', 'post', 'put', 'delete', 'patch']; + var VERB_SELECTOR = VERBS.map(function(verb){ + return "[hx-" + verb + "], [data-hx-" + verb + "]" + }).join(", "); + + //==================================================================== + // Utilities + //==================================================================== + + function parseInterval(str) { + if (str == undefined) { + return undefined + } + if (str.slice(-2) == "ms") { + return parseFloat(str.slice(0,-2)) || undefined + } + if (str.slice(-1) == "s") { + return (parseFloat(str.slice(0,-1)) * 1000) || undefined + } + if (str.slice(-1) == "m") { + return (parseFloat(str.slice(0,-1)) * 1000 * 60) || undefined + } + return parseFloat(str) || undefined + } + + /** + * @param {HTMLElement} elt + * @param {string} name + * @returns {(string | null)} + */ + function getRawAttribute(elt, name) { + return elt.getAttribute && elt.getAttribute(name); + } + + // resolve with both hx and data-hx prefixes + function hasAttribute(elt, qualifiedName) { + return elt.hasAttribute && (elt.hasAttribute(qualifiedName) || + elt.hasAttribute("data-" + qualifiedName)); + } + + /** + * + * @param {HTMLElement} elt + * @param {string} qualifiedName + * @returns {(string | null)} + */ + function getAttributeValue(elt, qualifiedName) { + return getRawAttribute(elt, qualifiedName) || getRawAttribute(elt, "data-" + qualifiedName); + } + + /** + * @param {HTMLElement} elt + * @returns {HTMLElement | null} + */ + function parentElt(elt) { + return elt.parentElement; + } + + /** + * @returns {Document} + */ + function getDocument() { + return document; + } + + /** + * @param {HTMLElement} elt + * @param {(e:HTMLElement) => boolean} condition + * @returns {HTMLElement | null} + */ + function getClosestMatch(elt, condition) { + while (elt && !condition(elt)) { + elt = parentElt(elt); + } + + return elt ? elt : null; + } + + function getAttributeValueWithDisinheritance(initialElement, ancestor, attributeName){ + var attributeValue = getAttributeValue(ancestor, attributeName); + var disinherit = getAttributeValue(ancestor, "hx-disinherit"); + if (initialElement !== ancestor && disinherit && (disinherit === "*" || disinherit.split(" ").indexOf(attributeName) >= 0)) { + return "unset"; + } else { + return attributeValue + } + } + + /** + * @param {HTMLElement} elt + * @param {string} attributeName + * @returns {string | null} + */ + function getClosestAttributeValue(elt, attributeName) { + var closestAttr = null; + getClosestMatch(elt, function (e) { + return closestAttr = getAttributeValueWithDisinheritance(elt, e, attributeName); + }); + if (closestAttr !== "unset") { + return closestAttr; + } + } + + /** + * @param {HTMLElement} elt + * @param {string} selector + * @returns {boolean} + */ + function matches(elt, selector) { + // @ts-ignore: non-standard properties for browser compatibility + // noinspection JSUnresolvedVariable + var matchesFunction = elt.matches || elt.matchesSelector || elt.msMatchesSelector || elt.mozMatchesSelector || elt.webkitMatchesSelector || elt.oMatchesSelector; + return matchesFunction && matchesFunction.call(elt, selector); + } + + /** + * @param {string} str + * @returns {string} + */ + function getStartTag(str) { + var tagMatcher = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i + var match = tagMatcher.exec( str ); + if (match) { + return match[1].toLowerCase(); + } else { + return ""; + } + } + + /** + * + * @param {string} resp + * @param {number} depth + * @returns {Element} + */ + function parseHTML(resp, depth) { + var parser = new DOMParser(); + var responseDoc = parser.parseFromString(resp, "text/html"); + + /** @type {Element} */ + var responseNode = responseDoc.body; + while (depth > 0) { + depth--; + // @ts-ignore + responseNode = responseNode.firstChild; + } + if (responseNode == null) { + // @ts-ignore + responseNode = getDocument().createDocumentFragment(); + } + return responseNode; + } + + function aFullPageResponse(resp) { + return resp.match(/", 0); + // @ts-ignore type mismatch between DocumentFragment and Element. + // TODO: Are these close enough for htmx to use interchangeably? + return documentFragment.querySelector('template').content; + } else { + var startTag = getStartTag(resp); + switch (startTag) { + case "thead": + case "tbody": + case "tfoot": + case "colgroup": + case "caption": + return parseHTML("" + resp + "
", 1); + case "col": + return parseHTML("" + resp + "
", 2); + case "tr": + return parseHTML("" + resp + "
", 2); + case "td": + case "th": + return parseHTML("" + resp + "
", 3); + case "script": + case "style": + return parseHTML("
" + resp + "
", 1); + default: + return parseHTML(resp, 0); + } + } + } + + /** + * @param {Function} func + */ + function maybeCall(func){ + if(func) { + func(); + } + } + + /** + * @param {any} o + * @param {string} type + * @returns + */ + function isType(o, type) { + return Object.prototype.toString.call(o) === "[object " + type + "]"; + } + + /** + * @param {*} o + * @returns {o is Function} + */ + function isFunction(o) { + return isType(o, "Function"); + } + + /** + * @param {*} o + * @returns {o is Object} + */ + function isRawObject(o) { + return isType(o, "Object"); + } + + /** + * getInternalData retrieves "private" data stored by htmx within an element + * @param {HTMLElement} elt + * @returns {*} + */ + function getInternalData(elt) { + var dataProp = 'htmx-internal-data'; + var data = elt[dataProp]; + if (!data) { + data = elt[dataProp] = {}; + } + return data; + } + + /** + * toArray converts an ArrayLike object into a real array. + * @param {ArrayLike} arr + * @returns {any[]} + */ + function toArray(arr) { + var returnArr = []; + if (arr) { + for (var i = 0; i < arr.length; i++) { + returnArr.push(arr[i]); + } + } + return returnArr + } + + function forEach(arr, func) { + if (arr) { + for (var i = 0; i < arr.length; i++) { + func(arr[i]); + } + } + } + + function isScrolledIntoView(el) { + var rect = el.getBoundingClientRect(); + var elemTop = rect.top; + var elemBottom = rect.bottom; + return elemTop < window.innerHeight && elemBottom >= 0; + } + + function bodyContains(elt) { + // IE Fix + if (elt.getRootNode && elt.getRootNode() instanceof window.ShadowRoot) { + return getDocument().body.contains(elt.getRootNode().host); + } else { + return getDocument().body.contains(elt); + } + } + + function splitOnWhitespace(trigger) { + return trigger.trim().split(/\s+/); + } + + /** + * mergeObjects takes all of the keys from + * obj2 and duplicates them into obj1 + * @param {Object} obj1 + * @param {Object} obj2 + * @returns {Object} + */ + function mergeObjects(obj1, obj2) { + for (var key in obj2) { + if (obj2.hasOwnProperty(key)) { + obj1[key] = obj2[key]; + } + } + return obj1; + } + + function parseJSON(jString) { + try { + return JSON.parse(jString); + } catch(error) { + logError(error); + return null; + } + } + + function canAccessLocalStorage() { + var test = 'htmx:localStorageTest'; + try { + localStorage.setItem(test, test); + localStorage.removeItem(test); + return true; + } catch(e) { + return false; + } + } + + function normalizePath(path) { + try { + var url = new URL(path); + if (url) { + path = url.pathname + url.search; + } + // remove trailing slash, unless index page + if (!path.match('^/$')) { + path = path.replace(/\/+$/, ''); + } + return path; + } catch (e) { + // be kind to IE11, which doesn't support URL() + return path; + } + } + + //========================================================================================== + // public API + //========================================================================================== + + function internalEval(str){ + return maybeEval(getDocument().body, function () { + return eval(str); + }); + } + + function onLoadHelper(callback) { + var value = htmx.on("htmx:load", function(evt) { + callback(evt.detail.elt); + }); + return value; + } + + function logAll(){ + htmx.logger = function(elt, event, data) { + if(console) { + console.log(event, elt, data); + } + } + } + + function logNone() { + htmx.logger = null + } + + function find(eltOrSelector, selector) { + if (selector) { + return eltOrSelector.querySelector(selector); + } else { + return find(getDocument(), eltOrSelector); + } + } + + function findAll(eltOrSelector, selector) { + if (selector) { + return eltOrSelector.querySelectorAll(selector); + } else { + return findAll(getDocument(), eltOrSelector); + } + } + + function removeElement(elt, delay) { + elt = resolveTarget(elt); + if (delay) { + setTimeout(function(){ + removeElement(elt); + elt = null; + }, delay); + } else { + elt.parentElement.removeChild(elt); + } + } + + function addClassToElement(elt, clazz, delay) { + elt = resolveTarget(elt); + if (delay) { + setTimeout(function(){ + addClassToElement(elt, clazz); + elt = null; + }, delay); + } else { + elt.classList && elt.classList.add(clazz); + } + } + + function removeClassFromElement(elt, clazz, delay) { + elt = resolveTarget(elt); + if (delay) { + setTimeout(function(){ + removeClassFromElement(elt, clazz); + elt = null; + }, delay); + } else { + if (elt.classList) { + elt.classList.remove(clazz); + // if there are no classes left, remove the class attribute + if (elt.classList.length === 0) { + elt.removeAttribute("class"); + } + } + } + } + + function toggleClassOnElement(elt, clazz) { + elt = resolveTarget(elt); + elt.classList.toggle(clazz); + } + + function takeClassForElement(elt, clazz) { + elt = resolveTarget(elt); + forEach(elt.parentElement.children, function(child){ + removeClassFromElement(child, clazz); + }) + addClassToElement(elt, clazz); + } + + function closest(elt, selector) { + elt = resolveTarget(elt); + if (elt.closest) { + return elt.closest(selector); + } else { + // TODO remove when IE goes away + do{ + if (elt == null || matches(elt, selector)){ + return elt; + } + } + while (elt = elt && parentElt(elt)); + return null; + } + } + + function startsWith(str, prefix) { + return str.substring(0, prefix.length) === prefix + } + + function endsWith(str, suffix) { + return str.substring(str.length - suffix.length) === suffix + } + + function normalizeSelector(selector) { + var trimmedSelector = selector.trim(); + if (startsWith(trimmedSelector, "<") && endsWith(trimmedSelector, "/>")) { + return trimmedSelector.substring(1, trimmedSelector.length - 2); + } else { + return trimmedSelector; + } + } + + function querySelectorAllExt(elt, selector) { + if (selector.indexOf("closest ") === 0) { + return [closest(elt, normalizeSelector(selector.substr(8)))]; + } else if (selector.indexOf("find ") === 0) { + return [find(elt, normalizeSelector(selector.substr(5)))]; + } else if (selector === "next") { + return [elt.nextElementSibling] + } else if (selector.indexOf("next ") === 0) { + return [scanForwardQuery(elt, normalizeSelector(selector.substr(5)))]; + } else if (selector === "previous") { + return [elt.previousElementSibling] + } else if (selector.indexOf("previous ") === 0) { + return [scanBackwardsQuery(elt, normalizeSelector(selector.substr(9)))]; + } else if (selector === 'document') { + return [document]; + } else if (selector === 'window') { + return [window]; + } else if (selector === 'body') { + return [document.body]; + } else { + return getDocument().querySelectorAll(normalizeSelector(selector)); + } + } + + var scanForwardQuery = function(start, match) { + var results = getDocument().querySelectorAll(match); + for (var i = 0; i < results.length; i++) { + var elt = results[i]; + if (elt.compareDocumentPosition(start) === Node.DOCUMENT_POSITION_PRECEDING) { + return elt; + } + } + } + + var scanBackwardsQuery = function(start, match) { + var results = getDocument().querySelectorAll(match); + for (var i = results.length - 1; i >= 0; i--) { + var elt = results[i]; + if (elt.compareDocumentPosition(start) === Node.DOCUMENT_POSITION_FOLLOWING) { + return elt; + } + } + } + + function querySelectorExt(eltOrSelector, selector) { + if (selector) { + return querySelectorAllExt(eltOrSelector, selector)[0]; + } else { + return querySelectorAllExt(getDocument().body, eltOrSelector)[0]; + } + } + + function resolveTarget(arg2) { + if (isType(arg2, 'String')) { + return find(arg2); + } else { + return arg2; + } + } + + function processEventArgs(arg1, arg2, arg3) { + if (isFunction(arg2)) { + return { + target: getDocument().body, + event: arg1, + listener: arg2 + } + } else { + return { + target: resolveTarget(arg1), + event: arg2, + listener: arg3 + } + } + + } + + function addEventListenerImpl(arg1, arg2, arg3) { + ready(function(){ + var eventArgs = processEventArgs(arg1, arg2, arg3); + eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); + }) + var b = isFunction(arg2); + return b ? arg2 : arg3; + } + + function removeEventListenerImpl(arg1, arg2, arg3) { + ready(function(){ + var eventArgs = processEventArgs(arg1, arg2, arg3); + eventArgs.target.removeEventListener(eventArgs.event, eventArgs.listener); + }) + return isFunction(arg2) ? arg2 : arg3; + } + + //==================================================================== + // Node processing + //==================================================================== + + var DUMMY_ELT = getDocument().createElement("output"); // dummy element for bad selectors + function findAttributeTargets(elt, attrName) { + var attrTarget = getClosestAttributeValue(elt, attrName); + if (attrTarget) { + if (attrTarget === "this") { + return [findThisElement(elt, attrName)]; + } else { + var result = querySelectorAllExt(elt, attrTarget); + if (result.length === 0) { + logError('The selector "' + attrTarget + '" on ' + attrName + " returned no matches!"); + return [DUMMY_ELT] + } else { + return result; + } + } + } + } + + function findThisElement(elt, attribute){ + return getClosestMatch(elt, function (elt) { + return getAttributeValue(elt, attribute) != null; + }) + } + + function getTarget(elt) { + var targetStr = getClosestAttributeValue(elt, "hx-target"); + if (targetStr) { + if (targetStr === "this") { + return findThisElement(elt,'hx-target'); + } else { + return querySelectorExt(elt, targetStr) + } + } else { + var data = getInternalData(elt); + if (data.boosted) { + return getDocument().body; + } else { + return elt; + } + } + } + + function shouldSettleAttribute(name) { + var attributesToSettle = htmx.config.attributesToSettle; + for (var i = 0; i < attributesToSettle.length; i++) { + if (name === attributesToSettle[i]) { + return true; + } + } + return false; + } + + function cloneAttributes(mergeTo, mergeFrom) { + forEach(mergeTo.attributes, function (attr) { + if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) { + mergeTo.removeAttribute(attr.name) + } + }); + forEach(mergeFrom.attributes, function (attr) { + if (shouldSettleAttribute(attr.name)) { + mergeTo.setAttribute(attr.name, attr.value); + } + }); + } + + function isInlineSwap(swapStyle, target) { + var extensions = getExtensions(target); + for (var i = 0; i < extensions.length; i++) { + var extension = extensions[i]; + try { + if (extension.isInlineSwap(swapStyle)) { + return true; + } + } catch(e) { + logError(e); + } + } + return swapStyle === "outerHTML"; + } + + /** + * + * @param {string} oobValue + * @param {HTMLElement} oobElement + * @param {*} settleInfo + * @returns + */ + function oobSwap(oobValue, oobElement, settleInfo) { + var selector = "#" + getRawAttribute(oobElement, "id"); + var swapStyle = "outerHTML"; + if (oobValue === "true") { + // do nothing + } else if (oobValue.indexOf(":") > 0) { + swapStyle = oobValue.substr(0, oobValue.indexOf(":")); + selector = oobValue.substr(oobValue.indexOf(":") + 1, oobValue.length); + } else { + swapStyle = oobValue; + } + + var targets = getDocument().querySelectorAll(selector); + if (targets) { + forEach( + targets, + function (target) { + var fragment; + var oobElementClone = oobElement.cloneNode(true); + fragment = getDocument().createDocumentFragment(); + fragment.appendChild(oobElementClone); + if (!isInlineSwap(swapStyle, target)) { + fragment = oobElementClone; // if this is not an inline swap, we use the content of the node, not the node itself + } + + var beforeSwapDetails = {shouldSwap: true, target: target, fragment:fragment }; + if (!triggerEvent(target, 'htmx:oobBeforeSwap', beforeSwapDetails)) return; + + target = beforeSwapDetails.target; // allow re-targeting + if (beforeSwapDetails['shouldSwap']){ + swap(swapStyle, target, target, fragment, settleInfo); + } + forEach(settleInfo.elts, function (elt) { + triggerEvent(elt, 'htmx:oobAfterSwap', beforeSwapDetails); + }); + } + ); + oobElement.parentNode.removeChild(oobElement); + } else { + oobElement.parentNode.removeChild(oobElement); + triggerErrorEvent(getDocument().body, "htmx:oobErrorNoTarget", {content: oobElement}); + } + return oobValue; + } + + function handleOutOfBandSwaps(elt, fragment, settleInfo) { + var oobSelects = getClosestAttributeValue(elt, "hx-select-oob"); + if (oobSelects) { + var oobSelectValues = oobSelects.split(","); + for (let i = 0; i < oobSelectValues.length; i++) { + var oobSelectValue = oobSelectValues[i].split(":", 2); + var id = oobSelectValue[0].trim(); + if (id.indexOf("#") === 0) { + id = id.substring(1); + } + var oobValue = oobSelectValue[1] || "true"; + var oobElement = fragment.querySelector("#" + id); + if (oobElement) { + oobSwap(oobValue, oobElement, settleInfo); + } + } + } + forEach(findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]'), function (oobElement) { + var oobValue = getAttributeValue(oobElement, "hx-swap-oob"); + if (oobValue != null) { + oobSwap(oobValue, oobElement, settleInfo); + } + }); + } + + function handlePreservedElements(fragment) { + forEach(findAll(fragment, '[hx-preserve], [data-hx-preserve]'), function (preservedElt) { + var id = getAttributeValue(preservedElt, "id"); + var oldElt = getDocument().getElementById(id); + if (oldElt != null) { + preservedElt.parentNode.replaceChild(oldElt, preservedElt); + } + }); + } + + function handleAttributes(parentNode, fragment, settleInfo) { + forEach(fragment.querySelectorAll("[id]"), function (newNode) { + var id = getRawAttribute(newNode, "id") + if (id && id.length > 0) { + var normalizedId = id.replace("'", "\\'"); + var normalizedTag = newNode.tagName.replace(':', '\\:'); + var oldNode = parentNode.querySelector(normalizedTag + "[id='" + normalizedId + "']"); + if (oldNode && oldNode !== parentNode) { + var newAttributes = newNode.cloneNode(); + cloneAttributes(newNode, oldNode); + settleInfo.tasks.push(function () { + cloneAttributes(newNode, newAttributes); + }); + } + } + }); + } + + function makeAjaxLoadTask(child) { + return function () { + removeClassFromElement(child, htmx.config.addedClass); + processNode(child); + processScripts(child); + processFocus(child) + triggerEvent(child, 'htmx:load'); + }; + } + + function processFocus(child) { + var autofocus = "[autofocus]"; + var autoFocusedElt = matches(child, autofocus) ? child : child.querySelector(autofocus) + if (autoFocusedElt != null) { + autoFocusedElt.focus(); + } + } + + function insertNodesBefore(parentNode, insertBefore, fragment, settleInfo) { + handleAttributes(parentNode, fragment, settleInfo); + while(fragment.childNodes.length > 0){ + var child = fragment.firstChild; + addClassToElement(child, htmx.config.addedClass); + parentNode.insertBefore(child, insertBefore); + if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) { + settleInfo.tasks.push(makeAjaxLoadTask(child)); + } + } + } + + // based on https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0, + // derived from Java's string hashcode implementation + function stringHash(string, hash) { + var char = 0; + while (char < string.length){ + hash = (hash << 5) - hash + string.charCodeAt(char++) | 0; // bitwise or ensures we have a 32-bit int + } + return hash; + } + + function attributeHash(elt) { + var hash = 0; + // IE fix + if (elt.attributes) { + for (var i = 0; i < elt.attributes.length; i++) { + var attribute = elt.attributes[i]; + if(attribute.value){ // only include attributes w/ actual values (empty is same as non-existent) + hash = stringHash(attribute.name, hash); + hash = stringHash(attribute.value, hash); + } + } + } + return hash; + } + + function deInitOnHandlers(elt) { + var internalData = getInternalData(elt); + if (internalData.onHandlers) { + for (let i = 0; i < internalData.onHandlers.length; i++) { + const handlerInfo = internalData.onHandlers[i]; + elt.removeEventListener(handlerInfo.event, handlerInfo.listener); + } + delete internalData.onHandlers + } + } + + function deInitNode(element) { + var internalData = getInternalData(element); + if (internalData.timeout) { + clearTimeout(internalData.timeout); + } + if (internalData.webSocket) { + internalData.webSocket.close(); + } + if (internalData.sseEventSource) { + internalData.sseEventSource.close(); + } + if (internalData.listenerInfos) { + forEach(internalData.listenerInfos, function (info) { + if (info.on) { + info.on.removeEventListener(info.trigger, info.listener); + } + }); + } + if (internalData.initHash) { + internalData.initHash = null + } + deInitOnHandlers(element); + } + + function cleanUpElement(element) { + triggerEvent(element, "htmx:beforeCleanupElement") + deInitNode(element); + if (element.children) { // IE + forEach(element.children, function(child) { cleanUpElement(child) }); + } + } + + function swapOuterHTML(target, fragment, settleInfo) { + if (target.tagName === "BODY") { + return swapInnerHTML(target, fragment, settleInfo); + } else { + // @type {HTMLElement} + var newElt + var eltBeforeNewContent = target.previousSibling; + insertNodesBefore(parentElt(target), target, fragment, settleInfo); + if (eltBeforeNewContent == null) { + newElt = parentElt(target).firstChild; + } else { + newElt = eltBeforeNewContent.nextSibling; + } + getInternalData(target).replacedWith = newElt; // tuck away so we can fire events on it later + settleInfo.elts = settleInfo.elts.filter(function(e) { return e != target }); + while(newElt && newElt !== target) { + if (newElt.nodeType === Node.ELEMENT_NODE) { + settleInfo.elts.push(newElt); + } + newElt = newElt.nextElementSibling; + } + cleanUpElement(target); + parentElt(target).removeChild(target); + } + } + + function swapAfterBegin(target, fragment, settleInfo) { + return insertNodesBefore(target, target.firstChild, fragment, settleInfo); + } + + function swapBeforeBegin(target, fragment, settleInfo) { + return insertNodesBefore(parentElt(target), target, fragment, settleInfo); + } + + function swapBeforeEnd(target, fragment, settleInfo) { + return insertNodesBefore(target, null, fragment, settleInfo); + } + + function swapAfterEnd(target, fragment, settleInfo) { + return insertNodesBefore(parentElt(target), target.nextSibling, fragment, settleInfo); + } + function swapDelete(target, fragment, settleInfo) { + cleanUpElement(target); + return parentElt(target).removeChild(target); + } + + function swapInnerHTML(target, fragment, settleInfo) { + var firstChild = target.firstChild; + insertNodesBefore(target, firstChild, fragment, settleInfo); + if (firstChild) { + while (firstChild.nextSibling) { + cleanUpElement(firstChild.nextSibling) + target.removeChild(firstChild.nextSibling); + } + cleanUpElement(firstChild) + target.removeChild(firstChild); + } + } + + function maybeSelectFromResponse(elt, fragment, selectOverride) { + var selector = selectOverride || getClosestAttributeValue(elt, "hx-select"); + if (selector) { + var newFragment = getDocument().createDocumentFragment(); + forEach(fragment.querySelectorAll(selector), function (node) { + newFragment.appendChild(node); + }); + fragment = newFragment; + } + return fragment; + } + + function swap(swapStyle, elt, target, fragment, settleInfo) { + switch (swapStyle) { + case "none": + return; + case "outerHTML": + swapOuterHTML(target, fragment, settleInfo); + return; + case "afterbegin": + swapAfterBegin(target, fragment, settleInfo); + return; + case "beforebegin": + swapBeforeBegin(target, fragment, settleInfo); + return; + case "beforeend": + swapBeforeEnd(target, fragment, settleInfo); + return; + case "afterend": + swapAfterEnd(target, fragment, settleInfo); + return; + case "delete": + swapDelete(target, fragment, settleInfo); + return; + default: + var extensions = getExtensions(elt); + for (var i = 0; i < extensions.length; i++) { + var ext = extensions[i]; + try { + var newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo); + if (newElements) { + if (typeof newElements.length !== 'undefined') { + // if handleSwap returns an array (like) of elements, we handle them + for (var j = 0; j < newElements.length; j++) { + var child = newElements[j]; + if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) { + settleInfo.tasks.push(makeAjaxLoadTask(child)); + } + } + } + return; + } + } catch (e) { + logError(e); + } + } + if (swapStyle === "innerHTML") { + swapInnerHTML(target, fragment, settleInfo); + } else { + swap(htmx.config.defaultSwapStyle, elt, target, fragment, settleInfo); + } + } + } + + function findTitle(content) { + if (content.indexOf(' -1) { + var contentWithSvgsRemoved = content.replace(/]*>|>)([\s\S]*?)<\/svg>/gim, ''); + var result = contentWithSvgsRemoved.match(/]*>|>)([\s\S]*?)<\/title>/im); + + if (result) { + return result[2]; + } + } + } + + function selectAndSwap(swapStyle, target, elt, responseText, settleInfo, selectOverride) { + settleInfo.title = findTitle(responseText); + var fragment = makeFragment(responseText); + if (fragment) { + handleOutOfBandSwaps(elt, fragment, settleInfo); + fragment = maybeSelectFromResponse(elt, fragment, selectOverride); + handlePreservedElements(fragment); + return swap(swapStyle, elt, target, fragment, settleInfo); + } + } + + function handleTrigger(xhr, header, elt) { + var triggerBody = xhr.getResponseHeader(header); + if (triggerBody.indexOf("{") === 0) { + var triggers = parseJSON(triggerBody); + for (var eventName in triggers) { + if (triggers.hasOwnProperty(eventName)) { + var detail = triggers[eventName]; + if (!isRawObject(detail)) { + detail = {"value": detail} + } + triggerEvent(elt, eventName, detail); + } + } + } else { + var eventNames = triggerBody.split(",") + for (var i = 0; i < eventNames.length; i++) { + triggerEvent(elt, eventNames[i].trim(), []); + } + } + } + + var WHITESPACE = /\s/; + var WHITESPACE_OR_COMMA = /[\s,]/; + var SYMBOL_START = /[_$a-zA-Z]/; + var SYMBOL_CONT = /[_$a-zA-Z0-9]/; + var STRINGISH_START = ['"', "'", "/"]; + var NOT_WHITESPACE = /[^\s]/; + function tokenizeString(str) { + var tokens = []; + var position = 0; + while (position < str.length) { + if(SYMBOL_START.exec(str.charAt(position))) { + var startPosition = position; + while (SYMBOL_CONT.exec(str.charAt(position + 1))) { + position++; + } + tokens.push(str.substr(startPosition, position - startPosition + 1)); + } else if (STRINGISH_START.indexOf(str.charAt(position)) !== -1) { + var startChar = str.charAt(position); + var startPosition = position; + position++; + while (position < str.length && str.charAt(position) !== startChar ) { + if (str.charAt(position) === "\\") { + position++; + } + position++; + } + tokens.push(str.substr(startPosition, position - startPosition + 1)); + } else { + var symbol = str.charAt(position); + tokens.push(symbol); + } + position++; + } + return tokens; + } + + function isPossibleRelativeReference(token, last, paramName) { + return SYMBOL_START.exec(token.charAt(0)) && + token !== "true" && + token !== "false" && + token !== "this" && + token !== paramName && + last !== "."; + } + + function maybeGenerateConditional(elt, tokens, paramName) { + if (tokens[0] === '[') { + tokens.shift(); + var bracketCount = 1; + var conditionalSource = " return (function(" + paramName + "){ return ("; + var last = null; + while (tokens.length > 0) { + var token = tokens[0]; + if (token === "]") { + bracketCount--; + if (bracketCount === 0) { + if (last === null) { + conditionalSource = conditionalSource + "true"; + } + tokens.shift(); + conditionalSource += ")})"; + try { + var conditionFunction = maybeEval(elt,function () { + return Function(conditionalSource)(); + }, + function(){return true}) + conditionFunction.source = conditionalSource; + return conditionFunction; + } catch (e) { + triggerErrorEvent(getDocument().body, "htmx:syntax:error", {error:e, source:conditionalSource}) + return null; + } + } + } else if (token === "[") { + bracketCount++; + } + if (isPossibleRelativeReference(token, last, paramName)) { + conditionalSource += "((" + paramName + "." + token + ") ? (" + paramName + "." + token + ") : (window." + token + "))"; + } else { + conditionalSource = conditionalSource + token; + } + last = tokens.shift(); + } + } + } + + function consumeUntil(tokens, match) { + var result = ""; + while (tokens.length > 0 && !tokens[0].match(match)) { + result += tokens.shift(); + } + return result; + } + + var INPUT_SELECTOR = 'input, textarea, select'; + + /** + * @param {HTMLElement} elt + * @returns {import("./htmx").HtmxTriggerSpecification[]} + */ + function getTriggerSpecs(elt) { + var explicitTrigger = getAttributeValue(elt, 'hx-trigger'); + var triggerSpecs = []; + if (explicitTrigger) { + var tokens = tokenizeString(explicitTrigger); + do { + consumeUntil(tokens, NOT_WHITESPACE); + var initialLength = tokens.length; + var trigger = consumeUntil(tokens, /[,\[\s]/); + if (trigger !== "") { + if (trigger === "every") { + var every = {trigger: 'every'}; + consumeUntil(tokens, NOT_WHITESPACE); + every.pollInterval = parseInterval(consumeUntil(tokens, /[,\[\s]/)); + consumeUntil(tokens, NOT_WHITESPACE); + var eventFilter = maybeGenerateConditional(elt, tokens, "event"); + if (eventFilter) { + every.eventFilter = eventFilter; + } + triggerSpecs.push(every); + } else if (trigger.indexOf("sse:") === 0) { + triggerSpecs.push({trigger: 'sse', sseEvent: trigger.substr(4)}); + } else { + var triggerSpec = {trigger: trigger}; + var eventFilter = maybeGenerateConditional(elt, tokens, "event"); + if (eventFilter) { + triggerSpec.eventFilter = eventFilter; + } + while (tokens.length > 0 && tokens[0] !== ",") { + consumeUntil(tokens, NOT_WHITESPACE) + var token = tokens.shift(); + if (token === "changed") { + triggerSpec.changed = true; + } else if (token === "once") { + triggerSpec.once = true; + } else if (token === "consume") { + triggerSpec.consume = true; + } else if (token === "delay" && tokens[0] === ":") { + tokens.shift(); + triggerSpec.delay = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA)); + } else if (token === "from" && tokens[0] === ":") { + tokens.shift(); + var from_arg = consumeUntil(tokens, WHITESPACE_OR_COMMA); + if (from_arg === "closest" || from_arg === "find" || from_arg === "next" || from_arg === "previous") { + tokens.shift(); + var selector = consumeUntil( + tokens, + WHITESPACE_OR_COMMA + ) + // `next` and `previous` allow a selector-less syntax + if (selector.length > 0) { + from_arg += " " + selector; + } + } + triggerSpec.from = from_arg; + } else if (token === "target" && tokens[0] === ":") { + tokens.shift(); + triggerSpec.target = consumeUntil(tokens, WHITESPACE_OR_COMMA); + } else if (token === "throttle" && tokens[0] === ":") { + tokens.shift(); + triggerSpec.throttle = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA)); + } else if (token === "queue" && tokens[0] === ":") { + tokens.shift(); + triggerSpec.queue = consumeUntil(tokens, WHITESPACE_OR_COMMA); + } else if ((token === "root" || token === "threshold") && tokens[0] === ":") { + tokens.shift(); + triggerSpec[token] = consumeUntil(tokens, WHITESPACE_OR_COMMA); + } else { + triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()}); + } + } + triggerSpecs.push(triggerSpec); + } + } + if (tokens.length === initialLength) { + triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()}); + } + consumeUntil(tokens, NOT_WHITESPACE); + } while (tokens[0] === "," && tokens.shift()) + } + + if (triggerSpecs.length > 0) { + return triggerSpecs; + } else if (matches(elt, 'form')) { + return [{trigger: 'submit'}]; + } else if (matches(elt, 'input[type="button"], input[type="submit"]')){ + return [{trigger: 'click'}]; + } else if (matches(elt, INPUT_SELECTOR)) { + return [{trigger: 'change'}]; + } else { + return [{trigger: 'click'}]; + } + } + + function cancelPolling(elt) { + getInternalData(elt).cancelled = true; + } + + function processPolling(elt, handler, spec) { + var nodeData = getInternalData(elt); + nodeData.timeout = setTimeout(function () { + if (bodyContains(elt) && nodeData.cancelled !== true) { + if (!maybeFilterEvent(spec, elt, makeEvent('hx:poll:trigger', { + triggerSpec: spec, + target: elt + }))) { + handler(elt); + } + processPolling(elt, handler, spec); + } + }, spec.pollInterval); + } + + function isLocalLink(elt) { + return location.hostname === elt.hostname && + getRawAttribute(elt,'href') && + getRawAttribute(elt,'href').indexOf("#") !== 0; + } + + function boostElement(elt, nodeData, triggerSpecs) { + if ((elt.tagName === "A" && isLocalLink(elt) && (elt.target === "" || elt.target === "_self")) || elt.tagName === "FORM") { + nodeData.boosted = true; + var verb, path; + if (elt.tagName === "A") { + verb = "get"; + path = getRawAttribute(elt, 'href') + } else { + var rawAttribute = getRawAttribute(elt, "method"); + verb = rawAttribute ? rawAttribute.toLowerCase() : "get"; + if (verb === "get") { + } + path = getRawAttribute(elt, 'action'); + } + triggerSpecs.forEach(function(triggerSpec) { + addEventListener(elt, function(elt, evt) { + if (closest(elt, htmx.config.disableSelector)) { + cleanUpElement(elt) + return + } + issueAjaxRequest(verb, path, elt, evt) + }, nodeData, triggerSpec, true); + }); + } + } + + /** + * + * @param {Event} evt + * @param {HTMLElement} elt + * @returns + */ + function shouldCancel(evt, elt) { + if (evt.type === "submit" || evt.type === "click") { + if (elt.tagName === "FORM") { + return true; + } + if (matches(elt, 'input[type="submit"], button') && closest(elt, 'form') !== null) { + return true; + } + if (elt.tagName === "A" && elt.href && + (elt.getAttribute('href') === '#' || elt.getAttribute('href').indexOf("#") !== 0)) { + return true; + } + } + return false; + } + + function ignoreBoostedAnchorCtrlClick(elt, evt) { + return getInternalData(elt).boosted && elt.tagName === "A" && evt.type === "click" && (evt.ctrlKey || evt.metaKey); + } + + function maybeFilterEvent(triggerSpec, elt, evt) { + var eventFilter = triggerSpec.eventFilter; + if(eventFilter){ + try { + return eventFilter.call(elt, evt) !== true; + } catch(e) { + triggerErrorEvent(getDocument().body, "htmx:eventFilter:error", {error: e, source:eventFilter.source}); + return true; + } + } + return false; + } + + function addEventListener(elt, handler, nodeData, triggerSpec, explicitCancel) { + var elementData = getInternalData(elt); + var eltsToListenOn; + if (triggerSpec.from) { + eltsToListenOn = querySelectorAllExt(elt, triggerSpec.from); + } else { + eltsToListenOn = [elt]; + } + // store the initial values of the elements, so we can tell if they change + if (triggerSpec.changed) { + eltsToListenOn.forEach(function (eltToListenOn) { + var eltToListenOnData = getInternalData(eltToListenOn); + eltToListenOnData.lastValue = eltToListenOn.value; + }) + } + forEach(eltsToListenOn, function (eltToListenOn) { + var eventListener = function (evt) { + if (!bodyContains(elt)) { + eltToListenOn.removeEventListener(triggerSpec.trigger, eventListener); + return; + } + if (ignoreBoostedAnchorCtrlClick(elt, evt)) { + return; + } + if (explicitCancel || shouldCancel(evt, elt)) { + evt.preventDefault(); + } + if (maybeFilterEvent(triggerSpec, elt, evt)) { + return; + } + var eventData = getInternalData(evt); + eventData.triggerSpec = triggerSpec; + if (eventData.handledFor == null) { + eventData.handledFor = []; + } + if (eventData.handledFor.indexOf(elt) < 0) { + eventData.handledFor.push(elt); + if (triggerSpec.consume) { + evt.stopPropagation(); + } + if (triggerSpec.target && evt.target) { + if (!matches(evt.target, triggerSpec.target)) { + return; + } + } + if (triggerSpec.once) { + if (elementData.triggeredOnce) { + return; + } else { + elementData.triggeredOnce = true; + } + } + if (triggerSpec.changed) { + var eltToListenOnData = getInternalData(eltToListenOn) + if (eltToListenOnData.lastValue === eltToListenOn.value) { + return; + } + eltToListenOnData.lastValue = eltToListenOn.value + } + if (elementData.delayed) { + clearTimeout(elementData.delayed); + } + if (elementData.throttle) { + return; + } + + if (triggerSpec.throttle) { + if (!elementData.throttle) { + handler(elt, evt); + elementData.throttle = setTimeout(function () { + elementData.throttle = null; + }, triggerSpec.throttle); + } + } else if (triggerSpec.delay) { + elementData.delayed = setTimeout(function() { handler(elt, evt) }, triggerSpec.delay); + } else { + triggerEvent(elt, 'htmx:trigger') + handler(elt, evt); + } + } + }; + if (nodeData.listenerInfos == null) { + nodeData.listenerInfos = []; + } + nodeData.listenerInfos.push({ + trigger: triggerSpec.trigger, + listener: eventListener, + on: eltToListenOn + }) + eltToListenOn.addEventListener(triggerSpec.trigger, eventListener); + }); + } + + var windowIsScrolling = false // used by initScrollHandler + var scrollHandler = null; + function initScrollHandler() { + if (!scrollHandler) { + scrollHandler = function() { + windowIsScrolling = true + }; + window.addEventListener("scroll", scrollHandler) + setInterval(function() { + if (windowIsScrolling) { + windowIsScrolling = false; + forEach(getDocument().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"), function (elt) { + maybeReveal(elt); + }) + } + }, 200); + } + } + + function maybeReveal(elt) { + if (!hasAttribute(elt,'data-hx-revealed') && isScrolledIntoView(elt)) { + elt.setAttribute('data-hx-revealed', 'true'); + var nodeData = getInternalData(elt); + if (nodeData.initHash) { + triggerEvent(elt, 'revealed'); + } else { + // if the node isn't initialized, wait for it before triggering the request + elt.addEventListener("htmx:afterProcessNode", function(evt) { triggerEvent(elt, 'revealed') }, {once: true}); + } + } + } + + //==================================================================== + // Web Sockets + //==================================================================== + + function processWebSocketInfo(elt, nodeData, info) { + var values = splitOnWhitespace(info); + for (var i = 0; i < values.length; i++) { + var value = values[i].split(/:(.+)/); + if (value[0] === "connect") { + ensureWebSocket(elt, value[1], 0); + } + if (value[0] === "send") { + processWebSocketSend(elt); + } + } + } + + function ensureWebSocket(elt, wssSource, retryCount) { + if (!bodyContains(elt)) { + return; // stop ensuring websocket connection when socket bearing element ceases to exist + } + + if (wssSource.indexOf("/") == 0) { // complete absolute paths only + var base_part = location.hostname + (location.port ? ':'+location.port: ''); + if (location.protocol == 'https:') { + wssSource = "wss://" + base_part + wssSource; + } else if (location.protocol == 'http:') { + wssSource = "ws://" + base_part + wssSource; + } + } + var socket = htmx.createWebSocket(wssSource); + socket.onerror = function (e) { + triggerErrorEvent(elt, "htmx:wsError", {error:e, socket:socket}); + maybeCloseWebSocketSource(elt); + }; + + socket.onclose = function (e) { + if ([1006, 1012, 1013].indexOf(e.code) >= 0) { // Abnormal Closure/Service Restart/Try Again Later + var delay = getWebSocketReconnectDelay(retryCount); + setTimeout(function() { + ensureWebSocket(elt, wssSource, retryCount+1); // creates a websocket with a new timeout + }, delay); + } + }; + socket.onopen = function (e) { + retryCount = 0; + } + + getInternalData(elt).webSocket = socket; + socket.addEventListener('message', function (event) { + if (maybeCloseWebSocketSource(elt)) { + return; + } + + var response = event.data; + withExtensions(elt, function(extension){ + response = extension.transformResponse(response, null, elt); + }); + + var settleInfo = makeSettleInfo(elt); + var fragment = makeFragment(response); + var children = toArray(fragment.children); + for (var i = 0; i < children.length; i++) { + var child = children[i]; + oobSwap(getAttributeValue(child, "hx-swap-oob") || "true", child, settleInfo); + } + + settleImmediately(settleInfo.tasks); + }); + } + + function maybeCloseWebSocketSource(elt) { + if (!bodyContains(elt)) { + getInternalData(elt).webSocket.close(); + return true; + } + } + + function processWebSocketSend(elt) { + var webSocketSourceElt = getClosestMatch(elt, function (parent) { + return getInternalData(parent).webSocket != null; + }); + if (webSocketSourceElt) { + elt.addEventListener(getTriggerSpecs(elt)[0].trigger, function (evt) { + var webSocket = getInternalData(webSocketSourceElt).webSocket; + var headers = getHeaders(elt, webSocketSourceElt); + var results = getInputValues(elt, 'post'); + var errors = results.errors; + var rawParameters = results.values; + var expressionVars = getExpressionVars(elt); + var allParameters = mergeObjects(rawParameters, expressionVars); + var filteredParameters = filterValues(allParameters, elt); + filteredParameters['HEADERS'] = headers; + if (errors && errors.length > 0) { + triggerEvent(elt, 'htmx:validation:halted', errors); + return; + } + webSocket.send(JSON.stringify(filteredParameters)); + if(shouldCancel(evt, elt)){ + evt.preventDefault(); + } + }); + } else { + triggerErrorEvent(elt, "htmx:noWebSocketSourceError"); + } + } + + function getWebSocketReconnectDelay(retryCount) { + var delay = htmx.config.wsReconnectDelay; + if (typeof delay === 'function') { + // @ts-ignore + return delay(retryCount); + } + if (delay === 'full-jitter') { + var exp = Math.min(retryCount, 6); + var maxDelay = 1000 * Math.pow(2, exp); + return maxDelay * Math.random(); + } + logError('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"'); + } + + //==================================================================== + // Server Sent Events + //==================================================================== + + function processSSEInfo(elt, nodeData, info) { + var values = splitOnWhitespace(info); + for (var i = 0; i < values.length; i++) { + var value = values[i].split(/:(.+)/); + if (value[0] === "connect") { + processSSESource(elt, value[1]); + } + + if ((value[0] === "swap")) { + processSSESwap(elt, value[1]) + } + } + } + + function processSSESource(elt, sseSrc) { + var source = htmx.createEventSource(sseSrc); + source.onerror = function (e) { + triggerErrorEvent(elt, "htmx:sseError", {error:e, source:source}); + maybeCloseSSESource(elt); + }; + getInternalData(elt).sseEventSource = source; + } + + function processSSESwap(elt, sseEventName) { + var sseSourceElt = getClosestMatch(elt, hasEventSource); + if (sseSourceElt) { + var sseEventSource = getInternalData(sseSourceElt).sseEventSource; + var sseListener = function (event) { + if (maybeCloseSSESource(sseSourceElt)) { + return; + } + if (!bodyContains(elt)) { + sseEventSource.removeEventListener(sseEventName, sseListener); + return; + } + + /////////////////////////// + // TODO: merge this code with AJAX and WebSockets code in the future. + + var response = event.data; + withExtensions(elt, function(extension){ + response = extension.transformResponse(response, null, elt); + }); + + var swapSpec = getSwapSpecification(elt) + var target = getTarget(elt) + var settleInfo = makeSettleInfo(elt); + + selectAndSwap(swapSpec.swapStyle, target, elt, response, settleInfo) + settleImmediately(settleInfo.tasks) + triggerEvent(elt, "htmx:sseMessage", event) + }; + + getInternalData(elt).sseListener = sseListener; + sseEventSource.addEventListener(sseEventName, sseListener); + } else { + triggerErrorEvent(elt, "htmx:noSSESourceError"); + } + } + + function processSSETrigger(elt, handler, sseEventName) { + var sseSourceElt = getClosestMatch(elt, hasEventSource); + if (sseSourceElt) { + var sseEventSource = getInternalData(sseSourceElt).sseEventSource; + var sseListener = function () { + if (!maybeCloseSSESource(sseSourceElt)) { + if (bodyContains(elt)) { + handler(elt); + } else { + sseEventSource.removeEventListener(sseEventName, sseListener); + } + } + }; + getInternalData(elt).sseListener = sseListener; + sseEventSource.addEventListener(sseEventName, sseListener); + } else { + triggerErrorEvent(elt, "htmx:noSSESourceError"); + } + } + + function maybeCloseSSESource(elt) { + if (!bodyContains(elt)) { + getInternalData(elt).sseEventSource.close(); + return true; + } + } + + function hasEventSource(node) { + return getInternalData(node).sseEventSource != null; + } + + //==================================================================== + + function loadImmediately(elt, handler, nodeData, delay) { + var load = function(){ + if (!nodeData.loaded) { + nodeData.loaded = true; + handler(elt); + } + } + if (delay) { + setTimeout(load, delay); + } else { + load(); + } + } + + function processVerbs(elt, nodeData, triggerSpecs) { + var explicitAction = false; + forEach(VERBS, function (verb) { + if (hasAttribute(elt,'hx-' + verb)) { + var path = getAttributeValue(elt, 'hx-' + verb); + explicitAction = true; + nodeData.path = path; + nodeData.verb = verb; + triggerSpecs.forEach(function(triggerSpec) { + addTriggerHandler(elt, triggerSpec, nodeData, function (elt, evt) { + if (closest(elt, htmx.config.disableSelector)) { + cleanUpElement(elt) + return + } + issueAjaxRequest(verb, path, elt, evt) + }) + }); + } + }); + return explicitAction; + } + + function addTriggerHandler(elt, triggerSpec, nodeData, handler) { + if (triggerSpec.sseEvent) { + processSSETrigger(elt, handler, triggerSpec.sseEvent); + } else if (triggerSpec.trigger === "revealed") { + initScrollHandler(); + addEventListener(elt, handler, nodeData, triggerSpec); + maybeReveal(elt); + } else if (triggerSpec.trigger === "intersect") { + var observerOptions = {}; + if (triggerSpec.root) { + observerOptions.root = querySelectorExt(elt, triggerSpec.root) + } + if (triggerSpec.threshold) { + observerOptions.threshold = parseFloat(triggerSpec.threshold); + } + var observer = new IntersectionObserver(function (entries) { + for (var i = 0; i < entries.length; i++) { + var entry = entries[i]; + if (entry.isIntersecting) { + triggerEvent(elt, "intersect"); + break; + } + } + }, observerOptions); + observer.observe(elt); + addEventListener(elt, handler, nodeData, triggerSpec); + } else if (triggerSpec.trigger === "load") { + if (!maybeFilterEvent(triggerSpec, elt, makeEvent("load", {elt: elt}))) { + loadImmediately(elt, handler, nodeData, triggerSpec.delay); + } + } else if (triggerSpec.pollInterval) { + nodeData.polling = true; + processPolling(elt, handler, triggerSpec); + } else { + addEventListener(elt, handler, nodeData, triggerSpec); + } + } + + function evalScript(script) { + if (htmx.config.allowScriptTags && (script.type === "text/javascript" || script.type === "module" || script.type === "") ) { + var newScript = getDocument().createElement("script"); + forEach(script.attributes, function (attr) { + newScript.setAttribute(attr.name, attr.value); + }); + newScript.textContent = script.textContent; + newScript.async = false; + if (htmx.config.inlineScriptNonce) { + newScript.nonce = htmx.config.inlineScriptNonce; + } + var parent = script.parentElement; + + try { + parent.insertBefore(newScript, script); + } catch (e) { + logError(e); + } finally { + // remove old script element, but only if it is still in DOM + if (script.parentElement) { + script.parentElement.removeChild(script); + } + } + } + } + + function processScripts(elt) { + if (matches(elt, "script")) { + evalScript(elt); + } + forEach(findAll(elt, "script"), function (script) { + evalScript(script); + }); + } + + function hasChanceOfBeingBoosted() { + return document.querySelector("[hx-boost], [data-hx-boost]"); + } + + function findHxOnWildcardElements(elt) { + var node = null + var elements = [] + + if (document.evaluate) { + var iter = document.evaluate('//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") ]]', elt) + while (node = iter.iterateNext()) elements.push(node) + } else { + var allElements = document.getElementsByTagName("*") + for (var i = 0; i < allElements.length; i++) { + var attributes = allElements[i].attributes + for (var j = 0; j < attributes.length; j++) { + var attrName = attributes[j].name + if (startsWith(attrName, "hx-on:") || startsWith(attrName, "data-hx-on:")) { + elements.push(allElements[i]) + } + } + } + } + + return elements + } + + function findElementsToProcess(elt) { + if (elt.querySelectorAll) { + var boostedElts = hasChanceOfBeingBoosted() ? ", a" : ""; + var results = elt.querySelectorAll(VERB_SELECTOR + boostedElts + ", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws]," + + " [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]"); + return results; + } else { + return []; + } + } + + // Handle submit buttons/inputs that have the form attribute set + // see https://developer.mozilla.org/docs/Web/HTML/Element/button + function maybeSetLastButtonClicked(evt) { + var elt = closest(evt.target, "button, input[type='submit']"); + var internalData = getRelatedFormData(evt) + if (internalData) { + internalData.lastButtonClicked = elt; + } + }; + function maybeUnsetLastButtonClicked(evt){ + var internalData = getRelatedFormData(evt) + if (internalData) { + internalData.lastButtonClicked = null; + } + } + function getRelatedFormData(evt) { + var elt = closest(evt.target, "button, input[type='submit']"); + if (!elt) { + return; + } + var form = resolveTarget('#' + getRawAttribute(elt, 'form')) || closest(elt, 'form'); + if (!form) { + return; + } + return getInternalData(form); + } + function initButtonTracking(elt) { + // need to handle both click and focus in: + // focusin - in case someone tabs in to a button and hits the space bar + // click - on OSX buttons do not focus on click see https://bugs.webkit.org/show_bug.cgi?id=13724 + elt.addEventListener('click', maybeSetLastButtonClicked) + elt.addEventListener('focusin', maybeSetLastButtonClicked) + elt.addEventListener('focusout', maybeUnsetLastButtonClicked) + } + + function countCurlies(line) { + var tokens = tokenizeString(line); + var netCurlies = 0; + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + if (token === "{") { + netCurlies++; + } else if (token === "}") { + netCurlies--; + } + } + return netCurlies; + } + + function addHxOnEventHandler(elt, eventName, code) { + var nodeData = getInternalData(elt); + if (!Array.isArray(nodeData.onHandlers)) { + nodeData.onHandlers = []; + } + var func; + var listener = function (e) { + return maybeEval(elt, function() { + if (!func) { + func = new Function("event", code); + } + func.call(elt, e); + }); + }; + elt.addEventListener(eventName, listener); + nodeData.onHandlers.push({event:eventName, listener:listener}); + } + + function processHxOn(elt) { + var hxOnValue = getAttributeValue(elt, 'hx-on'); + if (hxOnValue) { + var handlers = {} + var lines = hxOnValue.split("\n"); + var currentEvent = null; + var curlyCount = 0; + while (lines.length > 0) { + var line = lines.shift(); + var match = line.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/); + if (curlyCount === 0 && match) { + line.split(":") + currentEvent = match[1].slice(0, -1); // strip last colon + handlers[currentEvent] = match[2]; + } else { + handlers[currentEvent] += line; + } + curlyCount += countCurlies(line); + } + + for (var eventName in handlers) { + addHxOnEventHandler(elt, eventName, handlers[eventName]); + } + } + } + + function processHxOnWildcard(elt) { + // wipe any previous on handlers so that this function takes precedence + deInitOnHandlers(elt) + + for (var i = 0; i < elt.attributes.length; i++) { + var name = elt.attributes[i].name + var value = elt.attributes[i].value + if (startsWith(name, "hx-on:") || startsWith(name, "data-hx-on:")) { + let eventName = name.slice(name.indexOf(":") + 1) + // if the eventName starts with a colon, prepend "htmx" for shorthand support + if (startsWith(eventName, ":")) eventName = "htmx" + eventName + + addHxOnEventHandler(elt, eventName, value) + } + } + } + + function initNode(elt) { + if (closest(elt, htmx.config.disableSelector)) { + cleanUpElement(elt) + return; + } + var nodeData = getInternalData(elt); + if (nodeData.initHash !== attributeHash(elt)) { + // clean up any previously processed info + deInitNode(elt); + + nodeData.initHash = attributeHash(elt); + + processHxOn(elt); + + triggerEvent(elt, "htmx:beforeProcessNode") + + if (elt.value) { + nodeData.lastValue = elt.value; + } + + var triggerSpecs = getTriggerSpecs(elt); + var hasExplicitHttpAction = processVerbs(elt, nodeData, triggerSpecs); + + if (!hasExplicitHttpAction) { + if (getClosestAttributeValue(elt, "hx-boost") === "true") { + boostElement(elt, nodeData, triggerSpecs); + } else if (hasAttribute(elt, 'hx-trigger')) { + triggerSpecs.forEach(function (triggerSpec) { + // For "naked" triggers, don't do anything at all + addTriggerHandler(elt, triggerSpec, nodeData, function () { + }) + }) + } + } + + // Handle submit buttons/inputs that have the form attribute set + // see https://developer.mozilla.org/docs/Web/HTML/Element/button + if (elt.tagName === "FORM" || (getRawAttribute(elt, "type") === "submit" && hasAttribute(elt, "form"))) { + initButtonTracking(elt) + } + + var sseInfo = getAttributeValue(elt, 'hx-sse'); + if (sseInfo) { + processSSEInfo(elt, nodeData, sseInfo); + } + + var wsInfo = getAttributeValue(elt, 'hx-ws'); + if (wsInfo) { + processWebSocketInfo(elt, nodeData, wsInfo); + } + triggerEvent(elt, "htmx:afterProcessNode"); + } + } + + function processNode(elt) { + elt = resolveTarget(elt); + if (closest(elt, htmx.config.disableSelector)) { + cleanUpElement(elt) + return; + } + initNode(elt); + forEach(findElementsToProcess(elt), function(child) { initNode(child) }); + // Because it happens second, the new way of adding onHandlers superseeds the old one + // i.e. if there are any hx-on:eventName attributes, the hx-on attribute will be ignored + forEach(findHxOnWildcardElements(elt), processHxOnWildcard); + } + + //==================================================================== + // Event/Log Support + //==================================================================== + + function kebabEventName(str) { + return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); + } + + function makeEvent(eventName, detail) { + var evt; + if (window.CustomEvent && typeof window.CustomEvent === 'function') { + evt = new CustomEvent(eventName, {bubbles: true, cancelable: true, detail: detail}); + } else { + evt = getDocument().createEvent('CustomEvent'); + evt.initCustomEvent(eventName, true, true, detail); + } + return evt; + } + + function triggerErrorEvent(elt, eventName, detail) { + triggerEvent(elt, eventName, mergeObjects({error:eventName}, detail)); + } + + function ignoreEventForLogging(eventName) { + return eventName === "htmx:afterProcessNode" + } + + /** + * `withExtensions` locates all active extensions for a provided element, then + * executes the provided function using each of the active extensions. It should + * be called internally at every extendable execution point in htmx. + * + * @param {HTMLElement} elt + * @param {(extension:import("./htmx").HtmxExtension) => void} toDo + * @returns void + */ + function withExtensions(elt, toDo) { + forEach(getExtensions(elt), function(extension){ + try { + toDo(extension); + } catch (e) { + logError(e); + } + }); + } + + function logError(msg) { + if(console.error) { + console.error(msg); + } else if (console.log) { + console.log("ERROR: ", msg); + } + } + + function triggerEvent(elt, eventName, detail) { + elt = resolveTarget(elt); + if (detail == null) { + detail = {}; + } + detail["elt"] = elt; + var event = makeEvent(eventName, detail); + if (htmx.logger && !ignoreEventForLogging(eventName)) { + htmx.logger(elt, eventName, detail); + } + if (detail.error) { + logError(detail.error); + triggerEvent(elt, "htmx:error", {errorInfo:detail}) + } + var eventResult = elt.dispatchEvent(event); + var kebabName = kebabEventName(eventName); + if (eventResult && kebabName !== eventName) { + var kebabedEvent = makeEvent(kebabName, event.detail); + eventResult = eventResult && elt.dispatchEvent(kebabedEvent) + } + withExtensions(elt, function (extension) { + eventResult = eventResult && (extension.onEvent(eventName, event) !== false && !event.defaultPrevented) + }); + return eventResult; + } + + //==================================================================== + // History Support + //==================================================================== + var currentPathForHistory = location.pathname+location.search; + + function getHistoryElement() { + var historyElt = getDocument().querySelector('[hx-history-elt],[data-hx-history-elt]'); + return historyElt || getDocument().body; + } + + function saveToHistoryCache(url, content, title, scroll) { + if (!canAccessLocalStorage()) { + return; + } + + if (htmx.config.historyCacheSize <= 0) { + // make sure that an eventually already existing cache is purged + localStorage.removeItem("htmx-history-cache"); + return; + } + + url = normalizePath(url); + + var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || []; + for (var i = 0; i < historyCache.length; i++) { + if (historyCache[i].url === url) { + historyCache.splice(i, 1); + break; + } + } + var newHistoryItem = {url:url, content: content, title:title, scroll:scroll}; + triggerEvent(getDocument().body, "htmx:historyItemCreated", {item:newHistoryItem, cache: historyCache}) + historyCache.push(newHistoryItem) + while (historyCache.length > htmx.config.historyCacheSize) { + historyCache.shift(); + } + while(historyCache.length > 0){ + try { + localStorage.setItem("htmx-history-cache", JSON.stringify(historyCache)); + break; + } catch (e) { + triggerErrorEvent(getDocument().body, "htmx:historyCacheError", {cause:e, cache: historyCache}) + historyCache.shift(); // shrink the cache and retry + } + } + } + + function getCachedHistory(url) { + if (!canAccessLocalStorage()) { + return null; + } + + url = normalizePath(url); + + var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || []; + for (var i = 0; i < historyCache.length; i++) { + if (historyCache[i].url === url) { + return historyCache[i]; + } + } + return null; + } + + function cleanInnerHtmlForHistory(elt) { + var className = htmx.config.requestClass; + var clone = elt.cloneNode(true); + forEach(findAll(clone, "." + className), function(child){ + removeClassFromElement(child, className); + }); + return clone.innerHTML; + } + + function saveCurrentPageToHistory() { + var elt = getHistoryElement(); + var path = currentPathForHistory || location.pathname+location.search; + + // Allow history snapshot feature to be disabled where hx-history="false" + // is present *anywhere* in the current document we're about to save, + // so we can prevent privileged data entering the cache. + // The page will still be reachable as a history entry, but htmx will fetch it + // live from the server onpopstate rather than look in the localStorage cache + var disableHistoryCache + try { + disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]') + } catch (e) { + // IE11: insensitive modifier not supported so fallback to case sensitive selector + disableHistoryCache = getDocument().querySelector('[hx-history="false"],[data-hx-history="false"]') + } + if (!disableHistoryCache) { + triggerEvent(getDocument().body, "htmx:beforeHistorySave", {path: path, historyElt: elt}); + saveToHistoryCache(path, cleanInnerHtmlForHistory(elt), getDocument().title, window.scrollY); + } + + if (htmx.config.historyEnabled) history.replaceState({htmx: true}, getDocument().title, window.location.href); + } + + function pushUrlIntoHistory(path) { + // remove the cache buster parameter, if any + if (htmx.config.getCacheBusterParam) { + path = path.replace(/org\.htmx\.cache-buster=[^&]*&?/, '') + if (endsWith(path, '&') || endsWith(path, "?")) { + path = path.slice(0, -1); + } + } + if(htmx.config.historyEnabled) { + history.pushState({htmx:true}, "", path); + } + currentPathForHistory = path; + } + + function replaceUrlInHistory(path) { + if(htmx.config.historyEnabled) history.replaceState({htmx:true}, "", path); + currentPathForHistory = path; + } + + function settleImmediately(tasks) { + forEach(tasks, function (task) { + task.call(); + }); + } + + function loadHistoryFromServer(path) { + var request = new XMLHttpRequest(); + var details = {path: path, xhr:request}; + triggerEvent(getDocument().body, "htmx:historyCacheMiss", details); + request.open('GET', path, true); + request.setRequestHeader("HX-History-Restore-Request", "true"); + request.onload = function () { + if (this.status >= 200 && this.status < 400) { + triggerEvent(getDocument().body, "htmx:historyCacheMissLoad", details); + var fragment = makeFragment(this.response); + // @ts-ignore + fragment = fragment.querySelector('[hx-history-elt],[data-hx-history-elt]') || fragment; + var historyElement = getHistoryElement(); + var settleInfo = makeSettleInfo(historyElement); + var title = findTitle(this.response); + if (title) { + var titleElt = find("title"); + if (titleElt) { + titleElt.innerHTML = title; + } else { + window.document.title = title; + } + } + // @ts-ignore + swapInnerHTML(historyElement, fragment, settleInfo) + settleImmediately(settleInfo.tasks); + currentPathForHistory = path; + triggerEvent(getDocument().body, "htmx:historyRestore", {path: path, cacheMiss:true, serverResponse:this.response}); + } else { + triggerErrorEvent(getDocument().body, "htmx:historyCacheMissLoadError", details); + } + }; + request.send(); + } + + function restoreHistory(path) { + saveCurrentPageToHistory(); + path = path || location.pathname+location.search; + var cached = getCachedHistory(path); + if (cached) { + var fragment = makeFragment(cached.content); + var historyElement = getHistoryElement(); + var settleInfo = makeSettleInfo(historyElement); + swapInnerHTML(historyElement, fragment, settleInfo) + settleImmediately(settleInfo.tasks); + document.title = cached.title; + setTimeout(function () { + window.scrollTo(0, cached.scroll); + }, 0); // next 'tick', so browser has time to render layout + currentPathForHistory = path; + triggerEvent(getDocument().body, "htmx:historyRestore", {path:path, item:cached}); + } else { + if (htmx.config.refreshOnHistoryMiss) { + + // @ts-ignore: optional parameter in reload() function throws error + window.location.reload(true); + } else { + loadHistoryFromServer(path); + } + } + } + + function addRequestIndicatorClasses(elt) { + var indicators = findAttributeTargets(elt, 'hx-indicator'); + if (indicators == null) { + indicators = [elt]; + } + forEach(indicators, function (ic) { + var internalData = getInternalData(ic); + internalData.requestCount = (internalData.requestCount || 0) + 1; + ic.classList["add"].call(ic.classList, htmx.config.requestClass); + }); + return indicators; + } + + function disableElements(elt) { + var disabledElts = findAttributeTargets(elt, 'hx-disabled-elt'); + if (disabledElts == null) { + disabledElts = []; + } + forEach(disabledElts, function (disabledElement) { + var internalData = getInternalData(disabledElement); + internalData.requestCount = (internalData.requestCount || 0) + 1; + disabledElement.setAttribute("disabled", ""); + }); + return disabledElts; + } + + function removeRequestIndicators(indicators, disabled) { + forEach(indicators, function (ic) { + var internalData = getInternalData(ic); + internalData.requestCount = (internalData.requestCount || 0) - 1; + if (internalData.requestCount === 0) { + ic.classList["remove"].call(ic.classList, htmx.config.requestClass); + } + }); + forEach(disabled, function (disabledElement) { + var internalData = getInternalData(disabledElement); + internalData.requestCount = (internalData.requestCount || 0) - 1; + if (internalData.requestCount === 0) { + disabledElement.removeAttribute('disabled'); + } + }); + } + + //==================================================================== + // Input Value Processing + //==================================================================== + + function haveSeenNode(processed, elt) { + for (var i = 0; i < processed.length; i++) { + var node = processed[i]; + if (node.isSameNode(elt)) { + return true; + } + } + return false; + } + + function shouldInclude(elt) { + if(elt.name === "" || elt.name == null || elt.disabled) { + return false; + } + // ignore "submitter" types (see jQuery src/serialize.js) + if (elt.type === "button" || elt.type === "submit" || elt.tagName === "image" || elt.tagName === "reset" || elt.tagName === "file" ) { + return false; + } + if (elt.type === "checkbox" || elt.type === "radio" ) { + return elt.checked; + } + return true; + } + + function addValueToValues(name, value, values) { + // This is a little ugly because both the current value of the named value in the form + // and the new value could be arrays, so we have to handle all four cases :/ + if (name != null && value != null) { + var current = values[name]; + if (current === undefined) { + values[name] = value; + } else if (Array.isArray(current)) { + if (Array.isArray(value)) { + values[name] = current.concat(value); + } else { + current.push(value); + } + } else { + if (Array.isArray(value)) { + values[name] = [current].concat(value); + } else { + values[name] = [current, value]; + } + } + } + } + + function processInputValue(processed, values, errors, elt, validate) { + if (elt == null || haveSeenNode(processed, elt)) { + return; + } else { + processed.push(elt); + } + if (shouldInclude(elt)) { + var name = getRawAttribute(elt,"name"); + var value = elt.value; + if (elt.multiple && elt.tagName === "SELECT") { + value = toArray(elt.querySelectorAll("option:checked")).map(function (e) { return e.value }); + } + // include file inputs + if (elt.files) { + value = toArray(elt.files); + } + addValueToValues(name, value, values); + if (validate) { + validateElement(elt, errors); + } + } + if (matches(elt, 'form')) { + var inputs = elt.elements; + forEach(inputs, function(input) { + processInputValue(processed, values, errors, input, validate); + }); + } + } + + function validateElement(element, errors) { + if (element.willValidate) { + triggerEvent(element, "htmx:validation:validate") + if (!element.checkValidity()) { + errors.push({elt: element, message:element.validationMessage, validity:element.validity}); + triggerEvent(element, "htmx:validation:failed", {message:element.validationMessage, validity:element.validity}) + } + } + } + + /** + * @param {HTMLElement} elt + * @param {string} verb + */ + function getInputValues(elt, verb) { + var processed = []; + var values = {}; + var formValues = {}; + var errors = []; + var internalData = getInternalData(elt); + if (internalData.lastButtonClicked && !bodyContains(internalData.lastButtonClicked)) { + internalData.lastButtonClicked = null + } + + // only validate when form is directly submitted and novalidate or formnovalidate are not set + // or if the element has an explicit hx-validate="true" on it + var validate = (matches(elt, 'form') && elt.noValidate !== true) || getAttributeValue(elt, "hx-validate") === "true"; + if (internalData.lastButtonClicked) { + validate = validate && internalData.lastButtonClicked.formNoValidate !== true; + } + + // for a non-GET include the closest form + if (verb !== 'get') { + processInputValue(processed, formValues, errors, closest(elt, 'form'), validate); + } + + // include the element itself + processInputValue(processed, values, errors, elt, validate); + + // if a button or submit was clicked last, include its value + if (internalData.lastButtonClicked || elt.tagName === "BUTTON" || + (elt.tagName === "INPUT" && getRawAttribute(elt, "type") === "submit")) { + var button = internalData.lastButtonClicked || elt + var name = getRawAttribute(button, "name") + addValueToValues(name, button.value, formValues) + } + + // include any explicit includes + var includes = findAttributeTargets(elt, "hx-include"); + forEach(includes, function(node) { + processInputValue(processed, values, errors, node, validate); + // if a non-form is included, include any input values within it + if (!matches(node, 'form')) { + forEach(node.querySelectorAll(INPUT_SELECTOR), function (descendant) { + processInputValue(processed, values, errors, descendant, validate); + }) + } + }); + + // form values take precedence, overriding the regular values + values = mergeObjects(values, formValues); + + return {errors:errors, values:values}; + } + + function appendParam(returnStr, name, realValue) { + if (returnStr !== "") { + returnStr += "&"; + } + if (String(realValue) === "[object Object]") { + realValue = JSON.stringify(realValue); + } + var s = encodeURIComponent(realValue); + returnStr += encodeURIComponent(name) + "=" + s; + return returnStr; + } + + function urlEncode(values) { + var returnStr = ""; + for (var name in values) { + if (values.hasOwnProperty(name)) { + var value = values[name]; + if (Array.isArray(value)) { + forEach(value, function(v) { + returnStr = appendParam(returnStr, name, v); + }); + } else { + returnStr = appendParam(returnStr, name, value); + } + } + } + return returnStr; + } + + function makeFormData(values) { + var formData = new FormData(); + for (var name in values) { + if (values.hasOwnProperty(name)) { + var value = values[name]; + if (Array.isArray(value)) { + forEach(value, function(v) { + formData.append(name, v); + }); + } else { + formData.append(name, value); + } + } + } + return formData; + } + + //==================================================================== + // Ajax + //==================================================================== + + /** + * @param {HTMLElement} elt + * @param {HTMLElement} target + * @param {string} prompt + * @returns {Object} // TODO: Define/Improve HtmxHeaderSpecification + */ + function getHeaders(elt, target, prompt) { + var headers = { + "HX-Request" : "true", + "HX-Trigger" : getRawAttribute(elt, "id"), + "HX-Trigger-Name" : getRawAttribute(elt, "name"), + "HX-Target" : getAttributeValue(target, "id"), + "HX-Current-URL" : getDocument().location.href, + } + getValuesForElement(elt, "hx-headers", false, headers) + if (prompt !== undefined) { + headers["HX-Prompt"] = prompt; + } + if (getInternalData(elt).boosted) { + headers["HX-Boosted"] = "true"; + } + return headers; + } + + /** + * filterValues takes an object containing form input values + * and returns a new object that only contains keys that are + * specified by the closest "hx-params" attribute + * @param {Object} inputValues + * @param {HTMLElement} elt + * @returns {Object} + */ + function filterValues(inputValues, elt) { + var paramsValue = getClosestAttributeValue(elt, "hx-params"); + if (paramsValue) { + if (paramsValue === "none") { + return {}; + } else if (paramsValue === "*") { + return inputValues; + } else if(paramsValue.indexOf("not ") === 0) { + forEach(paramsValue.substr(4).split(","), function (name) { + name = name.trim(); + delete inputValues[name]; + }); + return inputValues; + } else { + var newValues = {} + forEach(paramsValue.split(","), function (name) { + name = name.trim(); + newValues[name] = inputValues[name]; + }); + return newValues; + } + } else { + return inputValues; + } + } + + function isAnchorLink(elt) { + return getRawAttribute(elt, 'href') && getRawAttribute(elt, 'href').indexOf("#") >=0 + } + + /** + * + * @param {HTMLElement} elt + * @param {string} swapInfoOverride + * @returns {import("./htmx").HtmxSwapSpecification} + */ + function getSwapSpecification(elt, swapInfoOverride) { + var swapInfo = swapInfoOverride ? swapInfoOverride : getClosestAttributeValue(elt, "hx-swap"); + var swapSpec = { + "swapStyle" : getInternalData(elt).boosted ? 'innerHTML' : htmx.config.defaultSwapStyle, + "swapDelay" : htmx.config.defaultSwapDelay, + "settleDelay" : htmx.config.defaultSettleDelay + } + if (htmx.config.scrollIntoViewOnBoost && getInternalData(elt).boosted && !isAnchorLink(elt)) { + swapSpec["show"] = "top" + } + if (swapInfo) { + var split = splitOnWhitespace(swapInfo); + if (split.length > 0) { + for (var i = 0; i < split.length; i++) { + var value = split[i]; + if (value.indexOf("swap:") === 0) { + swapSpec["swapDelay"] = parseInterval(value.substr(5)); + } else if (value.indexOf("settle:") === 0) { + swapSpec["settleDelay"] = parseInterval(value.substr(7)); + } else if (value.indexOf("transition:") === 0) { + swapSpec["transition"] = value.substr(11) === "true"; + } else if (value.indexOf("ignoreTitle:") === 0) { + swapSpec["ignoreTitle"] = value.substr(12) === "true"; + } else if (value.indexOf("scroll:") === 0) { + var scrollSpec = value.substr(7); + var splitSpec = scrollSpec.split(":"); + var scrollVal = splitSpec.pop(); + var selectorVal = splitSpec.length > 0 ? splitSpec.join(":") : null; + swapSpec["scroll"] = scrollVal; + swapSpec["scrollTarget"] = selectorVal; + } else if (value.indexOf("show:") === 0) { + var showSpec = value.substr(5); + var splitSpec = showSpec.split(":"); + var showVal = splitSpec.pop(); + var selectorVal = splitSpec.length > 0 ? splitSpec.join(":") : null; + swapSpec["show"] = showVal; + swapSpec["showTarget"] = selectorVal; + } else if (value.indexOf("focus-scroll:") === 0) { + var focusScrollVal = value.substr("focus-scroll:".length); + swapSpec["focusScroll"] = focusScrollVal == "true"; + } else if (i == 0) { + swapSpec["swapStyle"] = value; + } else { + logError('Unknown modifier in hx-swap: ' + value); + } + } + } + } + return swapSpec; + } + + function usesFormData(elt) { + return getClosestAttributeValue(elt, "hx-encoding") === "multipart/form-data" || + (matches(elt, "form") && getRawAttribute(elt, 'enctype') === "multipart/form-data"); + } + + function encodeParamsForBody(xhr, elt, filteredParameters) { + var encodedParameters = null; + withExtensions(elt, function (extension) { + if (encodedParameters == null) { + encodedParameters = extension.encodeParameters(xhr, filteredParameters, elt); + } + }); + if (encodedParameters != null) { + return encodedParameters; + } else { + if (usesFormData(elt)) { + return makeFormData(filteredParameters); + } else { + return urlEncode(filteredParameters); + } + } + } + + /** + * + * @param {Element} target + * @returns {import("./htmx").HtmxSettleInfo} + */ + function makeSettleInfo(target) { + return {tasks: [], elts: [target]}; + } + + function updateScrollState(content, swapSpec) { + var first = content[0]; + var last = content[content.length - 1]; + if (swapSpec.scroll) { + var target = null; + if (swapSpec.scrollTarget) { + target = querySelectorExt(first, swapSpec.scrollTarget); + } + if (swapSpec.scroll === "top" && (first || target)) { + target = target || first; + target.scrollTop = 0; + } + if (swapSpec.scroll === "bottom" && (last || target)) { + target = target || last; + target.scrollTop = target.scrollHeight; + } + } + if (swapSpec.show) { + var target = null; + if (swapSpec.showTarget) { + var targetStr = swapSpec.showTarget; + if (swapSpec.showTarget === "window") { + targetStr = "body"; + } + target = querySelectorExt(first, targetStr); + } + if (swapSpec.show === "top" && (first || target)) { + target = target || first; + target.scrollIntoView({block:'start', behavior: htmx.config.scrollBehavior}); + } + if (swapSpec.show === "bottom" && (last || target)) { + target = target || last; + target.scrollIntoView({block:'end', behavior: htmx.config.scrollBehavior}); + } + } + } + + /** + * @param {HTMLElement} elt + * @param {string} attr + * @param {boolean=} evalAsDefault + * @param {Object=} values + * @returns {Object} + */ + function getValuesForElement(elt, attr, evalAsDefault, values) { + if (values == null) { + values = {}; + } + if (elt == null) { + return values; + } + var attributeValue = getAttributeValue(elt, attr); + if (attributeValue) { + var str = attributeValue.trim(); + var evaluateValue = evalAsDefault; + if (str === "unset") { + return null; + } + if (str.indexOf("javascript:") === 0) { + str = str.substr(11); + evaluateValue = true; + } else if (str.indexOf("js:") === 0) { + str = str.substr(3); + evaluateValue = true; + } + if (str.indexOf('{') !== 0) { + str = "{" + str + "}"; + } + var varsValues; + if (evaluateValue) { + varsValues = maybeEval(elt,function () {return Function("return (" + str + ")")();}, {}); + } else { + varsValues = parseJSON(str); + } + for (var key in varsValues) { + if (varsValues.hasOwnProperty(key)) { + if (values[key] == null) { + values[key] = varsValues[key]; + } + } + } + } + return getValuesForElement(parentElt(elt), attr, evalAsDefault, values); + } + + function maybeEval(elt, toEval, defaultVal) { + if (htmx.config.allowEval) { + return toEval(); + } else { + triggerErrorEvent(elt, 'htmx:evalDisallowedError'); + return defaultVal; + } + } + + /** + * @param {HTMLElement} elt + * @param {*} expressionVars + * @returns + */ + function getHXVarsForElement(elt, expressionVars) { + return getValuesForElement(elt, "hx-vars", true, expressionVars); + } + + /** + * @param {HTMLElement} elt + * @param {*} expressionVars + * @returns + */ + function getHXValsForElement(elt, expressionVars) { + return getValuesForElement(elt, "hx-vals", false, expressionVars); + } + + /** + * @param {HTMLElement} elt + * @returns {Object} + */ + function getExpressionVars(elt) { + return mergeObjects(getHXVarsForElement(elt), getHXValsForElement(elt)); + } + + function safelySetHeaderValue(xhr, header, headerValue) { + if (headerValue !== null) { + try { + xhr.setRequestHeader(header, headerValue); + } catch (e) { + // On an exception, try to set the header URI encoded instead + xhr.setRequestHeader(header, encodeURIComponent(headerValue)); + xhr.setRequestHeader(header + "-URI-AutoEncoded", "true"); + } + } + } + + function getPathFromResponse(xhr) { + // NB: IE11 does not support this stuff + if (xhr.responseURL && typeof(URL) !== "undefined") { + try { + var url = new URL(xhr.responseURL); + return url.pathname + url.search; + } catch (e) { + triggerErrorEvent(getDocument().body, "htmx:badResponseUrl", {url: xhr.responseURL}); + } + } + } + + function hasHeader(xhr, regexp) { + return xhr.getAllResponseHeaders().match(regexp); + } + + function ajaxHelper(verb, path, context) { + verb = verb.toLowerCase(); + if (context) { + if (context instanceof Element || isType(context, 'String')) { + return issueAjaxRequest(verb, path, null, null, { + targetOverride: resolveTarget(context), + returnPromise: true + }); + } else { + return issueAjaxRequest(verb, path, resolveTarget(context.source), context.event, + { + handler : context.handler, + headers : context.headers, + values : context.values, + targetOverride: resolveTarget(context.target), + swapOverride: context.swap, + returnPromise: true + }); + } + } else { + return issueAjaxRequest(verb, path, null, null, { + returnPromise: true + }); + } + } + + function hierarchyForElt(elt) { + var arr = []; + while (elt) { + arr.push(elt); + elt = elt.parentElement; + } + return arr; + } + + function verifyPath(elt, path, requestConfig) { + var sameHost + var url + if (typeof URL === "function") { + url = new URL(path, document.location.href); + var origin = document.location.origin; + sameHost = origin === url.origin; + } else { + // IE11 doesn't support URL + url = path + sameHost = startsWith(path, document.location.origin) + } + + if (htmx.config.selfRequestsOnly) { + if (!sameHost) { + return false; + } + } + return triggerEvent(elt, "htmx:validateUrl", mergeObjects({url: url, sameHost: sameHost}, requestConfig)); + } + + function issueAjaxRequest(verb, path, elt, event, etc, confirmed) { + var resolve = null; + var reject = null; + etc = etc != null ? etc : {}; + if(etc.returnPromise && typeof Promise !== "undefined"){ + var promise = new Promise(function (_resolve, _reject) { + resolve = _resolve; + reject = _reject; + }); + } + if(elt == null) { + elt = getDocument().body; + } + var responseHandler = etc.handler || handleAjaxResponse; + + if (!bodyContains(elt)) { + // do not issue requests for elements removed from the DOM + maybeCall(resolve); + return promise; + } + var target = etc.targetOverride || getTarget(elt); + if (target == null || target == DUMMY_ELT) { + triggerErrorEvent(elt, 'htmx:targetError', {target: getAttributeValue(elt, "hx-target")}); + maybeCall(reject); + return promise; + } + + var eltData = getInternalData(elt); + var submitter = eltData.lastButtonClicked; + + if (submitter) { + var buttonPath = getRawAttribute(submitter, "formaction"); + if (buttonPath != null) { + path = buttonPath; + } + + var buttonVerb = getRawAttribute(submitter, "formmethod") + if (buttonVerb != null) { + // ignore buttons with formmethod="dialog" + if (buttonVerb.toLowerCase() !== "dialog") { + verb = buttonVerb; + } + } + } + + var confirmQuestion = getClosestAttributeValue(elt, "hx-confirm"); + // allow event-based confirmation w/ a callback + if (confirmed === undefined) { + var issueRequest = function(skipConfirmation) { + return issueAjaxRequest(verb, path, elt, event, etc, !!skipConfirmation); + } + var confirmDetails = {target: target, elt: elt, path: path, verb: verb, triggeringEvent: event, etc: etc, issueRequest: issueRequest, question: confirmQuestion}; + if (triggerEvent(elt, 'htmx:confirm', confirmDetails) === false) { + maybeCall(resolve); + return promise; + } + } + + var syncElt = elt; + var syncStrategy = getClosestAttributeValue(elt, "hx-sync"); + var queueStrategy = null; + var abortable = false; + if (syncStrategy) { + var syncStrings = syncStrategy.split(":"); + var selector = syncStrings[0].trim(); + if (selector === "this") { + syncElt = findThisElement(elt, 'hx-sync'); + } else { + syncElt = querySelectorExt(elt, selector); + } + // default to the drop strategy + syncStrategy = (syncStrings[1] || 'drop').trim(); + eltData = getInternalData(syncElt); + if (syncStrategy === "drop" && eltData.xhr && eltData.abortable !== true) { + maybeCall(resolve); + return promise; + } else if (syncStrategy === "abort") { + if (eltData.xhr) { + maybeCall(resolve); + return promise; + } else { + abortable = true; + } + } else if (syncStrategy === "replace") { + triggerEvent(syncElt, 'htmx:abort'); // abort the current request and continue + } else if (syncStrategy.indexOf("queue") === 0) { + var queueStrArray = syncStrategy.split(" "); + queueStrategy = (queueStrArray[1] || "last").trim(); + } + } + + if (eltData.xhr) { + if (eltData.abortable) { + triggerEvent(syncElt, 'htmx:abort'); // abort the current request and continue + } else { + if(queueStrategy == null){ + if (event) { + var eventData = getInternalData(event); + if (eventData && eventData.triggerSpec && eventData.triggerSpec.queue) { + queueStrategy = eventData.triggerSpec.queue; + } + } + if (queueStrategy == null) { + queueStrategy = "last"; + } + } + if (eltData.queuedRequests == null) { + eltData.queuedRequests = []; + } + if (queueStrategy === "first" && eltData.queuedRequests.length === 0) { + eltData.queuedRequests.push(function () { + issueAjaxRequest(verb, path, elt, event, etc) + }); + } else if (queueStrategy === "all") { + eltData.queuedRequests.push(function () { + issueAjaxRequest(verb, path, elt, event, etc) + }); + } else if (queueStrategy === "last") { + eltData.queuedRequests = []; // dump existing queue + eltData.queuedRequests.push(function () { + issueAjaxRequest(verb, path, elt, event, etc) + }); + } + maybeCall(resolve); + return promise; + } + } + + var xhr = new XMLHttpRequest(); + eltData.xhr = xhr; + eltData.abortable = abortable; + var endRequestLock = function(){ + eltData.xhr = null; + eltData.abortable = false; + if (eltData.queuedRequests != null && + eltData.queuedRequests.length > 0) { + var queuedRequest = eltData.queuedRequests.shift(); + queuedRequest(); + } + } + var promptQuestion = getClosestAttributeValue(elt, "hx-prompt"); + if (promptQuestion) { + var promptResponse = prompt(promptQuestion); + // prompt returns null if cancelled and empty string if accepted with no entry + if (promptResponse === null || + !triggerEvent(elt, 'htmx:prompt', {prompt: promptResponse, target:target})) { + maybeCall(resolve); + endRequestLock(); + return promise; + } + } + + if (confirmQuestion && !confirmed) { + if(!confirm(confirmQuestion)) { + maybeCall(resolve); + endRequestLock() + return promise; + } + } + + + var headers = getHeaders(elt, target, promptResponse); + if (etc.headers) { + headers = mergeObjects(headers, etc.headers); + } + var results = getInputValues(elt, verb); + var errors = results.errors; + var rawParameters = results.values; + if (etc.values) { + rawParameters = mergeObjects(rawParameters, etc.values); + } + var expressionVars = getExpressionVars(elt); + var allParameters = mergeObjects(rawParameters, expressionVars); + var filteredParameters = filterValues(allParameters, elt); + + if (verb !== 'get' && !usesFormData(elt)) { + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } + + if (htmx.config.getCacheBusterParam && verb === 'get') { + filteredParameters['org.htmx.cache-buster'] = getRawAttribute(target, "id") || "true"; + } + + // behavior of anchors w/ empty href is to use the current URL + if (path == null || path === "") { + path = getDocument().location.href; + } + + + var requestAttrValues = getValuesForElement(elt, 'hx-request'); + + var eltIsBoosted = getInternalData(elt).boosted; + + var useUrlParams = htmx.config.methodsThatUseUrlParams.indexOf(verb) >= 0 + + var requestConfig = { + boosted: eltIsBoosted, + useUrlParams: useUrlParams, + parameters: filteredParameters, + unfilteredParameters: allParameters, + headers:headers, + target:target, + verb:verb, + errors:errors, + withCredentials: etc.credentials || requestAttrValues.credentials || htmx.config.withCredentials, + timeout: etc.timeout || requestAttrValues.timeout || htmx.config.timeout, + path:path, + triggeringEvent:event + }; + + if(!triggerEvent(elt, 'htmx:configRequest', requestConfig)){ + maybeCall(resolve); + endRequestLock(); + return promise; + } + + // copy out in case the object was overwritten + path = requestConfig.path; + verb = requestConfig.verb; + headers = requestConfig.headers; + filteredParameters = requestConfig.parameters; + errors = requestConfig.errors; + useUrlParams = requestConfig.useUrlParams; + + if(errors && errors.length > 0){ + triggerEvent(elt, 'htmx:validation:halted', requestConfig) + maybeCall(resolve); + endRequestLock(); + return promise; + } + + var splitPath = path.split("#"); + var pathNoAnchor = splitPath[0]; + var anchor = splitPath[1]; + + var finalPath = path + if (useUrlParams) { + finalPath = pathNoAnchor; + var values = Object.keys(filteredParameters).length !== 0; + if (values) { + if (finalPath.indexOf("?") < 0) { + finalPath += "?"; + } else { + finalPath += "&"; + } + finalPath += urlEncode(filteredParameters); + if (anchor) { + finalPath += "#" + anchor; + } + } + } + + if (!verifyPath(elt, finalPath, requestConfig)) { + triggerErrorEvent(elt, 'htmx:invalidPath', requestConfig) + maybeCall(reject); + return promise; + }; + + xhr.open(verb.toUpperCase(), finalPath, true); + xhr.overrideMimeType("text/html"); + xhr.withCredentials = requestConfig.withCredentials; + xhr.timeout = requestConfig.timeout; + + // request headers + if (requestAttrValues.noHeaders) { + // ignore all headers + } else { + for (var header in headers) { + if (headers.hasOwnProperty(header)) { + var headerValue = headers[header]; + safelySetHeaderValue(xhr, header, headerValue); + } + } + } + + var responseInfo = { + xhr: xhr, target: target, requestConfig: requestConfig, etc: etc, boosted: eltIsBoosted, + pathInfo: { + requestPath: path, + finalRequestPath: finalPath, + anchor: anchor + } + }; + + xhr.onload = function () { + try { + var hierarchy = hierarchyForElt(elt); + responseInfo.pathInfo.responsePath = getPathFromResponse(xhr); + responseHandler(elt, responseInfo); + removeRequestIndicators(indicators, disableElts); + triggerEvent(elt, 'htmx:afterRequest', responseInfo); + triggerEvent(elt, 'htmx:afterOnLoad', responseInfo); + // if the body no longer contains the element, trigger the event on the closest parent + // remaining in the DOM + if (!bodyContains(elt)) { + var secondaryTriggerElt = null; + while (hierarchy.length > 0 && secondaryTriggerElt == null) { + var parentEltInHierarchy = hierarchy.shift(); + if (bodyContains(parentEltInHierarchy)) { + secondaryTriggerElt = parentEltInHierarchy; + } + } + if (secondaryTriggerElt) { + triggerEvent(secondaryTriggerElt, 'htmx:afterRequest', responseInfo); + triggerEvent(secondaryTriggerElt, 'htmx:afterOnLoad', responseInfo); + } + } + maybeCall(resolve); + endRequestLock(); + } catch (e) { + triggerErrorEvent(elt, 'htmx:onLoadError', mergeObjects({error:e}, responseInfo)); + throw e; + } + } + xhr.onerror = function () { + removeRequestIndicators(indicators, disableElts); + triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); + triggerErrorEvent(elt, 'htmx:sendError', responseInfo); + maybeCall(reject); + endRequestLock(); + } + xhr.onabort = function() { + removeRequestIndicators(indicators, disableElts); + triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); + triggerErrorEvent(elt, 'htmx:sendAbort', responseInfo); + maybeCall(reject); + endRequestLock(); + } + xhr.ontimeout = function() { + removeRequestIndicators(indicators, disableElts); + triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); + triggerErrorEvent(elt, 'htmx:timeout', responseInfo); + maybeCall(reject); + endRequestLock(); + } + if(!triggerEvent(elt, 'htmx:beforeRequest', responseInfo)){ + maybeCall(resolve); + endRequestLock() + return promise + } + var indicators = addRequestIndicatorClasses(elt); + var disableElts = disableElements(elt); + + forEach(['loadstart', 'loadend', 'progress', 'abort'], function(eventName) { + forEach([xhr, xhr.upload], function (target) { + target.addEventListener(eventName, function(event){ + triggerEvent(elt, "htmx:xhr:" + eventName, { + lengthComputable:event.lengthComputable, + loaded:event.loaded, + total:event.total + }); + }) + }); + }); + triggerEvent(elt, 'htmx:beforeSend', responseInfo); + var params = useUrlParams ? null : encodeParamsForBody(xhr, elt, filteredParameters) + xhr.send(params); + return promise; + } + + function determineHistoryUpdates(elt, responseInfo) { + + var xhr = responseInfo.xhr; + + //=========================================== + // First consult response headers + //=========================================== + var pathFromHeaders = null; + var typeFromHeaders = null; + if (hasHeader(xhr,/HX-Push:/i)) { + pathFromHeaders = xhr.getResponseHeader("HX-Push"); + typeFromHeaders = "push"; + } else if (hasHeader(xhr,/HX-Push-Url:/i)) { + pathFromHeaders = xhr.getResponseHeader("HX-Push-Url"); + typeFromHeaders = "push"; + } else if (hasHeader(xhr,/HX-Replace-Url:/i)) { + pathFromHeaders = xhr.getResponseHeader("HX-Replace-Url"); + typeFromHeaders = "replace"; + } + + // if there was a response header, that has priority + if (pathFromHeaders) { + if (pathFromHeaders === "false") { + return {} + } else { + return { + type: typeFromHeaders, + path : pathFromHeaders + } + } + } + + //=========================================== + // Next resolve via DOM values + //=========================================== + var requestPath = responseInfo.pathInfo.finalRequestPath; + var responsePath = responseInfo.pathInfo.responsePath; + + var pushUrl = getClosestAttributeValue(elt, "hx-push-url"); + var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url"); + var elementIsBoosted = getInternalData(elt).boosted; + + var saveType = null; + var path = null; + + if (pushUrl) { + saveType = "push"; + path = pushUrl; + } else if (replaceUrl) { + saveType = "replace"; + path = replaceUrl; + } else if (elementIsBoosted) { + saveType = "push"; + path = responsePath || requestPath; // if there is no response path, go with the original request path + } + + if (path) { + // false indicates no push, return empty object + if (path === "false") { + return {}; + } + + // true indicates we want to follow wherever the server ended up sending us + if (path === "true") { + path = responsePath || requestPath; // if there is no response path, go with the original request path + } + + // restore any anchor associated with the request + if (responseInfo.pathInfo.anchor && + path.indexOf("#") === -1) { + path = path + "#" + responseInfo.pathInfo.anchor; + } + + return { + type:saveType, + path: path + } + } else { + return {}; + } + } + + function handleAjaxResponse(elt, responseInfo) { + var xhr = responseInfo.xhr; + var target = responseInfo.target; + var etc = responseInfo.etc; + var requestConfig = responseInfo.requestConfig; + + if (!triggerEvent(elt, 'htmx:beforeOnLoad', responseInfo)) return; + + if (hasHeader(xhr, /HX-Trigger:/i)) { + handleTrigger(xhr, "HX-Trigger", elt); + } + + if (hasHeader(xhr, /HX-Location:/i)) { + saveCurrentPageToHistory(); + var redirectPath = xhr.getResponseHeader("HX-Location"); + var swapSpec; + if (redirectPath.indexOf("{") === 0) { + swapSpec = parseJSON(redirectPath); + // what's the best way to throw an error if the user didn't include this + redirectPath = swapSpec['path']; + delete swapSpec['path']; + } + ajaxHelper('GET', redirectPath, swapSpec).then(function(){ + pushUrlIntoHistory(redirectPath); + }); + return; + } + + var shouldRefresh = hasHeader(xhr, /HX-Refresh:/i) && "true" === xhr.getResponseHeader("HX-Refresh"); + + if (hasHeader(xhr, /HX-Redirect:/i)) { + location.href = xhr.getResponseHeader("HX-Redirect"); + shouldRefresh && location.reload(); + return; + } + + if (shouldRefresh) { + location.reload(); + return; + } + + if (hasHeader(xhr,/HX-Retarget:/i)) { + responseInfo.target = getDocument().querySelector(xhr.getResponseHeader("HX-Retarget")); + } + + var historyUpdate = determineHistoryUpdates(elt, responseInfo); + + // by default htmx only swaps on 200 return codes and does not swap + // on 204 'No Content' + // this can be ovverriden by responding to the htmx:beforeSwap event and + // overriding the detail.shouldSwap property + var shouldSwap = xhr.status >= 200 && xhr.status < 400 && xhr.status !== 204; + var serverResponse = xhr.response; + var isError = xhr.status >= 400; + var ignoreTitle = htmx.config.ignoreTitle + var beforeSwapDetails = mergeObjects({shouldSwap: shouldSwap, serverResponse:serverResponse, isError:isError, ignoreTitle:ignoreTitle }, responseInfo); + if (!triggerEvent(target, 'htmx:beforeSwap', beforeSwapDetails)) return; + + target = beforeSwapDetails.target; // allow re-targeting + serverResponse = beforeSwapDetails.serverResponse; // allow updating content + isError = beforeSwapDetails.isError; // allow updating error + ignoreTitle = beforeSwapDetails.ignoreTitle; // allow updating ignoring title + + responseInfo.target = target; // Make updated target available to response events + responseInfo.failed = isError; // Make failed property available to response events + responseInfo.successful = !isError; // Make successful property available to response events + + if (beforeSwapDetails.shouldSwap) { + if (xhr.status === 286) { + cancelPolling(elt); + } + + withExtensions(elt, function (extension) { + serverResponse = extension.transformResponse(serverResponse, xhr, elt); + }); + + // Save current page if there will be a history update + if (historyUpdate.type) { + saveCurrentPageToHistory(); + } + + var swapOverride = etc.swapOverride; + if (hasHeader(xhr,/HX-Reswap:/i)) { + swapOverride = xhr.getResponseHeader("HX-Reswap"); + } + var swapSpec = getSwapSpecification(elt, swapOverride); + + if (swapSpec.hasOwnProperty('ignoreTitle')) { + ignoreTitle = swapSpec.ignoreTitle; + } + + target.classList.add(htmx.config.swappingClass); + + // optional transition API promise callbacks + var settleResolve = null; + var settleReject = null; + + var doSwap = function () { + try { + var activeElt = document.activeElement; + var selectionInfo = {}; + try { + selectionInfo = { + elt: activeElt, + // @ts-ignore + start: activeElt ? activeElt.selectionStart : null, + // @ts-ignore + end: activeElt ? activeElt.selectionEnd : null + }; + } catch (e) { + // safari issue - see https://github.com/microsoft/playwright/issues/5894 + } + + var selectOverride; + if (hasHeader(xhr, /HX-Reselect:/i)) { + selectOverride = xhr.getResponseHeader("HX-Reselect"); + } + + var settleInfo = makeSettleInfo(target); + selectAndSwap(swapSpec.swapStyle, target, elt, serverResponse, settleInfo, selectOverride); + + if (selectionInfo.elt && + !bodyContains(selectionInfo.elt) && + getRawAttribute(selectionInfo.elt, "id")) { + var newActiveElt = document.getElementById(getRawAttribute(selectionInfo.elt, "id")); + var focusOptions = { preventScroll: swapSpec.focusScroll !== undefined ? !swapSpec.focusScroll : !htmx.config.defaultFocusScroll }; + if (newActiveElt) { + // @ts-ignore + if (selectionInfo.start && newActiveElt.setSelectionRange) { + // @ts-ignore + try { + newActiveElt.setSelectionRange(selectionInfo.start, selectionInfo.end); + } catch (e) { + // the setSelectionRange method is present on fields that don't support it, so just let this fail + } + } + newActiveElt.focus(focusOptions); + } + } + + target.classList.remove(htmx.config.swappingClass); + forEach(settleInfo.elts, function (elt) { + if (elt.classList) { + elt.classList.add(htmx.config.settlingClass); + } + triggerEvent(elt, 'htmx:afterSwap', responseInfo); + }); + + if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) { + var finalElt = elt; + if (!bodyContains(elt)) { + finalElt = getDocument().body; + } + handleTrigger(xhr, "HX-Trigger-After-Swap", finalElt); + } + + var doSettle = function () { + forEach(settleInfo.tasks, function (task) { + task.call(); + }); + forEach(settleInfo.elts, function (elt) { + if (elt.classList) { + elt.classList.remove(htmx.config.settlingClass); + } + triggerEvent(elt, 'htmx:afterSettle', responseInfo); + }); + + // if we need to save history, do so + if (historyUpdate.type) { + triggerEvent(getDocument().body, 'htmx:beforeHistoryUpdate', mergeObjects({ history: historyUpdate }, responseInfo)); + if (historyUpdate.type === "push") { + pushUrlIntoHistory(historyUpdate.path); + triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: historyUpdate.path}); + } else { + replaceUrlInHistory(historyUpdate.path); + triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: historyUpdate.path}); + } + } + if (responseInfo.pathInfo.anchor) { + var anchorTarget = getDocument().getElementById(responseInfo.pathInfo.anchor); + if(anchorTarget) { + anchorTarget.scrollIntoView({block:'start', behavior: "auto"}); + } + } + + if(settleInfo.title && !ignoreTitle) { + var titleElt = find("title"); + if(titleElt) { + titleElt.innerHTML = settleInfo.title; + } else { + window.document.title = settleInfo.title; + } + } + + updateScrollState(settleInfo.elts, swapSpec); + + if (hasHeader(xhr, /HX-Trigger-After-Settle:/i)) { + var finalElt = elt; + if (!bodyContains(elt)) { + finalElt = getDocument().body; + } + handleTrigger(xhr, "HX-Trigger-After-Settle", finalElt); + } + maybeCall(settleResolve); + } + + if (swapSpec.settleDelay > 0) { + setTimeout(doSettle, swapSpec.settleDelay) + } else { + doSettle(); + } + } catch (e) { + triggerErrorEvent(elt, 'htmx:swapError', responseInfo); + maybeCall(settleReject); + throw e; + } + }; + + var shouldTransition = htmx.config.globalViewTransitions + if(swapSpec.hasOwnProperty('transition')){ + shouldTransition = swapSpec.transition; + } + + if(shouldTransition && + triggerEvent(elt, 'htmx:beforeTransition', responseInfo) && + typeof Promise !== "undefined" && document.startViewTransition){ + var settlePromise = new Promise(function (_resolve, _reject) { + settleResolve = _resolve; + settleReject = _reject; + }); + // wrap the original doSwap() in a call to startViewTransition() + var innerDoSwap = doSwap; + doSwap = function() { + document.startViewTransition(function () { + innerDoSwap(); + return settlePromise; + }); + } + } + + + if (swapSpec.swapDelay > 0) { + setTimeout(doSwap, swapSpec.swapDelay) + } else { + doSwap(); + } + } + if (isError) { + triggerErrorEvent(elt, 'htmx:responseError', mergeObjects({error: "Response Status Error Code " + xhr.status + " from " + responseInfo.pathInfo.requestPath}, responseInfo)); + } + } + + //==================================================================== + // Extensions API + //==================================================================== + + /** @type {Object} */ + var extensions = {}; + + /** + * extensionBase defines the default functions for all extensions. + * @returns {import("./htmx").HtmxExtension} + */ + function extensionBase() { + return { + init: function(api) {return null;}, + onEvent : function(name, evt) {return true;}, + transformResponse : function(text, xhr, elt) {return text;}, + isInlineSwap : function(swapStyle) {return false;}, + handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;}, + encodeParameters : function(xhr, parameters, elt) {return null;} + } + } + + /** + * defineExtension initializes the extension and adds it to the htmx registry + * + * @param {string} name + * @param {import("./htmx").HtmxExtension} extension + */ + function defineExtension(name, extension) { + if(extension.init) { + extension.init(internalAPI) + } + extensions[name] = mergeObjects(extensionBase(), extension); + } + + /** + * removeExtension removes an extension from the htmx registry + * + * @param {string} name + */ + function removeExtension(name) { + delete extensions[name]; + } + + /** + * getExtensions searches up the DOM tree to return all extensions that can be applied to a given element + * + * @param {HTMLElement} elt + * @param {import("./htmx").HtmxExtension[]=} extensionsToReturn + * @param {import("./htmx").HtmxExtension[]=} extensionsToIgnore + */ + function getExtensions(elt, extensionsToReturn, extensionsToIgnore) { + + if (elt == undefined) { + return extensionsToReturn; + } + if (extensionsToReturn == undefined) { + extensionsToReturn = []; + } + if (extensionsToIgnore == undefined) { + extensionsToIgnore = []; + } + var extensionsForElement = getAttributeValue(elt, "hx-ext"); + if (extensionsForElement) { + forEach(extensionsForElement.split(","), function(extensionName){ + extensionName = extensionName.replace(/ /g, ''); + if (extensionName.slice(0, 7) == "ignore:") { + extensionsToIgnore.push(extensionName.slice(7)); + return; + } + if (extensionsToIgnore.indexOf(extensionName) < 0) { + var extension = extensions[extensionName]; + if (extension && extensionsToReturn.indexOf(extension) < 0) { + extensionsToReturn.push(extension); + } + } + }); + } + return getExtensions(parentElt(elt), extensionsToReturn, extensionsToIgnore); + } + + //==================================================================== + // Initialization + //==================================================================== + var isReady = false + getDocument().addEventListener('DOMContentLoaded', function() { + isReady = true + }) + + /** + * Execute a function now if DOMContentLoaded has fired, otherwise listen for it. + * + * This function uses isReady because there is no realiable way to ask the browswer whether + * the DOMContentLoaded event has already been fired; there's a gap between DOMContentLoaded + * firing and readystate=complete. + */ + function ready(fn) { + // Checking readyState here is a failsafe in case the htmx script tag entered the DOM by + // some means other than the initial page load. + if (isReady || getDocument().readyState === 'complete') { + fn(); + } else { + getDocument().addEventListener('DOMContentLoaded', fn); + } + } + + function insertIndicatorStyles() { + if (htmx.config.includeIndicatorStyles !== false) { + getDocument().head.insertAdjacentHTML("beforeend", + ""); + } + } + + function getMetaConfig() { + var element = getDocument().querySelector('meta[name="htmx-config"]'); + if (element) { + // @ts-ignore + return parseJSON(element.content); + } else { + return null; + } + } + + function mergeMetaConfig() { + var metaConfig = getMetaConfig(); + if (metaConfig) { + htmx.config = mergeObjects(htmx.config , metaConfig) + } + } + + // initialize the document + ready(function () { + mergeMetaConfig(); + insertIndicatorStyles(); + var body = getDocument().body; + processNode(body); + var restoredElts = getDocument().querySelectorAll( + "[hx-trigger='restored'],[data-hx-trigger='restored']" + ); + body.addEventListener("htmx:abort", function (evt) { + var target = evt.target; + var internalData = getInternalData(target); + if (internalData && internalData.xhr) { + internalData.xhr.abort(); + } + }); + var originalPopstate = window.onpopstate; + window.onpopstate = function (event) { + if (event.state && event.state.htmx) { + restoreHistory(); + forEach(restoredElts, function(elt){ + triggerEvent(elt, 'htmx:restored', { + 'document': getDocument(), + 'triggerEvent': triggerEvent + }); + }); + } else { + if (originalPopstate) { + originalPopstate(event); + } + } + }; + setTimeout(function () { + triggerEvent(body, 'htmx:load', {}); // give ready handlers a chance to load up before firing this event + body = null; // kill reference for gc + }, 0); + }) + + return htmx; + } +)() +})); diff --git a/public/js/htmx/htmx.min.js b/public/js/htmx/htmx.min.js new file mode 100644 index 0000000..daab078 --- /dev/null +++ b/public/js/htmx/htmx.min.js @@ -0,0 +1 @@ +(function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var Y={onLoad:t,process:Dt,on:Z,off:K,trigger:fe,ajax:Cr,find:E,findAll:f,closest:d,values:function(e,t){var r=or(e,t||"post");return r.values},remove:B,addClass:F,removeClass:n,toggleClass:V,takeClass:j,defineExtension:Ar,removeExtension:Nr,logAll:X,logNone:U,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"],selfRequestsOnly:false,scrollIntoViewOnBoost:true},parseInterval:v,_:e,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=Y.config.wsBinaryType;return t},version:"1.9.7"};var r={addTriggerHandler:St,bodyContains:oe,canAccessLocalStorage:M,findThisElement:ve,filterValues:cr,hasAttribute:o,getAttributeValue:ee,getClosestAttributeValue:re,getClosestMatch:c,getExpressionVars:wr,getHeaders:fr,getInputValues:or,getInternalData:ie,getSwapSpecification:dr,getTriggerSpecs:Ze,getTarget:ge,makeFragment:l,mergeObjects:se,makeSettleInfo:T,oobSwap:ye,querySelectorExt:le,selectAndSwap:Ue,settleImmediately:Jt,shouldCancel:tt,triggerEvent:fe,triggerErrorEvent:ue,withExtensions:C};var b=["get","post","put","delete","patch"];var w=b.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");function v(e){if(e==undefined){return undefined}if(e.slice(-2)=="ms"){return parseFloat(e.slice(0,-2))||undefined}if(e.slice(-1)=="s"){return parseFloat(e.slice(0,-1))*1e3||undefined}if(e.slice(-1)=="m"){return parseFloat(e.slice(0,-1))*1e3*60||undefined}return parseFloat(e)||undefined}function Q(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function ee(e,t){return Q(e,t)||Q(e,"data-"+t)}function u(e){return e.parentElement}function te(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function R(e,t,r){var n=ee(t,r);var i=ee(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function re(t,r){var n=null;c(t,function(e){return n=R(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function q(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function i(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=te().createDocumentFragment()}return i}function H(e){return e.match(/",0);return r.querySelector("template").content}else{var n=q(e);switch(n){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return i(""+e+"
",1);case"col":return i(""+e+"
",2);case"tr":return i(""+e+"
",2);case"td":case"th":return i(""+e+"
",3);case"script":case"style":return i("
"+e+"
",1);default:return i(e,0)}}}function ne(e){if(e){e()}}function L(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function A(e){return L(e,"Function")}function N(e){return L(e,"Object")}function ie(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function I(e){var t=[];if(e){for(var r=0;r=0}function oe(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return te().body.contains(e.getRootNode().host)}else{return te().body.contains(e)}}function P(e){return e.trim().split(/\s+/)}function se(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function S(e){try{return JSON.parse(e)}catch(e){y(e);return null}}function M(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function D(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!t.match("^/$")){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function e(e){return xr(te().body,function(){return eval(e)})}function t(t){var e=Y.on("htmx:load",function(e){t(e.detail.elt)});return e}function X(){Y.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function U(){Y.logger=null}function E(e,t){if(t){return e.querySelector(t)}else{return E(te(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(te(),e)}}function B(e,t){e=s(e);if(t){setTimeout(function(){B(e);e=null},t)}else{e.parentElement.removeChild(e)}}function F(e,t,r){e=s(e);if(r){setTimeout(function(){F(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=s(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function V(e,t){e=s(e);e.classList.toggle(t)}function j(e,t){e=s(e);ae(e.parentElement.children,function(e){n(e,t)});F(e,t)}function d(e,t){e=s(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function g(e,t){return e.substring(0,t.length)===t}function _(e,t){return e.substring(e.length-t.length)===t}function z(e){var t=e.trim();if(g(t,"<")&&_(t,"/>")){return t.substring(1,t.length-2)}else{return t}}function W(e,t){if(t.indexOf("closest ")===0){return[d(e,z(t.substr(8)))]}else if(t.indexOf("find ")===0){return[E(e,z(t.substr(5)))]}else if(t==="next"){return[e.nextElementSibling]}else if(t.indexOf("next ")===0){return[$(e,z(t.substr(5)))]}else if(t==="previous"){return[e.previousElementSibling]}else if(t.indexOf("previous ")===0){return[G(e,z(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return te().querySelectorAll(z(t))}}var $=function(e,t){var r=te().querySelectorAll(t);for(var n=0;n=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function le(e,t){if(t){return W(e,t)[0]}else{return W(te().body,e)[0]}}function s(e){if(L(e,"String")){return E(e)}else{return e}}function J(e,t,r){if(A(t)){return{target:te().body,event:e,listener:t}}else{return{target:s(e),event:t,listener:r}}}function Z(t,r,n){Pr(function(){var e=J(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=A(r);return e?r:n}function K(t,r,n){Pr(function(){var e=J(t,r,n);e.target.removeEventListener(e.event,e.listener)});return A(r)?r:n}var he=te().createElement("output");function de(e,t){var r=re(e,t);if(r){if(r==="this"){return[ve(e,t)]}else{var n=W(e,r);if(n.length===0){y('The selector "'+r+'" on '+t+" returned no matches!");return[he]}else{return n}}}}function ve(e,t){return c(e,function(e){return ee(e,t)!=null})}function ge(e){var t=re(e,"hx-target");if(t){if(t==="this"){return ve(e,"hx-target")}else{return le(e,t)}}else{var r=ie(e);if(r.boosted){return te().body}else{return e}}}function me(e){var t=Y.config.attributesToSettle;for(var r=0;r0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=te().querySelectorAll(t);if(r){ae(r,function(e){var t;var r=i.cloneNode(true);t=te().createDocumentFragment();t.appendChild(r);if(!xe(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!fe(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){De(o,e,e,t,a)}ae(a.elts,function(e){fe(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);ue(te().body,"htmx:oobErrorNoTarget",{content:i})}return e}function be(e,t,r){var n=re(e,"hx-select-oob");if(n){var i=n.split(",");for(let e=0;e0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();pe(e,i);s.tasks.push(function(){pe(e,a)})}}})}function Ee(e){return function(){n(e,Y.config.addedClass);Dt(e);Ct(e);Ce(e);fe(e,"htmx:load")}}function Ce(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){Se(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;F(i,Y.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Ee(i))}}}function Te(e,t){var r=0;while(r-1){var t=e.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,"");var r=t.match(/]*>|>)([\s\S]*?)<\/title>/im);if(r){return r[2]}}}function Ue(e,t,r,n,i,a){i.title=Xe(n);var o=l(n);if(o){be(r,o,i);o=Me(r,o,a);we(o);return De(e,r,t,o,i)}}function Be(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=S(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!N(o)){o={value:o}}fe(r,a,o)}}}else{var s=n.split(",");for(var l=0;l0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=xr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){ue(te().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if($e(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function x(e,t){var r="";while(e.length>0&&!e[0].match(t)){r+=e.shift()}return r}var Je="input, textarea, select";function Ze(e){var t=ee(e,"hx-trigger");var r=[];if(t){var n=We(t);do{x(n,ze);var i=n.length;var a=x(n,/[,\[\s]/);if(a!==""){if(a==="every"){var o={trigger:"every"};x(n,ze);o.pollInterval=v(x(n,/[,\[\s]/));x(n,ze);var s=Ge(e,n,"event");if(s){o.eventFilter=s}r.push(o)}else if(a.indexOf("sse:")===0){r.push({trigger:"sse",sseEvent:a.substr(4)})}else{var l={trigger:a};var s=Ge(e,n,"event");if(s){l.eventFilter=s}while(n.length>0&&n[0]!==","){x(n,ze);var u=n.shift();if(u==="changed"){l.changed=true}else if(u==="once"){l.once=true}else if(u==="consume"){l.consume=true}else if(u==="delay"&&n[0]===":"){n.shift();l.delay=v(x(n,p))}else if(u==="from"&&n[0]===":"){n.shift();var f=x(n,p);if(f==="closest"||f==="find"||f==="next"||f==="previous"){n.shift();var c=x(n,p);if(c.length>0){f+=" "+c}}l.from=f}else if(u==="target"&&n[0]===":"){n.shift();l.target=x(n,p)}else if(u==="throttle"&&n[0]===":"){n.shift();l.throttle=v(x(n,p))}else if(u==="queue"&&n[0]===":"){n.shift();l.queue=x(n,p)}else if((u==="root"||u==="threshold")&&n[0]===":"){n.shift();l[u]=x(n,p)}else{ue(e,"htmx:syntax:error",{token:n.shift()})}}r.push(l)}}if(n.length===i){ue(e,"htmx:syntax:error",{token:n.shift()})}x(n,ze)}while(n[0]===","&&n.shift())}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"], input[type="submit"]')){return[{trigger:"click"}]}else if(h(e,Je)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function Ke(e){ie(e).cancelled=true}function Ye(e,t,r){var n=ie(e);n.timeout=setTimeout(function(){if(oe(e)&&n.cancelled!==true){if(!nt(r,e,Ut("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}Ye(e,t,r)}},r.pollInterval)}function Qe(e){return location.hostname===e.hostname&&Q(e,"href")&&Q(e,"href").indexOf("#")!==0}function et(t,r,e){if(t.tagName==="A"&&Qe(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=Q(t,"href")}else{var a=Q(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=Q(t,"action")}e.forEach(function(e){it(t,function(e,t){if(d(e,Y.config.disableSelector)){m(e);return}ce(n,i,e,t)},r,e,true)})}}function tt(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&d(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function rt(e,t){return ie(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function nt(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){ue(te().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function it(a,o,e,s,l){var u=ie(a);var t;if(s.from){t=W(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ie(e);t.lastValue=e.value})}ae(t,function(n){var i=function(e){if(!oe(a)){n.removeEventListener(s.trigger,i);return}if(rt(a,e)){return}if(l||tt(e,a)){e.preventDefault()}if(nt(s,a,e)){return}var t=ie(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!h(e.target,s.target)){return}}if(s.once){if(u.triggeredOnce){return}else{u.triggeredOnce=true}}if(s.changed){var r=ie(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{fe(a,"htmx:trigger");o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var at=false;var ot=null;function st(){if(!ot){ot=function(){at=true};window.addEventListener("scroll",ot);setInterval(function(){if(at){at=false;ae(te().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){lt(e)})}},200)}}function lt(t){if(!o(t,"data-hx-revealed")&&k(t)){t.setAttribute("data-hx-revealed","true");var e=ie(t);if(e.initHash){fe(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){fe(t,"revealed")},{once:true})}}}function ut(e,t,r){var n=P(r);for(var i=0;i=0){var t=dt(n);setTimeout(function(){ft(s,r,n+1)},t)}};t.onopen=function(e){n=0};ie(s).webSocket=t;t.addEventListener("message",function(e){if(ct(s)){return}var t=e.data;C(s,function(e){t=e.transformResponse(t,null,s)});var r=T(s);var n=l(t);var i=I(n.children);for(var a=0;a0){fe(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(tt(e,u)){e.preventDefault()}})}else{ue(u,"htmx:noWebSocketSourceError")}}function dt(e){var t=Y.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}y('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function vt(e,t,r){var n=P(r);for(var i=0;i0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=Nt(o)}for(var l in r){It(e,l,r[l])}}}function Pt(t){Re(t);for(var e=0;eY.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){ue(te().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function _t(e){if(!M()){return null}e=D(e);var t=S(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r=200&&this.status<400){fe(te().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Vt();var r=T(t);var n=Xe(this.response);if(n){var i=E("title");if(i){i.innerHTML=n}else{window.document.title=n}}Pe(t,e,r);Jt(r.tasks);Ft=a;fe(te().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{ue(te().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function Kt(e){Wt();e=e||location.pathname+location.search;var t=_t(e);if(t){var r=l(t.content);var n=Vt();var i=T(n);Pe(n,r,i);Jt(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Ft=e;fe(te().body,"htmx:historyRestore",{path:e,item:t})}else{if(Y.config.refreshOnHistoryMiss){window.location.reload(true)}else{Zt(e)}}}function Yt(e){var t=de(e,"hx-indicator");if(t==null){t=[e]}ae(t,function(e){var t=ie(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,Y.config.requestClass)});return t}function Qt(e){var t=de(e,"hx-disabled-elt");if(t==null){t=[]}ae(t,function(e){var t=ie(e);t.requestCount=(t.requestCount||0)+1;e.setAttribute("disabled","")});return t}function er(e,t){ae(e,function(e){var t=ie(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,Y.config.requestClass)}});ae(t,function(e){var t=ie(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.removeAttribute("disabled")}})}function tr(e,t){for(var r=0;r=0}function dr(e,t){var r=t?t:re(e,"hx-swap");var n={swapStyle:ie(e).boosted?"innerHTML":Y.config.defaultSwapStyle,swapDelay:Y.config.defaultSwapDelay,settleDelay:Y.config.defaultSettleDelay};if(Y.config.scrollIntoViewOnBoost&&ie(e).boosted&&!hr(e)){n["show"]="top"}if(r){var i=P(r);if(i.length>0){for(var a=0;a0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}else if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}else if(o.indexOf("focus-scroll:")===0){var d=o.substr("focus-scroll:".length);n["focusScroll"]=d=="true"}else if(a==0){n["swapStyle"]=o}else{y("Unknown modifier in hx-swap: "+o)}}}}return n}function vr(e){return re(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&Q(e,"enctype")==="multipart/form-data"}function gr(t,r,n){var i=null;C(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(vr(r)){return ur(n)}else{return lr(n)}}}function T(e){return{tasks:[],elts:[e]}}function mr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=le(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=le(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:Y.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:Y.config.scrollBehavior})}}}function pr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=ee(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=xr(e,function(){return Function("return ("+a+")")()},{})}else{s=S(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return pr(u(e),t,r,n)}function xr(e,t,r){if(Y.config.allowEval){return t()}else{ue(e,"htmx:evalDisallowedError");return r}}function yr(e,t){return pr(e,"hx-vars",true,t)}function br(e,t){return pr(e,"hx-vals",false,t)}function wr(e){return se(yr(e),br(e))}function Sr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function Er(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){ue(te().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function O(e,t){return e.getAllResponseHeaders().match(t)}function Cr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||L(r,"String")){return ce(e,t,null,null,{targetOverride:s(r),returnPromise:true})}else{return ce(e,t,s(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:s(r.target),swapOverride:r.swap,returnPromise:true})}}else{return ce(e,t,null,null,{returnPromise:true})}}function Tr(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function Or(e,t,r){var n;var i;if(typeof URL==="function"){i=new URL(t,document.location.href);var a=document.location.origin;n=a===i.origin}else{i=t;n=g(t,document.location.origin)}if(Y.config.selfRequestsOnly){if(!n){return false}}return fe(e,"htmx:validateUrl",se({url:i,sameHost:n},r))}function ce(t,r,n,i,a,e){var o=null;var s=null;a=a!=null?a:{};if(a.returnPromise&&typeof Promise!=="undefined"){var l=new Promise(function(e,t){o=e;s=t})}if(n==null){n=te().body}var M=a.handler||qr;if(!oe(n)){ne(o);return l}var u=a.targetOverride||ge(n);if(u==null||u==he){ue(n,"htmx:targetError",{target:ee(n,"hx-target")});ne(s);return l}var f=ie(n);var c=f.lastButtonClicked;if(c){var h=Q(c,"formaction");if(h!=null){r=h}var d=Q(c,"formmethod");if(d!=null){if(d.toLowerCase()!=="dialog"){t=d}}}var v=re(n,"hx-confirm");if(e===undefined){var D=function(e){return ce(t,r,n,i,a,!!e)};var X={target:u,elt:n,path:r,verb:t,triggeringEvent:i,etc:a,issueRequest:D,question:v};if(fe(n,"htmx:confirm",X)===false){ne(o);return l}}var g=n;var m=re(n,"hx-sync");var p=null;var x=false;if(m){var U=m.split(":");var B=U[0].trim();if(B==="this"){g=ve(n,"hx-sync")}else{g=le(n,B)}m=(U[1]||"drop").trim();f=ie(g);if(m==="drop"&&f.xhr&&f.abortable!==true){ne(o);return l}else if(m==="abort"){if(f.xhr){ne(o);return l}else{x=true}}else if(m==="replace"){fe(g,"htmx:abort")}else if(m.indexOf("queue")===0){var F=m.split(" ");p=(F[1]||"last").trim()}}if(f.xhr){if(f.abortable){fe(g,"htmx:abort")}else{if(p==null){if(i){var y=ie(i);if(y&&y.triggerSpec&&y.triggerSpec.queue){p=y.triggerSpec.queue}}if(p==null){p="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(p==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){ce(t,r,n,i,a)})}else if(p==="all"){f.queuedRequests.push(function(){ce(t,r,n,i,a)})}else if(p==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){ce(t,r,n,i,a)})}ne(o);return l}}var b=new XMLHttpRequest;f.xhr=b;f.abortable=x;var w=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var V=re(n,"hx-prompt");if(V){var S=prompt(V);if(S===null||!fe(n,"htmx:prompt",{prompt:S,target:u})){ne(o);w();return l}}if(v&&!e){if(!confirm(v)){ne(o);w();return l}}var E=fr(n,u,S);if(a.headers){E=se(E,a.headers)}var j=or(n,t);var C=j.errors;var T=j.values;if(a.values){T=se(T,a.values)}var _=wr(n);var z=se(T,_);var O=cr(z,n);if(t!=="get"&&!vr(n)){E["Content-Type"]="application/x-www-form-urlencoded"}if(Y.config.getCacheBusterParam&&t==="get"){O["org.htmx.cache-buster"]=Q(u,"id")||"true"}if(r==null||r===""){r=te().location.href}var R=pr(n,"hx-request");var W=ie(n).boosted;var q=Y.config.methodsThatUseUrlParams.indexOf(t)>=0;var H={boosted:W,useUrlParams:q,parameters:O,unfilteredParameters:z,headers:E,target:u,verb:t,errors:C,withCredentials:a.credentials||R.credentials||Y.config.withCredentials,timeout:a.timeout||R.timeout||Y.config.timeout,path:r,triggeringEvent:i};if(!fe(n,"htmx:configRequest",H)){ne(o);w();return l}r=H.path;t=H.verb;E=H.headers;O=H.parameters;C=H.errors;q=H.useUrlParams;if(C&&C.length>0){fe(n,"htmx:validation:halted",H);ne(o);w();return l}var $=r.split("#");var G=$[0];var L=$[1];var A=r;if(q){A=G;var J=Object.keys(O).length!==0;if(J){if(A.indexOf("?")<0){A+="?"}else{A+="&"}A+=lr(O);if(L){A+="#"+L}}}if(!Or(n,A,H)){ue(n,"htmx:invalidPath",H);ne(s);return l}b.open(t.toUpperCase(),A,true);b.overrideMimeType("text/html");b.withCredentials=H.withCredentials;b.timeout=H.timeout;if(R.noHeaders){}else{for(var N in E){if(E.hasOwnProperty(N)){var Z=E[N];Sr(b,N,Z)}}}var I={xhr:b,target:u,requestConfig:H,etc:a,boosted:W,pathInfo:{requestPath:r,finalRequestPath:A,anchor:L}};b.onload=function(){try{var e=Tr(n);I.pathInfo.responsePath=Er(b);M(n,I);er(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:afterOnLoad",I);if(!oe(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(oe(r)){t=r}}if(t){fe(t,"htmx:afterRequest",I);fe(t,"htmx:afterOnLoad",I)}}ne(o);w()}catch(e){ue(n,"htmx:onLoadError",se({error:e},I));throw e}};b.onerror=function(){er(k,P);ue(n,"htmx:afterRequest",I);ue(n,"htmx:sendError",I);ne(s);w()};b.onabort=function(){er(k,P);ue(n,"htmx:afterRequest",I);ue(n,"htmx:sendAbort",I);ne(s);w()};b.ontimeout=function(){er(k,P);ue(n,"htmx:afterRequest",I);ue(n,"htmx:timeout",I);ne(s);w()};if(!fe(n,"htmx:beforeRequest",I)){ne(o);w();return l}var k=Yt(n);var P=Qt(n);ae(["loadstart","loadend","progress","abort"],function(t){ae([b,b.upload],function(e){e.addEventListener(t,function(e){fe(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});fe(n,"htmx:beforeSend",I);var K=q?null:gr(b,n,O);b.send(K);return l}function Rr(e,t){var r=t.xhr;var n=null;var i=null;if(O(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(O(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(O(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=re(e,"hx-push-url");var l=re(e,"hx-replace-url");var u=ie(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function qr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;var t=u.requestConfig;if(!fe(l,"htmx:beforeOnLoad",u))return;if(O(f,/HX-Trigger:/i)){Be(f,"HX-Trigger",l)}if(O(f,/HX-Location:/i)){Wt();var r=f.getResponseHeader("HX-Location");var h;if(r.indexOf("{")===0){h=S(r);r=h["path"];delete h["path"]}Cr("GET",r,h).then(function(){$t(r)});return}var n=O(f,/HX-Refresh:/i)&&"true"===f.getResponseHeader("HX-Refresh");if(O(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");n&&location.reload();return}if(n){location.reload();return}if(O(f,/HX-Retarget:/i)){u.target=te().querySelector(f.getResponseHeader("HX-Retarget"))}var d=Rr(l,u);var i=f.status>=200&&f.status<400&&f.status!==204;var v=f.response;var a=f.status>=400;var g=Y.config.ignoreTitle;var o=se({shouldSwap:i,serverResponse:v,isError:a,ignoreTitle:g},u);if(!fe(c,"htmx:beforeSwap",o))return;c=o.target;v=o.serverResponse;a=o.isError;g=o.ignoreTitle;u.target=c;u.failed=a;u.successful=!a;if(o.shouldSwap){if(f.status===286){Ke(l)}C(l,function(e){v=e.transformResponse(v,f,l)});if(d.type){Wt()}var s=e.swapOverride;if(O(f,/HX-Reswap:/i)){s=f.getResponseHeader("HX-Reswap")}var h=dr(l,s);if(h.hasOwnProperty("ignoreTitle")){g=h.ignoreTitle}c.classList.add(Y.config.swappingClass);var m=null;var p=null;var x=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(O(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}var n=T(c);Ue(h.swapStyle,c,l,v,n,r);if(t.elt&&!oe(t.elt)&&Q(t.elt,"id")){var i=document.getElementById(Q(t.elt,"id"));var a={preventScroll:h.focusScroll!==undefined?!h.focusScroll:!Y.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(Y.config.swappingClass);ae(n.elts,function(e){if(e.classList){e.classList.add(Y.config.settlingClass)}fe(e,"htmx:afterSwap",u)});if(O(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!oe(l)){o=te().body}Be(f,"HX-Trigger-After-Swap",o)}var s=function(){ae(n.tasks,function(e){e.call()});ae(n.elts,function(e){if(e.classList){e.classList.remove(Y.config.settlingClass)}fe(e,"htmx:afterSettle",u)});if(d.type){fe(te().body,"htmx:beforeHistoryUpdate",se({history:d},u));if(d.type==="push"){$t(d.path);fe(te().body,"htmx:pushedIntoHistory",{path:d.path})}else{Gt(d.path);fe(te().body,"htmx:replacedInHistory",{path:d.path})}}if(u.pathInfo.anchor){var e=te().getElementById(u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title&&!g){var t=E("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}mr(n.elts,h);if(O(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!oe(l)){r=te().body}Be(f,"HX-Trigger-After-Settle",r)}ne(m)};if(h.settleDelay>0){setTimeout(s,h.settleDelay)}else{s()}}catch(e){ue(l,"htmx:swapError",u);ne(p);throw e}};var y=Y.config.globalViewTransitions;if(h.hasOwnProperty("transition")){y=h.transition}if(y&&fe(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var b=new Promise(function(e,t){m=e;p=t});var w=x;x=function(){document.startViewTransition(function(){w();return b})}}if(h.swapDelay>0){setTimeout(x,h.swapDelay)}else{x()}}if(a){ue(l,"htmx:responseError",se({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Hr={};function Lr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Ar(e,t){if(t.init){t.init(r)}Hr[e]=se(Lr(),t)}function Nr(e){delete Hr[e]}function Ir(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=ee(e,"hx-ext");if(t){ae(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Hr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Ir(u(e),r,n)}var kr=false;te().addEventListener("DOMContentLoaded",function(){kr=true});function Pr(e){if(kr||te().readyState==="complete"){e()}else{te().addEventListener("DOMContentLoaded",e)}}function Mr(){if(Y.config.includeIndicatorStyles!==false){te().head.insertAdjacentHTML("beforeend","")}}function Dr(){var e=te().querySelector('meta[name="htmx-config"]');if(e){return S(e.content)}else{return null}}function Xr(){var e=Dr();if(e){Y.config=se(Y.config,e)}}Pr(function(){Xr();Mr();var e=te().body;Dt(e);var t=te().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ie(t);if(r&&r.xhr){r.xhr.abort()}});var r=window.onpopstate;window.onpopstate=function(e){if(e.state&&e.state.htmx){Kt();ae(t,function(e){fe(e,"htmx:restored",{document:te(),triggerEvent:fe})})}else{if(r){r(e)}}};setTimeout(function(){fe(e,"htmx:load",{});e=null},0)});return Y}()}); \ No newline at end of file diff --git a/public/js/htmx/htmx.min.js.gz b/public/js/htmx/htmx.min.js.gz new file mode 100644 index 0000000..7f7945c Binary files /dev/null and b/public/js/htmx/htmx.min.js.gz differ diff --git a/public/js/htmx/htmx.test.ts b/public/js/htmx/htmx.test.ts new file mode 100644 index 0000000..71ed2d2 --- /dev/null +++ b/public/js/htmx/htmx.test.ts @@ -0,0 +1,96 @@ +import htmx from "./htmx"; + +// add the class 'myClass' to the element with the id 'demo' +htmx.addClass(htmx.find("#demo"), "myClass"); + +// issue a GET to /example and put the response HTML into #myDiv +htmx.ajax("GET", "/example", "#myDiv"); + +// find the closest enclosing div of the element with the id 'demo' +htmx.closest(htmx.find("#demo"), "div"); + +// update the history cache size to 30 +htmx.config.historyCacheSize = 30; + +// override SSE event sources to not use credentials +htmx.createEventSource = function (url) { + return new EventSource(url, { withCredentials: false }); +}; + +// override WebSocket to use a specific protocol +htmx.createWebSocket = function (url) { + return new WebSocket(url, ["wss"]); +}; + +// defines a silly extension that just logs the name of all events triggered +htmx.defineExtension("silly", { + onEvent: function (name, evt) { + console.log("Event " + name + " was triggered!"); + } +}); + +// find div with id my-div +var div = htmx.find("#my-div"); + +// find div with id another-div within that div +var anotherDiv = htmx.find(div, "#another-div"); + +// find all divs +var allDivs = htmx.findAll("div"); + +// find all paragraphs within a given div +var allParagraphsInMyDiv = htmx.findAll(htmx.find("#my-div"), "p"); + +htmx.logAll(); + +// remove this click listener from the body +htmx.off("click", myEventListener); + +// remove this click listener from the given div +htmx.off("#my-div", "click", myEventListener); + +// add a click listener to the body +var myEventListener = htmx.on("click", function (evt) { + console.log(evt); +}); + +// add a click listener to the given div +var myEventListener = htmx.on("#my-div", "click", function (evt) { + console.log(evt); +}); + +const MyLibrary: any = null; + +htmx.onLoad(function (elt) { + MyLibrary.init(elt); +}); + +// returns 3000 +var milliseconds = htmx.parseInterval("3s"); + +// returns 3 - Caution +var milliseconds = htmx.parseInterval("3m"); + +document.body.innerHTML = "
Get it!
"; +// process the newly added content +htmx.process(document.body); + +// removes my-div from the DOM +htmx.remove(htmx.find("#my-div")); + +// removes .myClass from my-div +htmx.removeClass(htmx.find("#my-div"), "myClass"); + +htmx.removeExtension("my-extension"); + +// takes the selected class from tab2"s siblings +htmx.takeClass(htmx.find("#tab2"), "selected"); + +// toggles the selected class on tab2 +htmx.toggleClass(htmx.find("#tab2"), "selected"); + +// triggers the myEvent event on #tab2 with the answer 42 +htmx.trigger(htmx.find("#tab2"), "myEvent", { answer: 42 }); + +// gets the values associated with this form +var values = htmx.values(htmx.find("#myForm")); diff --git a/public/js/main.js b/public/js/main.js new file mode 100644 index 0000000..a97769a --- /dev/null +++ b/public/js/main.js @@ -0,0 +1,6 @@ +document.addEventListener("DOMContentLoaded", function(event) { + let menuItems = document.querySelectorAll("#topmenu a"); + menuItems.forEach( menuItem => { + menuItem.addEventListener('click', () => htmx.removeClass(htmx.find('#topmenu'), 'responsive')); + }); +}); \ No newline at end of file diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..760d605 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://speedtech.it/sitemap.xml \ No newline at end of file diff --git a/public/servizio/backend-siti-web-cms-personalizzati/index.html b/public/servizio/backend-siti-web-cms-personalizzati/index.html new file mode 100644 index 0000000..8bb2c4f --- /dev/null +++ b/public/servizio/backend-siti-web-cms-personalizzati/index.html @@ -0,0 +1,14 @@ +SpeedTech | Sviluppo backend siti web e CMS personalizzati +

Sviluppo backend siti web e CMS personalizzati

Progettazione e sviluppo di backend per siti web e CMS personalizzati

Progettazione e sviluppo di backend per siti web e CMS personalizzati con i più moderni frameworks. Integrazione del CMS con servizi esterni.

Vi sono molti vantaggi nello scegliere un CMS personalizzato rispetto ad una soluzione pre confezionata :

  • maggiore velocità del sito e delle sue funzionalità
  • utilizzo efficiente delle risorse hardware e software
  • backend personalizzato per un workflow efficiente ed immediato
  • facilità e velocità nell’aggiungere nuove funzioni
  • maggiore libertà sia per il cliente che per lo sviluppatore : possibile ogni tipo di personalizzazione
  • sicurezza : frontend e backend accedono con accessi separati, perchè di fatto sono due applicativi distinti. Il backend può essere bloccato durante la notte, i fine settimana o nei periodi inattività

Tecnologie utilizzate

Linguaggio e framework di sviluppo : PHP, CodeIgniter, HTMX +Database : MariaDB, PostgreSQL, SQLite

Applicazioni

  • Siti web pubblici
  • Intranet
  • Documentazione interna
\ No newline at end of file diff --git a/public/servizio/clients-con-linux/index.html b/public/servizio/clients-con-linux/index.html new file mode 100644 index 0000000..081eb2b --- /dev/null +++ b/public/servizio/clients-con-linux/index.html @@ -0,0 +1,14 @@ +SpeedTech | Sistemi clients con Linux: installazione e configurazione +

Sistemi clients con Linux: installazione e configurazione

Studio, valutazione delle necessità e selezione della distribuzione Linux più adatta alle esigenze del cliente. Configurazione del sistema base e delle periferiche, installazione, test e supporto a lungo termine

Ci sono molti vantaggi nell’utilizzare il sistema operativo Linux come client su dekstop e laptop, sia a casa che in ufficio.

Sicurezza

Linux è immune a virus e malaware, così nessuna protezione software è necessaria, come antivirus e antimalaware, è necessaria

Efficienza

Linux funziona bene alche su hardware meno recente in quanto è in grado di utilizzare le risorse della macchina con una migliore efficienza

Privacy

Linux fornisce molte soluzioni open source e gratuite per proteggere la privacy dell’utente consentendo di cifrarel’intero disco o solo i dati degli utenti

Personalizzazione

Sono disponibili molte interfacce utente ed ogni interfaccia può essere facilmente personalizzata

Disponibilità software

Moltissimo software di elevata qualità, gratuito e open source è dispoibile per soddisfare ogni esigenza

Manutenzione

Linux è facile da gestire, utilizzare e creare copie di sicurezza. Anche in caso sia necessaria una reinstallazione da zero, è semplice migrare i dati e le preferenze dell’utente

Contenimento dei costi

La maggior parte delle distribuzioni Linux sono completamente gratuite e non vi sono costi di licenza da sostenere

Le distribuzioni Linux consigliate per un desktop sono Linux Mint and Zorin OS

\ No newline at end of file diff --git a/public/servizio/domotica-opensource/index.html b/public/servizio/domotica-opensource/index.html new file mode 100644 index 0000000..068b7f2 --- /dev/null +++ b/public/servizio/domotica-opensource/index.html @@ -0,0 +1,14 @@ +SpeedTech | Soluzioni di domotica open source +

Soluzioni di domotica open source

Soluzioni software e hardware per la domotica open source basata su Home Assistant

Controllo remoto con accesso privato anche tramite VPN Wireguard. +Possibilità di ricevere notifiche in tempo reale attraverso diversi canali.

Tecnologie utilizzate

Home Assistant, Tasmota, Shelly, Sonoff, Athom

Applicazioni

  • Automazione illuminazione interna ed esterna
  • Automazione irrigazione
  • Automazione tapparelle
  • Apertura / chiusura cancelli e basculanti
\ No newline at end of file diff --git a/public/servizio/e-mail-privata/index.html b/public/servizio/e-mail-privata/index.html new file mode 100644 index 0000000..0f32be5 --- /dev/null +++ b/public/servizio/e-mail-privata/index.html @@ -0,0 +1,13 @@ +SpeedTech | E-mail privata: hosting, sicurezza ed archiviazione +

E-mail privata: hosting, sicurezza ed archiviazione

Soluzioni mail intelligenti e performanti, che rispettano completamente la privacy

I servers di posta elettronica che utilizzo si trovano in Germania e sono dotati esclusivamente di software open source : Linux Debian, Postfix, Dovecot, Rspamd, Roundcube.

I servers si trovano nei datacenters di Contabo e tutte le comunicazioni tra servers e clients sono cifrate con certificati OpenSSL validi firmati da LetsEncrypt.

Funzionalità

  • Servers ridondati
  • Antispam
  • Filtro antispam implementato tramite il software rspamd
  • Garanzia di consegna
  • La consegna dei messaggi ai destinatari è garantita tramite le tecnologie DKIM e DMARC
  • Webmail con interfaccia responsive che può essere utilizzata con ogni tipo di dispositivo (computer, smartphone, tablet).
  • Ogni utente può :
    • modificare la propria password
    • impostare un messaggio di assenza
    • modificare il livello desiderato di protezione antispam
    • cifrare le proprie email con GPG
  • Cifratura e compressione email lato server per una completa protezione della privacy
  • Backup cifrato e storicizzato delle email su un servizio cloud esterno

Funzionalità aggiuntive disponibili

  • Server dedicato
  • Il servizio può essere implementato su un server dedicato e privato
  • Piattaforma di collaborazione
  • Backup automatico e pianificato
  • Una copia delle emails può essere copiata su uno spazio di archiviazione del cliente come backup
\ No newline at end of file diff --git a/public/servizio/index.xml b/public/servizio/index.xml new file mode 100644 index 0000000..f829288 --- /dev/null +++ b/public/servizio/index.xml @@ -0,0 +1,19 @@ +Servizios on Information Technology Serviceshttps://speedtech.it/servizio/Recent content in Servizios on Information Technology ServicesHugo -- gohugo.ioitSviluppo backend siti web e CMS personalizzatihttps://speedtech.it/servizio/backend-siti-web-cms-personalizzati/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/backend-siti-web-cms-personalizzati/Progettazione e sviluppo di backend per siti web e CMS personalizzati con i più moderni frameworks. Integrazione del CMS con servizi esterni. +Vi sono molti vantaggi nello scegliere un CMS personalizzato rispetto ad una soluzione pre confezionata : +maggiore velocità del sito e delle sue funzionalità utilizzo efficiente delle risorse hardware e software backend personalizzato per un workflow efficiente ed immediato facilità e velocità nell&rsquo;aggiungere nuove funzioni maggiore libertà sia per il cliente che per lo sviluppatore : possibile ogni tipo di personalizzazione sicurezza : frontend e backend accedono con accessi separati, perchè di fatto sono due applicativi distinti.Sistemi clients con Linux: installazione e configurazionehttps://speedtech.it/servizio/clients-con-linux/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/clients-con-linux/Ci sono molti vantaggi nell&rsquo;utilizzare il sistema operativo Linux come client su dekstop e laptop, sia a casa che in ufficio. +Sicurezza Linux è immune a virus e malaware, così nessuna protezione software è necessaria, come antivirus e antimalaware, è necessaria +Efficienza Linux funziona bene alche su hardware meno recente in quanto è in grado di utilizzare le risorse della macchina con una migliore efficienza +Privacy Linux fornisce molte soluzioni open source e gratuite per proteggere la privacy dell&rsquo;utente consentendo di cifrarel&rsquo;intero disco o solo i dati degli utentiSoluzioni di condivisione e collaborazione online e offlinehttps://speedtech.it/servizio/soluzioni-collaborazione-online-offline/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/soluzioni-collaborazione-online-offline/Una soluzione NAS (Network Attached Storage), consente di centralizzare i documenti importanti della propria attività e di condividerli con i collaboratori. Consente inoltre anche di centralizzare il backup dei dati più importanti. +Un NAS può essere realizzato sia con hardware dedicato come Synology, oppure su hardware generico e selezionato in base alle specifiche necessità del cliente. +Tecnologie utilizzate NextCloud, OpenMediaVault, TrueNAS, Synology, Seafile +Applicazioni Condivisione files e documenti interna ed esterna Accesso centralizzato ai documenti dell&rsquo;attività con privilegi diversificati Piattaforma di collaborazione centralizzata e condivisa Backup centralizzatoSoluzioni di domotica open sourcehttps://speedtech.it/servizio/domotica-opensource/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/domotica-opensource/Controllo remoto con accesso privato anche tramite VPN Wireguard. Possibilità di ricevere notifiche in tempo reale attraverso diversi canali. +Tecnologie utilizzate Home Assistant, Tasmota, Shelly, Sonoff, Athom +Applicazioni Automazione illuminazione interna ed esterna Automazione irrigazione Automazione tapparelle Apertura / chiusura cancelli e basculantiServers Linux gestitihttps://speedtech.it/servizio/servers-linux-gestiti/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/servers-linux-gestiti/Gestione completa di server multifunzione fisici o virtuali equipaggiati con le distribuzioni Linux open source. +Dimensionamento Installazione Configurazione Manutenzione Aggiornamento Migrazione I server Linux servers posso offrire una vasta gamma di servizi : mail, web, backup, cloud, repository codice sorgente &hellip; +L&rsquo;accesso ai servizi dal&rsquo;esterno può essere reso sicuro utilizzando una VPN con OpenVPN o Wireguard o tramite tunnels SSH e il server può essere protetto dal suo firewall software e la sicurezza può essere incrementata integrando il supporto Security Enhanced Linux.E-mail privata: hosting, sicurezza ed archiviazionehttps://speedtech.it/servizio/e-mail-privata/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/e-mail-privata/I servers di posta elettronica che utilizzo si trovano in Germania e sono dotati esclusivamente di software open source : Linux Debian, Postfix, Dovecot, Rspamd, Roundcube. +I servers si trovano nei datacenters di Contabo e tutte le comunicazioni tra servers e clients sono cifrate con certificati OpenSSL validi firmati da LetsEncrypt. +Funzionalità Servers ridondati Antispam Filtro antispam implementato tramite il software rspamd Garanzia di consegna La consegna dei messaggi ai destinatari è garantita tramite le tecnologie DKIM e DMARC Webmail con interfaccia responsive che può essere utilizzata con ogni tipo di dispositivo (computer, smartphone, tablet).Strutture di sicurezza: firewalls, soluzioni di crifratura, backupshttps://speedtech.it/servizio/sicurezza-firewalls-vpn/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/sicurezza-firewalls-vpn/Firewalls Soluzioni software e hardware per proteggere le reti ed i server per ogni esigenza : +case e piccoli uffici grandi uffici sedi distaccate servers VPN Soluzioni Virtual Private Network per accedere ad una rete remota in modalità sicura o per connettere due o più sedi distaccate con una connessione cifrata. Una VPN puà essere implmentata utilizzando software IPSec, OpenVPN e WireGuard e permette a singoli computer, tablets o smartphones di connettersi ad una rete protetta attraverso un canale cifrato e di utilizzare le risorse remote in modo trasparente come se fossero fisicamente connessi alla stessa rete.Sviluppo e integrazione di piattaforme per l'e-commercehttps://speedtech.it/servizio/soluzioni-e-commerce/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/soluzioni-e-commerce/Progettazione e sviluppo di soluzioni personalizzate in base alle necessità specifiche del cliente, sia per prodotti fisici che virtuali, integrate con il calcolo dei costi di spedizione ed il tracking della merce spedita. +Installazione, configurazione e manutenzione di soluzioni ecommerce open source (Woocommerce, OpenCart), progettazione e sviluppo di soluzione personalizzate. Integrazione con diversi gateway di pagamento : (Stripe, Paypal, Satispay). +Tecnologie utilizzate Linguaggio e framework di sviluppo : PHP, CodeIgniter, HTMX Database : MariaDB, PostgreSQLProgettazione e sviluppo di applicazioni softwarehttps://speedtech.it/servizio/sviluppo-applicazioni/Mon, 01 Jan 0001 00:00:00 +0000https://speedtech.it/servizio/sviluppo-applicazioni/Applicazioni (gestione progetti, registrazione attività, magazzino, contabilià e fatturazione) progettate per funzionare in ogni moderno browser web, accessibili ovunque da ogni dispositivo e che utilizzano i più efficienti frameworks di sviluppo connessi con i migliori databases open source : MariaDB, PostgreSQL, SQLite +Le applicazioni sono accessibili da ovunque nel mondo (è sufficiente una connessione ad Internet), non richiedono nessuna installazione e possono essere utilizzati contemporaneamente da più postazioni e possono essere utlizzati da qualsiasi sistema operativo (MS Windows, Linux, Apple), compresi i dispositivi mobili (smartphone e tablet). \ No newline at end of file diff --git a/public/servizio/servers-linux-gestiti/index.html b/public/servizio/servers-linux-gestiti/index.html new file mode 100644 index 0000000..efd0b49 --- /dev/null +++ b/public/servizio/servers-linux-gestiti/index.html @@ -0,0 +1,13 @@ +SpeedTech | Servers Linux gestiti +

Servers Linux gestiti

Installazione, configurazione e manutenzione di server Linux sia su hardware fisico che virtuale (VPS)

Gestione completa di server multifunzione fisici o virtuali equipaggiati con le distribuzioni Linux open source.

  • Dimensionamento
  • Installazione
  • Configurazione
  • Manutenzione
  • Aggiornamento
  • Migrazione

I server Linux servers posso offrire una vasta gamma di servizi : mail, web, backup, cloud, repository codice sorgente …

L’accesso ai servizi dal’esterno può essere reso sicuro utilizzando una VPN con OpenVPN o Wireguard o tramite tunnels SSH e il server può essere protetto dal suo firewall software e la sicurezza può essere incrementata integrando il supporto Security Enhanced Linux.

Le connessioni al server web possono essere cifrate utilizzandoi certificati SSL di Let’s Encrypt (gratuiti) o utilizzando certificati commerciali.

Tecnologie utilizzate

  • Sistemi operativi basati su Linux : Debian, RockyLinux
  • Backup : Borg, Kopia, restic
  • Cloud : Nextcloud
  • Database : PostgreSQL, MariaDB
  • Mail : Postfix, Dovecot, Roundcube, Rspamd
  • Gestione password : Vaultwarden

Applicazioni

  • Mail server privato
  • Database server
  • Backup server
  • Cloud e file server privato
  • Server privato per stoccaggio password
  • Repository privato codice sorgente per sviluppatori

Una gamma completa di servizi di installazione, supporto e manutenzione, particolarmente adatti per per le piccole realtà, con contratti di supporto annuali o a chiamata o per intervento.

Il supporto è fornito da remoto tramite software di controllo.

\ No newline at end of file diff --git a/public/servizio/sicurezza-firewalls-vpn/index.html b/public/servizio/sicurezza-firewalls-vpn/index.html new file mode 100644 index 0000000..27e4f8f --- /dev/null +++ b/public/servizio/sicurezza-firewalls-vpn/index.html @@ -0,0 +1,17 @@ +SpeedTech | Strutture di sicurezza: firewalls, soluzioni di crifratura, backups +

Strutture di sicurezza: firewalls, soluzioni di crifratura, backups

Soluzioni software e hardware per proteggere le reti, i servers ed i dati sensibili

Firewalls

Soluzioni software e hardware per proteggere le reti ed i server per ogni esigenza :

  • case e piccoli uffici
  • grandi uffici
  • sedi distaccate
  • servers

VPN

Soluzioni Virtual Private Network per accedere ad una rete remota in modalità sicura o per connettere due o più sedi distaccate con una connessione cifrata. +Una VPN puà essere implmentata utilizzando software IPSec, OpenVPN e WireGuard e permette a singoli computer, tablets o smartphones di connettersi ad una rete protetta attraverso un canale cifrato e di utilizzare le risorse remote in modo trasparente come se fossero fisicamente connessi alla stessa rete. +Una VPN permette inoltre di connettere due o più sede distaccate consentendo loro di colalborare sugli stessi servers in modalità trasparente.

Cifratura dati

Soluzioni open source per cifrare e proteggere i dati sensibili su server, computer, tablet e smartphone. +La cifratura dei dati garantisce la protezione della privacy anche in caso di intrusione nel sistema o quando un dispositivo viene smarrito o compromesso.

La privacy e l’autenticità delle email può essere garantita utilizzando GPG ed integrandolo con il software email: solo il proprietario della chiave privata e della password può leggere le email che precedentemente sono state cifrate con la sua chiave pubblica.

Backup

Disporre di un backup automatico, efficiente e facilmente accessibile dei propri dati è fondamentale. Differenti soluzioni software e hardware sono disponibili per coprire ogni esigenza. +Per garantire la massima affidabilità diverse locazioni fisiche dei backup dovrebbero essere implementate. E per preservare la privacy i backup dovrebbero essere sempre cifrati. +Un backup verso uno storage S3 che supporti versioning ed object locking mette al riparo anche da eventuali attacchi ransomware.

\ No newline at end of file diff --git a/public/servizio/soluzioni-collaborazione-online-offline/index.html b/public/servizio/soluzioni-collaborazione-online-offline/index.html new file mode 100644 index 0000000..cf3d055 --- /dev/null +++ b/public/servizio/soluzioni-collaborazione-online-offline/index.html @@ -0,0 +1,15 @@ +SpeedTech | Soluzioni di condivisione e collaborazione online e offline +

Soluzioni di condivisione e collaborazione online e offline

Condivisione e collaborazione online con NextCloud, OpenMediaVault, TrueNAS e Synology

Una soluzione NAS (Network Attached Storage), consente di centralizzare i documenti importanti della propria attività e di condividerli con i +collaboratori. Consente inoltre anche di centralizzare il backup dei dati più importanti.

Un NAS può essere realizzato sia con hardware dedicato come Synology, oppure su hardware generico e selezionato in base alle specifiche necessità del cliente.

Tecnologie utilizzate

NextCloud, OpenMediaVault, TrueNAS, Synology, Seafile

Applicazioni

  • Condivisione files e documenti interna ed esterna
  • Accesso centralizzato ai documenti dell’attività con privilegi diversificati
  • Piattaforma di collaborazione centralizzata e condivisa
  • Backup centralizzato
\ No newline at end of file diff --git a/public/servizio/soluzioni-e-commerce/index.html b/public/servizio/soluzioni-e-commerce/index.html new file mode 100644 index 0000000..08287ef --- /dev/null +++ b/public/servizio/soluzioni-e-commerce/index.html @@ -0,0 +1,15 @@ +SpeedTech | Sviluppo e integrazione di piattaforme per l&rsquo;e-commerce +

Sviluppo e integrazione di piattaforme per l'e-commerce

Sviluppo di piattaforme per l'e-commerce personalizzate ed integrazione di piattaforme open source

Progettazione e sviluppo di soluzioni personalizzate in base alle necessità specifiche del cliente, sia per prodotti fisici che virtuali, integrate con il calcolo dei costi di spedizione ed il tracking della merce spedita.

Installazione, configurazione e manutenzione di soluzioni ecommerce open source (Woocommerce, OpenCart), progettazione e sviluppo di soluzione personalizzate. +Integrazione con diversi gateway di pagamento : (Stripe, Paypal, Satispay).

Tecnologie utilizzate

Linguaggio e framework di sviluppo : PHP, CodeIgniter, HTMX +Database : MariaDB, PostgreSQL

Applicazioni

Ogni tipo di attività commerciale che può vendere i propri prodotti e servizi tramite Internet.

\ No newline at end of file diff --git a/public/servizio/sviluppo-applicazioni/index.html b/public/servizio/sviluppo-applicazioni/index.html new file mode 100644 index 0000000..3fe8a06 --- /dev/null +++ b/public/servizio/sviluppo-applicazioni/index.html @@ -0,0 +1,13 @@ +SpeedTech | Progettazione e sviluppo di applicazioni software +

Progettazione e sviluppo di applicazioni software

Applicazioni software accessibili ovunque e con ogni dispositivo

Applicazioni (gestione progetti, registrazione attività, magazzino, contabilià e fatturazione) progettate per funzionare in ogni moderno browser web, accessibili ovunque da ogni dispositivo e che utilizzano i più efficienti frameworks di sviluppo connessi con i migliori databases open source : MariaDB, PostgreSQL, SQLite

Le applicazioni sono accessibili da ovunque nel mondo (è sufficiente una connessione ad Internet), non richiedono nessuna installazione e possono essere utilizzati contemporaneamente da più postazioni e possono essere utlizzati da qualsiasi sistema operativo (MS Windows, Linux, Apple), compresi i dispositivi mobili (smartphone e tablet).

Tecnologie utilizzate

Linguaggio e framework di sviluppo : PHP, CodeIgniter, HTMX, Ionic Framework, FreePascal e Lazarus IDE +Database : MariaDB, PostgreSQL, SQLite

Applicazioni

  • Gestione progetti
  • Rendicontazione attività
  • Magazzino
  • Fatturazione e contabilità
  • Applicazioni personalizzate
  • Sistemi di controllo domotico
  • Software per il noleggio

Le applicazioni sviluppate possono essere multi piattaforma e lavorare con le medesime modalità su qualsiasi computer e sistema operativo

\ No newline at end of file diff --git a/public/sitemap.xml b/public/sitemap.xml new file mode 100644 index 0000000..8fed3cc --- /dev/null +++ b/public/sitemap.xml @@ -0,0 +1 @@ +https://speedtech.it/it/sitemap.xml2025-10-30T00:00:00+00:00https://speedtech.it/en/sitemap.xml2025-10-30T00:00:00+00:00 \ No newline at end of file diff --git a/public/tags/custom-cms/index.html b/public/tags/custom-cms/index.html new file mode 100644 index 0000000..6c2df72 --- /dev/null +++ b/public/tags/custom-cms/index.html @@ -0,0 +1,72 @@ +SpeedTech | Custom CMS +

Procedure di sincronizzazione dati

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti con PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Museo e shop online

Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del server

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

Sviluppo software per Drupal

Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Svilluppo di applicazioni web

Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzati

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Sviluppo software per Drupal

Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

\ No newline at end of file diff --git a/public/tags/custom-cms/index.xml b/public/tags/custom-cms/index.xml new file mode 100644 index 0000000..5835adb --- /dev/null +++ b/public/tags/custom-cms/index.xml @@ -0,0 +1,9 @@ +Custom CMS on Information Technology Serviceshttps://speedtech.it/tags/custom-cms/Recent content in Custom CMS on Information Technology ServicesHugo -- gohugo.ioitMon, 07 Nov 2022 00:00:00 +0000Procedure di sincronizzazione datihttps://speedtech.it/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/blog/wmtrento-data-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti +con PHP, CodeIgniter, MySQL, Joomla, Virtuemart</p>Museo e shop onlinehttps://speedtech.it/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/blog/botta-museum/Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del serverSviluppo software per Drupalhttps://speedtech.it/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/blog/versantus-drupal.-development/Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)Svilluppo di applicazioni webhttps://speedtech.it/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/blog/guiet-web-development/Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzatiSviluppo software per Drupalhttps://speedtech.it/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/blog/lrm-drupal-development/Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL) \ No newline at end of file diff --git a/public/tags/custom-cms/page/1/index.html b/public/tags/custom-cms/page/1/index.html new file mode 100644 index 0000000..dbc26a0 --- /dev/null +++ b/public/tags/custom-cms/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/custom-cms/ + \ No newline at end of file diff --git a/public/tags/database/index.html b/public/tags/database/index.html new file mode 100644 index 0000000..4f4e2fd --- /dev/null +++ b/public/tags/database/index.html @@ -0,0 +1,56 @@ +SpeedTech | Database +

Database link con PostgreSQL

In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +PostgreSQL

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/tags/database/index.xml b/public/tags/database/index.xml new file mode 100644 index 0000000..043f133 --- /dev/null +++ b/public/tags/database/index.xml @@ -0,0 +1,5 @@ +Database on Information Technology Serviceshttps://speedtech.it/tags/database/Recent content in Database on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Database link con PostgreSQLhttps://speedtech.it/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/blog/postgresql-database-link/<p>In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che +risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.</p>Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p> \ No newline at end of file diff --git a/public/tags/database/page/1/index.html b/public/tags/database/page/1/index.html new file mode 100644 index 0000000..776f572 --- /dev/null +++ b/public/tags/database/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/database/ + \ No newline at end of file diff --git a/public/tags/desktop-application/index.html b/public/tags/desktop-application/index.html new file mode 100644 index 0000000..5dac313 --- /dev/null +++ b/public/tags/desktop-application/index.html @@ -0,0 +1,52 @@ +SpeedTech | Desktop Application +

Software per noleggio attrezzature per lo sci

Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.

Continua a leggere

Progetti | +Software Development +| +Desktop Application

Applicazioni per CRM, Oracle e certificazione PCI

Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro

Continua a leggere

Progetti | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/tags/desktop-application/index.xml b/public/tags/desktop-application/index.xml new file mode 100644 index 0000000..b363f3d --- /dev/null +++ b/public/tags/desktop-application/index.xml @@ -0,0 +1,5 @@ +Desktop Application on Information Technology Serviceshttps://speedtech.it/tags/desktop-application/Recent content in Desktop Application on Information Technology ServicesHugo -- gohugo.ioitTue, 12 Dec 2017 00:00:00 +0000Software per noleggio attrezzature per lo scihttps://speedtech.it/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/blog/cspolsa-renting/Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.Applicazioni per CRM, Oracle e certificazione PCIhttps://speedtech.it/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/blog/sint-crm/Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro \ No newline at end of file diff --git a/public/tags/desktop-application/page/1/index.html b/public/tags/desktop-application/page/1/index.html new file mode 100644 index 0000000..72b1036 --- /dev/null +++ b/public/tags/desktop-application/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/desktop-application/ + \ No newline at end of file diff --git a/public/tags/dovecot/index.html b/public/tags/dovecot/index.html new file mode 100644 index 0000000..edd3cf9 --- /dev/null +++ b/public/tags/dovecot/index.html @@ -0,0 +1,45 @@ +SpeedTech | Dovecot +
\ No newline at end of file diff --git a/public/tags/dovecot/index.xml b/public/tags/dovecot/index.xml new file mode 100644 index 0000000..b3754c7 --- /dev/null +++ b/public/tags/dovecot/index.xml @@ -0,0 +1,2 @@ +Dovecot on Information Technology Serviceshttps://speedtech.it/tags/dovecot/Recent content in Dovecot on Information Technology ServicesHugo -- gohugo.ioitFri, 08 Jul 2022 00:00:00 +0000Cifrare e comprimere le email lato serverhttps://speedtech.it/blog/cifrare-comprimere-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/cifrare-comprimere-email-server/<p>Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server +<a href="https://www.dovecot.org/">Dovecot</a> permette di cifrare e comprimere i files che contengono la posta elettronica.</p> \ No newline at end of file diff --git a/public/tags/dovecot/page/1/index.html b/public/tags/dovecot/page/1/index.html new file mode 100644 index 0000000..de1df1e --- /dev/null +++ b/public/tags/dovecot/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/dovecot/ + \ No newline at end of file diff --git a/public/tags/e-commerce/index.html b/public/tags/e-commerce/index.html new file mode 100644 index 0000000..bf2c995 --- /dev/null +++ b/public/tags/e-commerce/index.html @@ -0,0 +1,60 @@ +SpeedTech | E-Commerce +

Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezza

Cliente : Amor Cosmetics (Trento - IT) +Sito e-commerce website integrato con pagamenti tramite carta di credito

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

Museo e shop online

Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del server

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

Installazione e personalizzazione sito e-commerce

Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzate

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/tags/e-commerce/index.xml b/public/tags/e-commerce/index.xml new file mode 100644 index 0000000..47c6115 --- /dev/null +++ b/public/tags/e-commerce/index.xml @@ -0,0 +1,6 @@ +E-Commerce on Information Technology Serviceshttps://speedtech.it/tags/e-commerce/Recent content in E-Commerce on Information Technology ServicesHugo -- gohugo.ioitThu, 27 May 2021 00:00:00 +0000Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezzahttps://speedtech.it/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/blog/amorcosmetics-ecommerce/<p>Cliente : Amor Cosmetics (Trento - IT)</p> +<p>Sito e-commerce website integrato con pagamenti tramite carta di credito</p>Museo e shop onlinehttps://speedtech.it/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/blog/botta-museum/Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del serverInstallazione e personalizzazione sito e-commercehttps://speedtech.it/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzate \ No newline at end of file diff --git a/public/tags/e-commerce/page/1/index.html b/public/tags/e-commerce/page/1/index.html new file mode 100644 index 0000000..8559fe6 --- /dev/null +++ b/public/tags/e-commerce/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/e-commerce/ + \ No newline at end of file diff --git a/public/tags/file-server/index.html b/public/tags/file-server/index.html new file mode 100644 index 0000000..8f9cc21 --- /dev/null +++ b/public/tags/file-server/index.html @@ -0,0 +1,44 @@ +SpeedTech | File Server +
\ No newline at end of file diff --git a/public/tags/file-server/index.xml b/public/tags/file-server/index.xml new file mode 100644 index 0000000..f5cc73b --- /dev/null +++ b/public/tags/file-server/index.xml @@ -0,0 +1,5 @@ +File Server on Information Technology Serviceshttps://speedtech.it/tags/file-server/Recent content in File Server on Information Technology ServicesHugo -- gohugo.ioitSat, 03 Jul 2021 00:00:00 +0000Installazione e configurazione Synology NAShttps://speedtech.it/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/blog/synology-nas/<p>Cliente : diversi</p> +<ul> +<li>Installazione e configurazione Synology : utenti, privilegi di condivisione e backup</li> +<li>Configurazione clients MS Windows</li> +</ul> \ No newline at end of file diff --git a/public/tags/file-server/page/1/index.html b/public/tags/file-server/page/1/index.html new file mode 100644 index 0000000..29eda55 --- /dev/null +++ b/public/tags/file-server/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/file-server/ + \ No newline at end of file diff --git a/public/tags/firewall/index.html b/public/tags/firewall/index.html new file mode 100644 index 0000000..b69148c --- /dev/null +++ b/public/tags/firewall/index.html @@ -0,0 +1,75 @@ +SpeedTech | Firewall +

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Servers VPS, Firewall e VPN

Cliente : Finova (Bolzano - IT) +Progettazione ed implementazione rete e sicurezza per servizi SAS

Continua a leggere

Progetti | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewalls, VPN e filtraggio contenuti

Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse web

Continua a leggere

Firewall +| +VPN +| +Networking +| +OpnSense

Firewall, VPN e rete in server farm

Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi

Continua a leggere

Progetti | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/tags/firewall/index.xml b/public/tags/firewall/index.xml new file mode 100644 index 0000000..c3132ef --- /dev/null +++ b/public/tags/firewall/index.xml @@ -0,0 +1,9 @@ +Firewall on Information Technology Serviceshttps://speedtech.it/tags/firewall/Recent content in Firewall on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p>Servers VPS, Firewall e VPNhttps://speedtech.it/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/blog/finova-firewall/<p>Cliente : Finova (Bolzano - IT)</p> +<p>Progettazione ed implementazione rete e sicurezza per servizi SAS</p>Firewalls, VPN e filtraggio contenutihttps://speedtech.it/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/blog/villamaria-firewalls/Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse webFirewall, VPN e rete in server farmhttps://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi \ No newline at end of file diff --git a/public/tags/firewall/page/1/index.html b/public/tags/firewall/page/1/index.html new file mode 100644 index 0000000..9443a7b --- /dev/null +++ b/public/tags/firewall/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/firewall/ + \ No newline at end of file diff --git a/public/tags/home-assistant/index.html b/public/tags/home-assistant/index.html new file mode 100644 index 0000000..239f632 --- /dev/null +++ b/public/tags/home-assistant/index.html @@ -0,0 +1,41 @@ +SpeedTech | Home Assistant +
\ No newline at end of file diff --git a/public/tags/home-assistant/index.xml b/public/tags/home-assistant/index.xml new file mode 100644 index 0000000..15e1752 --- /dev/null +++ b/public/tags/home-assistant/index.xml @@ -0,0 +1 @@ +Home Assistant on Information Technology Serviceshttps://speedtech.it/tags/home-assistant/Recent content in Home Assistant on Information Technology ServicesHugo -- gohugo.ioitTue, 30 Aug 2022 00:00:00 +0000Automazione casa con Home Assistanthttps://speedtech.it/blog/automazione-casa-con-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/blog/automazione-casa-con-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> è uno strumento interamente open source per la domotica sia di ambienti residenziali che lavorativi.</p> \ No newline at end of file diff --git a/public/tags/home-assistant/page/1/index.html b/public/tags/home-assistant/page/1/index.html new file mode 100644 index 0000000..09d97d7 --- /dev/null +++ b/public/tags/home-assistant/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/home-assistant/ + \ No newline at end of file diff --git a/public/tags/home-automation/index.html b/public/tags/home-automation/index.html new file mode 100644 index 0000000..5ff84d4 --- /dev/null +++ b/public/tags/home-automation/index.html @@ -0,0 +1,41 @@ +SpeedTech | Home Automation +
\ No newline at end of file diff --git a/public/tags/home-automation/index.xml b/public/tags/home-automation/index.xml new file mode 100644 index 0000000..ffbc3bc --- /dev/null +++ b/public/tags/home-automation/index.xml @@ -0,0 +1 @@ +Home Automation on Information Technology Serviceshttps://speedtech.it/tags/home-automation/Recent content in Home Automation on Information Technology ServicesHugo -- gohugo.ioitTue, 30 Aug 2022 00:00:00 +0000Automazione casa con Home Assistanthttps://speedtech.it/blog/automazione-casa-con-home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/blog/automazione-casa-con-home-assistant/<p><a href="https://home-assistant.io">Home Assistant</a> è uno strumento interamente open source per la domotica sia di ambienti residenziali che lavorativi.</p> \ No newline at end of file diff --git a/public/tags/home-automation/page/1/index.html b/public/tags/home-automation/page/1/index.html new file mode 100644 index 0000000..2bf4812 --- /dev/null +++ b/public/tags/home-automation/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/home-automation/ + \ No newline at end of file diff --git a/public/tags/index.html b/public/tags/index.html new file mode 100644 index 0000000..1bf5a53 --- /dev/null +++ b/public/tags/index.html @@ -0,0 +1,38 @@ +SpeedTech | Tags +
\ No newline at end of file diff --git a/public/tags/index.xml b/public/tags/index.xml new file mode 100644 index 0000000..5ec2bf6 --- /dev/null +++ b/public/tags/index.xml @@ -0,0 +1 @@ +Tags on Information Technology Serviceshttps://speedtech.it/tags/Recent content in Tags on Information Technology ServicesHugo -- gohugo.ioitThu, 30 Oct 2025 00:00:00 +0000PWAhttps://speedtech.it/tags/pwa/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/tags/pwa/Software Developmenthttps://speedtech.it/tags/software-development/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/tags/software-development/Web Applicationhttps://speedtech.it/tags/web-application/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/tags/web-application/Databasehttps://speedtech.it/tags/database/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/tags/database/PostgreSQLhttps://speedtech.it/tags/postgresql/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/tags/postgresql/Serverhttps://speedtech.it/tags/server/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/tags/server/Custom CMShttps://speedtech.it/tags/custom-cms/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/tags/custom-cms/Home Assistanthttps://speedtech.it/tags/home-assistant/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/tags/home-assistant/Home Automationhttps://speedtech.it/tags/home-automation/Tue, 30 Aug 2022 00:00:00 +0000https://speedtech.it/tags/home-automation/Firewallhttps://speedtech.it/tags/firewall/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/tags/firewall/MariaDBhttps://speedtech.it/tags/mariadb/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/tags/mariadb/OpenSSLhttps://speedtech.it/tags/openssl/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/tags/openssl/UFWhttps://speedtech.it/tags/ufw/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/tags/ufw/Dovecothttps://speedtech.it/tags/dovecot/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/tags/dovecot/Networkinghttps://speedtech.it/tags/networking/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/tags/networking/Privacyhttps://speedtech.it/tags/privacy/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/tags/privacy/Routerhttps://speedtech.it/tags/router/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/tags/router/Securityhttps://speedtech.it/tags/security/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/tags/security/VPNhttps://speedtech.it/tags/vpn/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/tags/vpn/File Serverhttps://speedtech.it/tags/file-server/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/tags/file-server/NAShttps://speedtech.it/tags/nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/tags/nas/E-Commercehttps://speedtech.it/tags/e-commerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/tags/e-commerce/OpnSensehttps://speedtech.it/tags/opnsense/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/tags/opnsense/System Administrationhttps://speedtech.it/tags/system-administration/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/tags/system-administration/Desktop Applicationhttps://speedtech.it/tags/desktop-application/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/tags/desktop-application/Office Serverhttps://speedtech.it/tags/office-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/tags/office-server/Oracle Databasehttps://speedtech.it/tags/oracle-database/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/tags/oracle-database/Pascalhttps://speedtech.it/tags/pascal/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/tags/pascal/ \ No newline at end of file diff --git a/public/tags/mariadb/index.html b/public/tags/mariadb/index.html new file mode 100644 index 0000000..5e49229 --- /dev/null +++ b/public/tags/mariadb/index.html @@ -0,0 +1,50 @@ +SpeedTech | MariaDB +

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/tags/mariadb/index.xml b/public/tags/mariadb/index.xml new file mode 100644 index 0000000..48cca3b --- /dev/null +++ b/public/tags/mariadb/index.xml @@ -0,0 +1,4 @@ +MariaDB on Information Technology Serviceshttps://speedtech.it/tags/mariadb/Recent content in MariaDB on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p> \ No newline at end of file diff --git a/public/tags/mariadb/page/1/index.html b/public/tags/mariadb/page/1/index.html new file mode 100644 index 0000000..1342891 --- /dev/null +++ b/public/tags/mariadb/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/mariadb/ + \ No newline at end of file diff --git a/public/tags/nas/index.html b/public/tags/nas/index.html new file mode 100644 index 0000000..e99456e --- /dev/null +++ b/public/tags/nas/index.html @@ -0,0 +1,49 @@ +SpeedTech | NAS +

Installazione e configurazione Synology NAS

Cliente : diversi +Installazione e configurazione Synology : utenti, privilegi di condivisione e backup Configurazione clients MS Windows

Continua a leggere

Soluzioni | +Technology | +Progetti | +NAS +| +File Server

Server Linux come file e backup server

Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei files

Continua a leggere

Progetti | +NAS +| +Office Server

\ No newline at end of file diff --git a/public/tags/nas/index.xml b/public/tags/nas/index.xml new file mode 100644 index 0000000..688df43 --- /dev/null +++ b/public/tags/nas/index.xml @@ -0,0 +1,7 @@ +NAS on Information Technology Serviceshttps://speedtech.it/tags/nas/Recent content in NAS on Information Technology ServicesHugo -- gohugo.ioitSat, 03 Jul 2021 00:00:00 +0000Installazione e configurazione Synology NAShttps://speedtech.it/blog/synology-nas/Sat, 03 Jul 2021 00:00:00 +0000https://speedtech.it/blog/synology-nas/<p>Cliente : diversi</p> +<ul> +<li>Installazione e configurazione Synology : utenti, privilegi di condivisione e backup</li> +<li>Configurazione clients MS Windows</li> +</ul>Server Linux come file e backup serverhttps://speedtech.it/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/blog/deflorian-server/Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei files \ No newline at end of file diff --git a/public/tags/nas/page/1/index.html b/public/tags/nas/page/1/index.html new file mode 100644 index 0000000..e4530c2 --- /dev/null +++ b/public/tags/nas/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/nas/ + \ No newline at end of file diff --git a/public/tags/networking/index.html b/public/tags/networking/index.html new file mode 100644 index 0000000..ed3cd80 --- /dev/null +++ b/public/tags/networking/index.html @@ -0,0 +1,63 @@ +SpeedTech | Networking +

VPN con router Fritz!Box

I routers Fritz!Box di AVM forniscono già integrati due importanti servizi che consentono la connettività da remoto : +DNS dinamico VPN basata su protocollo ipsec

Continua a leggere

Soluzioni | +Technology | +VPN +| +Router +| +Networking

Servers VPS, Firewall e VPN

Cliente : Finova (Bolzano - IT) +Progettazione ed implementazione rete e sicurezza per servizi SAS

Continua a leggere

Progetti | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewalls, VPN e filtraggio contenuti

Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse web

Continua a leggere

Firewall +| +VPN +| +Networking +| +OpnSense

\ No newline at end of file diff --git a/public/tags/networking/index.xml b/public/tags/networking/index.xml new file mode 100644 index 0000000..729188b --- /dev/null +++ b/public/tags/networking/index.xml @@ -0,0 +1,9 @@ +Networking on Information Technology Serviceshttps://speedtech.it/tags/networking/Recent content in Networking on Information Technology ServicesHugo -- gohugo.ioitFri, 08 Jul 2022 00:00:00 +0000VPN con router Fritz!Boxhttps://speedtech.it/blog/vpn-con-frizbox/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/vpn-con-frizbox/<p>I routers <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> di AVM forniscono già integrati due importanti servizi che consentono +la connettività da remoto :</p> +<ul> +<li><strong>DNS dinamico</strong></li> +<li><strong>VPN basata su protocollo ipsec</strong></li> +</ul>Servers VPS, Firewall e VPNhttps://speedtech.it/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/blog/finova-firewall/<p>Cliente : Finova (Bolzano - IT)</p> +<p>Progettazione ed implementazione rete e sicurezza per servizi SAS</p>Firewalls, VPN e filtraggio contenutihttps://speedtech.it/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/blog/villamaria-firewalls/Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse web \ No newline at end of file diff --git a/public/tags/networking/page/1/index.html b/public/tags/networking/page/1/index.html new file mode 100644 index 0000000..1f28a04 --- /dev/null +++ b/public/tags/networking/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/networking/ + \ No newline at end of file diff --git a/public/tags/office-server/index.html b/public/tags/office-server/index.html new file mode 100644 index 0000000..dff9aef --- /dev/null +++ b/public/tags/office-server/index.html @@ -0,0 +1,43 @@ +SpeedTech | Office Server +

Server Linux come file e backup server

Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei files

Continua a leggere

Progetti | +NAS +| +Office Server

\ No newline at end of file diff --git a/public/tags/office-server/index.xml b/public/tags/office-server/index.xml new file mode 100644 index 0000000..841cad5 --- /dev/null +++ b/public/tags/office-server/index.xml @@ -0,0 +1,3 @@ +Office Server on Information Technology Serviceshttps://speedtech.it/tags/office-server/Recent content in Office Server on Information Technology ServicesHugo -- gohugo.ioitSat, 12 Mar 2011 00:00:00 +0000Server Linux come file e backup serverhttps://speedtech.it/blog/deflorian-server/Sat, 12 Mar 2011 00:00:00 +0000https://speedtech.it/blog/deflorian-server/Cliente : Deflorian Law Firm (Rovereto - IT) +Server Linux in un ambiente MS Windows per molti utenti con differenti privilegi +Server Debian Linux installazione e configurazione di base Configurazione del supporto software RAID Configurazione del file server ed assegnazione dei privilegi agli utenti Backup ridondato esterno con supporto per versioni dei files \ No newline at end of file diff --git a/public/tags/office-server/page/1/index.html b/public/tags/office-server/page/1/index.html new file mode 100644 index 0000000..1c1fc1a --- /dev/null +++ b/public/tags/office-server/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/office-server/ + \ No newline at end of file diff --git a/public/tags/openssl/index.html b/public/tags/openssl/index.html new file mode 100644 index 0000000..ee86fe6 --- /dev/null +++ b/public/tags/openssl/index.html @@ -0,0 +1,50 @@ +SpeedTech | OpenSSL +

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/tags/openssl/index.xml b/public/tags/openssl/index.xml new file mode 100644 index 0000000..6147ad9 --- /dev/null +++ b/public/tags/openssl/index.xml @@ -0,0 +1,4 @@ +OpenSSL on Information Technology Serviceshttps://speedtech.it/tags/openssl/Recent content in OpenSSL on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p> \ No newline at end of file diff --git a/public/tags/openssl/page/1/index.html b/public/tags/openssl/page/1/index.html new file mode 100644 index 0000000..f73407b --- /dev/null +++ b/public/tags/openssl/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/openssl/ + \ No newline at end of file diff --git a/public/tags/opnsense/index.html b/public/tags/opnsense/index.html new file mode 100644 index 0000000..d3ebbc1 --- /dev/null +++ b/public/tags/opnsense/index.html @@ -0,0 +1,56 @@ +SpeedTech | OpnSense +

Servers VPS, Firewall e VPN

Cliente : Finova (Bolzano - IT) +Progettazione ed implementazione rete e sicurezza per servizi SAS

Continua a leggere

Progetti | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewalls, VPN e filtraggio contenuti

Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse web

Continua a leggere

Firewall +| +VPN +| +Networking +| +OpnSense

\ No newline at end of file diff --git a/public/tags/opnsense/index.xml b/public/tags/opnsense/index.xml new file mode 100644 index 0000000..6991aab --- /dev/null +++ b/public/tags/opnsense/index.xml @@ -0,0 +1,4 @@ +OpnSense on Information Technology Serviceshttps://speedtech.it/tags/opnsense/Recent content in OpnSense on Information Technology ServicesHugo -- gohugo.ioitSat, 14 Sep 2019 00:00:00 +0000Servers VPS, Firewall e VPNhttps://speedtech.it/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/blog/finova-firewall/<p>Cliente : Finova (Bolzano - IT)</p> +<p>Progettazione ed implementazione rete e sicurezza per servizi SAS</p>Firewalls, VPN e filtraggio contenutihttps://speedtech.it/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/blog/villamaria-firewalls/Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse web \ No newline at end of file diff --git a/public/tags/opnsense/page/1/index.html b/public/tags/opnsense/page/1/index.html new file mode 100644 index 0000000..2def663 --- /dev/null +++ b/public/tags/opnsense/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/opnsense/ + \ No newline at end of file diff --git a/public/tags/oracle-database/index.html b/public/tags/oracle-database/index.html new file mode 100644 index 0000000..a3a4898 --- /dev/null +++ b/public/tags/oracle-database/index.html @@ -0,0 +1,47 @@ +SpeedTech | Oracle Database +

Applicazioni per CRM, Oracle e certificazione PCI

Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro

Continua a leggere

Progetti | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/tags/oracle-database/index.xml b/public/tags/oracle-database/index.xml new file mode 100644 index 0000000..7ae19a4 --- /dev/null +++ b/public/tags/oracle-database/index.xml @@ -0,0 +1,3 @@ +Oracle Database on Information Technology Serviceshttps://speedtech.it/tags/oracle-database/Recent content in Oracle Database on Information Technology ServicesHugo -- gohugo.ioitThu, 15 Jun 2000 00:00:00 +0000Applicazioni per CRM, Oracle e certificazione PCIhttps://speedtech.it/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/blog/sint-crm/Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro \ No newline at end of file diff --git a/public/tags/oracle-database/page/1/index.html b/public/tags/oracle-database/page/1/index.html new file mode 100644 index 0000000..7d26903 --- /dev/null +++ b/public/tags/oracle-database/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/oracle-database/ + \ No newline at end of file diff --git a/public/tags/page/1/index.html b/public/tags/page/1/index.html new file mode 100644 index 0000000..1c8fca6 --- /dev/null +++ b/public/tags/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/ + \ No newline at end of file diff --git a/public/tags/pascal/index.html b/public/tags/pascal/index.html new file mode 100644 index 0000000..b264d87 --- /dev/null +++ b/public/tags/pascal/index.html @@ -0,0 +1,47 @@ +SpeedTech | Pascal +

Applicazioni per CRM, Oracle e certificazione PCI

Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro

Continua a leggere

Progetti | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/tags/pascal/index.xml b/public/tags/pascal/index.xml new file mode 100644 index 0000000..70fc1ff --- /dev/null +++ b/public/tags/pascal/index.xml @@ -0,0 +1,3 @@ +Pascal on Information Technology Serviceshttps://speedtech.it/tags/pascal/Recent content in Pascal on Information Technology ServicesHugo -- gohugo.ioitThu, 15 Jun 2000 00:00:00 +0000Applicazioni per CRM, Oracle e certificazione PCIhttps://speedtech.it/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/blog/sint-crm/Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro \ No newline at end of file diff --git a/public/tags/pascal/page/1/index.html b/public/tags/pascal/page/1/index.html new file mode 100644 index 0000000..d1add26 --- /dev/null +++ b/public/tags/pascal/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/pascal/ + \ No newline at end of file diff --git a/public/tags/postgresql/index.html b/public/tags/postgresql/index.html new file mode 100644 index 0000000..8b98f7e --- /dev/null +++ b/public/tags/postgresql/index.html @@ -0,0 +1,44 @@ +SpeedTech | PostgreSQL +
\ No newline at end of file diff --git a/public/tags/postgresql/index.xml b/public/tags/postgresql/index.xml new file mode 100644 index 0000000..26e8bc1 --- /dev/null +++ b/public/tags/postgresql/index.xml @@ -0,0 +1,2 @@ +PostgreSQL on Information Technology Serviceshttps://speedtech.it/tags/postgresql/Recent content in PostgreSQL on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Database link con PostgreSQLhttps://speedtech.it/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/blog/postgresql-database-link/<p>In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che +risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.</p> \ No newline at end of file diff --git a/public/tags/postgresql/page/1/index.html b/public/tags/postgresql/page/1/index.html new file mode 100644 index 0000000..a29a6c0 --- /dev/null +++ b/public/tags/postgresql/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/postgresql/ + \ No newline at end of file diff --git a/public/tags/privacy/index.html b/public/tags/privacy/index.html new file mode 100644 index 0000000..64ab2a1 --- /dev/null +++ b/public/tags/privacy/index.html @@ -0,0 +1,45 @@ +SpeedTech | Privacy +
\ No newline at end of file diff --git a/public/tags/privacy/index.xml b/public/tags/privacy/index.xml new file mode 100644 index 0000000..48d4663 --- /dev/null +++ b/public/tags/privacy/index.xml @@ -0,0 +1,2 @@ +Privacy on Information Technology Serviceshttps://speedtech.it/tags/privacy/Recent content in Privacy on Information Technology ServicesHugo -- gohugo.ioitFri, 08 Jul 2022 00:00:00 +0000Cifrare e comprimere le email lato serverhttps://speedtech.it/blog/cifrare-comprimere-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/cifrare-comprimere-email-server/<p>Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server +<a href="https://www.dovecot.org/">Dovecot</a> permette di cifrare e comprimere i files che contengono la posta elettronica.</p> \ No newline at end of file diff --git a/public/tags/privacy/page/1/index.html b/public/tags/privacy/page/1/index.html new file mode 100644 index 0000000..ee181e4 --- /dev/null +++ b/public/tags/privacy/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/privacy/ + \ No newline at end of file diff --git a/public/tags/pwa/index.html b/public/tags/pwa/index.html new file mode 100644 index 0000000..2b2eb62 --- /dev/null +++ b/public/tags/pwa/index.html @@ -0,0 +1,43 @@ +SpeedTech | PWA +

BrainMinder - second brain web application

BrainMinder è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.

Continua a leggere

Projects | +Software Development +| +Web Application +| +PWA

\ No newline at end of file diff --git a/public/tags/pwa/index.xml b/public/tags/pwa/index.xml new file mode 100644 index 0000000..b0de613 --- /dev/null +++ b/public/tags/pwa/index.xml @@ -0,0 +1,2 @@ +PWA on Information Technology Serviceshttps://speedtech.it/tags/pwa/Recent content in PWA on Information Technology ServicesHugo -- gohugo.ioitThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/blog/brainminder-intro/<p><strong>BrainMinder</strong> è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. +I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.</p> \ No newline at end of file diff --git a/public/tags/pwa/page/1/index.html b/public/tags/pwa/page/1/index.html new file mode 100644 index 0000000..7dcae34 --- /dev/null +++ b/public/tags/pwa/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/pwa/ + \ No newline at end of file diff --git a/public/tags/router/index.html b/public/tags/router/index.html new file mode 100644 index 0000000..201368d --- /dev/null +++ b/public/tags/router/index.html @@ -0,0 +1,45 @@ +SpeedTech | Router +
\ No newline at end of file diff --git a/public/tags/router/index.xml b/public/tags/router/index.xml new file mode 100644 index 0000000..509ccda --- /dev/null +++ b/public/tags/router/index.xml @@ -0,0 +1,6 @@ +Router on Information Technology Serviceshttps://speedtech.it/tags/router/Recent content in Router on Information Technology ServicesHugo -- gohugo.ioitFri, 08 Jul 2022 00:00:00 +0000VPN con router Fritz!Boxhttps://speedtech.it/blog/vpn-con-frizbox/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/vpn-con-frizbox/<p>I routers <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> di AVM forniscono già integrati due importanti servizi che consentono +la connettività da remoto :</p> +<ul> +<li><strong>DNS dinamico</strong></li> +<li><strong>VPN basata su protocollo ipsec</strong></li> +</ul> \ No newline at end of file diff --git a/public/tags/router/page/1/index.html b/public/tags/router/page/1/index.html new file mode 100644 index 0000000..e5989ae --- /dev/null +++ b/public/tags/router/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/router/ + \ No newline at end of file diff --git a/public/tags/security/index.html b/public/tags/security/index.html new file mode 100644 index 0000000..0b5d661 --- /dev/null +++ b/public/tags/security/index.html @@ -0,0 +1,45 @@ +SpeedTech | Security +
\ No newline at end of file diff --git a/public/tags/security/index.xml b/public/tags/security/index.xml new file mode 100644 index 0000000..87a919b --- /dev/null +++ b/public/tags/security/index.xml @@ -0,0 +1,2 @@ +Security on Information Technology Serviceshttps://speedtech.it/tags/security/Recent content in Security on Information Technology ServicesHugo -- gohugo.ioitFri, 08 Jul 2022 00:00:00 +0000Cifrare e comprimere le email lato serverhttps://speedtech.it/blog/cifrare-comprimere-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/cifrare-comprimere-email-server/<p>Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server +<a href="https://www.dovecot.org/">Dovecot</a> permette di cifrare e comprimere i files che contengono la posta elettronica.</p> \ No newline at end of file diff --git a/public/tags/security/page/1/index.html b/public/tags/security/page/1/index.html new file mode 100644 index 0000000..ca32926 --- /dev/null +++ b/public/tags/security/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/security/ + \ No newline at end of file diff --git a/public/tags/server/index.html b/public/tags/server/index.html new file mode 100644 index 0000000..86fd9fa --- /dev/null +++ b/public/tags/server/index.html @@ -0,0 +1,63 @@ +SpeedTech | Server +

Database link con PostgreSQL

In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +PostgreSQL

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

Cifrare e comprimere le email lato server

Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server Dovecot permette di cifrare e comprimere i files che contengono la posta elettronica.

Continua a leggere

Soluzioni | +Security +| +Server +| +Privacy +| +Dovecot

\ No newline at end of file diff --git a/public/tags/server/index.xml b/public/tags/server/index.xml new file mode 100644 index 0000000..1485f50 --- /dev/null +++ b/public/tags/server/index.xml @@ -0,0 +1,6 @@ +Server on Information Technology Serviceshttps://speedtech.it/tags/server/Recent content in Server on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Database link con PostgreSQLhttps://speedtech.it/blog/postgresql-database-link/Sun, 11 Dec 2022 00:00:00 +0000https://speedtech.it/blog/postgresql-database-link/<p>In PostgreSQL è possibile creare dei database links e connettere due database separati, sia che +risiedano sullo stesso server o su servers separati, purchè siano accessibili tramite rete.</p>Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p>Cifrare e comprimere le email lato serverhttps://speedtech.it/blog/cifrare-comprimere-email-server/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/cifrare-comprimere-email-server/<p>Per migliorare la sicurezza e la privacy degli utenti e risparmiare spazio su disco, il mail server +<a href="https://www.dovecot.org/">Dovecot</a> permette di cifrare e comprimere i files che contengono la posta elettronica.</p> \ No newline at end of file diff --git a/public/tags/server/page/1/index.html b/public/tags/server/page/1/index.html new file mode 100644 index 0000000..df30b59 --- /dev/null +++ b/public/tags/server/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/server/ + \ No newline at end of file diff --git a/public/tags/software-development/index.html b/public/tags/software-development/index.html new file mode 100644 index 0000000..3877b4b --- /dev/null +++ b/public/tags/software-development/index.html @@ -0,0 +1,64 @@ +SpeedTech | Software Development +

BrainMinder - second brain web application

BrainMinder è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.

Continua a leggere

Projects | +Software Development +| +Web Application +| +PWA

Applicazione web con funzionalità di foglio di calcolo e sincronizzazione

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.

Continua a leggere

Progetti | +Software Development +| +Web Application

Procedure di sincronizzazione dati

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti con PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezza

Cliente : Amor Cosmetics (Trento - IT) +Sito e-commerce website integrato con pagamenti tramite carta di credito

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

Applicazioni web per contabilità, gestione soci e CMS personalizzato

Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional website

Continua a leggere

Progetti | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/tags/software-development/index.xml b/public/tags/software-development/index.xml new file mode 100644 index 0000000..650c5aa --- /dev/null +++ b/public/tags/software-development/index.xml @@ -0,0 +1,23 @@ +Software Development on Information Technology Serviceshttps://speedtech.it/tags/software-development/Recent content in Software Development on Information Technology ServicesHugo -- gohugo.ioitThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/blog/brainminder-intro/<p><strong>BrainMinder</strong> è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. +I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.</p>Applicazione web con funzionalità di foglio di calcolo e sincronizzazionehttps://speedtech.it/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/blog/wmtrento-spreadsheet-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database +con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p>Procedure di sincronizzazione datihttps://speedtech.it/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/blog/wmtrento-data-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti +con PHP, CodeIgniter, MySQL, Joomla, Virtuemart</p>Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezzahttps://speedtech.it/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/blog/amorcosmetics-ecommerce/<p>Cliente : Amor Cosmetics (Trento - IT)</p> +<p>Sito e-commerce website integrato con pagamenti tramite carta di credito</p>Applicazioni web per contabilità, gestione soci e CMS personalizzatohttps://speedtech.it/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/blog/agiati-web-applications/Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteSoftware per noleggio attrezzature per lo scihttps://speedtech.it/blog/cspolsa-renting/Tue, 12 Dec 2017 00:00:00 +0000https://speedtech.it/blog/cspolsa-renting/Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.Museo e shop onlinehttps://speedtech.it/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/blog/botta-museum/Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del serverSviluppo software per Drupalhttps://speedtech.it/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/blog/versantus-drupal.-development/Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)Svilluppo di applicazioni webhttps://speedtech.it/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/blog/guiet-web-development/Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzatiApplicazione per il tracciamento di Skibus con GPShttps://speedtech.it/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/blog/altevie-geomapping/Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobusInstallazione e personalizzazione sito e-commercehttps://speedtech.it/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzateSviluppo software per Drupalhttps://speedtech.it/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/blog/lrm-drupal-development/Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL)Applicazioni per CRM, Oracle e certificazione PCIhttps://speedtech.it/blog/sint-crm/Mon, 05 Jun 2000 00:00:00 +0000https://speedtech.it/blog/sint-crm/Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro \ No newline at end of file diff --git a/public/tags/software-development/page/1/index.html b/public/tags/software-development/page/1/index.html new file mode 100644 index 0000000..d22ca9b --- /dev/null +++ b/public/tags/software-development/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/software-development/ + \ No newline at end of file diff --git a/public/tags/software-development/page/2/index.html b/public/tags/software-development/page/2/index.html new file mode 100644 index 0000000..5e0cd59 --- /dev/null +++ b/public/tags/software-development/page/2/index.html @@ -0,0 +1,70 @@ +SpeedTech | Software Development +

Software per noleggio attrezzature per lo sci

Cliente: Centro Snowboard Polsa (Rovereto - IT) +Progettazione e sviluppo di un applicativo multi piattaforma per sistemi operativi MS Windows e Linux utilizzando : +Linguaggio ObjectPascal Lazaurs IDE MariaDB database Server Linux locale per il noleggio di sci ed accessori.

Continua a leggere

Progetti | +Software Development +| +Desktop Application

Museo e shop online

Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del server

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

Sviluppo software per Drupal

Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Svilluppo di applicazioni web

Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzati

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Applicazione per il tracciamento di Skibus con GPS

Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobus

Continua a leggere

Progetti | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/tags/software-development/page/3/index.html b/public/tags/software-development/page/3/index.html new file mode 100644 index 0000000..a845934 --- /dev/null +++ b/public/tags/software-development/page/3/index.html @@ -0,0 +1,60 @@ +SpeedTech | Software Development +

Installazione e personalizzazione sito e-commerce

Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzate

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

Sviluppo software per Drupal

Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Applicazioni per CRM, Oracle e certificazione PCI

Cliente : SINT (Torino - IT) +Applicazioni per la gestione CRM, integrate con database Oracle e con certificazione PCI +Disegno ed implementazione del database Oracle Sviluppo delle applicazioni desktop con funzionalità uniche : aggiornamenti automatici, client Oracle integratto, reports ntegrati Applicazioni sia per il backend che il frontend del CRM Instrastruttura del database e delle applicazioni aderente allo standard PCI per memorizzare in maniera sicura le informazioni sensibili : progettazione e sviluppo di un sistema di cifratura dei dati sul database Oracle innovativo ed estremamente sicuro

Continua a leggere

Progetti | +Software Development +| +Desktop Application +| +Oracle Database +| +Pascal

\ No newline at end of file diff --git a/public/tags/system-administration/index.html b/public/tags/system-administration/index.html new file mode 100644 index 0000000..4e7b4e8 --- /dev/null +++ b/public/tags/system-administration/index.html @@ -0,0 +1,55 @@ +SpeedTech | System Administration +

Servers VPS, Firewall e VPN

Cliente : Finova (Bolzano - IT) +Progettazione ed implementazione rete e sicurezza per servizi SAS

Continua a leggere

Progetti | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewall, VPN e rete in server farm

Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi

Continua a leggere

Progetti | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/tags/system-administration/index.xml b/public/tags/system-administration/index.xml new file mode 100644 index 0000000..df02743 --- /dev/null +++ b/public/tags/system-administration/index.xml @@ -0,0 +1,4 @@ +System Administration on Information Technology Serviceshttps://speedtech.it/tags/system-administration/Recent content in System Administration on Information Technology ServicesHugo -- gohugo.ioitSat, 14 Sep 2019 00:00:00 +0000Servers VPS, Firewall e VPNhttps://speedtech.it/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/blog/finova-firewall/<p>Cliente : Finova (Bolzano - IT)</p> +<p>Progettazione ed implementazione rete e sicurezza per servizi SAS</p>Firewall, VPN e rete in server farmhttps://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi \ No newline at end of file diff --git a/public/tags/system-administration/page/1/index.html b/public/tags/system-administration/page/1/index.html new file mode 100644 index 0000000..07a3179 --- /dev/null +++ b/public/tags/system-administration/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/system-administration/ + \ No newline at end of file diff --git a/public/tags/ufw/index.html b/public/tags/ufw/index.html new file mode 100644 index 0000000..79f10ce --- /dev/null +++ b/public/tags/ufw/index.html @@ -0,0 +1,50 @@ +SpeedTech | UFW +

Replicazione master-master MariaDB tramite Internet

MariaDB (e MySQL) consentono di configurare la replica master-slave tra due servers. Una replica di tipo master-master può esere implementata tramite Galera, ma richiede almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master duplicando in maniera incrociata la replica master-slave.

Continua a leggere

Soluzioni | +Technology | +Server +| +Database +| +Firewall +| +MariaDB +| +OpenSSL +| +UFW

\ No newline at end of file diff --git a/public/tags/ufw/index.xml b/public/tags/ufw/index.xml new file mode 100644 index 0000000..7c8b1c7 --- /dev/null +++ b/public/tags/ufw/index.xml @@ -0,0 +1,4 @@ +UFW on Information Technology Serviceshttps://speedtech.it/tags/ufw/Recent content in UFW on Information Technology ServicesHugo -- gohugo.ioitSun, 11 Dec 2022 00:00:00 +0000Replicazione master-master MariaDB tramite Internethttps://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/Tue, 19 Jul 2022 00:00:00 +0000https://speedtech.it/blog/mariadb-replicazione-master-master-tramite-internet/<p><a href="https://mariadb.org">MariaDB</a> (e MySQL) consentono di configurare la replica master-slave tra due servers. +Una replica di tipo master-master può esere implementata tramite Galera, ma richiede +almeno 3 servers. Se si dispone di 2 servers è possibile configurare una replica master-master +duplicando in maniera incrociata la replica master-slave.</p> \ No newline at end of file diff --git a/public/tags/ufw/page/1/index.html b/public/tags/ufw/page/1/index.html new file mode 100644 index 0000000..8ed1ee0 --- /dev/null +++ b/public/tags/ufw/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/ufw/ + \ No newline at end of file diff --git a/public/tags/vpn/index.html b/public/tags/vpn/index.html new file mode 100644 index 0000000..38d0d08 --- /dev/null +++ b/public/tags/vpn/index.html @@ -0,0 +1,70 @@ +SpeedTech | VPN +

VPN con router Fritz!Box

I routers Fritz!Box di AVM forniscono già integrati due importanti servizi che consentono la connettività da remoto : +DNS dinamico VPN basata su protocollo ipsec

Continua a leggere

Soluzioni | +Technology | +VPN +| +Router +| +Networking

Servers VPS, Firewall e VPN

Cliente : Finova (Bolzano - IT) +Progettazione ed implementazione rete e sicurezza per servizi SAS

Continua a leggere

Progetti | +Firewall +| +VPN +| +Networking +| +OpnSense +| +System Administration

Firewalls, VPN e filtraggio contenuti

Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse web

Continua a leggere

Firewall +| +VPN +| +Networking +| +OpnSense

Firewall, VPN e rete in server farm

Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi

Continua a leggere

Progetti | +VPN +| +Firewall +| +System Administration

\ No newline at end of file diff --git a/public/tags/vpn/index.xml b/public/tags/vpn/index.xml new file mode 100644 index 0000000..2ae8c63 --- /dev/null +++ b/public/tags/vpn/index.xml @@ -0,0 +1,11 @@ +VPN on Information Technology Serviceshttps://speedtech.it/tags/vpn/Recent content in VPN on Information Technology ServicesHugo -- gohugo.ioitFri, 08 Jul 2022 00:00:00 +0000VPN con router Fritz!Boxhttps://speedtech.it/blog/vpn-con-frizbox/Fri, 08 Jul 2022 00:00:00 +0000https://speedtech.it/blog/vpn-con-frizbox/<p>I routers <a href="https://it.avm.de/prodotti/fritzbox/">Fritz!Box</a> di AVM forniscono già integrati due importanti servizi che consentono +la connettività da remoto :</p> +<ul> +<li><strong>DNS dinamico</strong></li> +<li><strong>VPN basata su protocollo ipsec</strong></li> +</ul>Servers VPS, Firewall e VPNhttps://speedtech.it/blog/finova-firewall/Sat, 14 Sep 2019 00:00:00 +0000https://speedtech.it/blog/finova-firewall/<p>Cliente : Finova (Bolzano - IT)</p> +<p>Progettazione ed implementazione rete e sicurezza per servizi SAS</p>Firewalls, VPN e filtraggio contenutihttps://speedtech.it/blog/villamaria-firewalls/Thu, 14 Jan 2016 00:00:00 +0000https://speedtech.it/blog/villamaria-firewalls/Cliente : Cooperativa VillaMaria (Rovereto - IT) +Firewalls, VPN sede-sede e client-sede, controllo accessi al web ed ai contenuti +Configurazione dell&rsquo; hardware Installazione del sistema di firewall e configurazione del supporto RAID Installazione della VPN sede-sede basata su OpenVPN per connettere due sedi remote Installazione delle VPN per singole postazioni per consentire il tele lavoro Filtraggio trasparente dei contenuti per controllare l&rsquo;accesso alle risorse webFirewall, VPN e rete in server farmhttps://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Fri, 07 Jun 2002 00:00:00 +0000https://speedtech.it/blog/daxtor-firewall-vpn-server-farm/Cliente : Daxtor (Bolzano - IT) +Progettazione ed implementazione della rete e della sicurezza per un servizio SAS in server farm +Selezione dell&rsquo; hardware Disegno della rete Installazione e configurazione degli application server Linux Installazione del database server Oracle Configurazione e manutenzione dei firewalls ridondati Configurazione e manutenzione delle VPN IPSenc e OpenVPN per controllo degli accessi \ No newline at end of file diff --git a/public/tags/vpn/page/1/index.html b/public/tags/vpn/page/1/index.html new file mode 100644 index 0000000..6870381 --- /dev/null +++ b/public/tags/vpn/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/vpn/ + \ No newline at end of file diff --git a/public/tags/web-application/index.html b/public/tags/web-application/index.html new file mode 100644 index 0000000..aed9f70 --- /dev/null +++ b/public/tags/web-application/index.html @@ -0,0 +1,64 @@ +SpeedTech | Web Application +

BrainMinder - second brain web application

BrainMinder è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.

Continua a leggere

Projects | +Software Development +| +Web Application +| +PWA

Applicazione web con funzionalità di foglio di calcolo e sincronizzazione

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.

Continua a leggere

Progetti | +Software Development +| +Web Application

Procedure di sincronizzazione dati

Cliente : Web Marketing Trento (Trento - IT) +Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti con PHP, CodeIgniter, MySQL, Joomla, Virtuemart

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezza

Cliente : Amor Cosmetics (Trento - IT) +Sito e-commerce website integrato con pagamenti tramite carta di credito

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

Applicazioni web per contabilità, gestione soci e CMS personalizzato

Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional website

Continua a leggere

Progetti | +Software Development +| +Web Application

\ No newline at end of file diff --git a/public/tags/web-application/index.xml b/public/tags/web-application/index.xml new file mode 100644 index 0000000..63be95e --- /dev/null +++ b/public/tags/web-application/index.xml @@ -0,0 +1,19 @@ +Web Application on Information Technology Serviceshttps://speedtech.it/tags/web-application/Recent content in Web Application on Information Technology ServicesHugo -- gohugo.ioitThu, 30 Oct 2025 00:00:00 +0000BrainMinder - second brain web applicationhttps://speedtech.it/blog/brainminder-intro/Thu, 30 Oct 2025 00:00:00 +0000https://speedtech.it/blog/brainminder-intro/<p><strong>BrainMinder</strong> è un software per archiviare e organizzare il proprio archivio di conoscenze, condividerlo con gli altri, analizzare situazioni, idee, e problemi, e prendere decisioni ponderate. +I singoli articoli sono condivisi con gli utenti esterni via un url pre autorizzato e (opzionalmente) con una password aggiuntiva.</p>Applicazione web con funzionalità di foglio di calcolo e sincronizzazionehttps://speedtech.it/blog/wmtrento-spreadsheet-sync/Sun, 07 May 2023 00:00:00 +0000https://speedtech.it/blog/wmtrento-spreadsheet-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure di sincronizzazione dati tra differenti applicativi e database +con un interfaccia a foglio di calcolo con : PHP, MariaDB, Joomla, Virtuemart, CodeIgniter, VueJS.</p>Procedure di sincronizzazione datihttps://speedtech.it/blog/wmtrento-data-sync/Mon, 07 Nov 2022 00:00:00 +0000https://speedtech.it/blog/wmtrento-data-sync/<p>Cliente : Web Marketing Trento (Trento - IT)</p> +<p>Progettazione e sviluppo di procedure sincronizzazione dati tra applicativi e basi dati differenti +con PHP, CodeIgniter, MySQL, Joomla, Virtuemart</p>Configurazione e personalizzazione del sito di e-commerce per prodotti di bellezzahttps://speedtech.it/blog/amorcosmetics-ecommerce/Thu, 27 May 2021 00:00:00 +0000https://speedtech.it/blog/amorcosmetics-ecommerce/<p>Cliente : Amor Cosmetics (Trento - IT)</p> +<p>Sito e-commerce website integrato con pagamenti tramite carta di credito</p>Applicazioni web per contabilità, gestione soci e CMS personalizzatohttps://speedtech.it/blog/agiati-web-applications/Sat, 04 May 2019 00:00:00 +0000https://speedtech.it/blog/agiati-web-applications/Cliente : Accademia degli Agiati (Rovereto - IT) +Tecnologie utilizzate : PHP, Yii Framework, MariaDB, Bootstrap +Database design Logic and structure study Applications implementation and development Support and maintenance CMS for the institutional websiteMuseo e shop onlinehttps://speedtech.it/blog/botta-museum/Sat, 15 Apr 2017 00:00:00 +0000https://speedtech.it/blog/botta-museum/Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del serverSviluppo software per Drupalhttps://speedtech.it/blog/versantus-drupal.-development/Wed, 03 Feb 2016 00:00:00 +0000https://speedtech.it/blog/versantus-drupal.-development/Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)Svilluppo di applicazioni webhttps://speedtech.it/blog/guiet-web-development/Mon, 03 Aug 2015 00:00:00 +0000https://speedtech.it/blog/guiet-web-development/Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzatiApplicazione per il tracciamento di Skibus con GPShttps://speedtech.it/blog/altevie-geomapping/Sat, 31 Jan 2015 00:00:00 +0000https://speedtech.it/blog/altevie-geomapping/Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobusInstallazione e personalizzazione sito e-commercehttps://speedtech.it/blog/amore-ecommerce/Thu, 02 Aug 2012 00:00:00 +0000https://speedtech.it/blog/amore-ecommerce/Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzateSviluppo software per Drupalhttps://speedtech.it/blog/lrm-drupal-development/Sun, 13 Jun 2010 00:00:00 +0000https://speedtech.it/blog/lrm-drupal-development/Cliente : LeftRightMinds (Vancouver - CA) +Sviluppo moduli personalizzati per Drupal (Drupal, PHP, MySQL) \ No newline at end of file diff --git a/public/tags/web-application/page/1/index.html b/public/tags/web-application/page/1/index.html new file mode 100644 index 0000000..9b70613 --- /dev/null +++ b/public/tags/web-application/page/1/index.html @@ -0,0 +1,2 @@ +https://speedtech.it/tags/web-application/ + \ No newline at end of file diff --git a/public/tags/web-application/page/2/index.html b/public/tags/web-application/page/2/index.html new file mode 100644 index 0000000..683fa5e --- /dev/null +++ b/public/tags/web-application/page/2/index.html @@ -0,0 +1,72 @@ +SpeedTech | Web Application +

Museo e shop online

Cliente : Museo Botta (Rovereto - IT) +Museo virtuale per modelli d&rsquo;auto ed oggetti pubblicitari con e-commerce personalizzato +Impostazione del framework PHP Yii2 Implementazione del design del cliente Integrazione del framework Bootstrap 3 Negozio online con sistema d&rsquo;ordine e di pagamenti Installazione e configurazione del server

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce +| +Custom CMS

Sviluppo software per Drupal

Cliente : Versantus (Oxford - UK) +Sviluppo moduli personalizzati per Drupal CMS (Drupal, PHP, MySQL)

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Svilluppo di applicazioni web

Cliente : GUIET.com (Fribourg - CH) +Sviluppo in Drupal, CodeIgniter, Yii, e di CMS personalizzati +Progettazione dei database Studio della logica delle applicazioni ed implementazione dei backend Sviluppo di funzionalità personalizzate Supporto e manutenzione Progettazione e sviluppo di CMS con supporto multilingua personalizzati

Continua a leggere

Progetti | +Software Development +| +Web Application +| +Custom CMS

Applicazione per il tracciamento di Skibus con GPS

Cliente : Altevie (Trento - IT) +Applicazione web responsive con mappa responsive per il tracciamento della posizione di skibus dotati di gps +Progettazione e sviluppo dell&rsquo;applicazione Installazione e configurazione del database e del server Linux Integrazione con servizi esterni SOAP per la determinazione delle posizioni degli autobus e degli orari Sviluppo delle funzionalità della mappa con le posizioni delle fermate, posizione e direzione in tempo reale degli autobus

Continua a leggere

Progetti | +Software Development +| +Web Application

Installazione e personalizzazione sito e-commerce

Cliente : Ditta Amore (Rovereto - IT) +Sito di e-commerce integrato con pagamenti tramite carta di credito e calcolo spese di spedizione +Installazione e configurazione della piattaforma di e-commerce OpenCart Selezione, installazione e personalizzazione dei moduli Integrazione del sistema di pagamento tramite carta di credito Stripe Sviluppo del modulo di calcolo personalizzato delle spese di spedizione Sviluppo di funzionalità personalizzate

Continua a leggere

Progetti | +Software Development +| +Web Application +| +E-Commerce

\ No newline at end of file diff --git a/public/tags/web-application/page/3/index.html b/public/tags/web-application/page/3/index.html new file mode 100644 index 0000000..156d913 --- /dev/null +++ b/public/tags/web-application/page/3/index.html @@ -0,0 +1,44 @@ +SpeedTech | Web Application +
\ No newline at end of file diff --git a/resources/_gen/images/images/blog/amadeo_peter_giannini_hudd36464ff5c18d53204383ae26d0d0e1_49518_200x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/amadeo_peter_giannini_hudd36464ff5c18d53204383ae26d0d0e1_49518_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..a6040c2 Binary files /dev/null and b/resources/_gen/images/images/blog/amadeo_peter_giannini_hudd36464ff5c18d53204383ae26d0d0e1_49518_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/amadeo_peter_giannini_hudd36464ff5c18d53204383ae26d0d0e1_49518_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/amadeo_peter_giannini_hudd36464ff5c18d53204383ae26d0d0e1_49518_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..3964999 Binary files /dev/null and b/resources/_gen/images/images/blog/amadeo_peter_giannini_hudd36464ff5c18d53204383ae26d0d0e1_49518_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_200x0_resize_box_3.png b/resources/_gen/images/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_200x0_resize_box_3.png new file mode 100644 index 0000000..ac9e3ff Binary files /dev/null and b/resources/_gen/images/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_500x200_crop_box_smart1_3.png b/resources/_gen/images/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_500x200_crop_box_smart1_3.png new file mode 100644 index 0000000..37a82f2 Binary files /dev/null and b/resources/_gen/images/images/blog/brainminder_hu1e83e6fcbe10acdd81c6d0d0e9901bac_73079_500x200_crop_box_smart1_3.png differ diff --git a/resources/_gen/images/images/blog/dashcam_car_hu01664137a0a5882ded67f24c4b792271_35120_200x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/dashcam_car_hu01664137a0a5882ded67f24c4b792271_35120_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..369db62 Binary files /dev/null and b/resources/_gen/images/images/blog/dashcam_car_hu01664137a0a5882ded67f24c4b792271_35120_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/dashcam_car_hu01664137a0a5882ded67f24c4b792271_35120_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/dashcam_car_hu01664137a0a5882ded67f24c4b792271_35120_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..d7ad695 Binary files /dev/null and b/resources/_gen/images/images/blog/dashcam_car_hu01664137a0a5882ded67f24c4b792271_35120_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/economia-spiegata-facile-costantino-rover_hu6e73a4a91ed81b69b5ad633cb3f8fed7_226482_200x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/economia-spiegata-facile-costantino-rover_hu6e73a4a91ed81b69b5ad633cb3f8fed7_226482_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..f629242 Binary files /dev/null and b/resources/_gen/images/images/blog/economia-spiegata-facile-costantino-rover_hu6e73a4a91ed81b69b5ad633cb3f8fed7_226482_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/economia-spiegata-facile-costantino-rover_hu6e73a4a91ed81b69b5ad633cb3f8fed7_226482_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/economia-spiegata-facile-costantino-rover_hu6e73a4a91ed81b69b5ad633cb3f8fed7_226482_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..604360c Binary files /dev/null and b/resources/_gen/images/images/blog/economia-spiegata-facile-costantino-rover_hu6e73a4a91ed81b69b5ad633cb3f8fed7_226482_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/encrypt-compress-emails-on-server_hu8995f33c082518cd1ac5df8b558b3a81_102847_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/encrypt-compress-emails-on-server_hu8995f33c082518cd1ac5df8b558b3a81_102847_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..cb22a8a Binary files /dev/null and b/resources/_gen/images/images/blog/encrypt-compress-emails-on-server_hu8995f33c082518cd1ac5df8b558b3a81_102847_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/fritzbox_hu0e686bad92efa212c8c6740e66a8c0fd_22778_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/fritzbox_hu0e686bad92efa212c8c6740e66a8c0fd_22778_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..a54edda Binary files /dev/null and b/resources/_gen/images/images/blog/fritzbox_hu0e686bad92efa212c8c6740e66a8c0fd_22778_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_200x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..0a9c653 Binary files /dev/null and b/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..ff5f035 Binary files /dev/null and b/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_500x200_crop_q75_box_smart1.jpg b/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_500x200_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..416a6d5 Binary files /dev/null and b/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_500x200_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_600x400_crop_q75_box_smart1.jpg b/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_600x400_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..cf38f42 Binary files /dev/null and b/resources/_gen/images/images/blog/home-assistant_hud8587ebef75f9af2ca0bbe5f5b19dc45_61256_600x400_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/blog/mariadb-replication-master-master_hu9b6f22ee8f75055e2c369fb76658aa04_94974_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/mariadb-replication-master-master_hu9b6f22ee8f75055e2c369fb76658aa04_94974_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..c225220 Binary files /dev/null and b/resources/_gen/images/images/blog/mariadb-replication-master-master_hu9b6f22ee8f75055e2c369fb76658aa04_94974_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/mariadb-replication-master-master_hu9b6f22ee8f75055e2c369fb76658aa04_94974_500x200_crop_q75_box_smart1.jpg b/resources/_gen/images/images/blog/mariadb-replication-master-master_hu9b6f22ee8f75055e2c369fb76658aa04_94974_500x200_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..f8dbe3a Binary files /dev/null and b/resources/_gen/images/images/blog/mariadb-replication-master-master_hu9b6f22ee8f75055e2c369fb76658aa04_94974_500x200_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_200x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..a0798b8 Binary files /dev/null and b/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..cbe2513 Binary files /dev/null and b/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_500x200_crop_q75_box_smart1.jpg b/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_500x200_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..d627188 Binary files /dev/null and b/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_500x200_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_600x400_crop_q75_box_smart1.jpg b/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_600x400_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..7aa1281 Binary files /dev/null and b/resources/_gen/images/images/blog/postgresql_hu0d75c994c55fb1d165504c57f70131c4_34984_600x400_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/blog/tester_hua4e2e37f5b4b2a08b209054ba1d341ef_46945_200x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/tester_hua4e2e37f5b4b2a08b209054ba1d341ef_46945_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..bff9a1c Binary files /dev/null and b/resources/_gen/images/images/blog/tester_hua4e2e37f5b4b2a08b209054ba1d341ef_46945_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/blog/tester_hua4e2e37f5b4b2a08b209054ba1d341ef_46945_300x0_resize_q75_box.jpg b/resources/_gen/images/images/blog/tester_hua4e2e37f5b4b2a08b209054ba1d341ef_46945_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..e15f733 Binary files /dev/null and b/resources/_gen/images/images/blog/tester_hua4e2e37f5b4b2a08b209054ba1d341ef_46945_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_200x0_resize_box_3.png b/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_200x0_resize_box_3.png new file mode 100644 index 0000000..c7b0162 Binary files /dev/null and b/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_300x0_resize_box_3.png b/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_300x0_resize_box_3.png new file mode 100644 index 0000000..dcd3c30 Binary files /dev/null and b/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_500x200_crop_box_smart1_3.png b/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_500x200_crop_box_smart1_3.png new file mode 100644 index 0000000..6084213 Binary files /dev/null and b/resources/_gen/images/images/project/agiati-web-application-development_hu2946c766f49504156fccaa1dad5e0d06_106666_500x200_crop_box_smart1_3.png differ diff --git a/resources/_gen/images/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_200x0_resize_box_3.png b/resources/_gen/images/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_200x0_resize_box_3.png new file mode 100644 index 0000000..2cd183b Binary files /dev/null and b/resources/_gen/images/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_300x0_resize_box_3.png b/resources/_gen/images/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_300x0_resize_box_3.png new file mode 100644 index 0000000..8b331bc Binary files /dev/null and b/resources/_gen/images/images/project/altevie-web-application-geolocation_hu2d67f29c10ff24b21553ddfd87afa8e2_213880_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_200x0_resize_box_3.png b/resources/_gen/images/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_200x0_resize_box_3.png new file mode 100644 index 0000000..feafaf3 Binary files /dev/null and b/resources/_gen/images/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_300x0_resize_box_3.png b/resources/_gen/images/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_300x0_resize_box_3.png new file mode 100644 index 0000000..5e66f8d Binary files /dev/null and b/resources/_gen/images/images/project/amor-cosmetics-ecommerce_hua5329c0eed38dfdb229b283a167b1ec5_146810_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_200x0_resize_box_3.png b/resources/_gen/images/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_200x0_resize_box_3.png new file mode 100644 index 0000000..7e9dc2f Binary files /dev/null and b/resources/_gen/images/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_300x0_resize_box_3.png b/resources/_gen/images/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_300x0_resize_box_3.png new file mode 100644 index 0000000..9886a11 Binary files /dev/null and b/resources/_gen/images/images/project/amore-ecommerce_huc50add26cc38c43ca76fb0fed133f22e_83120_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_200x0_resize_box_3.png b/resources/_gen/images/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_200x0_resize_box_3.png new file mode 100644 index 0000000..0f28152 Binary files /dev/null and b/resources/_gen/images/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_300x0_resize_box_3.png b/resources/_gen/images/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_300x0_resize_box_3.png new file mode 100644 index 0000000..ada9ec5 Binary files /dev/null and b/resources/_gen/images/images/project/botta-online-museum_hua8182154a4113f55be195247f4013160_134178_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_200x0_resize_q75_box.jpg b/resources/_gen/images/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..4b18c73 Binary files /dev/null and b/resources/_gen/images/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..c76d90d Binary files /dev/null and b/resources/_gen/images/images/project/coopvillamaria-opnsense-firewalls_hu32e0fb49bfa71d102a7b586b2e305cb0_59874_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/cspolsa-renting-software_hud1bd90c3c950f52c1fd434a14269f4c1_134715_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/cspolsa-renting-software_hud1bd90c3c950f52c1fd434a14269f4c1_134715_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..188ee04 Binary files /dev/null and b/resources/_gen/images/images/project/cspolsa-renting-software_hud1bd90c3c950f52c1fd434a14269f4c1_134715_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_200x0_resize_q75_box.jpg b/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..03d3761 Binary files /dev/null and b/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..82e588a Binary files /dev/null and b/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_500x200_crop_q75_box_smart1.jpg b/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_500x200_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..84c28fe Binary files /dev/null and b/resources/_gen/images/images/project/daxtor-firewall-vpn-server-farm_hu17eaec8900e7d11c064c73dcb22fcfed_133645_500x200_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_200x0_resize_box_3.png b/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_200x0_resize_box_3.png new file mode 100644 index 0000000..45fcc0a Binary files /dev/null and b/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_300x0_resize_box_3.png b/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_300x0_resize_box_3.png new file mode 100644 index 0000000..3b843c5 Binary files /dev/null and b/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_500x200_crop_box_smart1_3.png b/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_500x200_crop_box_smart1_3.png new file mode 100644 index 0000000..8bc94d1 Binary files /dev/null and b/resources/_gen/images/images/project/deflorian-server_hud733027e7b83f6df68eb6aa9eecc0d63_78038_500x200_crop_box_smart1_3.png differ diff --git a/resources/_gen/images/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_200x0_resize_box_3.png b/resources/_gen/images/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_200x0_resize_box_3.png new file mode 100644 index 0000000..6a29bb4 Binary files /dev/null and b/resources/_gen/images/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_300x0_resize_box_3.png b/resources/_gen/images/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_300x0_resize_box_3.png new file mode 100644 index 0000000..c81a1cc Binary files /dev/null and b/resources/_gen/images/images/project/finova-oracle-apex_huc5c77e4cd93a9e76bb0e1e60cf209584_61279_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_200x0_resize_q75_box.jpg b/resources/_gen/images/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..6700ca4 Binary files /dev/null and b/resources/_gen/images/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..dfe565c Binary files /dev/null and b/resources/_gen/images/images/project/finova-vps-servers-firewall-vpn_hu0a91eb87363b67d2e0a624b87e2a6a5a_251373_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_200x0_resize_q75_box.jpg b/resources/_gen/images/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..8c441aa Binary files /dev/null and b/resources/_gen/images/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..d22c0b9 Binary files /dev/null and b/resources/_gen/images/images/project/guiet-web-application-development_hud2f56e0b925d14ab6b970929ed381a6e_49356_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_200x0_resize_box_3.png b/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_200x0_resize_box_3.png new file mode 100644 index 0000000..dfb7ff7 Binary files /dev/null and b/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_200x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_300x0_resize_box_3.png b/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_300x0_resize_box_3.png new file mode 100644 index 0000000..16fdd3e Binary files /dev/null and b/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_300x0_resize_box_3.png differ diff --git a/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_500x200_crop_box_smart1_3.png b/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_500x200_crop_box_smart1_3.png new file mode 100644 index 0000000..b4dbdfe Binary files /dev/null and b/resources/_gen/images/images/project/lrm-drupal_hub6255885ff6bf84844a08c7f01376c04_54288_500x200_crop_box_smart1_3.png differ diff --git a/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_200x0_resize_q75_box.jpg b/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..f8a93e7 Binary files /dev/null and b/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..edb21ff Binary files /dev/null and b/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_500x200_crop_q75_box_smart1.jpg b/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_500x200_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..5bd34c2 Binary files /dev/null and b/resources/_gen/images/images/project/sint-crm_huff2f50fa8a0a593f5ce69a113cc9f94d_81444_500x200_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/project/synology-nas_hu5ae6a5b01094e31b3f89e15395616b06_24878_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/synology-nas_hu5ae6a5b01094e31b3f89e15395616b06_24878_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..be58a3b Binary files /dev/null and b/resources/_gen/images/images/project/synology-nas_hu5ae6a5b01094e31b3f89e15395616b06_24878_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_200x0_resize_q75_box.jpg b/resources/_gen/images/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..623729a Binary files /dev/null and b/resources/_gen/images/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..30e615f Binary files /dev/null and b/resources/_gen/images/images/project/versantus-drupal_hua0b99ed76f32c1e0e77556899b765f65_29265_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_200x0_resize_q75_box.jpg b/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..03d4416 Binary files /dev/null and b/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..c32d22a Binary files /dev/null and b/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_500x200_crop_q75_box_smart1.jpg b/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_500x200_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..b24aad2 Binary files /dev/null and b/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_500x200_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_600x400_crop_q75_box_smart1.jpg b/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_600x400_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..229cc1c Binary files /dev/null and b/resources/_gen/images/images/project/wmtrento-data-sync_hu34ea70024152f2d9c23817aad8f1f542_66173_600x400_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_200x0_resize_q75_box.jpg b/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_200x0_resize_q75_box.jpg new file mode 100644 index 0000000..fad559f Binary files /dev/null and b/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_200x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_300x0_resize_q75_box.jpg b/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_300x0_resize_q75_box.jpg new file mode 100644 index 0000000..1e7a59b Binary files /dev/null and b/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_300x0_resize_q75_box.jpg differ diff --git a/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_500x200_crop_q75_box_smart1.jpg b/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_500x200_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..b7d5983 Binary files /dev/null and b/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_500x200_crop_q75_box_smart1.jpg differ diff --git a/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_600x400_crop_q75_box_smart1.jpg b/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_600x400_crop_q75_box_smart1.jpg new file mode 100644 index 0000000..7f7ac53 Binary files /dev/null and b/resources/_gen/images/images/project/wmtrento-jspreadsheet_hu80e88a9b53e97bd051be5a21f49c7525_29205_600x400_crop_q75_box_smart1.jpg differ diff --git a/static/css/main.css b/static/css/main.css index 79055fc..7492eac 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -92,6 +92,11 @@ footer .menu { padding: 10px; } +.articlecontent a { + color: var(--primary-color); + text-decoration: underline; +} + .servicesidebar h4 { margin-bottom: 16px; }