Compare commits
19 Commits
dev-full-r
...
master
Author | SHA1 | Date | |
---|---|---|---|
3e29592b48 | |||
30da615199 | |||
615affcc2d | |||
eb2ffa296b | |||
41286a8253 | |||
a20b45d86e | |||
690b3179ed | |||
b11ed247dc | |||
c58cb8a405 | |||
3e2b917d21 | |||
df93ee47b2 | |||
92d7b245a2 | |||
4f11e82290 | |||
cca310eeac | |||
9eba329603 | |||
ff0fa72a4b | |||
6276a74f30 | |||
accdf741f1 | |||
4d80ed906f |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,6 +4,7 @@
|
||||
|
||||
# Build artifacts
|
||||
__pycache__/
|
||||
*.tar
|
||||
|
||||
# NodeJS' BS
|
||||
node_modules/
|
||||
@@ -13,5 +14,6 @@ node_modules/
|
||||
*.ai
|
||||
|
||||
# Temp
|
||||
static/resources/DecimalJs*
|
||||
static/resources/SortableJS
|
||||
static/resources/Standalone
|
||||
|
9
app.py
9
app.py
@@ -9,7 +9,8 @@ from flask import render_template
|
||||
from werkzeug.exceptions import HTTPException
|
||||
|
||||
from website.content import get_projects, get_tools, sanitize_input_tags, load_content_items, get_content, \
|
||||
get_applets, get_projects_languages, get_projects_by_languages
|
||||
get_applets, get_projects_languages, get_projects_by_languages, get_sorted_tools_by_tags, \
|
||||
get_sorted_projects_by_tags
|
||||
from website.contributors import reload_contributors_data
|
||||
from website.domains import ALLOWED_DOMAINS
|
||||
from website.l10n.utils import get_user_lang, localize, reload_strings, l10n_url_abs, l10n_url_switch, DEFAULT_LANG
|
||||
@@ -119,9 +120,11 @@ def inject_processors():
|
||||
get_applets=get_applets,
|
||||
# get_articles=get_articles,
|
||||
get_projects=get_projects,
|
||||
get_projects_by_languages=get_projects_by_languages,
|
||||
get_projects_languages=get_projects_languages,
|
||||
# get_projects_by_languages=get_projects_by_languages,
|
||||
# get_projects_languages=get_projects_languages,
|
||||
get_tools=get_tools,
|
||||
get_sorted_projects_by_tags=get_sorted_projects_by_tags,
|
||||
get_sorted_tools_by_tags=get_sorted_tools_by_tags,
|
||||
|
||||
# Renderers
|
||||
render_button=render_button,
|
||||
|
7
data/applets/png-analyser.yml
Normal file
7
data/applets/png-analyser.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
applets:
|
||||
- id: "png-analyser"
|
||||
resources:
|
||||
scripts:
|
||||
- "applet://png-analyser.mjs"
|
||||
stylesheets:
|
||||
- "applet://png-analyser.css"
|
@@ -1,7 +0,0 @@
|
||||
applets:
|
||||
- id: "png-chunk-analyser"
|
||||
resources:
|
||||
scripts:
|
||||
- "applet://png-chunk-analyser.mjs"
|
||||
stylesheets:
|
||||
- "applet://png-chunk-analyser.css"
|
7
data/applets/vat-calculator.yml
Normal file
7
data/applets/vat-calculator.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
applets:
|
||||
- id: "vat-calculator"
|
||||
resources:
|
||||
scripts:
|
||||
- "applet://vat-calculator.mjs"
|
||||
stylesheets:
|
||||
- "applet://vat-calculator.css"
|
@@ -16,7 +16,7 @@ projects:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
index:
|
||||
priority: 105
|
||||
priority: 3000
|
||||
enable: true
|
||||
title_key: "meta.title"
|
||||
preamble_key: "meta.description"
|
||||
|
@@ -16,7 +16,7 @@ projects:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
index:
|
||||
priority: 105
|
||||
priority: 1000
|
||||
enable: true
|
||||
title_key: "meta.title"
|
||||
preamble_key: "meta.description"
|
||||
|
@@ -16,7 +16,7 @@ projects:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
index:
|
||||
priority: 105
|
||||
priority: 2000
|
||||
enable: true
|
||||
title_key: "meta.title"
|
||||
preamble_key: "meta.description"
|
||||
|
@@ -14,35 +14,41 @@
|
||||
#
|
||||
#-
|
||||
|
||||
- title_key: text.applications
|
||||
abs_href: "/content/?tags=application;web"
|
||||
icon: fad fa-browser
|
||||
active_id: application
|
||||
- title_key: text.projects
|
||||
abs_href: "/content/?tags="
|
||||
icon: fad fa-briefcase
|
||||
active_id: projects
|
||||
has_new_until_utc: 0
|
||||
|
||||
- title_key: text.libraries
|
||||
abs_href: "/content/?tags=library"
|
||||
icon: fad fa-puzzle-piece
|
||||
active_id: library
|
||||
has_new_until_utc: 0
|
||||
#- title_key: text.applications
|
||||
# abs_href: "/content/?tags=application;web"
|
||||
# icon: fad fa-browser
|
||||
# active_id: application
|
||||
# has_new_until_utc: 0
|
||||
#
|
||||
#- title_key: text.libraries
|
||||
# abs_href: "/content/?tags=library"
|
||||
# icon: fad fa-puzzle-piece
|
||||
# active_id: library
|
||||
# has_new_until_utc: 0
|
||||
#
|
||||
#- title_key: text.electronics
|
||||
# abs_href: "/content/?tags=electronic"
|
||||
# icon: fad fa-microchip
|
||||
# active_id: electronic
|
||||
# has_new_until_utc: 0
|
||||
|
||||
- title_key: text.electronics
|
||||
abs_href: "/content/?tags=electronic"
|
||||
icon: fad fa-microchip
|
||||
active_id: electronic
|
||||
has_new_until_utc: 0
|
||||
|
||||
- title_key: text.experiments
|
||||
abs_href: "/content/?tags=experiments"
|
||||
icon: fad fa-flask-vial
|
||||
active_id: electronic
|
||||
has_new_until_utc: 0
|
||||
#- title_key: text.experiments
|
||||
# abs_href: "/content/?tags=experiments"
|
||||
# icon: fad fa-flask-vial
|
||||
# active_id: electronic
|
||||
# has_new_until_utc: 0
|
||||
|
||||
- title_key: text.tools
|
||||
abs_href: "/tools"
|
||||
icon: fad fa-toolbox
|
||||
active_id: tools
|
||||
has_new_until_utc: 1760986472
|
||||
has_new_until_utc: 1759856025
|
||||
|
||||
- title_key: text.downloads
|
||||
raw_href: "https://files.nibblepoker.lu/"
|
||||
@@ -52,11 +58,11 @@
|
||||
|
||||
-
|
||||
|
||||
- title_key: text.about
|
||||
abs_href: "/about"
|
||||
icon: fad fa-user
|
||||
active_id: about
|
||||
has_new_until_utc: 0
|
||||
#- title_key: text.about
|
||||
# abs_href: "/about"
|
||||
# icon: fad fa-user
|
||||
# active_id: about
|
||||
# has_new_until_utc: 0
|
||||
|
||||
- title_key: text.contact
|
||||
abs_href: "/contact"
|
||||
|
@@ -14,3 +14,4 @@
|
||||
- "/tools/iban-generator/"
|
||||
- "/tools/excel-password-remover/"
|
||||
- "/tools/uuid-generator/"
|
||||
- "/tools/vat-calculator/"
|
||||
|
@@ -91,3 +91,48 @@ format.json: "JSON"
|
||||
format.yaml: "YAML"
|
||||
|
||||
action.generate: "Generate"
|
||||
|
||||
country.afghanistan: "Afghanistan"
|
||||
country.albania: "Albania"
|
||||
country.algeria: "Algeria"
|
||||
country.andorra: "Andorra"
|
||||
country.angola: "Angola"
|
||||
country.anguilla: "Anguilla"
|
||||
country.argentina: "Argentina"
|
||||
country.australia: "Australia"
|
||||
country.austria: "Austria"
|
||||
country.azerbaijan: "Azerbaijan"
|
||||
country.azores: "Azores"
|
||||
country.bahamas: "Bahamas"
|
||||
country.belgium: "Belgium"
|
||||
country.bulgaria: "Bulgaria"
|
||||
country.corsica: "Corsica"
|
||||
country.croatia: "Croatia"
|
||||
country.cyprus: "Cyprus"
|
||||
country.czechia: "Czechia"
|
||||
country.denmark: "Denmark"
|
||||
country.estonia: "Estonia"
|
||||
country.finland: "Finland"
|
||||
country.france: "France"
|
||||
country.france.corsica: "France - Corsica"
|
||||
country.germany: "Germany"
|
||||
country.greece: "Greece"
|
||||
country.hungary: "Hungary"
|
||||
country.ireland: "Ireland"
|
||||
country.italy: "Italy"
|
||||
country.latvia: "Latvia"
|
||||
country.lithuania: "lithuania"
|
||||
country.luxembourg: "Luxembourg"
|
||||
country.madeira: "Madeira"
|
||||
country.malta: "Malta"
|
||||
country.monaco: "Monaco"
|
||||
country.netherlands: "Netherlands"
|
||||
country.poland: "Poland"
|
||||
country.portugal: "Portugal"
|
||||
country.portugal.azores: "Portugal - Azores"
|
||||
country.portugal.madeira: "Portugal - Madeira"
|
||||
country.romania: "Romania"
|
||||
country.slovenia: "Slovenia"
|
||||
country.slovakia: "Slovakia"
|
||||
country.spain: "Spain"
|
||||
country.sweden: "Sweden"
|
||||
|
@@ -2,9 +2,13 @@
|
||||
|
||||
meta.title: Excel Password Remover
|
||||
meta.description: >-
|
||||
Small web page from which you can easily remove a password from an Excel
|
||||
Small web application from which you can easily remove a password from an Excel
|
||||
worksheet. It works by leaving the task of editing the XML files on an Excel
|
||||
document to your browser instead to keep everything local.
|
||||
meta.description.light: >-
|
||||
Small web application from which you can easily remove a password from an Excel
|
||||
worksheet directly in your browser.
|
||||
|
||||
#article.subtitle: >-
|
||||
# <a
|
||||
# href="https://github.com/aziascreations/Excel-Worksheet-Password-Remover"><i
|
||||
|
@@ -23,20 +23,24 @@ updates.title: Updates
|
||||
|
||||
updates.text.privacy: Updated our privacy policy.
|
||||
|
||||
updates.5.date: March 30 2025
|
||||
updates.5.text.1: Complete redesign of the site to use a standardized style.
|
||||
updates.5.text.2: Changed some of our VPS providers to <a href="https://hosteam.pl/">HosTeam</a>.
|
||||
|
||||
updates.4.date: November 30 2023
|
||||
updates.4.text.1: Centralized DNS servers & implemented GeoDNS.
|
||||
updates.4.text.2: Added US CDN hosted by <a href="https://www.chicagovps.net/">ChicagoVPS</a>.
|
||||
updates.4.text.3: All other regions use the EU CDN hosted by <a href="https://www.ionos.fr/">IONOS</a>.
|
||||
updates.4.text.3: All other regions use the EU CDN hosted by IONOS.
|
||||
|
||||
updates.3.date: November 12 2023
|
||||
updates.3.text.1: Other services are back online.
|
||||
updates.3.text.2: Changed our host to <a href="https://www.ionos.fr/">IONOS</a>.
|
||||
updates.3.text.2: Changed our host to IONOS.
|
||||
updates.3.text.3: Finished all side pages.
|
||||
|
||||
updates.2.date: August 15 2023
|
||||
updates.2.text.1: The website is back online.
|
||||
updates.2.text.2: New and much lighter design.
|
||||
updates.2.text.3: Changed our host to <a href="https://hostbrr.com/">HostBrr</a>.
|
||||
updates.2.text.3: Changed our host to HostBrr.
|
||||
updates.2.text.4: Added a section for web-based tools.
|
||||
|
||||
updates.1.date: September 9 2022
|
||||
|
@@ -1,16 +1,26 @@
|
||||
# IBAN Generator - EN
|
||||
|
||||
meta.title: "IBAN Generator"
|
||||
meta.description: "Web application that allows you to generate IBANs in bulk for the 89 countries that support them.<br>
|
||||
The IBANs are generated completely randomly and may contain a 'BankID' that has not yet been assigned by the
|
||||
national bank of the respective country."
|
||||
meta.description.light: "Web application that allows you to generate IBANs in bulk for the 89 countries that support them."
|
||||
|
||||
country.label: "Country"
|
||||
|
||||
option.count: "IBAN Count"
|
||||
option.human.readable: "Format for readability"
|
||||
option.prefer.numbers: "Prefer numbers over letters"
|
||||
option.for.each: "Generate <i>X</i> for each country"
|
||||
option.sepa.enable: "Enable SEPA countries"
|
||||
option.non-sepa.enable: "Enable non-SEPA countries"
|
||||
|
||||
option.prefer.random: "Do not prefer letters nor numbers"
|
||||
option.prefer.numbers: "Prefer numbers over letters"
|
||||
option.prefer.letters: "Prefer letters over numbers"
|
||||
|
||||
option.human.format.none: "No formatting"
|
||||
option.human.format.standard: "Use recommended spacing"
|
||||
option.human.format.4by4: "Use 4 character-wide spacing"
|
||||
|
||||
license.1: "The code for this project is released in the public domain."
|
||||
license.2: "The original source code can be found on <a href=\"https://github.com/aziascreations/Web-NibblePoker\">GitHub</a>."
|
||||
license.3: "Data from Swift's
|
||||
|
@@ -4,7 +4,8 @@ meta.title: "Icon Maker"
|
||||
meta.description: "..."
|
||||
|
||||
|
||||
|
||||
file.selection.title: "File Selection"
|
||||
file.selection.1: "Drop your file(s) here or click on the buttons."
|
||||
|
||||
enable.expert.mode: "Enable expert mode"
|
||||
enable.binary.blobs: "Allow binary blobs"
|
||||
|
@@ -89,19 +89,27 @@ v2.update.history.5.desc.1: Added a section regarding data collection through
|
||||
DNS servers.
|
||||
v2.update.history.5.desc.2: Changed references to external services to reflect
|
||||
the usage of ChicagoVPS
|
||||
|
||||
v2.update.history.6.date: 2025/03/30
|
||||
v2.update.history.6.desc.1: Simplification of the 'Third Parties' section.
|
||||
v2.update.history.6.desc.2: Removal of unnecessary mentions of our <abbr title="Virtual Private Server">VPS</abbr> providers.
|
||||
|
||||
v2.update.end.2: In the event of a change to our privacy policy, you will
|
||||
be informed explicitly, and a copy of previous versions of the policy will be available
|
||||
through this page.
|
||||
|
||||
v2.third.title: Third Parties
|
||||
v2.third.intro.1: Our websites uses some <abbr title="Virtual private server">VPS</abbr>
|
||||
provided by IONOS and ChicagoVPS in order to put in place a <abbr title="Content
|
||||
delivery network">CDN</abbr> system.
|
||||
v2.third.intro.2: The goal of this system is to improve your browsing experience
|
||||
with the help of a private caching service and custom traffic filtering rules.
|
||||
v2.third.intro.3: No data should be collected on their side due to the nature
|
||||
of the server leased to us.
|
||||
v2.third.intro.4: 'If you''d wish to consult their privacy policy and their
|
||||
partners'', you can do so by using the following URLs:'
|
||||
#v2.third.intro.1: Our websites uses some <abbr title="Virtual private server">VPS</abbr>
|
||||
# provided by IONOS and ChicagoVPS in order to put in place a <abbr title="Content
|
||||
# delivery network">CDN</abbr> system.
|
||||
#v2.third.intro.2: The goal of this system is to improve your browsing experience
|
||||
# with the help of a private caching service and custom traffic filtering rules.
|
||||
#v2.third.intro.3: No data should be collected on their side due to the nature
|
||||
# of the server leased to us.
|
||||
#v2.third.intro.4: 'If you''d wish to consult their privacy policy and their
|
||||
# partners'', you can do so by using the following URLs:'
|
||||
v3.third.intro.1: "Our services do not share any data with any third parties whatsoever."
|
||||
|
||||
v2.cookies.title: Cookies
|
||||
v2.cookies.intro.1: Our websites doesn't use nor store any cookies in your
|
||||
browser.
|
||||
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"tools.head.title": "Tools - NibblePoker",
|
||||
"tools.head.description": "TODO: description",
|
||||
"tools.og.title": "NibblePoker - Tools",
|
||||
"tools.og.description": "TODO: description",
|
||||
"tools.header.title": "Tools"
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
# EN - UUID Generator
|
||||
|
||||
meta.title: "UUID Generator"
|
||||
meta.description: "Web application that allows you to generate UUIDs in bulk for all your unique identifier needs."
|
||||
|
||||
type.label: "UUID Type"
|
||||
|
||||
@@ -9,6 +10,7 @@ type.uuid4: "UUID4 / GUID4"
|
||||
option.count: "UUID Count"
|
||||
option.hyphen: "Add hyphens"
|
||||
option.guid_brackets: "Add GUID brackets"
|
||||
option.uppercase: "Generate in uppercase"
|
||||
|
||||
generate: "Generate"
|
||||
|
||||
|
52
data/strings/en/vat-calculator.yml
Normal file
52
data/strings/en/vat-calculator.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
# EN - VAT Calculator
|
||||
|
||||
meta.title: "VAT Calculator"
|
||||
meta.description: "Simple VAT calculator with a selection of common rates for 32 countries/regions."
|
||||
|
||||
preset.label: "Official rates"
|
||||
|
||||
option.detailed: "Show VAT rate types"
|
||||
|
||||
radio.rate: "VAT rate: "
|
||||
radio.untaxed: "Excl. VAT: "
|
||||
radio.taxed: "Incl. VAT: "
|
||||
|
||||
text.radio.explanation: "The selected radio input indicates the automatically calculated field."
|
||||
|
||||
rate.option.custom: "Custom rate"
|
||||
|
||||
rate.type.standard: "Standard"
|
||||
rate.type.intermediate: "Intermediate"
|
||||
rate.type.preferential: "Preferential"
|
||||
rate.type.reduced: "Reduced"
|
||||
rate.type.reduced.super: "Super reduced"
|
||||
rate.type.special: "Special"
|
||||
|
||||
option.decimal-places: "Decimal places count"
|
||||
option.trim-zeroes: "Trim trailing zeroes"
|
||||
|
||||
rounding.mode.label: "Rounding mode"
|
||||
|
||||
rounding.mode.group.regular: "Regular rounding"
|
||||
rounding.mode.group.half: "Half rounding (Towards nearest neighbour)"
|
||||
|
||||
rounding.mode.up: "Away from zero (Up)"
|
||||
rounding.mode.down: "Towards zero (Down)"
|
||||
rounding.mode.ceil: "Towards infinity (Ceil)"
|
||||
rounding.mode.floor: "Towards negative infinity (Floor)"
|
||||
|
||||
rounding.mode.up.half: "Away from zero if equidistant (Half up)"
|
||||
rounding.mode.down.half: "Towards zero if equidistant (Half down)"
|
||||
rounding.mode.even.half: "Towards even neighbour if equidistant (Half even)"
|
||||
rounding.mode.ceil.half: "Towards infinity if equidistant (Half ceil)"
|
||||
rounding.mode.floor.half: "Towards negative infinity if equidistant (Half floor)"
|
||||
|
||||
#rounding.mode.up.half: "Towards nearest neighbour, away from zero if equidistant (Half up)"
|
||||
#rounding.mode.down.half: "Towards nearest neighbour, towards zero if equidistant (Half down)"
|
||||
#rounding.mode.even.half: "Towards nearest neighbour, towards even neighbour if equidistant (Half even)"
|
||||
#rounding.mode.ceil.half: "Towards nearest neighbour, towards infinity if equidistant (Half ceil)"
|
||||
#rounding.mode.floor.half: "Towards nearest neighbour, towards negative infinity if equidistant (Half floor)"
|
||||
|
||||
license.text.1: "This tool uses the <a href=\"https://github.com/MikeMcl/decimal.js-light\">decimal.js-light</a>
|
||||
library, which is licensed under the <a href=\"https://github.com/MikeMcl/decimal.js-light/blob/master/LICENCE.md\">MIT license</a>."
|
||||
license.text.2: "The rest of this tool's code is released in the <a href=\"https://github.com/aziascreations/Web-NibblePoker\">public domain</a>."
|
@@ -91,3 +91,48 @@ format.json: "JSON"
|
||||
format.yaml: "YAML"
|
||||
|
||||
action.generate: "Générer"
|
||||
|
||||
country.afghanistan: "Afghanistan"
|
||||
country.albania: "Albanie"
|
||||
country.algeria: "Algérie"
|
||||
country.andorra: "Andorre"
|
||||
country.angola: "Angola"
|
||||
country.anguilla: "Anguilla"
|
||||
country.argentina: "Argentine"
|
||||
country.australia: "Australie"
|
||||
country.austria: "Autriche"
|
||||
country.azerbaijan: "Azerbaïdjan"
|
||||
country.azores: "Açores"
|
||||
country.bahamas: "Bahamas"
|
||||
country.belgium: "Belgique"
|
||||
country.bulgaria: "Bulgarie"
|
||||
country.corsica: "Corse"
|
||||
country.croatia: "Croatie"
|
||||
country.cyprus: "Chypre"
|
||||
country.czechia: "Tchéquie"
|
||||
country.denmark: "Danemark"
|
||||
country.estonia: "Estonie"
|
||||
country.finland: "Finlande"
|
||||
country.france: "France"
|
||||
country.france.corsica: "France - Corse"
|
||||
country.germany: "Allemagne"
|
||||
country.greece: "Grèce"
|
||||
country.hungary: "Hongrie"
|
||||
country.ireland: "Irlande"
|
||||
country.italy: "Italie"
|
||||
country.latvia: "Lettonie"
|
||||
country.lithuania: "Lituanie"
|
||||
country.luxembourg: "Luxembourg"
|
||||
country.madeira: "Madère"
|
||||
country.malta: "Malte"
|
||||
country.monaco: "Monaco"
|
||||
country.netherlands: "Pays-Bas"
|
||||
country.poland: "Pologne"
|
||||
country.portugal: "Portugal"
|
||||
country.portugal.azores: "Portugal - Açores"
|
||||
country.portugal.madeira: "Portugal - Madère"
|
||||
country.romania: "Roumanie"
|
||||
country.slovenia: "Slovénie"
|
||||
country.slovakia: "Slovaquie"
|
||||
country.spain: "Espagne"
|
||||
country.sweden: "Suède"
|
||||
|
@@ -6,6 +6,10 @@ meta.description: >-
|
||||
feuille de calcul Excel depuis votre navigateur web sans avoir à uploader le
|
||||
fichier sur internet. Cette application laisse votre navigateur modifier les
|
||||
fichiers XML du fichier Excel afin de tout garder en local.
|
||||
meta.description.light: >-
|
||||
Application web qui permet de facilement retirer le mot de passe d'un ficher Excel depuis
|
||||
votre navigateur web sans avoir à uploader le fichier sur internet.
|
||||
|
||||
#article.subtitle: >-
|
||||
# <a
|
||||
# href="https://github.com/aziascreations/Excel-Worksheet-Password-Remover"><i
|
||||
|
@@ -15,7 +15,7 @@ header.title: Page d'accueil
|
||||
intro.title: Bienvenue sur %0
|
||||
intro.text.1: Ce site web contient une collection de mes travaux personnels tels
|
||||
que des articles de blog, des logiciels utilitaires ou d'autres formes de médias.<br>Tout
|
||||
est accessible gratuitement et sous des licences à l'open source.
|
||||
est accessible gratuitement et sous des licences open source.
|
||||
intro.text.2: Si vous souhaitez me contacter, vous pouvez le faire via la page
|
||||
de contact lié dans la barre de navigation latérale.
|
||||
|
||||
@@ -24,21 +24,24 @@ showcase.title: Vitrine
|
||||
updates.title: Updates
|
||||
updates.text.privacy: Mise-à-jour de notre politique de confidentialité.
|
||||
|
||||
updates.5.date: 30 mars 2025
|
||||
updates.5.text.1: Refonte complète du site pour utiliser un style standardisé.
|
||||
updates.5.text.2: Changements de certains providers de VPS pour <a href="https://hosteam.pl/">HosTeam</a>.
|
||||
|
||||
updates.4.date: 30 novembre 2023
|
||||
updates.4.text.1: Centralisation des serveurs DNS & implémentation de GeoDNS.
|
||||
updates.4.text.2: Ajout d'un CDN pour l'Amérique du Nord hébergé par <a href="https://www.chicagovps.net/">ChicagoVPS</a>.
|
||||
updates.4.text.3: Les autres régions utilisent le CDN Européen hébergé par <a
|
||||
href="https://www.ionos.fr/">IONOS</a>.
|
||||
updates.4.text.3: Les autres régions utilisent le CDN Européen hébergé par IONOS.
|
||||
|
||||
updates.3.date: 12 novembre 2023
|
||||
updates.3.text.1: Les services annexes sont disponibles.
|
||||
updates.3.text.2: Changement d'hébergeur vers <a href="https://www.ionos.fr/">IONOS</a>.
|
||||
updates.3.text.2: Changement d'hébergeur vers IONOS.
|
||||
updates.3.text.3: Finition des pages annexes.
|
||||
|
||||
updates.2.date: 15 août 2023
|
||||
updates.2.text.1: Le site internet est à nouveau disponible.
|
||||
updates.2.text.2: Mise en place d'un nouveau design plus léger.
|
||||
updates.2.text.3: Changement d'hébergeur vers <a href="https://hostbrr.com/">HostBrr</a>.
|
||||
updates.2.text.3: Changement d'hébergeur vers HostBrr.
|
||||
updates.2.text.4: Ajout d'une nouvelle section pour les outils.
|
||||
|
||||
updates.1.date: 9 septembre 2022
|
||||
|
@@ -1,16 +1,26 @@
|
||||
# IBAN Generator - FR
|
||||
|
||||
meta.title: "Générateur d'IBAN"
|
||||
meta.description: "Application web qui vous permet de générer des IBANs en masse pour les 89 pays qui les supportent.<br>
|
||||
Les IBANs sont générés complètement aléatoirement et risquent de contenir un 'BankID' qui n'est pas encore attribué
|
||||
par la banque nationale du pays concerné."
|
||||
meta.description.light: "Application web qui vous permet de générer des IBANs en masse pour les 89 pays qui les supportent."
|
||||
|
||||
country.label: "Pays"
|
||||
|
||||
option.count: "Nombre d'IBAN"
|
||||
option.human.readable: "Formatter pour lecture"
|
||||
option.prefer.numbers: "Favoriser les nombres aux lettres"
|
||||
option.for.each: "Générer <i>X</i> pour chaque pays"
|
||||
option.sepa.enable: "Activer les pays SEPA"
|
||||
option.non-sepa.enable: "Activer les pays non-SEPA"
|
||||
|
||||
option.prefer.random: "Pas de favorisation des lettres ou nombres"
|
||||
option.prefer.numbers: "Favoriser les nombres aux lettres"
|
||||
option.prefer.letters: "Favoriser les lettres aux nombres"
|
||||
|
||||
option.human.format.none: "Aucun formatage"
|
||||
option.human.format.standard: "Utiliser le format standard des pays"
|
||||
option.human.format.4by4: "Formater en segments de 4 caractères"
|
||||
|
||||
license.1: "Le code de ce projet est publié dans le domaine public."
|
||||
license.2: "Le code source original peut être trouvé sur <a href=\"https://github.com/aziascreations/Web-NibblePoker\">GitHub</a>."
|
||||
license.3: "Les données du
|
||||
|
@@ -4,7 +4,8 @@ meta.title: "Fabricateur d'icônes"
|
||||
meta.description: "..."
|
||||
|
||||
|
||||
|
||||
file.selection.title : "Sélection de fichier(s)"
|
||||
file.selection.1 : "Déposez vos fichiers ici ou cliquez sur les boutons."
|
||||
|
||||
enable.expert.mode: "Activer le mode expert"
|
||||
enable.binary.blobs: "Autoriser les blobs binaires"
|
||||
|
@@ -95,19 +95,27 @@ v2.update.history.5.desc.1: Ajout de la section sur la collection des données
|
||||
par le serveur DNS.
|
||||
v2.update.history.5.desc.2: Changement des références aux services externes
|
||||
pour indiquer l'utilisation de ChicagoVPS.
|
||||
|
||||
v2.update.history.6.date: 2025/03/30
|
||||
v2.update.history.6.desc.1: Simplification de la section 'Organismes tiers'.
|
||||
v2.update.history.6.desc.2: Suppression des mentions inutiles de nous fournisseurs de <abbr title="Serveur privé virtuel">VPS</abbr>.
|
||||
|
||||
v2.update.end.2: En cas de changement, vous serez clairement informé et une
|
||||
copie des anciennes versions de notre politique sera disponible au travers de cette
|
||||
page.
|
||||
|
||||
v2.third.title: Organismes tiers
|
||||
v2.third.intro.1: Ce site web utilise des <abbr title="Serveur privé virtuel">VPS</abbr>
|
||||
proposés par IONOS et ChicagoVPS dans le but de mettre en place un système de <abbr
|
||||
title="Réseau de diffusion de contenu (CDN)">RDC</abbr>.
|
||||
v2.third.intro.2: Ceci a pour but d'améliorer l'expérience des personnes le
|
||||
visitant grâce à un système de filtrage et caching privé.
|
||||
v2.third.intro.3: Due à la nature des serveurs loués, aucune donnée ne devraient
|
||||
être collectées de leur côté.
|
||||
v2.third.intro.4: 'Si vous souhaitez consulter leur politique de confidentialité
|
||||
ainsi que celle de leur partenaires, vous pouvez le faire en suivant les liens ci-dessous:'
|
||||
#v2.third.intro.1: Ce site web utilise des <abbr title="Serveur privé virtuel">VPS</abbr>
|
||||
# proposés par IONOS et ChicagoVPS dans le but de mettre en place un système de <abbr
|
||||
# title="Réseau de diffusion de contenu (CDN)">RDC</abbr>.
|
||||
#v2.third.intro.2: Ceci a pour but d'améliorer l'expérience des personnes le
|
||||
# visitant grâce à un système de filtrage et caching privé.
|
||||
#v2.third.intro.3: Due à la nature des serveurs loués, aucune donnée ne devraient
|
||||
# être collectées de leur côté.
|
||||
#v2.third.intro.4: 'Si vous souhaitez consulter leur politique de confidentialité
|
||||
# ainsi que celle de leur partenaires, vous pouvez le faire en suivant les liens ci-dessous:'
|
||||
v3.third.intro.1: "Nos services ne partagent aucune donnée avec des tiers, quels qu'ils soient."
|
||||
|
||||
v2.cookies.title: Cookies de navigation
|
||||
v2.cookies.intro.1: Ce site web n'utilise pas, et ne stocke aucun cookies
|
||||
dans votre navigateur internet.
|
||||
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"tools.head.title": "Outils - NibblePoker",
|
||||
"tools.head.description": "TODO: description",
|
||||
"tools.og.title": "NibblePoker - Outils",
|
||||
"tools.og.description": "TODO: description",
|
||||
"tools.header.title": "Outils"
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
# FR - UUID Generator
|
||||
|
||||
meta.title: "Générateur d'UUID"
|
||||
meta.description: "Application web qui vous permet de générer des UUID en masse pour tout vos besoins en identifiants uniques."
|
||||
|
||||
type.label: "Type d'UUID"
|
||||
|
||||
@@ -9,6 +10,7 @@ type.uuid4: "UUID4 / GUID4"
|
||||
option.count: "Nombre d'UUID/GUID"
|
||||
option.hyphen: "Ajouter trait d'union"
|
||||
option.guid_brackets: "Ajouter accolades pour GUID"
|
||||
option.uppercase: "Générer en majuscules"
|
||||
|
||||
generate: "Générer"
|
||||
|
||||
|
52
data/strings/fr/vat-calculator.yml
Normal file
52
data/strings/fr/vat-calculator.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
# FR - VAT Calculator
|
||||
|
||||
meta.title: "Calculateur de TVA"
|
||||
meta.description: "Simple calculateur de TVA avec une selection de taux communs pour 32 pays/régions."
|
||||
|
||||
preset.label: "Taux officiel"
|
||||
|
||||
option.detailed: "Afficher le type de TVA"
|
||||
|
||||
radio.rate: "Taux: "
|
||||
radio.untaxed: "<abbr title=\"Hors Taxe sur la Valeur Ajoutée\">HTVA</abbr>: "
|
||||
radio.taxed: "<abbr title=\"Toutes Taxes Comprises\">TTC</abbr>: "
|
||||
|
||||
text.radio.explanation: "Le cercle en vert indique la valeur automatiquement calculée."
|
||||
|
||||
rate.option.custom: "Taux personalisé"
|
||||
|
||||
rate.type.standard: "Standard"
|
||||
rate.type.intermediate: "Intermédiaire"
|
||||
rate.type.preferential: "Préférentiel"
|
||||
rate.type.reduced: "Réduit"
|
||||
rate.type.reduced.super: "Super réduit"
|
||||
rate.type.special: "Spécial"
|
||||
|
||||
option.decimal-places: "Nombre de décimales"
|
||||
option.trim-zeroes: "Supprimer les zéros de fin"
|
||||
|
||||
rounding.mode.label: "Type d'arrondi"
|
||||
|
||||
rounding.mode.group.regular: "Arrondis classiques"
|
||||
rounding.mode.group.half: "Demi-arrondis (Vers le plus proche)"
|
||||
|
||||
rounding.mode.up: "Loin de zéro (Arrondi au supérieur)"
|
||||
rounding.mode.down: "Vers zéro (Arrondi à l'inférieur)"
|
||||
rounding.mode.ceil: "Vers l'infini (Par plafond)"
|
||||
rounding.mode.floor: "Vers moins l'infini (Par plancher)"
|
||||
|
||||
rounding.mode.up.half: "Loin de zéro si équidistant (Demi supérieur)"
|
||||
rounding.mode.down.half: "Vers zéro si équidistant (Demi inférieur)"
|
||||
rounding.mode.even.half: "Vers le pair si équidistant (Demi pair)"
|
||||
rounding.mode.ceil.half: "Vers l'infini (Demi plafond)"
|
||||
rounding.mode.floor.half: "Vers moins l'infini (Demi plancher)"
|
||||
|
||||
#rounding.mode.up.half: "Vers le plus proche, loin de zéro si équidistant (Demi supérieur)"
|
||||
#rounding.mode.down.half: "Vers le plus proche, vers zéro si équidistant (Demi inférieur)"
|
||||
#rounding.mode.even.half: "Vers le plus proche, vers le pair si équidistant (Demi pair)"
|
||||
#rounding.mode.ceil.half: "Vers le plus proche, vers l'infini (Demi plafond)"
|
||||
#rounding.mode.floor.half: "Vers le plus proche, vers moins l'infini (Demi plancher)"
|
||||
|
||||
license.text.1: "Cet outil utilise la bibliothèque <a href=\"https://github.com/MikeMcl/decimal.js-light\">decimal.js-light</a>,
|
||||
qui est distribuée sous licence <a href=\"https://github.com/MikeMcl/decimal.js-light/blob/master/LICENCE.md\">MIT</a>."
|
||||
license.text.2: "Le reste du code de cet outil est placé dans le <a href=\"https://github.com/aziascreations/Web-NibblePoker\">domaine public</a>."
|
@@ -5,10 +5,10 @@ tools:
|
||||
metadata:
|
||||
head:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
description_key: "meta.description.light"
|
||||
opengraph:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
description_key: "meta.description.light"
|
||||
type: null
|
||||
url: null
|
||||
image_url: "/resources/NibblePoker/images/tools/excel-password-remover/main.png"
|
||||
@@ -17,7 +17,7 @@ tools:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
index:
|
||||
priority: 100
|
||||
priority: 2000
|
||||
enable: true
|
||||
title_key: "meta.title"
|
||||
preamble_key: "meta.description"
|
||||
|
@@ -5,10 +5,10 @@ tools:
|
||||
metadata:
|
||||
head:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
description_key: "meta.description.light"
|
||||
opengraph:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
description_key: "meta.description.light"
|
||||
type: null
|
||||
url: null
|
||||
image_url: "/resources/NibblePoker/images/tools/iban-generator/main.png"
|
||||
@@ -17,14 +17,14 @@ tools:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
index:
|
||||
priority: 100
|
||||
priority: 3000
|
||||
enable: true
|
||||
title_key: "meta.title"
|
||||
preamble_key: "meta.description"
|
||||
image_url: "/resources/NibblePoker/images/tools/iban-generator/main.png"
|
||||
image_alt_key: ""
|
||||
general:
|
||||
icon: "fa-duotone fa-solid fa-credit-card-front"
|
||||
icon: "fa-duotone fa-credit-card-front"
|
||||
title_key: "meta.title"
|
||||
subtitle_key: "article.subtitle"
|
||||
tags:
|
||||
|
@@ -16,7 +16,7 @@ tools:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
index:
|
||||
priority: 100
|
||||
priority: 1500
|
||||
enable: true
|
||||
title_key: "meta.title"
|
||||
preamble_key: "meta.description"
|
||||
@@ -27,4 +27,5 @@ tools:
|
||||
title_key: "meta.title"
|
||||
subtitle_key: "article.subtitle"
|
||||
tags:
|
||||
- "undefined"
|
||||
- "utility"
|
||||
- "graphics"
|
@@ -1,6 +1,6 @@
|
||||
tools:
|
||||
- id: "png-chunk-analyser"
|
||||
applet_id: "png-chunk-analyser"
|
||||
- id: "png-analyser"
|
||||
applet_id: "png-analyser"
|
||||
metadata:
|
||||
head:
|
||||
title_key: "meta.title"
|
@@ -17,14 +17,14 @@ tools:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
index:
|
||||
priority: 100
|
||||
priority: 1000
|
||||
enable: true
|
||||
title_key: "meta.title"
|
||||
preamble_key: "meta.description"
|
||||
image_url: "/resources/NibblePoker/images/tools/uuid-generator/main.png"
|
||||
image_alt_key: ""
|
||||
general:
|
||||
icon: "fab fa-python"
|
||||
icon: "fa-duotone fa-memo-pad"
|
||||
title_key: "meta.title"
|
||||
subtitle_key: "article.subtitle"
|
||||
tags:
|
||||
|
32
data/tools/vat-calculator.yml
Normal file
32
data/tools/vat-calculator.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
tools:
|
||||
- id: "vat-calculator"
|
||||
applet_id: "vat-calculator"
|
||||
metadata:
|
||||
head:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
opengraph:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
type: null
|
||||
url: null
|
||||
image_url: "/resources/NibblePoker/images/tools/vat-calculator/main-quiet.png"
|
||||
image_type: null
|
||||
twitter:
|
||||
title_key: "meta.title"
|
||||
description_key: "meta.description"
|
||||
index:
|
||||
priority: 500
|
||||
enable: true
|
||||
title_key: "meta.title"
|
||||
preamble_key: "meta.description"
|
||||
image_url: "/resources/NibblePoker/images/tools/vat-calculator/main-quiet.png"
|
||||
image_alt_key: ""
|
||||
general:
|
||||
icon: "fa-solid fa-memo-pad"
|
||||
title_key: "meta.title"
|
||||
subtitle_key: "article.subtitle"
|
||||
tags:
|
||||
- "calculator"
|
||||
- "finance"
|
@@ -83,6 +83,26 @@ call "%~dp0node_modules\.bin\rollup" uuid-generator.mjs --file uuid-generator.js
|
||||
call "%~dp0node_modules\.bin\terser" uuid-generator.js -c -m -o uuid-generator.min.js
|
||||
popd
|
||||
|
||||
|
||||
:js-pnganalyser-minify
|
||||
echo Minifying PNG Analyzer
|
||||
pushd %CD%
|
||||
cd %~dp0\..\static\resources\NibblePoker\applets\png-analyser\
|
||||
echo ^> static\resources\NibblePoker\applets\png-analyser\png-analyser.mjs
|
||||
call "%~dp0node_modules\.bin\rollup" png-analyser.mjs --file png-analyser.js
|
||||
call "%~dp0node_modules\.bin\terser" png-analyser.js -c -m -o png-analyser.min.js
|
||||
popd
|
||||
|
||||
|
||||
:js-vatcalculator-minify
|
||||
echo Minifying VAT Calculator
|
||||
pushd %CD%
|
||||
cd %~dp0\..\static\resources\NibblePoker\applets\vat-calculator\
|
||||
echo ^> static\resources\NibblePoker\applets\vat-calculator\vat-calculator.mjs
|
||||
call "%~dp0node_modules\.bin\rollup" vat-calculator.mjs --file vat-calculator.js
|
||||
call "%~dp0node_modules\.bin\terser" vat-calculator.js -c -m -o vat-calculator.min.js
|
||||
popd
|
||||
|
||||
:js-nibblepoker-end
|
||||
|
||||
:end
|
||||
|
17
scripts/delete-minified-js.cmd
Normal file
17
scripts/delete-minified-js.cmd
Normal file
@@ -0,0 +1,17 @@
|
||||
@echo off
|
||||
|
||||
pushd %CD%
|
||||
|
||||
cd /D "%~dp0"
|
||||
cd ..\static\resources\NibblePoker
|
||||
|
||||
echo.
|
||||
echo Removing minified JS files
|
||||
echo --------------------------
|
||||
|
||||
echo Deleting "*.js" in "static\resources\NibblePoker" ...
|
||||
del /S /Q *.js
|
||||
|
||||
|
||||
:end
|
||||
popd
|
31
scripts/package-for-release.cmd
Normal file
31
scripts/package-for-release.cmd
Normal file
@@ -0,0 +1,31 @@
|
||||
@echo off
|
||||
|
||||
pushd %CD%
|
||||
|
||||
:: Going into the project's directory
|
||||
cd /D "%~dp0"
|
||||
call delete-pycache.cmd
|
||||
cd ..
|
||||
|
||||
echo.
|
||||
echo Creating Release Package
|
||||
echo ------------------------
|
||||
|
||||
echo %CD%
|
||||
|
||||
del release.tar 2> nul
|
||||
|
||||
7z a "release.tar" ^
|
||||
-xr!*.pdn ^
|
||||
-xr!*.ai ^
|
||||
data/ ^
|
||||
static/ ^
|
||||
templates/ ^
|
||||
website/ ^
|
||||
.dockerignore ^
|
||||
.env ^
|
||||
app.py ^
|
||||
Dockerfile ^
|
||||
requirements.txt
|
||||
|
||||
popd
|
3
scripts/package-lock.json
generated
3
scripts/package-lock.json
generated
@@ -5,9 +5,10 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"browserify": "^17.0.1",
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"minify": "^10.2.0",
|
||||
"rollup": "^3.27.2",
|
||||
"rollup": "^4.48.1",
|
||||
"sass": "^1.63.6",
|
||||
"terser": "^5.19.0",
|
||||
"typescript": "^5.1.6"
|
||||
|
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"minify": "^10.2.0",
|
||||
"rollup": "^3.27.2",
|
||||
"rollup": "^4.48.1",
|
||||
"sass": "^1.63.6",
|
||||
"terser": "^5.19.0",
|
||||
"typescript": "^5.1.6",
|
||||
"html-minifier-terser": "^7.2.0"
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"browserify": "^17.0.1"
|
||||
}
|
||||
}
|
||||
|
1
static/resources/Externals/.gitignore
vendored
Normal file
1
static/resources/Externals/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.svg
|
@@ -30,10 +30,20 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
|
||||
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionCount = document.querySelector("input#iban-generator-option-count");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionPrettyPrint = document.querySelector("input#iban-generator-option-pretty");
|
||||
|
||||
///** @type {HTMLInputElement} */
|
||||
//const eOptionPreferRandom = document.querySelector("input#iban-generator-option-prefer-random");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionPreferNumbers = document.querySelector("input#iban-generator-option-prefer-numbers");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionPreferLetters = document.querySelector("input#iban-generator-option-prefer-letters");
|
||||
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionFormatNone = document.querySelector("input#iban-generator-option-format-none");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionFormatStandard = document.querySelector("input#iban-generator-option-format-standard");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionFormat4By4 = document.querySelector("input#iban-generator-option-format-4by4");
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
const eGenerateButton = document.querySelector("#iban-generator-generate");
|
||||
@@ -75,14 +85,14 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
|
||||
|
||||
/** @returns {number} */
|
||||
function getDesiredCount() {
|
||||
return getInputCount(eOptionCount, 1, 1000);
|
||||
return getInputCount(eOptionCount, 1, 10000);
|
||||
}
|
||||
|
||||
function changeDesiredCount(difference = 0) {
|
||||
if(difference !== 0) {
|
||||
eOptionCount.value = getDesiredCount(eOptionCount, 1, 1000) + difference;
|
||||
eOptionCount.value = getDesiredCount(eOptionCount, 1, 10000) + difference;
|
||||
}
|
||||
eOptionCount.value = getDesiredCount(eOptionCount, 1, 1000);
|
||||
eOptionCount.value = getDesiredCount(eOptionCount, 1, 10000);
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
@@ -108,27 +118,58 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
|
||||
let desiredCount = getDesiredCount();
|
||||
|
||||
let preferNumbers = eOptionPreferNumbers.checked;
|
||||
let prettyIban = eOptionPrettyPrint.checked;
|
||||
let preferLetters = eOptionPreferLetters.checked;
|
||||
|
||||
let ibanFormat = (
|
||||
eOptionFormatNone.checked ? 0 : (
|
||||
eOptionFormatStandard.checked ? 1 : (
|
||||
eOptionFormat4By4.checked ? 2 : 0
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
/** @type {IbanSpecification[]} */
|
||||
let targetSpecs;
|
||||
if(eOptionForEach.checked) {
|
||||
targetSpecs = Object.values(countriesSpecs);
|
||||
|
||||
// BUGFIX: Removing unwanted specs.
|
||||
if(!eOptionEnableSepa.checked) {
|
||||
targetSpecs = targetSpecs.filter(ibanSpec => !ibanSpec.isSepa);
|
||||
}
|
||||
if(!eOptionEnableNonSepa.checked) {
|
||||
targetSpecs = targetSpecs.filter(ibanSpec => ibanSpec.isSepa);
|
||||
}
|
||||
} else {
|
||||
targetSpecs = [countriesSpecs[eOptionCountry.value]];
|
||||
}
|
||||
|
||||
targetSpecs.forEach(spec => {
|
||||
if((spec.isSepa && !eOptionEnableSepa.checked) || (!spec.isSepa && !eOptionEnableNonSepa.checked)) {
|
||||
return;
|
||||
}
|
||||
for(let i = 0; i < desiredCount; i++) {
|
||||
if(prettyIban) {
|
||||
if(ibanFormat === 1) {
|
||||
// standard
|
||||
lastIBANs.push(
|
||||
spec.getFormattedIban(
|
||||
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers), spec).toString()
|
||||
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers, preferLetters), spec)
|
||||
.toString()
|
||||
)
|
||||
);
|
||||
} else {
|
||||
} else if(ibanFormat === 2) {
|
||||
// 4-by-4
|
||||
lastIBANs.push(
|
||||
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers), spec).toString()
|
||||
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers, preferLetters), spec)
|
||||
.toString()
|
||||
.match(/.{1,4}/g)
|
||||
.join(' ')
|
||||
);
|
||||
} else {
|
||||
// none
|
||||
lastIBANs.push(
|
||||
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers, preferLetters), spec)
|
||||
.toString()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,8 @@
|
||||
|
||||
.ico-maker-advanced {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input[type="checkbox"]#ico-maker-enable-expert-mode:checked ~ .ico-maker-advanced {
|
||||
display: block;
|
||||
}
|
||||
|
@@ -0,0 +1,34 @@
|
||||
|
||||
import {initCore} from "../../js/nibblepoker-core.mjs"
|
||||
import {parsePngFile} from "../../libs/png-utils.mjs";
|
||||
import {parseBmpFile} from "../../libs/bmp-utils.mjs";
|
||||
|
||||
{
|
||||
initCore();
|
||||
|
||||
const toolId = "png-analyser";
|
||||
|
||||
const eFileInput = document.getElementById(`${toolId}-test-input`);
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
eFileInput.addEventListener('change', function(e) {
|
||||
let files = e.target.files;
|
||||
|
||||
console.log(files);
|
||||
|
||||
if(files[0].name.endsWith(".png")) {
|
||||
parsePngFile(files[0]).then(pngFile => {
|
||||
console.log(pngFile);
|
||||
console.log(pngFile.getImageHeaderChunk().getWidth());
|
||||
console.log(pngFile.getImageHeaderChunk().getHeight());
|
||||
});
|
||||
} else if(files[0].name.endsWith(".bmp")) {
|
||||
parseBmpFile(files[0]).then(bmpFile => {
|
||||
console.log(bmpFile);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
}
|
@@ -19,6 +19,8 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
|
||||
const eOptionHyphenInput = document.querySelector("input#uuid-generator-option-hyphens");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionGuidBracketsInput = document.querySelector("input#uuid-generator-option-guid-brackets");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eOptionUppercaseInput = document.querySelector("input#uuid-generator-option-uppercase");
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
const eGenerateButton = document.querySelector("#uuid-generator-generate");
|
||||
@@ -40,14 +42,14 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
|
||||
}
|
||||
|
||||
function changeDesiredCount(difference = 0) {
|
||||
if(difference !== 0) {
|
||||
if (difference !== 0) {
|
||||
eOptionCountInput.value = getDesiredCount() + difference;
|
||||
}
|
||||
eOptionCountInput.value = getDesiredCount();
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
eGenerateButton.addEventListener("click", function() {
|
||||
eGenerateButton.addEventListener("click", function () {
|
||||
ePreviewTextArea.value = "";
|
||||
|
||||
let desiredCount = getDesiredCount();
|
||||
@@ -57,20 +59,26 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
|
||||
let addGuidBrackets = eOptionGuidBracketsInput.checked;
|
||||
|
||||
lastUUIDs = [];
|
||||
for(let i= 0; i < desiredCount; i++) {
|
||||
lastUUIDs.push(uuidGenerator(addHyphens, addGuidBrackets));
|
||||
ePreviewTextArea.value += uuidGenerator(addHyphens, addGuidBrackets) + "\n";
|
||||
if (eOptionUppercaseInput.checked) {
|
||||
for (let i = 0; i < desiredCount; i++) {
|
||||
lastUUIDs.push(uuidGenerator(addHyphens, addGuidBrackets).toUpperCase());
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < desiredCount; i++) {
|
||||
lastUUIDs.push(uuidGenerator(addHyphens, addGuidBrackets));
|
||||
}
|
||||
}
|
||||
|
||||
ePreviewTextArea.value = lastUUIDs.join("\n");
|
||||
});
|
||||
|
||||
// Count option
|
||||
eOptionCountInput.addEventListener("change", function() {
|
||||
eOptionCountInput.addEventListener("change", function () {
|
||||
changeDesiredCount(0);
|
||||
});
|
||||
eOptionCountInput.addEventListener("mousewheel", function(e) {
|
||||
eOptionCountInput.addEventListener("mousewheel", function (e) {
|
||||
// Handling wheel scroll on count field.
|
||||
if(e.wheelDelta < 0) {
|
||||
if (e.wheelDelta < 0) {
|
||||
changeDesiredCount(-1);
|
||||
} else {
|
||||
changeDesiredCount(1);
|
||||
@@ -78,19 +86,19 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
|
||||
});
|
||||
|
||||
// Download buttons
|
||||
eDownloadRawButton.addEventListener("click", function() {
|
||||
eDownloadRawButton.addEventListener("click", function () {
|
||||
if (lastUUIDs.length <= 0) {
|
||||
return;
|
||||
}
|
||||
downloadStringAsFile(lastUUIDs.join("\n"), "uuids.txt", "text/plain");
|
||||
});
|
||||
eDownloadJsonButton.addEventListener("click", function() {
|
||||
eDownloadJsonButton.addEventListener("click", function () {
|
||||
if (lastUUIDs.length <= 0) {
|
||||
return;
|
||||
}
|
||||
downloadStringAsFile(JSON.stringify(lastUUIDs, null, 4), "uuids.json", "application/json");
|
||||
});
|
||||
eDownloadYamlButton.addEventListener("click", function() {
|
||||
eDownloadYamlButton.addEventListener("click", function () {
|
||||
if (lastUUIDs.length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
@@ -0,0 +1,248 @@
|
||||
import {initCore} from "../../js/nibblepoker-core.mjs";
|
||||
//import {Decimal} from "../../../DecimalJs/10.6.0/decimal.mjs";
|
||||
import {Decimal} from "../../../DecimalJs-Light/2.5.1/decimal.mjs";
|
||||
import {getInputCount, getInputNumber} from "../../libs/input-utils.mjs";
|
||||
|
||||
// Tool-centric stuff
|
||||
{
|
||||
initCore();
|
||||
|
||||
const classesReadonly = ["bkgd-gray"];
|
||||
|
||||
const calcRadioGroupName = "vat_calc_target";
|
||||
|
||||
/** @type {HTMLLabelElement} */
|
||||
const ePresetShortLabel = document.querySelector("label[for=vat-calculator-preset-short]");
|
||||
/** @type {HTMLSelectElement} */
|
||||
const ePresetShortSelect = document.getElementById("vat-calculator-preset-short");
|
||||
|
||||
/** @type {HTMLLabelElement} */
|
||||
const ePresetDetailedLabel = document.querySelector("label[for=vat-calculator-preset-detailed]");
|
||||
/** @type {HTMLSelectElement} */
|
||||
const ePresetDetailedSelect = document.getElementById("vat-calculator-preset-detailed");
|
||||
|
||||
/** @type {HTMLInputElement} */
|
||||
const eCheckboxDetailedPreset = document.getElementById("vat-calculator-detailed-presets");
|
||||
|
||||
/** @type {HTMLSpanElement} */
|
||||
const ePresetEchoedCountry = document.getElementById("vat-calculator-preset-country-echo");
|
||||
|
||||
/** @type {HTMLButtonElement} */
|
||||
const eButtonDecimalPlacesMinus = document.getElementById("vat-calculator-decimal-places-minus");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eInputDecimalPlaces = document.getElementById("vat-calculator-option-decimal-places");
|
||||
/** @type {HTMLButtonElement} */
|
||||
const eButtonDecimalPlacesPlus = document.getElementById("vat-calculator-decimal-places-plus");
|
||||
|
||||
/* #vat-calculator-detailed-trim-zeroes */
|
||||
|
||||
/** @type {HTMLInputElement} */
|
||||
const eCalcRateRadio = document.getElementById("vat-calculator-radio-rate");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eCalcRateInput = document.getElementById("vat-calculator-input-rate");
|
||||
|
||||
/** @type {HTMLInputElement} */
|
||||
const eCalcUntaxedRadio = document.getElementById("vat-calculator-radio-untaxed");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eCalcUntaxedInput = document.getElementById("vat-calculator-input-untaxed");
|
||||
|
||||
/** @type {HTMLInputElement} */
|
||||
const eCalcTaxedRadio = document.getElementById("vat-calculator-radio-taxed");
|
||||
/** @type {HTMLInputElement} */
|
||||
const eCalcTaxedInput = document.getElementById("vat-calculator-input-taxed");
|
||||
|
||||
/** @type {HTMLSelectElement} */
|
||||
const eRoundingModeSelect = document.getElementById("vat-calculator-rounding-mode");
|
||||
|
||||
/**
|
||||
* Handles the switch between the short and detailed standard rates selects
|
||||
*/
|
||||
function handlePresetDetailLevelChange() {
|
||||
ePresetShortLabel.hidden = eCheckboxDetailedPreset.checked;
|
||||
ePresetShortSelect.hidden = eCheckboxDetailedPreset.checked;
|
||||
ePresetDetailedLabel.hidden = !eCheckboxDetailedPreset.checked;
|
||||
ePresetDetailedSelect.hidden = !eCheckboxDetailedPreset.checked;
|
||||
}
|
||||
|
||||
/** @returns {number} */
|
||||
function getDecimalPlaces() {
|
||||
return getInputCount(eInputDecimalPlaces, 0, 99);
|
||||
}
|
||||
|
||||
function changeDecimalPlacesDesiredCount(difference = 0) {
|
||||
if (difference !== 0) {
|
||||
eInputDecimalPlaces.value = getInputCount(eInputDecimalPlaces, 0, 99) + difference;
|
||||
}
|
||||
eInputDecimalPlaces.value = getInputCount(eInputDecimalPlaces, 0, 99);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the locking and unlocking of the calculator input fields.
|
||||
* @param eInput {HTMLInputElement}
|
||||
* @param isLocked {boolean}
|
||||
*/
|
||||
function setCalcFieldLockStatus(eInput, isLocked) {
|
||||
eInput.readOnly = isLocked;
|
||||
classesReadonly.forEach((roClass) => {
|
||||
eInput.classList.remove(roClass);
|
||||
if(isLocked) {
|
||||
eInput.classList.add(roClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleCalcValueChange() {
|
||||
let vatRate = getInputNumber(eCalcRateInput);
|
||||
let untaxedValue = getInputNumber(eCalcUntaxedInput);
|
||||
let taxedValue = getInputNumber(eCalcTaxedInput);
|
||||
|
||||
if(eCalcRateRadio.checked) {
|
||||
if(untaxedValue === null || taxedValue === null || isNaN(untaxedValue) || isNaN(taxedValue)) {
|
||||
return;
|
||||
}
|
||||
untaxedValue = new Decimal(eCalcUntaxedInput.value);
|
||||
taxedValue = new Decimal(eCalcTaxedInput.value);
|
||||
|
||||
eCalcRateInput.value = taxedValue
|
||||
.minus(untaxedValue)
|
||||
.div(untaxedValue)
|
||||
.times(100)
|
||||
.toDecimalPlaces(getDecimalPlaces());
|
||||
} else if(eCalcUntaxedRadio.checked) {
|
||||
if(vatRate === null || taxedValue === null || isNaN(vatRate) || isNaN(taxedValue)) {
|
||||
return;
|
||||
}
|
||||
vatRate = new Decimal(eCalcRateInput.value).dividedBy(100).plus(1);
|
||||
taxedValue = new Decimal(eCalcTaxedInput.value);
|
||||
|
||||
eCalcUntaxedInput.value = taxedValue
|
||||
.dividedBy(vatRate)
|
||||
.toDecimalPlaces(getDecimalPlaces());
|
||||
} else if(eCalcTaxedRadio.checked) {
|
||||
if(vatRate === null || untaxedValue === null || isNaN(vatRate) || isNaN(untaxedValue)) {
|
||||
return;
|
||||
}
|
||||
vatRate = new Decimal(eCalcRateInput.value).dividedBy(100).plus(1);
|
||||
untaxedValue = new Decimal(eCalcUntaxedInput.value);
|
||||
|
||||
eCalcTaxedInput.value = untaxedValue
|
||||
.times(vatRate)
|
||||
.toDecimalPlaces(getDecimalPlaces());
|
||||
}
|
||||
}
|
||||
|
||||
function handleDecimalConfigChange() {
|
||||
Decimal.set({
|
||||
rounding: getInputCount(eRoundingModeSelect, 0, 8),
|
||||
precision: 99,
|
||||
defaults: true,
|
||||
});
|
||||
}
|
||||
|
||||
function handlePresetChange() {
|
||||
if(ePresetShortSelect.value.length > 0) {
|
||||
let eSelectedOption = ePresetShortSelect.querySelector('option:checked');
|
||||
if(eSelectedOption === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let eSelectedOptionGroup = eSelectedOption.closest('optgroup');
|
||||
if(eSelectedOptionGroup === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ePresetEchoedCountry.innerHTML = eSelectedOptionGroup.label;
|
||||
} else {
|
||||
ePresetEchoedCountry.innerHTML = "";
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
// Handling the detailed rate toggle
|
||||
eCheckboxDetailedPreset.addEventListener("click", function () {
|
||||
handlePresetDetailLevelChange();
|
||||
});
|
||||
|
||||
// Handling the rate select input
|
||||
ePresetShortSelect.addEventListener("change", function () {
|
||||
ePresetDetailedSelect.selectedIndex = ePresetShortSelect.selectedIndex;
|
||||
eCalcRateInput.value = ePresetShortSelect.value;
|
||||
handlePresetChange();
|
||||
handleCalcValueChange();
|
||||
});
|
||||
ePresetDetailedSelect.addEventListener("change", function () {
|
||||
ePresetShortSelect.selectedIndex = ePresetDetailedSelect.selectedIndex;
|
||||
eCalcRateInput.value = ePresetDetailedSelect.value;
|
||||
handlePresetChange();
|
||||
handleCalcValueChange();
|
||||
});
|
||||
|
||||
// Handling calc radio input change
|
||||
document.addEventListener("change", (e) => {
|
||||
if (e.target.type === "radio" && e.target.name === calcRadioGroupName) {
|
||||
setCalcFieldLockStatus(eCalcRateInput, e.target.value === "0");
|
||||
setCalcFieldLockStatus(eCalcUntaxedInput, e.target.value === "1");
|
||||
setCalcFieldLockStatus(eCalcTaxedInput, e.target.value === "2");
|
||||
|
||||
ePresetDetailedSelect.disabled = e.target === eCalcRateRadio;
|
||||
ePresetShortSelect.disabled = e.target === eCalcRateRadio;
|
||||
}
|
||||
});
|
||||
eCalcRateRadio.addEventListener("change", function () {
|
||||
ePresetShortSelect.selectedIndex = 0;
|
||||
ePresetDetailedSelect.selectedIndex = 0;
|
||||
handlePresetChange();
|
||||
});
|
||||
|
||||
// Handling decimal places options
|
||||
eButtonDecimalPlacesMinus.addEventListener("click", function () {
|
||||
changeDecimalPlacesDesiredCount(-1);
|
||||
handleDecimalConfigChange();
|
||||
handleCalcValueChange();
|
||||
});
|
||||
eButtonDecimalPlacesPlus.addEventListener("click", function () {
|
||||
changeDecimalPlacesDesiredCount(1);
|
||||
handleDecimalConfigChange();
|
||||
handleCalcValueChange();
|
||||
});
|
||||
eInputDecimalPlaces.addEventListener("change", function() {
|
||||
changeDecimalPlacesDesiredCount(0);
|
||||
handleDecimalConfigChange();
|
||||
handleCalcValueChange();
|
||||
});
|
||||
eInputDecimalPlaces.addEventListener("mousewheel", function(e) {
|
||||
// Handling wheel scroll on count field.
|
||||
if(e.wheelDelta < 0) {
|
||||
changeDecimalPlacesDesiredCount(-1);
|
||||
} else {
|
||||
changeDecimalPlacesDesiredCount(1);
|
||||
}
|
||||
handleDecimalConfigChange();
|
||||
handleCalcValueChange();
|
||||
});
|
||||
|
||||
// Handling other DecimalJs config fields
|
||||
eRoundingModeSelect.addEventListener("change", function() {
|
||||
handleDecimalConfigChange();
|
||||
handleCalcValueChange();
|
||||
});
|
||||
|
||||
// Handling the calculator field changes
|
||||
eCalcRateInput.addEventListener("change", function() {
|
||||
ePresetShortSelect.selectedIndex = 0;
|
||||
ePresetDetailedSelect.selectedIndex = 0;
|
||||
handleCalcValueChange();
|
||||
handlePresetChange();
|
||||
});
|
||||
eCalcUntaxedInput.addEventListener("change", function() {
|
||||
handleCalcValueChange();
|
||||
});
|
||||
eCalcTaxedInput.addEventListener("change", function() {
|
||||
handleCalcValueChange();
|
||||
});
|
||||
|
||||
handlePresetDetailLevelChange();
|
||||
handleDecimalConfigChange();
|
||||
handlePresetChange();
|
||||
}
|
||||
}
|
@@ -15,22 +15,6 @@ input[type=file].np-file-input-drop {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Nicer checkboxes, move to CSS 8 */
|
||||
input[type=checkbox] {
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
|
||||
&:before {
|
||||
content: "✘";
|
||||
}
|
||||
|
||||
&:checked {
|
||||
&:before {
|
||||
content: "✔";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Top margin trimmer for heading renderer */
|
||||
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
57
static/resources/NibblePoker/libs/bmp-utils.mjs
Normal file
57
static/resources/NibblePoker/libs/bmp-utils.mjs
Normal file
@@ -0,0 +1,57 @@
|
||||
import {loadFileAsUint8Array} from "./file-utils.mjs";
|
||||
import {peekUInt32BE, peekUInt16BE} from "./data-utils.mjs";
|
||||
|
||||
/*export const test = {
|
||||
WINDOWS: "BM",
|
||||
OS2_STRUCT_BITMAP_ARRAY: "BA",
|
||||
OS2_STRUCT_COLOR_ICON: "CI",
|
||||
OS2_CONST_COLOR_POINTER: "CP",
|
||||
OS2_STRUCT_ICON: "IC",
|
||||
OS2_POINTER: "PT",
|
||||
}*/
|
||||
|
||||
export class BmpHeader {
|
||||
/** @type {Uint8Array} */
|
||||
data;
|
||||
|
||||
/**
|
||||
* @param byteArray {Uint8Array|null}
|
||||
*/
|
||||
constructor(byteArray) {
|
||||
if(byteArray === null || byteArray === undefined) {
|
||||
this.data = new Uint8Array(14);
|
||||
} else {
|
||||
this.data = byteArray;
|
||||
}
|
||||
}
|
||||
|
||||
getSignature() {
|
||||
return peekUInt16BE(this.data, 0);
|
||||
}
|
||||
|
||||
getFileSize() {
|
||||
return peekUInt32BE(this.data, 2);
|
||||
}
|
||||
|
||||
getReserved() {
|
||||
return peekUInt32BE(this.data, 6);
|
||||
}
|
||||
|
||||
getDataOffset() {
|
||||
return peekUInt32BE(this.data, 10);
|
||||
}
|
||||
}
|
||||
|
||||
export class CrudeBmpFile {
|
||||
|
||||
constructor(file = null, fileData = null) {
|
||||
this.originalFile = file;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function parseBmpFile(file) {
|
||||
return loadFileAsUint8Array(file).then(byteBuffer => {
|
||||
return new CrudeBmpFile(file, byteBuffer);
|
||||
});
|
||||
}
|
33
static/resources/NibblePoker/libs/crc32.mjs
Normal file
33
static/resources/NibblePoker/libs/crc32.mjs
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
/**
|
||||
* @param data {Uint8Array}
|
||||
* @param crc32 {number}
|
||||
* @return {number}
|
||||
*/
|
||||
export function stepCrc32IEEE(data, crc32 = 0xffffffff) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
crc32 ^= data[i];
|
||||
for (let j = 0; j < 8; j++) {
|
||||
crc32 = (crc32 >>> 1) ^ (crc32 & 1 ? 0xedb88320 : 0);
|
||||
}
|
||||
}
|
||||
return crc32;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param crc32 {number}
|
||||
* @return {number}
|
||||
*/
|
||||
export function finishCrc32IEEE(crc32) {
|
||||
return (crc32 ^ 0xffffffff) >>> 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the CRC32-IEEE for the given data
|
||||
* @param data {Uint8Array}
|
||||
* @param crc32 {number}
|
||||
* @return {number} The resulting CRC32
|
||||
*/
|
||||
export function crc32IEEE(data, crc32 = 0xffffffff) {
|
||||
return finishCrc32IEEE(stepCrc32IEEE(data, crc32));
|
||||
}
|
113
static/resources/NibblePoker/libs/data-utils.mjs
Normal file
113
static/resources/NibblePoker/libs/data-utils.mjs
Normal file
@@ -0,0 +1,113 @@
|
||||
|
||||
/**
|
||||
* Compares two UintXArray and checks if their content is the same.
|
||||
* @param array1 {Uint8Array|Uint16Array|Uint32Array}
|
||||
* @param array2 {Uint8Array|Uint16Array|Uint32Array}
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function areUintArraysEqual(array1, array2) {
|
||||
if ((typeof array1) !== (typeof array2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array1.length !== array2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array1.length; i++) {
|
||||
if (array1[i] !== array2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks a UInt16 from the given data at the given offset in Big-Endian.
|
||||
* @param data {Uint8Array} - Data to read from.
|
||||
* @param offset {number} - Offset to read from in the given `data`.
|
||||
* @return {number} The peeked number.
|
||||
* @throws RangeError If the given offset is too close or over the end of the data.
|
||||
*/
|
||||
export function peekUInt16BE(data, offset = 0) {
|
||||
if(offset + 2 > data.length) {
|
||||
throw new RangeError(`Offset is too far into the given data ! (${offset} & ${data.length})`);
|
||||
}
|
||||
return new DataView(data.buffer, offset, 2).getUint16(0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks a UInt16 from the given data at the given offset in Little-Endian.
|
||||
* @param data {Uint8Array} - Data to read from.
|
||||
* @param offset {number} - Offset to read from in the given `data`.
|
||||
* @return {number} The peeked number.
|
||||
* @throws RangeError If the given offset is too close or over the end of the data.
|
||||
*/
|
||||
export function peekUInt16LE(data, offset = 0) {
|
||||
if(offset + 2 > data.length) {
|
||||
throw new RangeError(`Offset is too far into the given data ! (${offset} & ${data.length})`);
|
||||
}
|
||||
return new DataView(data.buffer, offset, 2).getUint16(0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks a UInt32 from the given data at the given offset in Big-Endian.
|
||||
* @param data {Uint8Array} - Data to read from.
|
||||
* @param offset {number} - Offset to read from in the given `data`.
|
||||
* @return {number} The peeked number.
|
||||
* @throws RangeError If the given offset is too close or over the end of the data.
|
||||
*/
|
||||
export function peekUInt32BE(data, offset = 0) {
|
||||
if(offset + 4 > data.length) {
|
||||
throw new RangeError(`Offset is too far into the given data ! (${offset} & ${data.length})`);
|
||||
}
|
||||
return new DataView(data.buffer, offset, 4).getUint32(0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks a UInt32 from the given data at the given offset in Little-Endian.
|
||||
* @param data {Uint8Array} - Data to read from.
|
||||
* @param offset {number} - Offset to read from in the given `data`.
|
||||
* @return {number} The peeked number.
|
||||
* @throws RangeError If the given offset is too close or over the end of the data.
|
||||
*/
|
||||
export function peekUInt32LE(data, offset = 0) {
|
||||
if(offset + 4 > data.length) {
|
||||
throw new RangeError(`Offset is too far into the given data ! (${offset} & ${data.length})`);
|
||||
}
|
||||
return new DataView(data.buffer, offset, 4).getUint32(0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given `Uint8Array` to a hexadecimal representation.
|
||||
* @param data The data to be transformed into a string.
|
||||
* @return {string} The resulting hexadecimal string.
|
||||
*/
|
||||
export function Uint8ArrayToHex(data) {
|
||||
return Array.prototype.map.call(data, x => ('00' + x.toString(16)).slice(-2)).join('');
|
||||
}
|
||||
|
||||
/*export function decimalToHexString(number) {
|
||||
if (number < 0) {
|
||||
number = 0xFFFFFFFF + number + 1;
|
||||
}
|
||||
return number.toString(16).toUpperCase();
|
||||
}*/
|
||||
|
||||
export function AsciiStringToUint8Array(asciiText) {
|
||||
return Uint8Array.from(Array.from(asciiText).map(asciiLetter => asciiLetter.charCodeAt(0)));
|
||||
}
|
||||
|
||||
export function Int32ToUint8Array(number) {
|
||||
/*let arr = new ArrayBuffer(4);
|
||||
new DataView(arr).setUint32(0, number);
|
||||
return new Uint8Array(arr);*/
|
||||
|
||||
return new Uint8Array([
|
||||
(number >>> 24) & 0xFF,
|
||||
(number >>> 16) & 0xFF,
|
||||
(number >>> 8) & 0xFF,
|
||||
number & 0xFF
|
||||
]);
|
||||
}
|
28
static/resources/NibblePoker/libs/file-utils.mjs
Normal file
28
static/resources/NibblePoker/libs/file-utils.mjs
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
/**
|
||||
* Reads a file and returns its content as a string.
|
||||
* @param {File} file - The file to read.
|
||||
* @returns {Promise<string>} A promise that resolves with the file content as a string.
|
||||
*/
|
||||
export function loadFileAsText(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = reject;
|
||||
reader.readAsText(file);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file and returns its content as a `Uint8Array`.
|
||||
* @param {File} file - The file to read.
|
||||
* @returns {Promise<Uint8Array>} A promise that resolves with the file content as a byte buffer.
|
||||
*/
|
||||
export function loadFileAsUint8Array(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(new Uint8Array(reader.result));
|
||||
reader.onerror = reject;
|
||||
reader.readAsArrayBuffer(file);
|
||||
});
|
||||
}
|
@@ -269,7 +269,7 @@ export class IbanSpecification {
|
||||
return iban.match(/.{1,4}/g).join(' ');
|
||||
}
|
||||
|
||||
generateRandomBban(preferNumbers = false) {
|
||||
generateRandomBban(preferNumbers = false, preferLetters = false) {
|
||||
let returnedBban = "";
|
||||
let patternParts = ("_" + this.bbanFormat + "0").split("!");
|
||||
|
||||
@@ -290,9 +290,13 @@ export class IbanSpecification {
|
||||
case 'C':
|
||||
if(preferNumbers) {
|
||||
elementChoices = charsN;
|
||||
} else {
|
||||
if(preferLetters) {
|
||||
elementChoices = charsA;
|
||||
} else {
|
||||
elementChoices = charsC;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
|
@@ -2,21 +2,7 @@
|
||||
// Author: Herwin Bozet (@NibblePoker)
|
||||
// License: Public Domain (This code)
|
||||
|
||||
/**
|
||||
* Retrieves the number from an `HTMLInputElement`
|
||||
* @param eInput {HTMLInputElement} The `HTMLInputElement` from which the value will be retrieved.
|
||||
* @param min {number|null} If given, sets a minimum the value can have when returned.
|
||||
* @param max {number|null} If given, sets a maximum the value can have when returned.
|
||||
* @returns {number} The value from the given `HTMLInputElement`, or `1` if no valid one was given.
|
||||
*/
|
||||
export function getInputCount(eInput, min = null, max = null) {
|
||||
let desiredCount = null;
|
||||
try {
|
||||
desiredCount = parseInt(eInput.value);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
function postProcessNumber(desiredCount, min = null, max = null) {
|
||||
if (desiredCount === null) {
|
||||
desiredCount = 1;
|
||||
}
|
||||
@@ -34,3 +20,37 @@ export function getInputCount(eInput, min = null, max = null) {
|
||||
|
||||
return desiredCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the integer number from an `HTMLInputElement`
|
||||
* @param eInput {HTMLInputElement|HTMLSelectElement} The `HTMLInputElement` from which the value will be retrieved.
|
||||
* @param min {number|null} If given, sets a minimum the value can have when returned.
|
||||
* @param max {number|null} If given, sets a maximum the value can have when returned.
|
||||
* @returns {number|NaN} The value from the given `HTMLInputElement`, or `1` if no valid one was given.
|
||||
*/
|
||||
export function getInputCount(eInput, min = null, max = null) {
|
||||
let desiredCount = null;
|
||||
try {
|
||||
desiredCount = parseInt(eInput.value);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return postProcessNumber(desiredCount, min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the float number from an `HTMLInputElement`
|
||||
* @param eInput {HTMLInputElement|HTMLSelectElement} The `HTMLInputElement` from which the value will be retrieved.
|
||||
* @param min {number|null} If given, sets a minimum the value can have when returned.
|
||||
* @param max {number|null} If given, sets a maximum the value can have when returned.
|
||||
* @returns {number|NaN} The value from the given `HTMLInputElement`, or `1` if no valid one was given.
|
||||
*/
|
||||
export function getInputNumber(eInput, min = null, max = null) {
|
||||
let desiredCount = null;
|
||||
try {
|
||||
desiredCount = parseFloat(eInput.value);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return postProcessNumber(desiredCount, min, max);
|
||||
}
|
||||
|
261
static/resources/NibblePoker/libs/png-utils.mjs
Normal file
261
static/resources/NibblePoker/libs/png-utils.mjs
Normal file
@@ -0,0 +1,261 @@
|
||||
|
||||
import {stepCrc32IEEE, finishCrc32IEEE} from "./crc32.mjs";
|
||||
import {areUintArraysEqual, peekUInt32BE, AsciiStringToUint8Array, Int32ToUint8Array, Uint8ArrayToHex} from "./data-utils.mjs"
|
||||
import {loadFileAsUint8Array} from "./file-utils.mjs";
|
||||
|
||||
/**
|
||||
* Parent class extended by all PNG-related errors.
|
||||
*/
|
||||
export class PngError extends Error {}
|
||||
|
||||
export class PngInvalidFileHeaderError extends PngError {}
|
||||
|
||||
export class PngInvalidStructureError extends PngError {}
|
||||
|
||||
export class PngInvalidChunkNameError extends PngError {}
|
||||
|
||||
export class PngInvalidChunkChecksumError extends PngError {}
|
||||
|
||||
export class PngInvalidImageHeaderError extends PngError {}
|
||||
|
||||
export class PngMissingCriticalChunksError extends PngError {}
|
||||
|
||||
export const PngFileHeader = new Uint8Array([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
|
||||
|
||||
export class PngChunk {
|
||||
/** @type {string} */
|
||||
type;
|
||||
|
||||
/** @type {Uint8Array} */
|
||||
data;
|
||||
|
||||
/**
|
||||
* @param type {string}
|
||||
* @param data {Uint8Array}
|
||||
* @param expectedChecksum {Uint8Array|null}
|
||||
* @throws PngInvalidChunkNameError If the given chunk name isn't a valid chunk name.
|
||||
*/
|
||||
constructor(type, data, expectedChecksum) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
|
||||
if(expectedChecksum !== null) {
|
||||
if(!areUintArraysEqual(expectedChecksum, this.getChecksumUint8Array())) {
|
||||
throw new PngInvalidChunkChecksumError(
|
||||
`Invalid checksum was given ! (Expected ${
|
||||
Uint8ArrayToHex(expectedChecksum)}, got ${
|
||||
Uint8ArrayToHex(this.getChecksumUint8Array())})`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getChecksumNumber() {
|
||||
return finishCrc32IEEE(
|
||||
stepCrc32IEEE(
|
||||
this.data,
|
||||
stepCrc32IEEE(AsciiStringToUint8Array(this.type))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
getChecksumUint8Array() {
|
||||
return Int32ToUint8Array(this.getChecksumNumber());
|
||||
}
|
||||
}
|
||||
|
||||
class PngImageHeaderChunk extends PngChunk {
|
||||
/**
|
||||
* @param type {string}
|
||||
* @param data {Uint8Array}
|
||||
* @param expectedChecksum {Uint8Array|null}
|
||||
* @throws PngInvalidChunkNameError If the given chunk name isn't a valid chunk name.
|
||||
* @throws PngInvalidImageHeaderError If the given chunk's size isn't exactly 13 bytes.
|
||||
*/
|
||||
constructor(type, data, expectedChecksum) {
|
||||
super(type, data, expectedChecksum);
|
||||
|
||||
if(this.data.length !== 13) {
|
||||
throw new PngInvalidImageHeaderError(`Invalid IHDR chunk size, got ${this.data.length} instead of 13 !`);
|
||||
}
|
||||
}
|
||||
|
||||
getWidth() {
|
||||
return peekUInt32BE(this.data, 0);
|
||||
}
|
||||
|
||||
getHeight() {
|
||||
return peekUInt32BE(this.data, 4);
|
||||
}
|
||||
|
||||
getBitDepth() {
|
||||
return this.data[8];
|
||||
}
|
||||
|
||||
getColorType() {
|
||||
return this.data[9];
|
||||
}
|
||||
|
||||
getCompressionMethod() {
|
||||
return this.data[10];
|
||||
}
|
||||
|
||||
getFilterMethod() {
|
||||
return this.data[11];
|
||||
}
|
||||
|
||||
getInterlaceMethod() {
|
||||
return this.data[12];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a `PngChunk` to a `PngImageHeaderChunk`.
|
||||
* @param pngChunk {PngChunk}
|
||||
* @return {PngImageHeaderChunk}
|
||||
*/
|
||||
static fromPngChunk(pngChunk) {
|
||||
return new PngImageHeaderChunk(pngChunk.type, pngChunk.data, null);
|
||||
}
|
||||
}
|
||||
|
||||
export class PngFile {
|
||||
/** @type {File|null} */
|
||||
originalFile;
|
||||
|
||||
/**
|
||||
* Optional trailing data located after the 'IEND' chunk.
|
||||
* @type {Uint8Array|null}
|
||||
*/
|
||||
trailingData;
|
||||
|
||||
/** @type {PngChunk[]} */
|
||||
chunks;
|
||||
|
||||
/**
|
||||
* @param file {File|null}
|
||||
* @param fileData {Uint8Array|null}
|
||||
* @throws PngInvalidFileHeaderError If `fileData` is provided and doesn't contain a valid PNG file header.
|
||||
* @throws PngMissingCriticalChunksError If `fileData` is provided and is missing some critical chunks.
|
||||
*/
|
||||
constructor(file = null, fileData = null) {
|
||||
this.originalFile = file;
|
||||
|
||||
this.chunks = [];
|
||||
|
||||
// Parsing and validating the data if given
|
||||
if(fileData !== null) {
|
||||
this.#validateFileHeader(fileData);
|
||||
this.#parseChunks(fileData);
|
||||
|
||||
if(!this.hasEndChunk() || this.getChunkByType("IHDR") === null) {
|
||||
throw new PngMissingCriticalChunksError("One or more critical chunk is missing from the PNG file !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param originalFileData {Uint8Array}
|
||||
*/
|
||||
#validateFileHeader = (originalFileData) => {
|
||||
if(originalFileData.length < 8) {
|
||||
throw new PngInvalidFileHeaderError(
|
||||
`The file header's length is smaller than the required 8 ! (Got: ${originalFileData.length})`);
|
||||
}
|
||||
|
||||
if(!areUintArraysEqual(originalFileData.slice(0, 8), PngFileHeader)) {
|
||||
throw new PngInvalidFileHeaderError(
|
||||
"The file header didn't have the expected data !\n" +
|
||||
`Expected: ${PngFileHeader}\\n` +
|
||||
`Got: ${originalFileData.slice(0, 8)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param originalFileData {Uint8Array}
|
||||
* @throws TypeError If a chunk's type couldn't be parsed.
|
||||
*/
|
||||
#parseChunks = (originalFileData) => {
|
||||
let currentOffset = PngFileHeader.length;
|
||||
|
||||
while(currentOffset < originalFileData.length) {
|
||||
// Checking if we haven't encountered an IEND, and we encountered a truncated file or trash data.
|
||||
if(currentOffset + 12 > originalFileData.length) {
|
||||
throw new PngInvalidStructureError("Unable to parse more chunks and no 'IEND' was encountered !");
|
||||
}
|
||||
|
||||
const chunkLength = peekUInt32BE(originalFileData.slice(currentOffset, currentOffset + 4));
|
||||
const chunkType = new TextDecoder().decode(originalFileData.slice(currentOffset + 4, currentOffset + 8));
|
||||
|
||||
// Checking if we have enough data left to read for the chunk's data.
|
||||
if(currentOffset + 12 + chunkLength > originalFileData.length) {
|
||||
throw new PngInvalidStructureError("Not enough data left to read the chunk !")
|
||||
}
|
||||
|
||||
let chunkChecksum = originalFileData.slice(
|
||||
currentOffset + 8 + chunkLength, currentOffset + 8 + chunkLength + 4);
|
||||
|
||||
this.chunks.push(
|
||||
new PngChunk(
|
||||
chunkType,
|
||||
(chunkLength === 0) ?
|
||||
new Uint8Array(0) :
|
||||
originalFileData.slice(currentOffset + 8, currentOffset + 8 + chunkLength),
|
||||
chunkChecksum,
|
||||
//originalFileData.slice(currentOffset + 4, currentOffset + 8)
|
||||
)
|
||||
);
|
||||
|
||||
if(chunkType === "IEND") {
|
||||
break;
|
||||
}
|
||||
|
||||
currentOffset += 12 + chunkLength;
|
||||
}
|
||||
|
||||
// Handling trailing data
|
||||
if(currentOffset !== originalFileData.length) {
|
||||
this.trailingData = originalFileData.slice(currentOffset, originalFileData.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to retrieve a chunk via its type.
|
||||
* @param chunkName {string} The desired chunk's type.
|
||||
* @return {PngChunk|null}
|
||||
*/
|
||||
getChunkByType(chunkName) {
|
||||
for(let iChunk in this.chunks) {
|
||||
if(this.chunks[iChunk].type === chunkName) {
|
||||
return this.chunks[iChunk];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
hasEndChunk() {
|
||||
return this.getChunkByType("IEND") !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {PngImageHeaderChunk|null}
|
||||
*/
|
||||
getImageHeaderChunk() {
|
||||
let desiredChunk = this.getChunkByType("IHDR");
|
||||
if(desiredChunk !== null) {
|
||||
desiredChunk = PngImageHeaderChunk.fromPngChunk(desiredChunk);
|
||||
}
|
||||
return desiredChunk;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and parses a given PNG file.
|
||||
* @param {File} file - The PNG file to process.
|
||||
* @returns {Promise<PngFile>} A promise that resolves with parsed PNG file.
|
||||
*/
|
||||
export function parsePngFile(file) {
|
||||
return loadFileAsUint8Array(file).then(byteBuffer => {
|
||||
return new PngFile(file, byteBuffer);
|
||||
});
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
# Introduction
|
||||
This privacy policy is written in accordance with the 12th and 13th articles of the GDPR.
|
||||
|
||||
If you wish to consult it, you can do so on the following websites:
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# What data do we collect ?
|
||||
This website, does not collect any personal data, be it through access logs, cookies or any third-party services.
|
||||
|
||||
|
||||
# Changes to our privacy policy
|
||||
The content of this privacy policy was written and last updated on the 4th of December 2021.
|
||||
|
||||
In the event of a change to our privacy policy, you will be informed explicitly, and a copy of previous versions of the policy will be available on this page.
|
||||
|
||||
|
||||
# How to contact us ?
|
||||
If you wish to contact us for more information regarding our privacy policy, please contact us via the form included on the contact page, or at the following email address:
|
||||
* herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# How to contact the appropriate authorities ?
|
||||
Should you wish to report a complaint or if you feel that our privacy policy has not addressed your concern in a satisfactory manner, you may contact your national Data Protection Authority (DPA).
|
||||
|
||||
More information on this procedure can be found on the following websites:
|
||||
* https://ec.europa.eu/ (English)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (French)
|
@@ -0,0 +1,29 @@
|
||||
# Introduction
|
||||
La politique de confidentialité ci-présente a été écrite en accord avec les articles 12 et 13 de la RGPD.
|
||||
|
||||
Si vous souhaitez consulter le texte officiel en question, vous pouvez le faire sur les sites internet suivants :
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Quelles données sont collectées ?
|
||||
Ce site web ne collecte aucune donnée personnelle, que ce soit au travers des journaux d'évènements sur nos serveurs, des cookies ou via quelconque autre tiers parti.
|
||||
|
||||
|
||||
# Changements à notre politique de confidentialité
|
||||
Le contenu de notre politique de confidentialité a été écrit et modifié pour la dernière fois le 4 décembre 2021.
|
||||
|
||||
En cas de changement, vous serez clairement informé et une copie des anciennes versions de notre politique sera disponible sur cette page.
|
||||
|
||||
|
||||
# Comment nous contacter ?
|
||||
Si vous souhaitez nous contacter afin d'obtenir plus d'informations concernant notre politique de confidentialité, nous vous recommandons d'utiliser le formulaire présent sur la page de contact, ou par courriel à l'adresse suivante:
|
||||
* herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# Comment contacter les autorités compétentes ?
|
||||
Dans l'éventualité où vous souhaiteriez déposer une plainte pour une quelconque raison en rapport avec notre politique de confidentialité, veuillez vous adresser à l'autorité nationale de protection des données (DPA).
|
||||
|
||||
Les informations concernant cette procédure peuvent être trouvées sur les sites internet suivants:
|
||||
* https://ec.europa.eu/ (Anglais)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (Français)
|
@@ -0,0 +1,76 @@
|
||||
# Introduction
|
||||
This privacy policy is written in accordance with the 12th and 13th articles of the GDPR.
|
||||
|
||||
If you wish to consult it, you can do so on the following websites:
|
||||
https://gdpr.eu/
|
||||
https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Data collection
|
||||
This websites only collects data through generic access logs in order to detect and block bad actors from accessing this website.
|
||||
None of the data collected is used for any other purpose,it is never shared with any other third-party and is never use in any sort of analytics.
|
||||
|
||||
Here is the list of private data being collected:
|
||||
* IP address forwarded to us by CloudFlare
|
||||
* Browser's User-Agent
|
||||
|
||||
And here is the list of non-private data being collected:
|
||||
* Requested resource' URI
|
||||
* Date and time
|
||||
|
||||
Once the data has been logged in the access logs, it is automatically retrieved and processed by a locally-hosted application every 30 seconds and then deleted from said logs.
|
||||
|
||||
This application compares this information against a list of known threat sources, targets and behaviours and if a match is found, the private information is anonymized and stored for 7 days pending a manual review.
|
||||
Once that 7 day period has elapsed, or once the report has been reviewed, all the relevant data is automatically deleted.
|
||||
|
||||
If your request wasn't flagged as potentially malicious, every data collected from it is thrown out instantly.
|
||||
|
||||
This process should normally never be triggered for regular traffic since most of the triggering actions are ones that should not be possible to accomplish through normal browsing.
|
||||
However, this process isn't infallible and there is always an off chance that false positives may happen.
|
||||
|
||||
|
||||
# Third Parties
|
||||
Our websites uses some services provided by CloudFlare in order to prevent bad actors from accessing this website via their "Web Application Firewall", as well as for caching purpose in order to improve your browsing experience.
|
||||
|
||||
None of the data that may be gathered by CloudFlare is ever used.
|
||||
|
||||
If you'd wish to consult their privacy policy, you can do so on their "Trust Hub" at the following URLs:
|
||||
https://www.cloudflare.com/trust-hub/gdpr/ (English)
|
||||
https://www.cloudflare.com/fr-fr/trust-hub/gdpr/ (French)
|
||||
|
||||
|
||||
# Cookies
|
||||
Our websites doesn't use nor store any cookies in your browser.
|
||||
|
||||
In the unlikely event one is present, we recommend you check CloudFlare's privacy policy on their "Trust Hub" at the following URLs:
|
||||
https://www.cloudflare.com/trust-hub/gdpr/ (English)
|
||||
https://www.cloudflare.com/fr-fr/trust-hub/gdpr/ (French)
|
||||
|
||||
This can be caused by malicious traffic coming from your network, or when you visit some private and restricted subdomains.
|
||||
|
||||
|
||||
# Changes to our privacy policy
|
||||
The content of this privacy policy was originally written on the 4th of December 2021 and was last updated on the 18th of March 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Original version
|
||||
|
||||
* 2022/03/18
|
||||
* Changed section on data collection to reflect new policy.
|
||||
* Added mention about CloudFlare and linked to their privacy policy.
|
||||
* Improved the "Changes to our privacy policy" section.
|
||||
|
||||
In the event of a change to our privacy policy, you will be informed explicitly, and a copy of previous versions of the policy will be available through this page.
|
||||
|
||||
|
||||
# How to contact us ?
|
||||
If you wish to contact us for more information regarding our privacy policy, please contact us via the form included on the contact page, or at the following email address:
|
||||
* herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# How to contact the appropriate authorities ?
|
||||
Should you wish to report a complaint or if you feel that our privacy policy has not addressed your concern in a satisfactory manner, you may contact your national Data Protection Authority (DPA).
|
||||
|
||||
More information on this procedure can be found on the following websites:
|
||||
* https://ec.europa.eu/ (English)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (French)
|
@@ -0,0 +1,77 @@
|
||||
# Introduction
|
||||
La politique de confidentialité ci-présente a été écrite en accord avec les articles 12 et 13 de la RGPD.
|
||||
|
||||
Si vous souhaitez consulter le texte officiel en question, vous pouvez le faire sur les sites internet suivants :
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Collecte de données
|
||||
Ce site web collecte des données au travers des journaux d'évènements afin de détecter et bloquer de potentiels acteurs malveillants.
|
||||
Les données collectées ne sont en aucun cas utilisées pour une quelconque autre raison.
|
||||
|
||||
Voici la liste des données personelles collectées:
|
||||
* L'addresse IP source détéctée par CloudFlare
|
||||
* Le "User-Agent" de votre navigateur internet
|
||||
|
||||
Et voici la liste des données non-personelles collectées:
|
||||
* L'URI de la ressource demandée
|
||||
* La date et l'heure
|
||||
|
||||
Les données présentes dans les journaux d'évènements sont extraites et retirées pour être traitées par une application qui tourne en local toute les 30 secondes.
|
||||
|
||||
L'application en question utilise et compare ces informations avec une liste d'acteurs malveillants et comportement suspects connus.
|
||||
Si une correspondance est détectée, les informations privées sont anonymisées et sont stockées pendant 7 jours en attendant qu'un examen manuel soit effectué.
|
||||
Après cette période de 7 jours, ou après qu'un examen ait été effectué, les données sont automatiquement supprimées.
|
||||
|
||||
Toute information concernant une requête non suspecte est automatiquement supprimée.
|
||||
|
||||
Ce processus n'est normalement jamais utilisé sur des requêtes provenant d'un trafic légitime dû au fait qu'il isole principalement les actions et requêtes qui ne devraient pas être possible sur ce site.
|
||||
Cependant, ce processus n'est pas infaillible et il est toujours possible qu'une requête soit isolée par erreur.
|
||||
|
||||
|
||||
# Organismes tiers
|
||||
Ce site web utilise les services proposés par CloudFlare afin d'empêcher des acteurs malveillants d'y accéder grâce au "web application Firewall", ainsi que pour améliorer l'expérience des personnes le visitant grâce à leur CDN.
|
||||
|
||||
Aucune des données collectées et stockées par CloudFlare n'est utilisé.
|
||||
|
||||
Si vous souhaitez consulter leur politique de confidentialité, vous pouvez le faire sur leur "Trust Hub" en utilisant les liens ci-dessous:
|
||||
* https://www.cloudflare.com/trust-hub/gdpr/ (Anglais)
|
||||
* https://www.cloudflare.com/fr-fr/trust-hub/gdpr/ (Français)
|
||||
|
||||
|
||||
# Cookies de navigation
|
||||
Ce site web n'utilise pas, et ne stocke aucun cookies dans votre navigateur internet.
|
||||
|
||||
Dans l'éventualité où l'un serait présent, nous vous recommandons de consulter le "Trust Hub" de CloudFlare via les liens suivants pour plus d'informations:
|
||||
* https://www.cloudflare.com/trust-hub/gdpr/ (Anglais)
|
||||
* https://www.cloudflare.com/fr-fr/trust-hub/gdpr/ (Français)
|
||||
|
||||
Ce genre de situation peut être causée par le fait que du trafic suspect provient de votre navigateur internet, ou lors d'une visite sur un de nos sous-domaines privés.
|
||||
|
||||
|
||||
# Changements à notre politique de confidentialité
|
||||
Le contenu de notre politique de confidentialité a été originalement écrit et le 4 décembre 2021 modifié pour la dernière fois le 18 mars 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Version originale
|
||||
|
||||
* 2022/03/18
|
||||
* Mise-à-jour de la section sur la collection des données.
|
||||
* Ajout d'une mention de CloudFlare et ajout de liens vers leur politique de confidentialité.
|
||||
* Amélioration de la section "Changements à notre politique de confidentialité".
|
||||
|
||||
En cas de changement, vous serez clairement informé et une copie des anciennes versions de notre politique sera disponible au travers de cette page.
|
||||
|
||||
|
||||
# Comment nous contacter ?
|
||||
Si vous souhaitez nous contacter afin d'obtenir plus d'informations concernant notre politique de confidentialité, nous vous recommandons d'utiliser le formulaire présent sur la page de contact, ou par courriel à l'adresse suivante:
|
||||
* herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# Comment contacter les autorités compétentes ?
|
||||
Dans l'éventualité où vous souhaiteriez déposer une plainte pour une quelconque raison en rapport avec notre politique de confidentialité, veuillez vous adresser à l'autorité nationale de protection des données (DPA).
|
||||
|
||||
Les informations concernant cette procédure peuvent être trouvées sur les sites internet suivants:
|
||||
* https://ec.europa.eu/ (Anglais)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (Français)
|
@@ -0,0 +1,77 @@
|
||||
# Introduction
|
||||
This privacy policy is written in accordance with the 12th and 13th articles of the GDPR.
|
||||
|
||||
If you wish to consult it, you can do so on the following websites:
|
||||
https://gdpr.eu/
|
||||
https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Data collection
|
||||
This websites only collects data through generic access logs in order to detect and block bad actors from accessing this website.
|
||||
None of the data collected is used for any other purpose,it is never shared with any other third-party and is never use in any sort of analytics.
|
||||
|
||||
Here is the list of private data being collected:
|
||||
* IP address
|
||||
* Browser's User-Agent
|
||||
|
||||
And here is the list of non-private data being collected:
|
||||
* Requested resource' URI
|
||||
* Date and time
|
||||
|
||||
Once the data has been logged in the access logs, it is automatically retrieved and processed by a locally-hosted application every 30 seconds and then deleted from said logs.
|
||||
|
||||
This application compares this information against a list of known threat sources, targets and behaviours and if a match is found, the private information is anonymized and stored for 7 days pending a manual review.
|
||||
Once that 7 day period has elapsed, or once the report has been reviewed, all the relevant data is automatically deleted.
|
||||
|
||||
If your request wasn't flagged as potentially malicious, every data collected from it is thrown out instantly.
|
||||
|
||||
This process should normally never be triggered for regular traffic since most of the triggering actions are ones that should not be possible to accomplish through normal browsing.
|
||||
However, this process isn't infallible and there is always an off chance that false positives may happen.
|
||||
|
||||
|
||||
# Third Parties
|
||||
Our websites uses some services provided by v6Node in order to prevent bad actors from accessing this website and in order to put in place a reverse-proxy system.
|
||||
The goal of this system is to improve your browsing experience with the help of a private caching service and custom traffic filtering rules.
|
||||
|
||||
None of the data that may be gathered by v6Node or the system described above is ever used or stored.
|
||||
|
||||
If you'd wish to consult their privacy policy and their partners', you can do so by using the following URLs:
|
||||
* https://v6node.com/legal (English & German)
|
||||
* https://v6node.b-cdn.net/legal/dataprotection.pdf (German)
|
||||
|
||||
|
||||
# Cookies
|
||||
Our websites doesn't use nor store any cookies in your browser.
|
||||
|
||||
|
||||
# Changes to our privacy policy
|
||||
The content of this privacy policy was originally written on the 4th of December 2021 and was last updated on the 18th of March 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Original version
|
||||
|
||||
* 2022/03/18
|
||||
* Changed section on data collection to reflect new policy.
|
||||
* Added mention about CloudFlare and linked to their privacy policy.
|
||||
* Improved the "Changes to our privacy policy" section.
|
||||
|
||||
* 2022/09/09
|
||||
* Changed references to external services to reflect the migration to v6Node.
|
||||
* Added mention about v6Node and linked to their privacy policy.
|
||||
* Removed mentions of CloudFlare.
|
||||
* Changed the "Cookies" section to indicate that none should be used on public domains.
|
||||
|
||||
In the event of a change to our privacy policy, you will be informed explicitly, and a copy of previous versions of the policy will be available through this page.
|
||||
|
||||
|
||||
# How to contact us ?
|
||||
If you wish to contact us for more information regarding our privacy policy, please contact us via the form included on the contact page, or at the following email address:
|
||||
* herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# How to contact the appropriate authorities ?
|
||||
Should you wish to report a complaint or if you feel that our privacy policy has not addressed your concern in a satisfactory manner, you may contact your national Data Protection Authority (DPA).
|
||||
|
||||
More information on this procedure can be found on the following websites:
|
||||
* https://ec.europa.eu/ (English)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (French)
|
@@ -0,0 +1,78 @@
|
||||
# Introduction
|
||||
La politique de confidentialité ci-présente a été écrite en accord avec les articles 12 et 13 de la RGPD.
|
||||
|
||||
Si vous souhaitez consulter le texte officiel en question, vous pouvez le faire sur les sites internet suivants :
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Collecte de données
|
||||
Ce site web collecte des données au travers des journaux d'évènements afin de détecter et bloquer de potentiels acteurs malveillants.
|
||||
Les données collectées ne sont en aucun cas utilisées pour une quelconque autre raison.
|
||||
|
||||
Voici la liste des données personelles collectées:
|
||||
* L'addresse IP source
|
||||
* Le "User-Agent" de votre navigateur internet
|
||||
|
||||
Et voici la liste des données non-personelles collectées:
|
||||
* L'URI de la ressource demandée
|
||||
* La date et l'heure
|
||||
|
||||
Les données présentes dans les journaux d'évènements sont extraites et retirées pour être traitées par une application qui tourne en local toute les 30 secondes.
|
||||
|
||||
L'application en question utilise et compare ces informations avec une liste d'acteurs malveillants et comportement suspects connus.
|
||||
Si une correspondance est détectée, les informations privées sont anonymisées et sont stockées pendant 7 jours en attendant qu'un examen manuel soit effectué.
|
||||
Après cette période de 7 jours, ou après qu'un examen ait été effectué, les données sont automatiquement supprimées.
|
||||
|
||||
Toute information concernant une requête non suspecte est automatiquement supprimée.
|
||||
|
||||
Ce processus n'est normalement jamais utilisé sur des requêtes provenant d'un trafic légitime dû au fait qu'il isole principalement les actions et requêtes qui ne devraient pas être possible sur ce site.
|
||||
Cependant, ce processus n'est pas infaillible et il est toujours possible qu'une requête soit isolée par erreur.
|
||||
|
||||
|
||||
# Organismes tiers
|
||||
Ce site web utilise les services proposés par v6Node afin d'empêcher des acteurs malveillants d'y accéder et dans le but de mettre en place un système de reverse-proxy.
|
||||
Ceci a pour but d'améliorer l'expérience des personnes le visitant grâce à un système de filtrage et caching privé.
|
||||
|
||||
Aucune des données collectées et stockées par v6Node et le système décris ci-dessus n'est utilisé ou stocké.
|
||||
|
||||
Si vous souhaitez consulter leur politique de confidentialité ainsi que celle de leur partenaires, vous pouvez le faire en suivant les liens ci-dessous:
|
||||
* https://v6node.com/legal (Allemand & Anglais)
|
||||
* https://v6node.b-cdn.net/legal/dataprotection.pdf (Allemand)
|
||||
|
||||
|
||||
# Cookies de navigation
|
||||
Ce site web n'utilise pas, et ne stocke aucun cookies dans votre navigateur internet.
|
||||
|
||||
|
||||
# Changements à notre politique de confidentialité
|
||||
Le contenu de notre politique de confidentialité a été originalement écrit et le 4 décembre 2021 modifié pour la dernière fois le 18 mars 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Version originale
|
||||
|
||||
* 2022/03/18
|
||||
* Mise-à-jour de la section sur la collection des données.
|
||||
* Ajout d'une mention de CloudFlare et ajout de liens vers leur politique de confidentialité.
|
||||
* Amélioration de la section "Changements à notre politique de confidentialité".
|
||||
|
||||
* 2022/09/09
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de v6Node.
|
||||
* Ajout de mentions de v6Node et liens vers leur politique de vie confidentialité.
|
||||
* Suppression de mentions de CloudFlare.
|
||||
* Changement de la section "Cookies" afin d'indiquer qu'ils ne seront plus utilisés sur les domaines publics.
|
||||
|
||||
En cas de changement, vous serez clairement informé et une copie des anciennes versions de notre politique sera disponible au travers de cette page.
|
||||
|
||||
|
||||
# Comment nous contacter ?
|
||||
Si vous souhaitez nous contacter afin d'obtenir plus d'informations concernant notre politique de confidentialité, nous vous recommandons d'utiliser le formulaire présent sur la page de contact, ou par courriel à l'adresse suivante:
|
||||
* herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# Comment contacter les autorités compétentes ?
|
||||
Dans l'éventualité où vous souhaiteriez déposer une plainte pour une quelconque raison en rapport avec notre politique de confidentialité, veuillez vous adresser à l'autorité nationale de protection des données (DPA).
|
||||
|
||||
Les informations concernant cette procédure peuvent être trouvées sur les sites internet suivants:
|
||||
* https://ec.europa.eu/ (Anglais)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (Français)
|
@@ -0,0 +1,82 @@
|
||||
# Introduction
|
||||
This privacy policy is written in accordance with the 12th and 13th articles of the GDPR.
|
||||
|
||||
If you wish to consult it, you can do so on the following websites:
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Data collection
|
||||
This websites only collects data through generic access logs in order to detect and block bad actors from accessing this website.
|
||||
None of the data collected is used for any other purpose, it is never shared with any other third-party and is never use in any sort of analytics.
|
||||
|
||||
Here is the list of private data being collected:
|
||||
* IP address
|
||||
* Browser's User-Agent
|
||||
|
||||
And here is the list of non-private data being collected:
|
||||
* Requested resource' URI
|
||||
* Date and time
|
||||
|
||||
Once the data has been logged in the access logs, it is automatically retrieved and processed by a locally-hosted applications every 30-60 seconds and then deleted from said logs.
|
||||
|
||||
This application compares this information against a list of known threat sources, targets and behaviours and if a match is found, the private information is stored for 7 days pending a manual review.
|
||||
Once that 7 day period has elapsed, or once the report has been reviewed, all the relevant data is automatically deleted.
|
||||
|
||||
If your request wasn't flagged as potentially malicious, every data collected from it is thrown out instantly.
|
||||
|
||||
This process should normally never be triggered for regular traffic since most of the triggering actions are ones that should not be possible to accomplish through normal browsing.
|
||||
However, this process isn't infallible and there is always an off chance that false positives may happen.
|
||||
|
||||
|
||||
# Third Parties
|
||||
Our websites uses some VPS provided by IONOS in order to put in place a reverse-proxy system.
|
||||
The goal of this system is to improve your browsing experience with the help of a private caching service and custom traffic filtering rules.
|
||||
|
||||
No data should be collected on their side due to the nature of the server leased from IONOS.
|
||||
|
||||
If you'd wish to consult their privacy policy and their partners', you can do so by using the following URLs:
|
||||
* https://www.ionos.fr/terms-gtc/clause-de-confidentialite/ (French)
|
||||
* https://www.ionos.com/terms-gtc/privacy-policy/ (English)
|
||||
|
||||
|
||||
# Cookies
|
||||
Our websites doesn't use nor store any cookies in your browser.
|
||||
|
||||
|
||||
# Changes to our privacy policy
|
||||
The content of this privacy policy was originally written on the 4th of December 2021 and was last updated on the 18th of March 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Original version
|
||||
|
||||
* 2022/03/18
|
||||
* Changed section on data collection to reflect new policy.
|
||||
* Added mention about CloudFlare and linked to their privacy policy.
|
||||
* Improved the "Changes to our privacy policy" section.
|
||||
|
||||
* 2022/09/09
|
||||
* Changed references to external services to reflect the migration to v6Node.
|
||||
* Added mention about v6Node and linked to their privacy policy.
|
||||
* Removed mentions of CloudFlare.
|
||||
* Changed the "Cookies" section to indicate that none should be used on public domains.
|
||||
|
||||
* 2023/11/11
|
||||
* Changed references to external services to reflect the migration to IONOS.
|
||||
* Removed mentions of v6Node.
|
||||
* Changed section on data collection to reflect new timings & infrastructure.
|
||||
|
||||
In the event of a change to our privacy policy, you will be informed explicitly, and a copy of previous versions of the policy will be available through this page.
|
||||
|
||||
|
||||
# How to contact us ?
|
||||
If you wish to contact us for more information regarding our privacy policy, please contact us via the form included on the contact page, or at the following email address:
|
||||
* herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# How to contact the appropriate authorities ?
|
||||
Should you wish to report a complaint or if you feel that our privacy policy has not addressed your concern in a satisfactory manner, you may contact your national Data Protection Authority (DPA).
|
||||
|
||||
More information on this procedure can be found on the following websites:
|
||||
* https://ec.europa.eu/ (English)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (French)
|
@@ -0,0 +1,83 @@
|
||||
# Introduction
|
||||
La politique de confidentialité ci-présente a été écrite en accord avec les articles 12 et 13 de la RGPD.
|
||||
|
||||
Si vous souhaitez consulter le texte officiel en question, vous pouvez le faire sur les sites internet suivants :
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Collecte de données
|
||||
Ce site web collecte des données au travers des journaux d'évènements afin de détecter et bloquer de potentiels acteurs malveillants.
|
||||
Les données collectées ne sont en aucun cas utilisées pour une quelconque autre raison.
|
||||
|
||||
Voici la liste des données personelles collectées:
|
||||
* L'addresse IP source
|
||||
* Le "User-Agent" de votre navigateur internet
|
||||
|
||||
Et voici la liste des données non-personelles collectées:
|
||||
* L'URI de la ressource demandée
|
||||
* La date et l'heure
|
||||
|
||||
Les données présentes dans les journaux d'évènements sont extraites et retirées pour être traitées par des applications qui tournent en local toute les 30 à 60 secondes.
|
||||
|
||||
L'application en question utilise et compare ces informations avec une liste d'acteurs malveillants et comportement suspects connus.
|
||||
Si une correspondance est détectée, les informations privées sont stockées pendant 7 jours en attendant qu'un examen manuel soit effectué.
|
||||
Après cette période de 7 jours, ou après qu'un examen ait été effectué, les données sont automatiquement supprimées.
|
||||
|
||||
Toute information concernant une requête non suspecte est automatiquement supprimée.
|
||||
|
||||
Ce processus n'est normalement jamais utilisé sur des requêtes provenant d'un trafic légitime dû au fait qu'il isole principalement les actions et requêtes qui ne devraient pas être possible sur ce site.
|
||||
Cependant, ce processus n'est pas infaillible et il est toujours possible qu'une requête soit isolée par erreur.
|
||||
|
||||
|
||||
# Organismes tiers
|
||||
Ce site web utilise un VPS proposés par IONOS dans le but de mettre en place un système de reverse-proxy.
|
||||
Ceci a pour but d'améliorer l'expérience des personnes le visitant grâce à un système de filtrage et caching privé.
|
||||
|
||||
Due à la nature du serveur loué à IONOS, aucune donnée ne devraient être collectées de leur côté.
|
||||
|
||||
Si vous souhaitez consulter leur politique de confidentialité ainsi que celle de leur partenaires, vous pouvez le faire en suivant les liens ci-dessous:
|
||||
* https://www.ionos.fr/terms-gtc/clause-de-confidentialite/ (Français)
|
||||
* https://www.ionos.com/terms-gtc/privacy-policy/ (Anglais)
|
||||
|
||||
|
||||
# Cookies de navigation
|
||||
Ce site web n'utilise pas, et ne stocke aucun cookies dans votre navigateur internet.
|
||||
|
||||
|
||||
# Changements à notre politique de confidentialité
|
||||
Le contenu de notre politique de confidentialité a été originalement écrit et le 4 décembre 2021 modifié pour la dernière fois le 18 mars 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Version originale
|
||||
|
||||
* 2022/03/18
|
||||
* Mise-à-jour de la section sur la collection des données.
|
||||
* Ajout d'une mention de CloudFlare et ajout de liens vers leur politique de confidentialité.
|
||||
* Amélioration de la section "Changements à notre politique de confidentialité".
|
||||
|
||||
* 2022/09/09
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de v6Node.
|
||||
* Ajout de mentions de v6Node et liens vers leur politique de vie confidentialité.
|
||||
* Suppression de mentions de CloudFlare.
|
||||
* Changement de la section "Cookies" afin d'indiquer qu'ils ne seront plus utilisés sur les domaines publics.
|
||||
|
||||
* 2023/11/11
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de IONOS.
|
||||
* Suppression de mentions de v6Node.
|
||||
* Changement des temps de traitement et mentions de l'infrastructure dans la section "Changements à notre politique de confidentialité".
|
||||
|
||||
En cas de changement, vous serez clairement informé et une copie des anciennes versions de notre politique sera disponible au travers de cette page.
|
||||
|
||||
|
||||
# Comment nous contacter ?
|
||||
Si vous souhaitez nous contacter afin d'obtenir plus d'informations concernant notre politique de confidentialité, nous vous recommandons d'utiliser le formulaire présent sur la page de contact, ou par courriel à l'adresse suivante:
|
||||
* herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# Comment contacter les autorités compétentes ?
|
||||
Dans l'éventualité où vous souhaiteriez déposer une plainte pour une quelconque raison en rapport avec notre politique de confidentialité, veuillez vous adresser à l'autorité nationale de protection des données (DPA).
|
||||
|
||||
Les informations concernant cette procédure peuvent être trouvées sur les sites internet suivants:
|
||||
* https://ec.europa.eu/ (Anglais)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (Français)
|
103
static/resources/NibblePoker/privacy/privacy_2023-11-30_en.txt
Normal file
103
static/resources/NibblePoker/privacy/privacy_2023-11-30_en.txt
Normal file
@@ -0,0 +1,103 @@
|
||||
# Introduction
|
||||
This privacy policy is written in accordance with the 12th and 13th articles of the GDPR.
|
||||
|
||||
If you wish to consult it, you can do so on the following websites:
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Data collection (Web)
|
||||
This websites only collects data through generic access logs in order to detect and block bad actors from accessing this website.
|
||||
None of the data collected is used for any other purpose, it is never shared with any other third-party and is never use in any sort of analytics.
|
||||
|
||||
Here is the list of private data being collected:
|
||||
* IP address
|
||||
* Browser's User-Agent
|
||||
|
||||
And here is the list of non-private data being collected:
|
||||
* Requested resource' URI
|
||||
* Date and time
|
||||
|
||||
Once the data has been logged in the access logs, it is automatically retrieved and processed by a locally-hosted applications every 30-60 seconds and then deleted from said logs.
|
||||
|
||||
This application compares this information against a list of known threat sources, targets and behaviours and if a match is found, the private information is stored for 7 days pending a manual review.
|
||||
Once that 7 day period has elapsed, or once the report has been reviewed, all the relevant data is automatically deleted.
|
||||
|
||||
If your request wasn't flagged as potentially malicious, every data collected from it is thrown out instantly.
|
||||
|
||||
This process should normally never be triggered for regular traffic since most of the triggering actions are ones that should not be possible to accomplish through normal browsing.
|
||||
However, this process isn't infallible and there is always an off chance that false positives may happen.
|
||||
|
||||
|
||||
# Data collection (DNS)
|
||||
Our DNS servers collects data through generic access logs in order to detect and block bad actors.
|
||||
None of the data collected is used for any other purpose, it is never shared with any other third-party and is never use in any sort of analytics.
|
||||
|
||||
Here is the list of private data being collected:
|
||||
* IP address
|
||||
|
||||
And here is the list of non-private data being collected:
|
||||
* Requested DNS record
|
||||
* Date and time
|
||||
|
||||
All private data is deleted after a period of 7 days.
|
||||
|
||||
|
||||
# Third Parties
|
||||
Our websites uses some VPS provided by IONOS and ChicagoVPS in order to put in place a CDN system.
|
||||
The goal of this system is to improve your browsing experience with the help of a private caching service and custom traffic filtering rules.
|
||||
|
||||
No data should be collected on their side due to the nature of the server leased to us.
|
||||
|
||||
If you'd wish to consult their privacy policy and their partners', you can do so by using the following URLs:
|
||||
* IONOS
|
||||
* French -> https://www.ionos.fr/terms-gtc/clause-de-confidentialite/
|
||||
* English -> https://www.ionos.com/terms-gtc/privacy-policy/
|
||||
* ChicagoVPS
|
||||
* English -> https://www.chicagovps.net/wp-content/uploads/2023/07/Terms-and-Conditions-ChicagoVPS.pdf
|
||||
|
||||
|
||||
# Cookies
|
||||
Our websites doesn't use nor store any cookies in your browser.
|
||||
|
||||
|
||||
# Changes to our privacy policy
|
||||
The content of this privacy policy was originally written on the 4th of December 2021 and was last updated on the 18th of March 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Original version
|
||||
|
||||
* 2022/03/18
|
||||
* Changed section on data collection to reflect new policy.
|
||||
* Added mention about CloudFlare and linked to their privacy policy.
|
||||
* Improved the "Changes to our privacy policy" section.
|
||||
|
||||
* 2022/09/09
|
||||
* Changed references to external services to reflect the migration to v6Node.
|
||||
* Added mention about v6Node and linked to their privacy policy.
|
||||
* Removed mentions of CloudFlare.
|
||||
* Changed the "Cookies" section to indicate that none should be used on public domains.
|
||||
|
||||
* 2023/11/11
|
||||
* Changed references to external services to reflect the migration to IONOS.
|
||||
* Removed mentions of v6Node.
|
||||
* Changed section on data collection to reflect new timings & infrastructure.
|
||||
|
||||
* 2023/11/30
|
||||
* Added a section regarding data collection through DNS servers.
|
||||
* Changed references to external services to reflect the usage of ChicagoVPS
|
||||
|
||||
In the event of a change to our privacy policy, you will be informed explicitly, and a copy of previous versions of the policy will be available through this page.
|
||||
|
||||
|
||||
# How to contact us ?
|
||||
If you wish to contact us for more information regarding our privacy policy, please contact us via the form included on the contact page, or at the following email address:
|
||||
herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# How to contact the appropriate authorities ?
|
||||
Should you wish to report a complaint or if you feel that our privacy policy has not addressed your concern in a satisfactory manner, you may contact your national Data Protection Authority (DPA).
|
||||
|
||||
More information on this procedure can be found on the following websites:
|
||||
* https://ec.europa.eu/ (English)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (French)
|
104
static/resources/NibblePoker/privacy/privacy_2023-11-30_fr.txt
Normal file
104
static/resources/NibblePoker/privacy/privacy_2023-11-30_fr.txt
Normal file
@@ -0,0 +1,104 @@
|
||||
# Introduction
|
||||
La politique de confidentialité ci-présente a été écrite en accord avec les articles 12 et 13 de la RGPD.
|
||||
|
||||
Si vous souhaitez consulter le texte officiel en question, vous pouvez le faire sur les sites internet suivants :
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Collecte de données (Web)
|
||||
Ce site web collecte des données au travers des journaux d'évènements afin de détecter et bloquer de potentiels acteurs malveillants.
|
||||
Les données collectées ne sont en aucun cas utilisées pour une quelconque autre raison.
|
||||
|
||||
Voici la liste des données personnelles collectées:
|
||||
* L'addresse IP source
|
||||
* Le "User-Agent" de votre navigateur internet
|
||||
|
||||
Et voici la liste des données non-personnelles collectées:
|
||||
* L'URI de la ressource demandée
|
||||
* La date et l'heure
|
||||
|
||||
Les données présentes dans les journaux d'évènements sont extraites et retirées pour être traitées par des applications qui tournent en local toute les 30 à 60 secondes.
|
||||
|
||||
L'application en question utilise et compare ces informations avec une liste d'acteurs malveillants et comportement suspects connus.
|
||||
Si une correspondance est détectée, les informations privées sont stockées pendant 7 jours en attendant qu'un examen manuel soit effectué.
|
||||
Après cette période de 7 jours, ou après qu'un examen ait été effectué, les données sont automatiquement supprimées.
|
||||
|
||||
Toute information concernant une requête non suspecte est automatiquement supprimée.
|
||||
|
||||
Ce processus n'est normalement jamais utilisé sur des requêtes provenant d'un trafic légitime dû au fait qu'il isole principalement les actions et requêtes qui ne devraient pas être possible sur ce site.
|
||||
Cependant, ce processus n'est pas infaillible et il est toujours possible qu'une requête soit isolée par erreur.
|
||||
|
||||
|
||||
# Collecte de données (DNS)
|
||||
Nos serveurs DNS collectent des données au travers des journaux d'évènements afin de détecter et bloquer de potentiels acteurs malveillants.
|
||||
Les données collectées ne sont en aucun cas utilisées pour une quelconque autre raison.
|
||||
|
||||
Voici la liste des données personnelles collectées:
|
||||
* L'addresse IP source
|
||||
|
||||
Et voici la liste des données non-personnelles collectées:
|
||||
* L'enregistrement DNS demandée
|
||||
* La date et l'heure
|
||||
|
||||
Toutes les données personnelles sont automatiquement supprimées après une période de 7 jours.
|
||||
|
||||
|
||||
# Organismes tiers
|
||||
Ce site web utilise des VPS proposés par IONOS et ChicagoVPS dans le but de mettre en place un système de RDC.
|
||||
Ceci a pour but d'améliorer l'expérience des personnes le visitant grâce à un système de filtrage et caching privé.
|
||||
|
||||
Due à la nature des serveurs loués, aucune donnée ne devraient être collectées de leur côté.
|
||||
|
||||
Si vous souhaitez consulter leur politique de confidentialité ainsi que celle de leur partenaires, vous pouvez le faire en suivant les liens ci-dessous:
|
||||
* IONOS
|
||||
* Français -> https://www.ionos.fr/terms-gtc/clause-de-confidentialite/
|
||||
* Anglais -> https://www.ionos.com/terms-gtc/privacy-policy/
|
||||
* ChicagoVPS
|
||||
* Anglais -> https://www.chicagovps.net/wp-content/uploads/2023/07/Terms-and-Conditions-ChicagoVPS.pdf
|
||||
|
||||
|
||||
# Cookies de navigation
|
||||
Ce site web n'utilise pas, et ne stocke aucun cookies dans votre navigateur internet.
|
||||
|
||||
|
||||
# Changements à notre politique de confidentialité
|
||||
Le contenu de notre politique de confidentialité a été originalement écrit et le 4 décembre 2021 modifié pour la dernière fois le 18 mars 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Version originale
|
||||
|
||||
* 2022/03/18
|
||||
* Mise-à-jour de la section sur la collection des données.
|
||||
* Ajout d'une mention de CloudFlare et ajout de liens vers leur politique de confidentialité.
|
||||
* Amélioration de la section "Changements à notre politique de confidentialité".
|
||||
|
||||
* 2022/09/09
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de v6Node.
|
||||
* Ajout de mentions de v6Node et liens vers leur politique de vie confidentialité.
|
||||
* Suppression de mentions de CloudFlare.
|
||||
* Changement de la section "Cookies" afin d'indiquer qu'ils ne seront plus utilisés sur les domaines publics.
|
||||
|
||||
* 2023/11/11
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de IONOS.
|
||||
* Suppression de mentions de v6Node.
|
||||
* Changement des temps de traitement et mentions de l'infrastructure dans la section "Changements à notre politique de confidentialité".
|
||||
|
||||
* 2023/11/30
|
||||
* Ajout de la section sur la collection des données par le serveur DNS.
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de ChicagoVPS.
|
||||
|
||||
En cas de changement, vous serez clairement informé et une copie des anciennes versions de notre politique sera disponible au travers de cette page.
|
||||
|
||||
|
||||
# Comment nous contacter ?
|
||||
Si vous souhaitez nous contacter afin d'obtenir plus d'informations concernant notre politique de confidentialité, nous vous recommandons d'utiliser le formulaire présent sur la page de contact, ou par courriel à l'adresse suivante:
|
||||
herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# Comment contacter les autorités compétentes ?
|
||||
Dans l'éventualité où vous souhaiteriez déposer une plainte pour une quelconque raison en rapport avec notre politique de confidentialité, veuillez vous adresser à l'autorité nationale de protection des données (DPA).
|
||||
|
||||
Les informations concernant cette procédure peuvent être trouvées sur les sites internet suivants:
|
||||
https://ec.europa.eu/ (Anglais)
|
||||
https://gegevensbeschermingsautoriteit.be/ (Français)
|
@@ -0,0 +1,97 @@
|
||||
# Introduction
|
||||
This privacy policy is written in accordance with the 12th and 13th articles of the GDPR.
|
||||
|
||||
If you wish to consult it, you can do so on the following websites:
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Data collection (Web)
|
||||
This websites only collects data through generic access logs in order to detect and block bad actors from accessing this website.
|
||||
None of the data collected is used for any other purpose, it is never shared with any other third-party and is never use in any sort of analytics.
|
||||
|
||||
Here is the list of private data being collected:
|
||||
* IP address
|
||||
* Browser's User-Agent
|
||||
|
||||
And here is the list of non-private data being collected:
|
||||
* Requested resource' URI
|
||||
* Date and time
|
||||
|
||||
Once the data has been logged in the access logs, it is automatically retrieved and processed by a locally-hosted applications every 30-60 seconds and then deleted from said logs.
|
||||
|
||||
This application compares this information against a list of known threat sources, targets and behaviours and if a match is found, the private information is stored for 7 days pending a manual review.
|
||||
Once that 7 day period has elapsed, or once the report has been reviewed, all the relevant data is automatically deleted.
|
||||
|
||||
If your request wasn't flagged as potentially malicious, every data collected from it is thrown out instantly.
|
||||
|
||||
This process should normally never be triggered for regular traffic since most of the triggering actions are ones that should not be possible to accomplish through normal browsing.
|
||||
However, this process isn't infallible and there is always an off chance that false positives may happen.
|
||||
|
||||
|
||||
# Data collection (DNS)
|
||||
Our DNS servers collects data through generic access logs in order to detect and block bad actors.
|
||||
None of the data collected is used for any other purpose, it is never shared with any other third-party and is never use in any sort of analytics.
|
||||
|
||||
Here is the list of private data being collected:
|
||||
* IP address
|
||||
|
||||
And here is the list of non-private data being collected:
|
||||
* Requested DNS record
|
||||
* Date and time
|
||||
|
||||
All private data is deleted after a period of 7 days.
|
||||
|
||||
|
||||
# Third Parties
|
||||
Our services do not share any data with any third parties whatsoever.
|
||||
|
||||
|
||||
# Cookies
|
||||
Our websites doesn't use nor store any cookies in your browser.
|
||||
|
||||
|
||||
# Changes to our privacy policy
|
||||
The content of this privacy policy was originally written on the 4th of December 2021 and was last updated on the 18th of March 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Original version
|
||||
|
||||
* 2022/03/18
|
||||
* Changed section on data collection to reflect new policy.
|
||||
* Added mention about CloudFlare and linked to their privacy policy.
|
||||
* Improved the "Changes to our privacy policy" section.
|
||||
|
||||
* 2022/09/09
|
||||
* Changed references to external services to reflect the migration to v6Node.
|
||||
* Added mention about v6Node and linked to their privacy policy.
|
||||
* Removed mentions of CloudFlare.
|
||||
* Changed the "Cookies" section to indicate that none should be used on public domains.
|
||||
|
||||
* 2023/11/11
|
||||
* Changed references to external services to reflect the migration to IONOS.
|
||||
* Removed mentions of v6Node.
|
||||
* Changed section on data collection to reflect new timings & infrastructure.
|
||||
|
||||
* 2023/11/30
|
||||
* Added a section regarding data collection through DNS servers.
|
||||
* Changed references to external services to reflect the usage of ChicagoVPS
|
||||
|
||||
* 2025/03/30
|
||||
* Simplification of the 'Third Parties' section.
|
||||
* Removal of unnecessary mentions of our VPS providers.
|
||||
|
||||
In the event of a change to our privacy policy, you will be informed explicitly, and a copy of previous versions of the policy will be available through this page.
|
||||
|
||||
|
||||
# How to contact us ?
|
||||
If you wish to contact us for more information regarding our privacy policy, please contact us via the form included on the contact page, or at the following email address:
|
||||
herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# How to contact the appropriate authorities ?
|
||||
Should you wish to report a complaint or if you feel that our privacy policy has not addressed your concern in a satisfactory manner, you may contact your national Data Protection Authority (DPA).
|
||||
|
||||
More information on this procedure can be found on the following websites:
|
||||
* https://ec.europa.eu/ (English)
|
||||
* https://gegevensbeschermingsautoriteit.be/ (French)
|
@@ -0,0 +1,98 @@
|
||||
# Introduction
|
||||
La politique de confidentialité ci-présente a été écrite en accord avec les articles 12 et 13 de la RGPD.
|
||||
|
||||
Si vous souhaitez consulter le texte officiel en question, vous pouvez le faire sur les sites internet suivants :
|
||||
* https://gdpr.eu/
|
||||
* https://eur-lex.europa.eu/
|
||||
|
||||
|
||||
# Collecte de données (Web)
|
||||
Ce site web collecte des données au travers des journaux d'évènements afin de détecter et bloquer de potentiels acteurs malveillants.
|
||||
Les données collectées ne sont en aucun cas utilisées pour une quelconque autre raison.
|
||||
|
||||
Voici la liste des données personnelles collectées:
|
||||
* L'addresse IP source
|
||||
* Le "User-Agent" de votre navigateur internet
|
||||
|
||||
Et voici la liste des données non-personnelles collectées:
|
||||
* L'URI de la ressource demandée
|
||||
* La date et l'heure
|
||||
|
||||
Les données présentes dans les journaux d'évènements sont extraites et retirées pour être traitées par des applications qui tournent en local toute les 30 à 60 secondes.
|
||||
|
||||
L'application en question utilise et compare ces informations avec une liste d'acteurs malveillants et comportement suspects connus.
|
||||
Si une correspondance est détectée, les informations privées sont stockées pendant 7 jours en attendant qu'un examen manuel soit effectué.
|
||||
Après cette période de 7 jours, ou après qu'un examen ait été effectué, les données sont automatiquement supprimées.
|
||||
|
||||
Toute information concernant une requête non suspecte est automatiquement supprimée.
|
||||
|
||||
Ce processus n'est normalement jamais utilisé sur des requêtes provenant d'un trafic légitime dû au fait qu'il isole principalement les actions et requêtes qui ne devraient pas être possible sur ce site.
|
||||
Cependant, ce processus n'est pas infaillible et il est toujours possible qu'une requête soit isolée par erreur.
|
||||
|
||||
|
||||
# Collecte de données (DNS)
|
||||
Nos serveurs DNS collectent des données au travers des journaux d'évènements afin de détecter et bloquer de potentiels acteurs malveillants.
|
||||
Les données collectées ne sont en aucun cas utilisées pour une quelconque autre raison.
|
||||
|
||||
Voici la liste des données personnelles collectées:
|
||||
* L'addresse IP source
|
||||
|
||||
Et voici la liste des données non-personnelles collectées:
|
||||
* L'enregistrement DNS demandée
|
||||
* La date et l'heure
|
||||
|
||||
Toutes les données personnelles sont automatiquement supprimées après une période de 7 jours.
|
||||
|
||||
|
||||
# Organismes tiers
|
||||
Nos services ne partagent aucune donnée avec des tiers, quels qu'ils soient.
|
||||
|
||||
|
||||
# Cookies de navigation
|
||||
Ce site web n'utilise pas, et ne stocke aucun cookies dans votre navigateur internet.
|
||||
|
||||
|
||||
# Changements à notre politique de confidentialité
|
||||
Le contenu de notre politique de confidentialité a été originalement écrit et le 4 décembre 2021 modifié pour la dernière fois le 18 mars 2022.
|
||||
|
||||
* 2021/12/04
|
||||
* Version originale
|
||||
|
||||
* 2022/03/18
|
||||
* Mise-à-jour de la section sur la collection des données.
|
||||
* Ajout d'une mention de CloudFlare et ajout de liens vers leur politique de confidentialité.
|
||||
* Amélioration de la section "Changements à notre politique de confidentialité".
|
||||
|
||||
* 2022/09/09
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de v6Node.
|
||||
* Ajout de mentions de v6Node et liens vers leur politique de vie confidentialité.
|
||||
* Suppression de mentions de CloudFlare.
|
||||
* Changement de la section "Cookies" afin d'indiquer qu'ils ne seront plus utilisés sur les domaines publics.
|
||||
|
||||
* 2023/11/11
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de IONOS.
|
||||
* Suppression de mentions de v6Node.
|
||||
* Changement des temps de traitement et mentions de l'infrastructure dans la section "Changements à notre politique de confidentialité".
|
||||
|
||||
* 2023/11/30
|
||||
* Ajout de la section sur la collection des données par le serveur DNS.
|
||||
* Changement des références aux services externes pour indiquer l'utilisation de ChicagoVPS.
|
||||
|
||||
* 2025/03/30
|
||||
* Simplification de la section 'Organismes tiers'.
|
||||
* Suppression des mentions inutiles de nous fournisseurs de VPS.
|
||||
|
||||
En cas de changement, vous serez clairement informé et une copie des anciennes versions de notre politique sera disponible au travers de cette page.
|
||||
|
||||
|
||||
# Comment nous contacter ?
|
||||
Si vous souhaitez nous contacter afin d'obtenir plus d'informations concernant notre politique de confidentialité, nous vous recommandons d'utiliser le formulaire présent sur la page de contact, ou par courriel à l'adresse suivante:
|
||||
herwin.bozet@gmail.com
|
||||
|
||||
|
||||
# Comment contacter les autorités compétentes ?
|
||||
Dans l'éventualité où vous souhaiteriez déposer une plainte pour une quelconque raison en rapport avec notre politique de confidentialité, veuillez vous adresser à l'autorité nationale de protection des données (DPA).
|
||||
|
||||
Les informations concernant cette procédure peuvent être trouvées sur les sites internet suivants:
|
||||
https://ec.europa.eu/ (Anglais)
|
||||
https://gegevensbeschermingsautoriteit.be/ (Français)
|
File diff suppressed because one or more lines are too long
@@ -2,17 +2,12 @@
|
||||
<!-- {{ render_h2(l10n("disclaimer.title", applet_data.id, user_lang)) }} -->
|
||||
|
||||
<label for="iban-generator-option-enable-sepa" class="mr-xxs">{{ l10n("option.sepa.enable", "iban-generator", user_lang) }}:</label>
|
||||
<input id="iban-generator-option-enable-sepa" class="r-m border" type="checkbox" checked>
|
||||
<input id="iban-generator-option-enable-sepa" class="r-m border cb-pretty" type="checkbox" checked>
|
||||
|
||||
<br>
|
||||
|
||||
<label for="iban-generator-option-enable-non-sepa" class="mr-xxs">{{ l10n("option.non-sepa.enable", "iban-generator", user_lang) }}:</label>
|
||||
<input id="iban-generator-option-enable-non-sepa" class="r-m border" type="checkbox" checked>
|
||||
|
||||
<br>
|
||||
|
||||
<label for="iban-generator-option-foreach" class="mr-xxs">{{ l10n("option.for.each", "iban-generator", user_lang) }}:</label>
|
||||
<input id="iban-generator-option-foreach" class="r-m border" type="checkbox">
|
||||
<input id="iban-generator-option-enable-non-sepa" class="r-m border cb-pretty" type="checkbox" checked>
|
||||
|
||||
<hr class="subtle">
|
||||
|
||||
@@ -113,17 +108,45 @@
|
||||
<br>
|
||||
|
||||
<label for="iban-generator-option-count" class="mr-xs">{{ l10n("option.count", "iban-generator", user_lang) }}:</label>
|
||||
<input id="iban-generator-option-count" class="p-xxs border r-s" type="number" value="4" min="1" max="1000">
|
||||
<input id="iban-generator-option-count" class="p-xxs border r-s" type="number" value="4" min="1" max="10000">
|
||||
|
||||
<br>
|
||||
|
||||
<label for="iban-generator-option-pretty" class="mr-xxs">{{ l10n("option.human.readable", "iban-generator", user_lang) }}:</label>
|
||||
<input id="iban-generator-option-pretty" class="r-m border" type="checkbox" checked>
|
||||
<label for="iban-generator-option-foreach" class="mr-xxs">{{ l10n("option.for.each", "iban-generator", user_lang) }}:</label>
|
||||
<input id="iban-generator-option-foreach" class="r-m border cb-pretty" type="checkbox">
|
||||
|
||||
<hr class="subtle">
|
||||
|
||||
|
||||
<input type="radio" id="iban-generator-option-prefer-random" name="iban_charset" value="0" class="radio-solid border mr-xxs radio-unchecked-subtle" checked>
|
||||
<label for="iban-generator-option-prefer-random">{{ l10n("option.prefer.random", "iban-generator", user_lang) }}</label>
|
||||
|
||||
<br>
|
||||
|
||||
<label for="iban-generator-option-prefer-numbers" class="mr-xxs">{{ l10n("option.prefer.numbers", "iban-generator", user_lang) }}:</label>
|
||||
<input id="iban-generator-option-prefer-numbers" class="r-m border" type="checkbox">
|
||||
<input type="radio" id="iban-generator-option-prefer-numbers" name="iban_charset" value="0" class="radio-solid border mr-xxs radio-unchecked-subtle">
|
||||
<label for="iban-generator-option-prefer-numbers">{{ l10n("option.prefer.numbers", "iban-generator", user_lang) }}</label>
|
||||
|
||||
<br>
|
||||
|
||||
<input type="radio" id="iban-generator-option-prefer-letters" name="iban_charset" value="0" class="radio-solid border mr-xxs radio-unchecked-subtle">
|
||||
<label for="iban-generator-option-prefer-letters">{{ l10n("option.prefer.letters", "iban-generator", user_lang) }}</label>
|
||||
|
||||
<hr class="subtle">
|
||||
|
||||
|
||||
<input type="radio" id="iban-generator-option-format-none" name="iban_format" value="none" class="radio-solid border mr-xxs radio-unchecked-subtle" checked>
|
||||
<label for="iban-generator-option-format-none">{{ l10n("option.human.format.none", "iban-generator", user_lang) }}</label>
|
||||
|
||||
<br>
|
||||
|
||||
<input type="radio" id="iban-generator-option-format-standard" name="iban_format" value="standard" class="radio-solid border mr-xxs radio-unchecked-subtle">
|
||||
<label for="iban-generator-option-format-standard">{{ l10n("option.human.format.standard", "iban-generator", user_lang) }}</label>
|
||||
|
||||
<br>
|
||||
|
||||
<input type="radio" id="iban-generator-option-format-4by4" name="iban_format" value="4by4" class="radio-solid border mr-xxs radio-unchecked-subtle">
|
||||
<label for="iban-generator-option-format-4by4">{{ l10n("option.human.format.4by4", "iban-generator", user_lang) }}</label>
|
||||
|
||||
|
||||
|
||||
<hr class="subtle">
|
||||
|
@@ -1,26 +1,14 @@
|
||||
|
||||
<section id="{{ applet_data.id }}-introduction">
|
||||
{{ render_h2(l10n("introduction.title", "commons", user_lang)) }}
|
||||
{{ render_paragraph(l10n("introduction.1", applet_data.id, user_lang)) }}
|
||||
{{ render_paragraph(l10n("introduction.2", applet_data.id, user_lang)) }}
|
||||
</section>
|
||||
{{ render_file_input(applet_data.id + "-image-input-file", true, ".png, .bmp, .ico", true, false, user_lang) }}
|
||||
|
||||
<section id="{{ applet_data.id }}-input">
|
||||
{{ render_h2(l10n("input.title", "commons", user_lang)) }}
|
||||
{{ render_paragraph(l10n("input.1", applet_data.id, user_lang)) }}
|
||||
<hr class="subtle">
|
||||
|
||||
{{ render_file_input(applet_data.id + "-image-input-file", true, ".png, .bmp, .ico", true, false, user_lang) }}
|
||||
|
||||
<hr class="subtle">
|
||||
|
||||
<label for="{{ applet_data.id }}-enable-expert-mode" class="mr-xxs">
|
||||
<label for="{{ applet_data.id }}-enable-expert-mode" class="mr-xxs">
|
||||
{{ l10n("enable.expert.mode", applet_data.id, user_lang) }}:
|
||||
</label>
|
||||
<input id="{{ applet_data.id }}-enable-expert-mode" class="r-m border" type="checkbox">
|
||||
<!--<span class="ml-s t-italic t-muted">Toggles some uncommon features.</span>-->
|
||||
|
||||
<br>
|
||||
</label>
|
||||
<input id="{{ applet_data.id }}-enable-expert-mode" class="r-m border" type="checkbox">
|
||||
|
||||
<div class="ico-maker-advanced">
|
||||
<label for="{{ applet_data.id }}-enable-binary-blobs" class="mr-xxs">
|
||||
{{ l10n("enable.binary.blobs", applet_data.id, user_lang) }}:
|
||||
</label>
|
||||
@@ -35,17 +23,16 @@
|
||||
|
||||
<span class="f-right">
|
||||
{{ render_button("<i class=\"fa-duotone fa-solid fa-remove\"></i>Remove Binary Blobs", False, None, "bkgd-orange") }}
|
||||
{{ render_button("<i class=\"fa-duotone fa-solid fa-remove\"></i>Remove Everything", False, None, "bkgd-red") }}
|
||||
<!--{{ render_button("<i class=\"fa-duotone fa-solid fa-remove\"></i>Remove Everything", False, None, "bkgd-red") }}-->
|
||||
</span>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section id="{{ applet_data.id }}-icon-parts">
|
||||
{{ render_h2(l10n("idk01.title", "commons", user_lang)) }}
|
||||
{{ render_paragraph(l10n("idk01.1", applet_data.id, user_lang)) }}
|
||||
<hr class="subtle">
|
||||
|
||||
{{ render_button("<i class=\"fa-duotone fa-solid fa-download\"></i>Download <span class=\"t-monospace\">.ico</span>", False, None, "bkgd-green") }}
|
||||
|
||||
<div class="border r-m">
|
||||
{{ render_button("<i class=\"fa-duotone fa-solid fa-download\"></i>Download <span class=\"t-monospace\">.ico</span>", False, None, "bkgd-green") }}
|
||||
|
||||
<div class="border r-m ico-maker-advanced">
|
||||
<table class="table-p-xxs ">
|
||||
<tr>
|
||||
<td class="bkgd-grid40 rl-m br t-size-14 t-noselect" rowspan="2">
|
||||
@@ -67,9 +54,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="{{ applet_data.id }}-icon-parts-list">
|
||||
<div id="{{ applet_data.id }}-icon-parts-list">
|
||||
|
||||
<div class="border r-m">
|
||||
<table class="table-p-xxs table-v-center">
|
||||
@@ -198,13 +185,12 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
<section id="{{ applet_data.id }}-licenses">
|
||||
{{ render_h2(l10n("licenses.title", "commons", user_lang)) }}
|
||||
|
||||
{% if is_standalone %}
|
||||
<hr class="subtle">
|
||||
{{ render_paragraph(l10n("licenses.1", applet_data.id, user_lang)) }}
|
||||
{{ render_paragraph(l10n("licenses.2", applet_data.id, user_lang)) }}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
38
templates/applets/png-analyser.jinja
Normal file
38
templates/applets/png-analyser.jinja
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
{{ render_file_input(tool_id + "-test-input", true, ".png, .bmp", true, true) }}
|
||||
|
||||
|
||||
<div class="w-full ox-auto">
|
||||
<table class="table-stylish table-p-s border r-m w-full table-no-wrap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="bkgd-grid30">Offset</th>
|
||||
<th class="bkgd-grid30">Chunk Header</th>
|
||||
<th class="bkgd-grid30">Chunk Data</th>
|
||||
<th class="bkgd-grid30">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="t-monospace">0x0000</td>
|
||||
<td>2</td>
|
||||
<td>2</td>
|
||||
<td>
|
||||
<button class="p-xs r-s border btn-primary">
|
||||
<i class="fa-duotone fa-solid fa-binary"></i><span class="ml-xxs mobile-hide">Hex dump</span>
|
||||
</button>
|
||||
<button class="p-xs r-s border btn-primary">
|
||||
<i class="fa-duotone fa-solid fa-download"></i><span class="ml-xxs mobile-hide">Export</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="t-monospace">0x0010</td>
|
||||
<td>4</td>
|
||||
<td>4</td>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@@ -1,5 +0,0 @@
|
||||
|
||||
{{ render_h2(l10n("upload.title", "commons", user_lang)) }}
|
||||
|
||||
{{ render_file_input("test-input", true, None, true, true) }}
|
||||
|
@@ -9,15 +9,20 @@
|
||||
<label for="uuid-generator-option-count" class="mr-xs">{{ l10n("option.count", "uuid-generator", user_lang) }}:</label>
|
||||
<input id="uuid-generator-option-count" class="p-xxs border r-s" type="number" value="4" min="1" max="1000">
|
||||
|
||||
<br>
|
||||
<hr class="subtle">
|
||||
|
||||
<label for="uuid-generator-option-hyphens" class="mr-xxs">{{ l10n("option.hyphen", "uuid-generator", user_lang) }}:</label>
|
||||
<input id="uuid-generator-option-hyphens" class="r-m border" type="checkbox" checked>
|
||||
<input id="uuid-generator-option-hyphens" class="r-m border cb-pretty" type="checkbox" checked>
|
||||
|
||||
<br>
|
||||
|
||||
<label for="uuid-generator-option-guid-brackets" class="mr-xxs">{{ l10n("option.guid_brackets", "uuid-generator", user_lang) }}:</label>
|
||||
<input id="uuid-generator-option-guid-brackets" class="r-m border" type="checkbox">
|
||||
<input id="uuid-generator-option-guid-brackets" class="r-m border cb-pretty" type="checkbox">
|
||||
|
||||
<br>
|
||||
|
||||
<label for="uuid-generator-option-uppercase" class="mr-xxs">{{ l10n("option.uppercase", "uuid-generator", user_lang) }}:</label>
|
||||
<input id="uuid-generator-option-uppercase" class="r-m border cb-pretty" type="checkbox">
|
||||
|
||||
<hr class="subtle">
|
||||
|
||||
|
295
templates/applets/vat-calculator.jinja
Normal file
295
templates/applets/vat-calculator.jinja
Normal file
@@ -0,0 +1,295 @@
|
||||
{%
|
||||
set all_vat_data = [
|
||||
["afghanistan",
|
||||
[[10, "standard"]], [
|
||||
"https://ard.gov.af/file_download/432/FAQs+of+VAT+English.pdf",
|
||||
]],
|
||||
["austria",
|
||||
[[10, "reduced"],[13, "reduced"],[20, "standard"]], [
|
||||
"https://www.usp.gv.at/en/themen/steuern-finanzen/umsatzsteuer-ueberblick/steuersaetze-und-steuerbefreiungen-der-umsatzsteuer.html",
|
||||
]],
|
||||
["belgium",
|
||||
[[6, "reduced"],[12, "intermediate"],[21, "standard"]], [
|
||||
"https://finance.belgium.be/en/enterprises/vat/vat-obligation/rates-and-calculation/vat-rates",
|
||||
]],
|
||||
["bulgaria",
|
||||
[[9, "reduced"],[20, "standard"]], [
|
||||
"https://www.bulgaria-tax-law.bg/vat-rates-eu-member-states.html"]],
|
||||
["croatia",
|
||||
[[5, "reduced"],[13, "reduced"],[25, "standard"]], [
|
||||
"https://porezna-uprava.gov.hr/en/value-added-tax-h-e-reinafter-vat-information-on-the-general-rules-rates-and-exemptions-registering-for-and-paying-vat-obtaining-a-refund/7313",
|
||||
]],
|
||||
["cyprus",
|
||||
[[3, "reduced"],[5, "reduced"],[9, "reduced"],[19, "standard"]], [
|
||||
"https://www.mof.gov.cy/mof/tax/taxdep.nsf/All/6F2D9F654287FF02C2258251002C8130",
|
||||
]],
|
||||
["czechia",
|
||||
[[12, "reduced"],[21, "standard"]], [
|
||||
"https://portal.gov.cz/en/informace/general-rules-and-vat-rates-INF-205",
|
||||
]],
|
||||
["denmark",
|
||||
[[25, "standard"]], [
|
||||
"https://skat.dk/erhverv/moms/fradrag-for-moms",
|
||||
]],
|
||||
["estonia",
|
||||
[[9, "reduced"],[13, "reduced"],[24, "standard"]], [
|
||||
"https://www.emta.ee/en/business-client/taxes-and-payment/value-added-tax",
|
||||
"https://www.e-resident.gov.ee/blog/posts/a-guide-to-vat-for-e-residents/",
|
||||
]],
|
||||
["finland",
|
||||
[[10, "reduced"],[14, "reduced"],[25.5, "standard"]], [
|
||||
"https://www.vero.fi/en/businesses-and-corporations/taxes-and-charges/vat/rates-of-vat/",
|
||||
]],
|
||||
["france",
|
||||
[[2.1, "reduced"],[5.5, "reduced"],[10, "intermediate"],[20, "standard"]], [
|
||||
"https://www.economie.gouv.fr/cedef/les-fiches-pratiques/quels-sont-les-taux-de-tva-en-vigueur-en-france-et-dans-lunion",
|
||||
]],
|
||||
["france.corsica",
|
||||
[[0.9, "special"],[2.1, "reduced"],[5.5, "reduced"],[10, "intermediate"],[13, "special"],[20, "standard"]], [
|
||||
"https://www.economie.gouv.fr/particuliers/impots-et-fiscalite/gerer-mes-autres-impots-et-taxes/tva-quels-sont-les-taux-de-votre",
|
||||
]],
|
||||
["germany",
|
||||
[[7, "reduced"],[19, "standard"]], [
|
||||
"https://www.bundesfinanzministerium.de/Content/DE/Downloads/BMF_Schreiben/Steuerarten/Umsatzsteuer/Merkblaetter/2024-03-05-Umsatzsteuer-Merkblatt-Personenbefoerderung-Kraftomnibusse-englisch.pdf",
|
||||
]],
|
||||
["greece",
|
||||
[[6, "reduced.super"],[13, "reduced"],[24, "standard"]], [
|
||||
"https://www.gov.gr/en/sdg/taxes/vat/general/basic-vat-rates",
|
||||
]],
|
||||
["hungary",
|
||||
[[5, "preferential"],[18, "preferential"],[27, "standard"]], [
|
||||
"https://nav.gov.hu/pfile/file?path=/en/taxation/taxinfo/vat-liabilities-of-foreign-marketers-in-hungary",
|
||||
]],
|
||||
["ireland",
|
||||
[[4.8, "reduced"],[9, "reduced"],[13.5, "reduced"],[23, "standard"]], [
|
||||
"https://www.revenue.ie/en/vat/vat-rates/search-vat-rates/current-vat-rates.aspx",
|
||||
]],
|
||||
["italy",
|
||||
[[4, "reduced"],[5, "reduced"],[10, "reduced"],[22, "standard"]], [
|
||||
"https://www.agenziaentrate.gov.it/portale/web/english/nse/services/vat-mini-one-stop-shop/faq/vat-rates",
|
||||
"https://www.agenziaentrate.gov.it/portale/web/english/general-vat-rules-and-rates"
|
||||
]],
|
||||
["latvia",
|
||||
[[5, "reduced"],[12, "reduced"],[21, "standard"]], [
|
||||
"https://www.fm.gov.lv/lv/tax-rates",
|
||||
]],
|
||||
["lithuania",
|
||||
[[5, "reduced"],[9, "reduced"],[21, "standard"]], [
|
||||
"https://finmin.lrv.lt/en/competence-areas/taxation/main-taxes/value-added-tax/",
|
||||
]],
|
||||
["luxembourg",
|
||||
[[3, "reduced.super"],[8, "reduced"],[14, "intermediate"],[17, "standard"]], [
|
||||
"https://logistics.public.lu/en/formalities-procedures/taxes/value-added-tax/national-operations.html",
|
||||
]],
|
||||
["malta",
|
||||
[[5, "reduced"],[7, "reduced"],[12, "reduced"],[18, "standard"]], [
|
||||
"https://mtca.gov.mt/business-tax/vat1/vat-compliance/vat-rates/vat-rates",
|
||||
]],
|
||||
["monaco",
|
||||
[[2.1, "reduced"],[5.5, "reduced"],[10, "intermediate"],[20, "standard"]], [
|
||||
"https://monentreprise.gouv.mc/en/themes/accounting-obligations-and-tax/tax/vat",
|
||||
"https://www.economie.gouv.fr/particuliers/impots-et-fiscalite/gerer-mes-autres-impots-et-taxes/tva-quels-sont-les-taux-de-votre"
|
||||
]],
|
||||
["netherlands",
|
||||
[[9, "reduced"],[21, "standard"]], [
|
||||
"https://business.gov.nl/regulation/vat-rates-exemptions/",
|
||||
]],
|
||||
["poland",
|
||||
[[5, "reduced"],[8, "reduced"],[23, "standard"]], [
|
||||
"https://www.podatki.gov.pl/en/value-added-tax/general-vat-rules-and-rates/list-of-vat-rates/",
|
||||
]],
|
||||
["portugal",
|
||||
[[6, "reduced"],[13, "intermediate"],[23, "standard"]], [
|
||||
"https://www2.gov.pt/en/cidadaos-europeus-viajar-viver-e-fazer-negocios-em-portugal/impostos-para-atividades-economicas-em-portugal/imposto-sobre-valor-acrescentado-iva-em-portugal",
|
||||
]],
|
||||
["portugal.azores",
|
||||
[[4, "reduced"],[9, "intermediate"],[16, "standard"]], [
|
||||
"https://www2.gov.pt/en/cidadaos-europeus-viajar-viver-e-fazer-negocios-em-portugal/impostos-para-atividades-economicas-em-portugal/imposto-sobre-valor-acrescentado-iva-em-portugal",
|
||||
]],
|
||||
["portugal.madeira",
|
||||
[[5, "reduced"],[12, "intermediate"],[22, "standard"]], [
|
||||
"https://www2.gov.pt/en/cidadaos-europeus-viajar-viver-e-fazer-negocios-em-portugal/impostos-para-atividades-economicas-em-portugal/imposto-sobre-valor-acrescentado-iva-em-portugal",
|
||||
]],
|
||||
["romania",
|
||||
[[5, "reduced"],[9, "reduced"],[19, "standard"]], [
|
||||
"https://mfinante.gov.ro/referinte-tva",
|
||||
"https://www.mfinante.gov.ro/static/10/Mfp/legislatie/Ghid_TVA_parteaI.htm"
|
||||
]],
|
||||
["slovakia",
|
||||
[[5, "reduced"],[19, "reduced"],[23, "standard"]], [
|
||||
"https://www.slovensko.sk/en/life-situation/life-situation/_value-added-tax/",
|
||||
]],
|
||||
["slovenia",
|
||||
[[9.5, "reduced"],[22, "standard"]], [
|
||||
"https://www.fu.gov.si/en/taxes_and_other_duties/areas_of_work/value_added_tax_vat",
|
||||
]],
|
||||
["spain",
|
||||
[[4, "reduced"],[10, "reduced"],[21, "standard"]], [
|
||||
"https://sede.agenciatributaria.gob.es/Sede/en_gb/iva/calculo-iva-repercutido-clientes/tipos-impositivos-iva.html"
|
||||
"https://sede.agenciatributaria.gob.es/Sede/iva.html",
|
||||
]],
|
||||
["sweden",
|
||||
[[6, "reduced"],[12, "reduced"],[25, "standard"]], [
|
||||
"https://www.skatteverket.se/servicelankar/otherlanguages/englishengelska/businessesandemployers/startingandrunningaswedishbusiness/declaringtaxesbusinesses/vat/vatratesandvatexemption.4.676f4884175c97df419255d.html",
|
||||
]],
|
||||
]
|
||||
%}
|
||||
|
||||
<label for="vat-calculator-preset-short" class="mr-xxs">
|
||||
{{ l10n("preset.label", "vat-calculator", user_lang) }}:
|
||||
</label>
|
||||
<select name="vat-calculator-preset-short" id="vat-calculator-preset-short" class="p-xxs border r-s">
|
||||
<option value="" selected>{{ l10n("rate.option.custom", "vat-calculator", user_lang) }}</option>
|
||||
<hr>
|
||||
|
||||
{% for country_vat_data in all_vat_data %}
|
||||
<optgroup label="{{ l10n("country." + country_vat_data[0], "commons", user_lang) }}">
|
||||
|
||||
{% for country_vat_rate in country_vat_data[1] %}
|
||||
<option value="{{ country_vat_rate[0] }}">
|
||||
{{ country_vat_rate[0] }} %
|
||||
</option>
|
||||
{% endfor %}
|
||||
|
||||
</optgroup>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<label for="vat-calculator-preset-detailed" class="mr-xxs" hidden>
|
||||
{{ l10n("preset.label", "vat-calculator", user_lang) }}:
|
||||
</label>
|
||||
<select name="vat-calculator-preset-detailed" id="vat-calculator-preset-detailed" class="p-xxs border r-s" hidden>
|
||||
<option value="" selected>{{ l10n("rate.option.custom", "vat-calculator", user_lang) }}</option>
|
||||
<hr>
|
||||
|
||||
{% for country_vat_data in all_vat_data %}
|
||||
<optgroup label="{{ l10n("country." + country_vat_data[0], "commons", user_lang) }}">
|
||||
|
||||
{% for country_vat_rate in country_vat_data[1] %}
|
||||
<option value="{{ country_vat_rate[0] }}">
|
||||
{{ country_vat_rate[0] }} % ({{ l10n("rate.type." + country_vat_rate[1], "vat-calculator", user_lang) }})
|
||||
</option>
|
||||
{% endfor %}
|
||||
|
||||
</optgroup>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<span id="vat-calculator-preset-country-echo" class="t-muted ml-xs t-italic mobile-hide"></span>
|
||||
|
||||
<br>
|
||||
|
||||
<label for="vat-calculator-detailed-presets" class="mr-xxs">{{ l10n("option.detailed", "vat-calculator", user_lang) }}:</label>
|
||||
<input id="vat-calculator-detailed-presets" class="r-m border cb-pretty" type="checkbox">
|
||||
|
||||
|
||||
<hr class="subtle">
|
||||
|
||||
<!-- TODO: Implement iframe-able template for multi-instance applets on the same page -->
|
||||
|
||||
<table class="">
|
||||
<tr>
|
||||
<td>
|
||||
<input type="radio" id="vat-calculator-radio-rate" name="vat_calc_target" value="0"
|
||||
class="radio-solid border mr-xxs radio-unchecked-subtle">
|
||||
<label for="vat-calculator-radio-rate">
|
||||
{{ l10n("radio.rate", "vat-calculator", user_lang) }}
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label for="vat-calculator-input-rate" class="mr-xs"></label>
|
||||
<input id="vat-calculator-input-rate" class="p-xxs border r-s" type="number" min="0">
|
||||
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-percent ml-xxs t-muted"></i>{% else %}%{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="pt-xxs">
|
||||
<input type="radio" id="vat-calculator-radio-untaxed" name="vat_calc_target" value="1"
|
||||
class="radio-solid border mr-xxs radio-unchecked-subtle" checked>
|
||||
<label for="vat-calculator-radio-untaxed">
|
||||
{{ l10n("radio.untaxed", "vat-calculator", user_lang) }}
|
||||
</label>
|
||||
</td>
|
||||
<td class="pt-xxs">
|
||||
<label for="vat-calculator-input-untaxed" class="mr-xs"></label>
|
||||
<input id="vat-calculator-input-untaxed" class="p-xxs border r-s bkgd-gray" type="number" min="0" readonly>
|
||||
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-money-bill ml-xxs t-muted"></i>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="pt-xxs">
|
||||
<input type="radio" id="vat-calculator-radio-taxed" name="vat_calc_target" value="2"
|
||||
class="radio-solid border mr-xxs radio-unchecked-subtle">
|
||||
<label for="vat-calculator-radio-taxed">
|
||||
{{ l10n("radio.taxed", "vat-calculator", user_lang) }}
|
||||
</label>
|
||||
</td>
|
||||
<td class="pt-xxs">
|
||||
<label for="vat-calculator-input-taxed" class="mr-xs"></label>
|
||||
<input id="vat-calculator-input-taxed" class="p-xxs border r-s" type="number" min="0">
|
||||
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-money-bill ml-xxs t-muted"></i>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="t-muted ml-xs mt-xs t-italic">{{ l10n("text.radio.explanation", "vat-calculator", user_lang) }}</p>
|
||||
|
||||
|
||||
<hr class="subtle">
|
||||
|
||||
<label for="vat-calculator-rounding-mode" class="mr-xxs">
|
||||
{{ l10n("rounding.mode.label", "vat-calculator", user_lang) }}:
|
||||
</label>
|
||||
<select name="vat-calculator-rounding-mode" id="vat-calculator-rounding-mode" class="p-xxs border r-s">
|
||||
<optgroup label="{{ l10n("rounding.mode.group.regular", "vat-calculator", user_lang) }}">
|
||||
<option value="0" selected>{{ l10n("rounding.mode.up", "vat-calculator", user_lang) }}</option>
|
||||
<option value="1">{{ l10n("rounding.mode.down", "vat-calculator", user_lang) }}</option>
|
||||
<option value="2">{{ l10n("rounding.mode.ceil", "vat-calculator", user_lang) }}</option>
|
||||
<option value="3">{{ l10n("rounding.mode.floor", "vat-calculator", user_lang) }}</option>
|
||||
</optgroup>
|
||||
|
||||
<optgroup label="{{ l10n("rounding.mode.group.half", "vat-calculator", user_lang) }}">
|
||||
<option value="4">{{ l10n("rounding.mode.up.half", "vat-calculator", user_lang) }}</option>
|
||||
<option value="5">{{ l10n("rounding.mode.down.half", "vat-calculator", user_lang) }}</option>
|
||||
<option value="6">{{ l10n("rounding.mode.even.half", "vat-calculator", user_lang) }}</option>
|
||||
<option value="7">{{ l10n("rounding.mode.ceil.half", "vat-calculator", user_lang) }}</option>
|
||||
<option value="8">{{ l10n("rounding.mode.floor.half", "vat-calculator", user_lang) }}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
|
||||
<br>
|
||||
|
||||
<label for="vat-calculator-option-decimal-places" class="mr-xs">{{ l10n("option.decimal-places", "vat-calculator", user_lang) }}:</label>
|
||||
|
||||
<button id="vat-calculator-decimal-places-minus" class="p-xxs border br-0 rl-s {% if is_standalone %}px-xs{% endif %}">
|
||||
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-minus"></i>{% else %}-{% endif %}
|
||||
</button>
|
||||
<input id="vat-calculator-option-decimal-places" class="p-xxs border" type="number" value="2" min="0" max="99">
|
||||
<button id="vat-calculator-decimal-places-plus" class="p-xxs border bl-0 rr-s {% if is_standalone %}px-xs{% endif %}">
|
||||
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-plus"></i>{% else %}+{% endif %}
|
||||
</button>
|
||||
|
||||
<br hidden>
|
||||
|
||||
<label for="vat-calculator-detailed-trim-zeroes" class="mr-xxs" hidden>{{ l10n("option.trim-zeroes", "vat-calculator", user_lang) }}:</label>
|
||||
<input id="vat-calculator-detailed-trim-zeroes" class="r-m border cb-pretty" type="checkbox" hidden>
|
||||
|
||||
|
||||
<!--<hr class="subtle">
|
||||
|
||||
<details class="border bkgd-dark r-m mt-s">
|
||||
<summary class="p-xs">Click to show/hide all classes</summary>
|
||||
<div class="p-xs bt bkgd-grey">
|
||||
<p>
|
||||
<span class="code mr-xs">p-0</span>
|
||||
</p>
|
||||
</div>
|
||||
</details>-->
|
||||
|
||||
{% if is_standalone %}
|
||||
<hr class="subtle">
|
||||
<p class="t-half-muted">
|
||||
{{ l10n("license.text.1", "vat-calculator", user_lang) }}<br>
|
||||
{{ l10n("license.text.2", "vat-calculator", user_lang) }}
|
||||
</p>
|
||||
{% endif %}
|
@@ -7,6 +7,7 @@
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<meta name="author" content="Herwin Bozet">
|
||||
<meta name="robots" content="index, follow">
|
||||
<meta name="theme-color" content="#6F2F65">
|
||||
|
||||
<!-- Note: https://css-tricks.com/probably-dont-base64-svg/ -->
|
||||
<link rel="icon"
|
||||
|
@@ -9,21 +9,20 @@
|
||||
<meta name="robots" content="index, follow">
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="alternate icon" href="/favicon.ico">
|
||||
<meta name="theme-color" content="#6F2F65">
|
||||
|
||||
<!--<link rel="dns-prefetch" href="https://cdn.nibblepoker.lu/"/>-->
|
||||
<link rel="preconnect" href="https://cdn.nibblepoker.lu/"/>
|
||||
<link rel="preconnect" href="https://cdn.nibblepoker.{{ domain_tld }}/"/>
|
||||
|
||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-brands-400.woff2" as="font" />
|
||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-duotone-900.woff2" as="font" />
|
||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-solid-900.woff2" as="font" />
|
||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/NibblePoker/StandardCSS/3px-tile-0.1.png" as="image" />
|
||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/NibblePoker/StandardCSS/3px-tile-0.4.png" as="image" />
|
||||
<link rel="prefetch" href="https://cdn.nibblepoker.{{ domain_tld }}/FontAwesomePro/6.7.2/webfonts/fa-brands-400.woff2" as="font" />
|
||||
<link rel="prefetch" href="https://cdn.nibblepoker.{{ domain_tld }}/FontAwesomePro/6.7.2/webfonts/fa-duotone-900.woff2" as="font" />
|
||||
<link rel="prefetch" href="https://cdn.nibblepoker.{{ domain_tld }}/FontAwesomePro/6.7.2/webfonts/fa-solid-900.woff2" as="font" />
|
||||
{% block extra_preloads %}{% endblock %}
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/FontAwesomePro/6.7.2/css/all.min.css">
|
||||
<!--<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/NibblePoker/StandardCSS/nibblepoker.min.css">-->
|
||||
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/NibblePoker/IndevCSS/nibblepoker.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/Quantum/Quantum.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/NibblePoker/StandardCSS/nibblepoker.min.css">
|
||||
<!--<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/Quantum/Quantum.min.css">-->
|
||||
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/FamFamFam/FlagsExtended/famfamfam-flags.min.css">
|
||||
|
||||
<link rel="stylesheet" href="{{ url_for("static", filename="resources/NibblePoker/css/extra.css") }}">
|
||||
|
||||
@@ -34,6 +33,10 @@
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>{% block head_title %}{% endblock %}</title>
|
||||
|
||||
{% block opengraph_tags %}{% endblock %}
|
||||
|
||||
{% block extra_head_tags %}{% endblock %}
|
||||
</head>
|
||||
<body class="layout-generic">
|
||||
|
||||
@@ -44,21 +47,42 @@
|
||||
<details id="lang-selector" class="border p-mxs px-s bkgd-blank-dark r-m">
|
||||
<summary>
|
||||
<i class="fad fa-language"></i>
|
||||
<span class="mobile-hide t-w-500"> {{ l10n("menu.title", "langs", lang) }}</span>
|
||||
<span class="mobile-hide t-w-500"> {{ l10n("menu.title", "langs", user_lang) }}</span>
|
||||
<i class="fa fa-angle-down"></i>
|
||||
</summary>
|
||||
|
||||
<div class="p-xs border bkgd-surround r-m t-w-500">
|
||||
<a href="{{ l10n_url_switch(request_path, "en") }}" class="a-hidden">
|
||||
<p class="mb-s px-xxs">{{ l10n("english", "langs", lang) }}</p>
|
||||
<table class="w-full table-p-xxs">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ l10n_url_switch(request_path, "en") }}" class="w-full d-inline-block a-hidden">
|
||||
{{ l10n("english", "langs", user_lang) }}
|
||||
</a>
|
||||
<a href="{{ l10n_url_switch(request_path, "fr") }}" class="a-hidden">
|
||||
<p class="my-s px-xxs">{{ l10n("french", "langs", lang) }}</p>
|
||||
</td>
|
||||
<td class="t-center"><i class="famfamfam-flag-us"></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ l10n_url_switch(request_path, "fr") }}" class="w-full d-inline-block a-hidden">
|
||||
{{ l10n("french", "langs", user_lang) }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="t-center"><i class="famfamfam-flag-be"></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<hr class="subtle m-0">
|
||||
<a href="{{ l10n_url_switch(request_path) }}" class="a-hidden">
|
||||
<p class="mt-xs px-xxs">{{ l10n("automatic", "langs", lang) }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ l10n_url_switch(request_path) }}" class="w-full d-inline-block a-hidden">
|
||||
{{ l10n("automatic", "langs", user_lang) }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="t-center"><i class="famfamfam-flag-unknown"></i></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</details>
|
||||
</header>
|
||||
@@ -67,7 +91,7 @@
|
||||
<a href="{{ l10n_url_abs('/', raw_lang) }}" class="no-select">
|
||||
<img class="logo-sidebar-v2"
|
||||
src="https://cdn.nibblepoker.{{ domain_tld }}/NibblePoker/Logos/v2_full_shaded_optimized.svg"
|
||||
alt="{{ l10n("logo.alt", "sidebar", lang) }}"
|
||||
alt="{{ l10n("logo.alt", "sidebar", user_lang) }}"
|
||||
draggable="false">
|
||||
</a>
|
||||
<div class="p-xs"></div>
|
||||
@@ -82,7 +106,7 @@
|
||||
>
|
||||
<p class="t-size-18 t-w-500 py-xs sidebar-entry">
|
||||
<i class="{{ sidebar_entry.icon }} pr-xs t-size-12 t-half-muted"></i>
|
||||
<span class="t-size-12">{{ l10n(sidebar_entry.title_key, "sidebar", lang) }}</span>
|
||||
<span class="t-size-12">{{ l10n(sidebar_entry.title_key, "sidebar", user_lang) }}</span>
|
||||
{% if sidebar_entry.has_new() %}
|
||||
<i class="fa-duotone fa-solid fa-sparkles ml-auto t-size-11 t-muted"></i>
|
||||
{% endif %}
|
||||
@@ -99,18 +123,19 @@
|
||||
</main>
|
||||
|
||||
<footer class="d-flex flex-align-center w-full p-s py-xs">
|
||||
<button id="sidebar-toggle-footer" class="p-xs border r-s t-size-10" aria-label="{{ l10n("alt.sidebar.button", "footer", lang) }}">
|
||||
<button id="sidebar-toggle-footer" class="p-xs border r-s t-size-10"
|
||||
aria-label="{{ l10n("alt.sidebar.button", "footer", user_lang) }}">
|
||||
<i class="fa fa-bars px-xxs" aria-hidden="true"></i>
|
||||
</button>
|
||||
<p class="flex-fill t-center t-size-10 t-w-500 t-muted">
|
||||
<a class="a-hidden" href="{{ l10n_url_abs('/privacy/', raw_lang) }}">
|
||||
{{ l10n("text.privacy", "footer", lang) }}
|
||||
{{ l10n("text.privacy", "footer", user_lang) }}
|
||||
</a>
|
||||
</p>
|
||||
<a href="{{ l10n_url_abs('/', raw_lang) }}">
|
||||
<img id="logo-footer"
|
||||
src="https://cdn.nibblepoker.{{ domain_tld }}/NibblePoker/Logos/v2_full_unshaded_original.svg"
|
||||
alt="{{ l10n("alt.logo", "footer", lang) }}" draggable="false">
|
||||
alt="{{ l10n("alt.logo", "footer", user_lang) }}" draggable="false">
|
||||
</a>
|
||||
</footer>
|
||||
|
||||
|
@@ -76,18 +76,7 @@
|
||||
<section>
|
||||
{{ render_h1(l10n("v2.third.title", "privacy", user_lang), "fad fa-handshake") }}
|
||||
<div class="content-spacer">
|
||||
{{ render_paragraph(l10n("v2.third.intro.1", "privacy", user_lang) +
|
||||
'<br>' + l10n("v2.third.intro.2", "privacy", user_lang)) }}
|
||||
{{ render_paragraph(l10n("v2.third.intro.3", "privacy", user_lang)) }}
|
||||
{{ render_paragraph(l10n('v2.third.intro.4', "privacy", user_lang) +
|
||||
'<br><i class="fad fa-globe ml-s t-size-8 mr-xs"></i>IONOS' +
|
||||
'<a class="ml-s" href="https://www.ionos.fr/terms-gtc/clause-de-confidentialite/">' +
|
||||
l10n('french', "langs", user_lang) + '</a>' +
|
||||
'<a class="ml-s" href="https://www.ionos.com/terms-gtc/privacy-policy/">' +
|
||||
l10n('english', "langs", user_lang) + '</a>' +
|
||||
'<br><i class="fad fa-globe ml-s t-size-8 mr-xs"></i>ChicagoVPS' +
|
||||
'<a class="ml-s" href="https://www.chicagovps.net/wp-content/uploads/2023/07/Terms-and-Conditions-ChicagoVPS.pdf">' +
|
||||
l10n('english', "langs", user_lang) + '</a>') }}
|
||||
{{ render_paragraph(l10n("v3.third.intro.1", "privacy", user_lang)) }}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -105,18 +94,18 @@
|
||||
<div class="content-spacer">
|
||||
{{ render_paragraph(l10n("v2.update.intro.1", "privacy", user_lang)) }}
|
||||
{{ render_paragraph('<i class="fad fa-calendar-alt mr-xs"></i>' + l10n("v2.update.history.1.date", "privacy", user_lang) +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2021-12-04_en.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2021-12-04_en.txt">' +
|
||||
l10n('english', "langs", user_lang) + '</a></span>' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2021-12-04_fr.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2021-12-04_fr.txt">' +
|
||||
l10n('french', "langs", user_lang) + '</a></span>' )}}
|
||||
{{ render_list_ul([
|
||||
l10n('v2.update.history.1.desc.1', "privacy", user_lang)
|
||||
]) }}
|
||||
|
||||
{{ render_paragraph('<i class="fad fa-calendar-alt mr-xs"></i>' + l10n("v2.update.history.2.date", "privacy", user_lang) +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2022-03-18_en.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2022-03-18_en.txt">' +
|
||||
l10n('english', "langs", user_lang) + '</a></span>' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2022-03-18_fr.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2022-03-18_fr.txt">' +
|
||||
l10n('french', "langs", user_lang) + '</a></span>' )}}
|
||||
{{ render_list_ul([
|
||||
l10n('v2.update.history.2.desc.1', "privacy", user_lang),
|
||||
@@ -125,9 +114,9 @@
|
||||
]) }}
|
||||
|
||||
{{ render_paragraph('<i class="fad fa-calendar-alt mr-xs"></i>' + l10n("v2.update.history.3.date", "privacy", user_lang) +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2022-09-09_en.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2022-09-09_en.txt">' +
|
||||
l10n('english', "langs", user_lang) + '</a></span>' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2022-09-09_fr.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2022-09-09_fr.txt">' +
|
||||
l10n('french', "langs", user_lang) + '</a></span>' )}}
|
||||
{{ render_list_ul([
|
||||
l10n('v2.update.history.3.desc.1', "privacy", user_lang),
|
||||
@@ -137,9 +126,9 @@
|
||||
]) }}
|
||||
|
||||
{{ render_paragraph('<i class="fad fa-calendar-alt mr-xs"></i>' + l10n("v2.update.history.4.date", "privacy", user_lang) +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2023-11-11_en.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2023-11-11_en.txt">' +
|
||||
l10n('english', "langs", user_lang) + '</a></span>' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2023-11-11_fr.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2023-11-11_fr.txt">' +
|
||||
l10n('french', "langs", user_lang) + '</a></span>' )}}
|
||||
{{ render_list_ul([
|
||||
l10n('v2.update.history.4.desc.1', "privacy", user_lang),
|
||||
@@ -148,15 +137,25 @@
|
||||
]) }}
|
||||
|
||||
{{ render_paragraph('<i class="fad fa-calendar-alt mr-xs"></i>' + l10n("v2.update.history.5.date", "privacy", user_lang) +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2023-11-30_en.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2023-11-30_en.txt">' +
|
||||
l10n('english', "langs", user_lang) + '</a></span>' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/privacy/privacy_2023-11-30_fr.txt">' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2023-11-30_fr.txt">' +
|
||||
l10n('french', "langs", user_lang) + '</a></span>' )}}
|
||||
{{ render_list_ul([
|
||||
l10n('v2.update.history.5.desc.1', "privacy", user_lang),
|
||||
l10n('v2.update.history.5.desc.2', "privacy", user_lang)
|
||||
]) }}
|
||||
|
||||
{{ render_paragraph('<i class="fad fa-calendar-alt mr-xs"></i>' + l10n("v2.update.history.6.date", "privacy", user_lang) +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2025-03-30_en.txt">' +
|
||||
l10n('english', "langs", user_lang) + '</a></span>' +
|
||||
'<span class="ml-l"><i class="fad fa-globe t-size-8 mr-xxs"></i><a href="/resources/NibblePoker/privacy/privacy_2025-03-30_fr.txt">' +
|
||||
l10n('french', "langs", user_lang) + '</a></span>' )}}
|
||||
{{ render_list_ul([
|
||||
l10n('v2.update.history.6.desc.1', "privacy", user_lang),
|
||||
l10n('v2.update.history.6.desc.2', "privacy", user_lang)
|
||||
]) }}
|
||||
|
||||
{{ render_paragraph(l10n("v2.update.end.2", "privacy", user_lang)) }}
|
||||
</div>
|
||||
</section>
|
||||
|
@@ -14,21 +14,21 @@
|
||||
|
||||
{% block content_listing %}
|
||||
|
||||
{% for project_id, project_data in get_projects().items() %}
|
||||
{% for project_data in get_sorted_projects_by_tags(requested_tags) %}
|
||||
|
||||
<hr class="subtle">
|
||||
|
||||
<!--<div class="p-s border r-m">-->
|
||||
<div class="p-xs r-m">
|
||||
<a href="{{ l10n_url_abs('/content/' + project_id, raw_lang) }}" class="a-hidden">
|
||||
<a href="{{ l10n_url_abs('/content/' + project_data.id, raw_lang) }}" class="a-hidden">
|
||||
<div class="content-search-entry">
|
||||
<img class="content-search-image mr-s r-l"
|
||||
src="{{ url_for("static", filename=project_data.metadata.index.image_url) }}"
|
||||
alt="TODO">
|
||||
<h3 class="mb-xs">
|
||||
{{ l10n(project_data.metadata.index.title_key, project_id, user_lang) }}
|
||||
{{ l10n(project_data.metadata.index.title_key, project_data.id, user_lang) }}
|
||||
</h3>
|
||||
<p>{{ l10n(project_data.metadata.index.preamble_key, project_id, user_lang) }}</p>
|
||||
<p>{{ l10n(project_data.metadata.index.preamble_key, project_data.id, user_lang) }}</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
@@ -12,14 +12,26 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block main_content %}
|
||||
<section>
|
||||
{{ render_h1(l10n("intro.title", "home", user_lang, ["NibblePoker." + domain_tld] )) }}
|
||||
|
||||
<div class="content-spacer">
|
||||
{{ render_paragraph(l10n("intro.text.1", "home", user_lang)) }}
|
||||
{{ render_paragraph(l10n("intro.text.2", "home", user_lang)) }}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
{{ render_h2(l10n("updates.title", "home", user_lang)) }}
|
||||
|
||||
<div class="content-spacer">
|
||||
<p><i class="fad fa-calendar-alt mr-xs"></i>{{ l10n("updates.5.date", "home", user_lang) }}</p>
|
||||
{{ render_list_ul([
|
||||
l10n("updates.5.text.1", "home", user_lang),
|
||||
l10n("updates.5.text.2", "home", user_lang),
|
||||
l10n("updates.text.privacy", "home", user_lang)
|
||||
]) }}
|
||||
|
||||
<p><i class="fad fa-calendar-alt mr-xs mt-s"></i>{{ l10n("updates.4.date", "home", user_lang) }}</p>
|
||||
{{ render_list_ul([
|
||||
l10n("updates.4.text.1", "home", user_lang),
|
||||
@@ -50,6 +62,8 @@
|
||||
l10n("updates.1.text.1", "home", user_lang),
|
||||
l10n("updates.text.privacy", "home", user_lang)
|
||||
]) }}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
@@ -14,20 +14,20 @@
|
||||
|
||||
{% block content_listing %}
|
||||
|
||||
{% for tool_id, tool_data in get_tools().items() %}
|
||||
{% for tool_data in get_sorted_tools_by_tags(requested_tags) %}
|
||||
<hr class="subtle">
|
||||
|
||||
<!--<div class="p-s border r-m">-->
|
||||
<div class="p-xs r-m">
|
||||
<a href="{{ l10n_url_abs('/tools/' + tool_id, raw_lang) }}" class="a-hidden">
|
||||
<a href="{{ l10n_url_abs('/tools/' + tool_data.id, raw_lang) }}" class="a-hidden">
|
||||
<div class="content-search-entry">
|
||||
<img class="content-search-image mr-s r-l"
|
||||
src="{{ url_for("static", filename=tool_data.metadata.index.image_url) }}"
|
||||
alt="TODO">
|
||||
<h3 class="mb-xs">
|
||||
{{ l10n(tool_data.metadata.index.title_key, tool_id, user_lang) }}
|
||||
{{ l10n(tool_data.metadata.index.title_key, tool_data.id, user_lang) }}
|
||||
</h3>
|
||||
<p>{{ l10n(tool_data.metadata.index.preamble_key, tool_id, user_lang) }}</p>
|
||||
<p>{{ l10n(tool_data.metadata.index.preamble_key, tool_data.id, user_lang) }}</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
@@ -23,6 +23,32 @@
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block opengraph_tags %}
|
||||
<!-- Required fields -->
|
||||
<meta property="og:title"
|
||||
content="{{ l10n(tool_data.metadata.opengraph.title_key, tool_id, user_lang) }}">
|
||||
<meta property="og:url"
|
||||
content="{{ "https://nibblepoker." + domain_tld + "/tools/" + tool_id }}">
|
||||
<meta property="og:description"
|
||||
content="{{ l10n(tool_data.metadata.opengraph.description_key, tool_id, user_lang) }}">
|
||||
|
||||
<!-- Optional fields -->
|
||||
{% if tool_data.metadata.opengraph.image_url is not none %}
|
||||
<meta property="og:image"
|
||||
content="{{ "https://nibblepoker." + domain_tld + tool_data.metadata.opengraph.image_url }}">
|
||||
{% if tool_data.metadata.opengraph.image_type is not none %}
|
||||
<meta property="og:image:type"
|
||||
content="{{ tool_data.metadata.opengraph.image_type }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_head_tags %}
|
||||
<meta name="description"
|
||||
content="{{ l10n(tool_data.metadata.head.description_key, tool_id, user_lang) }}">
|
||||
<!--<meta name="keywords" content="HTML, CSS, JavaScript">-->
|
||||
{% endblock %}
|
||||
|
||||
{% block main_content %}
|
||||
{% if not is_standalone %}
|
||||
{{ render_h1(
|
||||
|
@@ -13,6 +13,32 @@
|
||||
<span class="mobile-hide"><span class="mx-s t-size-15">❱</span>{{ l10n(project_data.metadata.general.title_key, project_id, user_lang) }}</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block opengraph_tags %}
|
||||
<!-- Required fields -->
|
||||
<meta property="og:title"
|
||||
content="{{ l10n(project_data.metadata.opengraph.title_key, project_id, user_lang) }}">
|
||||
<meta property="og:url"
|
||||
content="{{ "https://nibblepoker." + domain_tld + "/content/" + project_id }}">
|
||||
<meta property="og:description"
|
||||
content="{{ l10n(project_data.metadata.opengraph.description_key, project_id, user_lang) }}">
|
||||
|
||||
<!-- Optional fields -->
|
||||
{% if project_data.metadata.opengraph.image_url is not none %}
|
||||
<meta property="og:image"
|
||||
content="{{ "https://nibblepoker." + domain_tld + project_data.metadata.opengraph.image_url }}">
|
||||
{% if project_data.metadata.opengraph.image_type is not none %}
|
||||
<meta property="og:image:type"
|
||||
content="{{ project_data.metadata.opengraph.image_type }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_head_tags %}
|
||||
<meta name="description"
|
||||
content="{{ l10n(project_data.metadata.head.description_key, project_id, user_lang) }}">
|
||||
<!--<meta name="keywords" content="HTML, CSS, JavaScript">-->
|
||||
{% endblock %}
|
||||
|
||||
{% block main_content %}
|
||||
{{ render_h1(
|
||||
'<i class="' + project_data.metadata.general.icon + ' t-size-16 mr-s t-muted"></i>' +
|
||||
@@ -37,6 +63,7 @@
|
||||
<script src="https://cdn.nibblepoker.lu/SplideJS/4.1.3/js/splide.min.js"></script>
|
||||
<script src="https://cdn.nibblepoker.lu/HighlightJS/11.9.0-custom/highlight.min.js"></script>
|
||||
|
||||
<script src="{{ url_for("static", filename="resources/NibblePoker/js/nibblepoker-default.min.js") }}"></script>
|
||||
<script src="{{ url_for("static", filename="/resources/NibblePoker/js/nibblepoker-splide.min.js") }}"></script>
|
||||
<script src="{{ url_for("static", filename="/resources/NibblePoker/js/nibblepoker-code.min.js") }}"></script>
|
||||
{% endblock %}
|
||||
|
@@ -25,12 +25,17 @@ def get_projects() -> LockedDict[str, ContentProject]:
|
||||
return __CONTENT.projects
|
||||
|
||||
|
||||
def get_projects_by_tags(tags: list[str]) -> dict[Any, ContentProject]:
|
||||
project_obj: ContentProject
|
||||
return {
|
||||
project_key: project_value for project_key, project_value in __CONTENT.projects.items()
|
||||
if any(tag in project_value.metadata.general.tags for tag in tags)
|
||||
}
|
||||
def get_sorted_projects_by_tags(tags: Optional[list[str]]) -> list[ContentProject]:
|
||||
if tags is None:
|
||||
return sorted(__CONTENT.projects.values(), key=lambda x: x.metadata.index.priority, reverse=True)
|
||||
elif len(tags) == 0:
|
||||
return sorted(__CONTENT.projects.values(), key=lambda x: x.metadata.index.priority, reverse=True)
|
||||
else:
|
||||
returned_list = [
|
||||
x for x in __CONTENT.projects.values()
|
||||
if any(tag in x.metadata.general.tags for tag in tags)
|
||||
]
|
||||
return sorted(returned_list, key=lambda x: x.metadata.index.priority, reverse=True)
|
||||
|
||||
|
||||
def get_projects_by_languages(languages: list[str]) -> dict[Any, ContentProject]:
|
||||
@@ -49,12 +54,17 @@ def get_tools() -> LockedDict[str, ContentTool]:
|
||||
return __CONTENT.tools
|
||||
|
||||
|
||||
def get_tools_by_tags(tags: list[str]) -> dict[Any, ContentProject]:
|
||||
tool_obj: ContentTool
|
||||
return {
|
||||
tool_key: tool_value for tool_key, tool_value in __CONTENT.tools.items()
|
||||
if any(tag in tool_value.metadata.general.tags for tag in tags)
|
||||
}
|
||||
def get_sorted_tools_by_tags(tags: Optional[list[str]]) -> list[ContentProject]:
|
||||
if tags is None:
|
||||
return sorted(__CONTENT.tools.values(), key=lambda x: x.metadata.index.priority, reverse=True)
|
||||
elif len(tags) == 0:
|
||||
return sorted(__CONTENT.tools.values(), key=lambda x: x.metadata.index.priority, reverse=True)
|
||||
else:
|
||||
returned_list = [
|
||||
x for x in __CONTENT.tools.values()
|
||||
if any(tag in x.metadata.general.tags for tag in tags)
|
||||
]
|
||||
return sorted(returned_list, key=lambda x: x.metadata.index.priority, reverse=True)
|
||||
|
||||
|
||||
def sanitize_input_tags(input_tags: str) -> list[str]:
|
||||
@@ -108,30 +118,7 @@ def load_content_items() -> None:
|
||||
__CONTENT.projects[_project.id] = _project
|
||||
#print(_project)
|
||||
|
||||
"""for project_item in os.listdir(os.path.join(os.getcwd(), "data/projects")):
|
||||
project_item_path = os.path.join(os.getcwd(), "data/projects/", project_item)
|
||||
if not os.path.isfile(project_item_path) or project_item.startswith("."):
|
||||
continue
|
||||
|
||||
project_id = Path(project_item_path).stem
|
||||
project_page_path = os.path.join(os.getcwd(), f"templates/projects/{project_id}.jinja")
|
||||
|
||||
if not all(os.path.isfile(project_file) for project_file in
|
||||
[project_item_path, project_page_path]):
|
||||
print(f"Unable to load project '{project_item}' due to missing files !")
|
||||
continue
|
||||
|
||||
try:
|
||||
__CONTENT_PROJECTS[project_id] = ContentProject(
|
||||
id=project_id,
|
||||
metadata=ContentMetadata(**yaml.safe_load(open(project_item_path))),
|
||||
# strings=json.load(open(project_strings_path)) # Deprecated
|
||||
)
|
||||
print(f"Loaded project '{project_id}'")
|
||||
except Exception as e:
|
||||
print(f"Unable to load project '{project_id}' due to an exception !")
|
||||
print(e)"""
|
||||
|
||||
# Loading tools definition files
|
||||
for tools_file in os.listdir(os.path.join(os.getcwd(), "data/tools")):
|
||||
tools_file_path = os.path.join(os.getcwd(), "data/tools", tools_file)
|
||||
if not os.path.isfile(tools_file_path) or tools_file.startswith("."):
|
||||
|
@@ -43,7 +43,7 @@ def reload_strings(strings_root: str) -> None:
|
||||
domain_key = str(Path(lang_domain).with_suffix(''))
|
||||
|
||||
if lang_domain.endswith(".json"):
|
||||
print(f"Loading JSON lang data from '{lang_domain_path}'...")
|
||||
#print(f"Loading JSON lang data from '{lang_domain_path}'...")
|
||||
L10N.add_domain(
|
||||
lang_dir,
|
||||
domain_key,
|
||||
@@ -51,7 +51,7 @@ def reload_strings(strings_root: str) -> None:
|
||||
)
|
||||
|
||||
if lang_domain.endswith(".yml"):
|
||||
print(f"Loading YAML lang data from '{lang_domain_path}'...")
|
||||
#print(f"Loading YAML lang data from '{lang_domain_path}'...")
|
||||
L10N.add_domain(
|
||||
lang_dir,
|
||||
domain_key,
|
||||
|
@@ -5,6 +5,8 @@ from flask import url_for
|
||||
from website.content import ContentApplet
|
||||
|
||||
|
||||
# FIXME: Implement preload support !
|
||||
|
||||
def render_applet_head(applet_data: ContentApplet, is_standalone: bool = False) -> str:
|
||||
applet_style_html = ""
|
||||
|
||||
|
Reference in New Issue
Block a user